jedioutcast/code/encryption/cpp_interface.cpp
2013-04-04 09:52:42 -05:00

419 lines
8 KiB
C++

#include "encryption.h"
#ifdef _ENCRYPTION_
#pragma warning( disable : 4786)
#pragma warning( disable : 4100)
#pragma warning( disable : 4511)
#pragma warning (push, 3) //go back down to 3 for the stl include
#include <map>
#include <string>
#pragma warning (pop)
#include "sockets.h"
#include "cpp_interface.h"
using namespace std;
extern "C" char *Cvar_VariableString( const char *var_name );
const char *GOOD_REQUEST = "GRANTED";
const char *BAD_REQUEST = "DENIED";
static cWinsock Winsock;
class cAuto
{
public:
cAuto(void);
~cAuto(void);
};
cAuto::cAuto(void)
{
Winsock.Init();
};
cAuto::~cAuto(void)
{
Winsock.Shutdown();
};
static cAuto Auto;
const int key_size = 4096;
const int user_size = 256;
const int buffer_size = 131072;
const unsigned short SERVER_PORT = 80;
unsigned char LastKey[key_size];
bool LastKeyValid = false;
class cEncryptedFile
{
private:
unsigned char MainBuffer[buffer_size];
int MainBufferPosition;
int MainBufferSize;
unsigned char Key[key_size];
bool KeyValid;
string FileName;
long FileSize;
long CurrentPosition;
public:
cEncryptedFile(char *InitFileName, long InitSize );
static cEncryptedFile *Create(char *FileName, unsigned char *InitKey = NULL);
bool GetKey(char *KeyUser, char *KeyPassword);
void SetKey(unsigned char *NewKey);
int Read(void *Buffer, int Position, int Amount, FILE *FH = NULL);
void SetPosition(long Offset, int origin);
long GetCurrentPosition(void) { return CurrentPosition; }
};
class cGameConnection : public cConnection
{
private:
cEncryptedFile *File;
public:
cGameConnection(cSocket *Init_Socket, cEncryptedFile *InitFile);
virtual bool ReadCallback(void);
virtual bool WriteCallback(void);
};
cGameConnection::cGameConnection(cSocket *Init_Socket, cEncryptedFile *InitFile)
:cConnection(Init_Socket, NULL, false),
File(InitFile)
{
}
bool cGameConnection::ReadCallback(void)
{
char *token;
bool GoodRequest = false;
bool ValidKey = false;
unsigned char *Key = NULL;
token = strtok((char *)GetBuffer().Get(), " \n\r");
while(token)
{
if (!strcmp(token, "Request:"))
{
token = strtok(NULL, "\n\r");
if (token)
{
printf("Request: '%s'\n", token);
if (!strcmp(token, GOOD_REQUEST))
{
GoodRequest = true;
}
}
}
else if (!strcmp(token, "Key:"))
{
token = strtok(NULL, "\n\r");
if (token)
{
if (token[0] == '\"' && strlen(token) == key_size+2 && token[key_size+1] == '\"')
{
ValidKey = true;
Key = (unsigned char *)token+1;
}
}
}
else
{
break;
}
token = strtok(NULL, " \n\r");
}
if (GoodRequest && ValidKey)
{
File->SetKey(Key);
}
return true;
}
bool cGameConnection::WriteCallback(void)
{
Reading = true;
Buffer.FreeBeforeNextAdd();
return false;
}
cEncryptedFile::cEncryptedFile(char *InitFileName, long InitSize)
:FileName(InitFileName), FileSize(InitSize)
{
MainBufferPosition = -1;
KeyValid = false;
CurrentPosition = 0;
}
cEncryptedFile *cEncryptedFile::Create(char *FileName, unsigned char *InitKey)
{
FILE *FH;
cEncryptedFile *new_file;
char userdata[user_size*2+2];
char KeyUser[user_size], KeyPassword[user_size];
long Size;
FH = fopen(FileName, "rb");
if (!FH)
{
return NULL;
}
fseek(FH, -(long)sizeof(userdata), SEEK_END);
Size = ftell(FH);
if (!InitKey)
{
fread(userdata, 1, sizeof(userdata), FH);
fclose(FH);
strcpy(KeyUser, userdata);
strcpy(KeyPassword, &userdata[strlen(KeyUser)+1]);
new_file = new cEncryptedFile(FileName, Size);
if (!new_file->GetKey(KeyUser, KeyPassword))
{
delete new_file;
return NULL;
}
}
else
{
fclose(FH);
new_file = new cEncryptedFile(FileName, Size);
new_file->SetKey(InitKey);
}
return new_file;
}
bool cEncryptedFile::GetKey(char *KeyUser, char *KeyPassword)
{
cSocket *Socket;
cWinsock Winsock;
cGameConnection *Connection;
unsigned long size;
char temp[256];
HKEY entry;
DWORD dwSize, dwType;
int value;
Winsock.Init();
Socket = new cSocket;
Connection = new cGameConnection(Socket, this);
if (Socket->Connect(204,97,248,145,SERVER_PORT))
{
Connection->Print("User: %s\r\n", KeyUser);
Connection->Print("Password: %s\r\n", KeyPassword);
size = sizeof(temp);
temp[0] = 0;
GetComputerName(temp, &size);
Connection->Print("Info: Computer Name '%s'\r\n", temp);
size = sizeof(temp);
temp[0] = 0;
GetUserName(temp, &size);
Connection->Print("Info: Network User Name '%s'\r\n", temp);
RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Microsoft\\MS Setup (ACME)\\User Info", NULL, KEY_READ, &entry);
dwSize = sizeof(temp);
temp[0] = 0;
value = RegQueryValueEx(entry, "DefCompany", NULL, &dwType, (unsigned char *)temp, &dwSize);
Connection->Print("Info: Company '%s'\r\n", temp);
temp[0] = 0;
value = RegQueryValueEx(entry, "DefName", NULL, &dwType, (unsigned char *)temp, &dwSize);
Connection->Print("Info: Name '%s'\r\n", temp);
RegCloseKey(entry);
extern int Sys_GetProcessorId( void );
Connection->Print("Info: procId: 0x%x\r\n", Sys_GetProcessorId() );
#include "../qcommon/stv_version.h"
Connection->Print("Info: Version '" Q3_VERSION " " __DATE__ "'\r\n");
Connection->Print("\r\n");
while(!Connection->Handle())
{
Sleep(50);
}
}
delete Connection; // delete's Socket
return KeyValid;
}
void cEncryptedFile::SetKey(unsigned char *NewKey)
{
if (!LastKeyValid)
{
memcpy(LastKey, NewKey, key_size);
LastKeyValid = true;
}
memcpy(Key, NewKey, key_size);
KeyValid = true;
}
int cEncryptedFile::Read(void *Buffer, int Position, int Amount, FILE *FH)
{
int total;
unsigned char *pos;
int i;
int offset;
int size;
bool do_close = false;
if (!KeyValid)
{
return -1;
}
if (Position == -1)
{
Position = CurrentPosition;
}
else
{
CurrentPosition = Position;
}
pos = (unsigned char *)Buffer;
total = 0;
offset = Position % key_size;
Position = Position - (Position % key_size);
while(Amount > 0)
{
if (MainBufferPosition == Position)
{
}
else
{
if (!FH)
{
FH = fopen(FileName.c_str(), "rb");
if (!FH)
{
return -1;
}
do_close = true;
}
fseek(FH, Position, SEEK_SET);
MainBufferPosition = Position;
MainBufferSize = fread(MainBuffer, 1, buffer_size, FH);
for(i=0;i<MainBufferSize;i++)
{
// MainBuffer[i] ^= Key[i % key_size];
MainBuffer[i] ^= Key[((Position + i) >> 17) % key_size];
}
}
size = MainBufferSize - offset;
if (size < 0)
{
break;
}
if (size > Amount)
{
size = Amount;
}
memcpy(pos, &MainBuffer[offset], size);
pos += size;
total += size;
Amount -= size;
Position += MainBufferSize;
offset = 0;
}
if (do_close)
{
fclose(FH);
}
CurrentPosition += total;
return total;
}
void cEncryptedFile::SetPosition(long Offset, int origin)
{
switch(origin)
{
case SEEK_SET:
CurrentPosition = Offset;
break;
case SEEK_CUR:
CurrentPosition += Offset;
break;
case SEEK_END:
CurrentPosition = FileSize - Offset;
break;
}
}
void *ENCRYPT_fopen(const char *Name, const char *Mode)
{
cEncryptedFile *File;
File = cEncryptedFile::Create((char *)Name, (LastKeyValid ? LastKey : NULL) );
return File;
}
void ENCRYPT_fclose(void *File)
{
delete (cEncryptedFile *)File;
}
int ENCRYPT_fseek(void *File, long offset, int origin)
{
((cEncryptedFile *)File)->SetPosition(offset, origin);
return 0;
}
size_t ENCRYPT_fread(void *buffer, size_t size, size_t count, void *File)
{
return ((cEncryptedFile *)File)->Read(buffer, -1, size*count) / size;
}
long ENCRYPT_ftell(void *File)
{
return ((cEncryptedFile *)File)->GetCurrentPosition();
}
#endif