#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 #include #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/game_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> 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