Initial commit.

This commit is contained in:
Jim Gray
2013-04-04 14:32:05 -07:00
parent ba5c81da32
commit d71d53e8ec
2180 changed files with 1393544 additions and 1 deletions

View File

@@ -0,0 +1,99 @@
#include "encryption.h"
#ifdef _ENCRYPTION_
#pragma warning (disable : 4514) //unref inline removed
#pragma warning (disable : 4711) //func selected for auto inline
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "buffer.h"
const int BufferIncrease = 1024;
cBuffer::cBuffer(int InitIncrease)
:Buffer(NULL),
Size(0),
Pos(0),
ActualSize(0),
FreeNextAdd(false)
{
Increase = InitIncrease;
}
char *cBuffer::Add(char *Data, int Amount)
{
if (FreeNextAdd)
{
Free();
FreeNextAdd = false;
}
if (Pos + Amount >= ActualSize)
{
ActualSize += Amount;
ActualSize -= ActualSize % Increase;
ActualSize += Increase;
Buffer = (char *)realloc(Buffer, ActualSize);
}
if (Data)
{
memcpy(Buffer+Pos, Data, Amount);
}
Pos += Amount;
Size += Amount;
return Buffer + Pos - Amount;
}
void cBuffer::Read(void)
{
ResetPos();
}
char *cBuffer::Read(int Amount)
{
Pos += Amount;
if (Pos < Size)
{
return Buffer + Pos - Amount;
}
return NULL;
}
size_t cBuffer::strcspn(const char *notin)
{
const char *s1, *s2;
for (s1 = Buffer+Pos; *s1; s1++)
{
for(s2 = notin; *s2 != *s1 && *s2; s2++)
{
}
if (*s2)
{
break;
}
}
return s1 - Buffer + Pos;
}
void cBuffer::Free(void)
{
if (Buffer)
{
free(Buffer);
Buffer = NULL;
Size= 0;
Pos = 0;
ActualSize = 0;
}
}
#endif

View File

@@ -0,0 +1,37 @@
#ifndef __BUFFER_H
#define __BUFFER_H
extern const int BufferIncrease;
class cBuffer
{
private:
char *Buffer;
int Size, ActualSize, Pos;
bool FreeNextAdd;
int Increase;
public:
cBuffer(int InitIncrease = BufferIncrease);
~cBuffer(void) { Free(); }
const char *Get(void) { return Buffer; }
const char *GetWithPos(void) { return Buffer + Pos; }
const int GetSize(void) { return Size; }
const int GetRemaining(void) { return Size - Pos; }
void FreeBeforeNextAdd(void) { FreeNextAdd = true; }
void ResetPos(void) { Pos = 0; }
void ResetSize(void) { Size = 0; }
char *Add(char *Data, int Amount);
void Read(void);
char *Read(int Amount);
bool ValidPos(void) { return (Pos < Size); }
size_t strcspn(const char *notin);
void Free(void);
};
#endif // __BUFFER_H

View File

@@ -0,0 +1,419 @@
#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/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<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

View File

@@ -0,0 +1,20 @@
#ifndef __CPP_INTERFACE_H
#define __CPP_INTERFACE_H
#ifdef __cplusplus
extern "C"
{
#endif
void *ENCRYPT_fopen(const char *Name, const char *Mode);
void ENCRYPT_fclose(void *File);
int ENCRYPT_fseek(void *File, long offset, int origin);
size_t ENCRYPT_fread(void *buffer, size_t size, size_t count, void *File);
long ENCRYPT_ftell(void *File);
#ifdef __cplusplus
}
#endif
#endif // __CPP_INTERFACE_H

View File

@@ -0,0 +1,6 @@
//Pakinator Main Header
//define this to enable all pak files encryption requirements
#ifdef FINAL_BUILD
//#define _ENCRYPTION_
#endif

View File

@@ -0,0 +1,427 @@
#include "encryption.h"
#ifdef _ENCRYPTION_
#include <stdio.h>
#include "sockets.h"
class cWinsock Winsock;
cSocket::cSocket(void)
{
Socket = INVALID_SOCKET;
}
cSocket::cSocket(SOCKET InitSocket)
:Socket(InitSocket)
{
}
cSocket::~cSocket(void)
{
Free();
}
void cSocket::Free(void)
{
if (Socket != INVALID_SOCKET)
{
shutdown(Socket, 2); // 2 = SD_BOTH which is defined for winsock2
closesocket(Socket);
Socket = INVALID_SOCKET;
}
}
bool cSocket::socket(int af, int type, int protocol)
{
Socket = ::socket(af, type, protocol);
return (Socket != INVALID_SOCKET);
}
bool cSocket::bind(const struct sockaddr FAR *name, int namelen)
{
if (Socket == INVALID_SOCKET)
{
return false;
}
return (::bind(Socket, name, namelen) != SOCKET_ERROR);
}
bool cSocket::listen(int backlog)
{
if (Socket == INVALID_SOCKET)
{
return false;
}
return (::listen(Socket, backlog) != SOCKET_ERROR);
}
SOCKET cSocket::accept(struct sockaddr FAR *addr, int FAR *addrlen)
{
if (Socket == INVALID_SOCKET)
{
return INVALID_SOCKET;
}
return ::accept(Socket, addr, addrlen);
}
bool cSocket::connect(struct sockaddr FAR *addr, int FAR addrlen)
{
if (Socket == INVALID_SOCKET)
{
return false;
}
return (::connect(Socket, addr, addrlen) != SOCKET_ERROR);
}
int cSocket::recv(char FAR *buf, int len, int flags)
{
if (Socket == INVALID_SOCKET)
{
return INVALID_SOCKET;
}
return ::recv(Socket, buf, len, flags);
}
int cSocket::send(const char FAR *buf, int len, int flags)
{
if (Socket == INVALID_SOCKET)
{
return INVALID_SOCKET;
}
return ::send(Socket, buf, len, flags);
}
bool cSocket::ioctlsocket(long cmd, u_long FAR *argp)
{
if (Socket == INVALID_SOCKET)
{
return false;
}
return (::ioctlsocket(Socket, cmd, argp) != SOCKET_ERROR);
}
bool cSocket::setsockopt(int level, int optname, const char FAR *optval, int optlen)
{
if (Socket == INVALID_SOCKET)
{
return false;
}
return (::setsockopt(Socket, level, optname, optval, optlen) != SOCKET_ERROR);
}
int cSocket::getsockopt(int level, int optname, char FAR *optval, int FAR *optlen)
{
if (Socket == INVALID_SOCKET)
{
return false;
}
return ::getsockopt(Socket, level, optname, optval, optlen);
}
bool cSocket::getpeername(struct sockaddr FAR *name, int FAR *namelen)
{
if (Socket == INVALID_SOCKET)
{
return false;
}
return (::getpeername(Socket, name, namelen) != SOCKET_ERROR);
}
bool cSocket::Create(u_short Port)
{
struct sockaddr_in addr;
addr.sin_port = Winsock.htons(Port);
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_family = PF_INET;
Free();
if (socket())
{
if (bind((const struct sockaddr *)&addr, sizeof(addr)))
{
return true;
}
Free();
}
return false;
}
bool cSocket::Connect(unsigned char U1, unsigned char U2, unsigned char U3, unsigned char U4, unsigned short Port)
{
struct sockaddr_in addr;
addr.sin_port = Winsock.htons(Port);
addr.sin_addr.s_net = U1;
addr.sin_addr.s_host = U2;
addr.sin_addr.s_lh = U3;
addr.sin_addr.s_impno = U4;
addr.sin_family = PF_INET;
Free();
if (socket())
{
if (connect((struct sockaddr *)&addr, sizeof(addr)))
{
return true;
}
Free();
}
return false;
}
cSocket *cSocket::GetConnection(void)
{
SOCKET new_socket;
new_socket = accept();
if (new_socket != INVALID_SOCKET)
{
return new cSocket(new_socket);
}
return NULL;
}
bool cSocket::SetBlocking(bool Enabled)
{
unsigned long blockval = (Enabled != true);
return ioctlsocket(FIONBIO, &blockval);
}
bool cSocket::SetKeepAlive(bool Enabled)
{
int keepaliveval = (Enabled == true);
return setsockopt(SOL_SOCKET, SO_KEEPALIVE, (char*)&keepaliveval, sizeof(keepaliveval));
}
bool cSocket::SetLinger(bool Enabled, u_short TimeLimit)
{
struct linger lingerval;
lingerval.l_onoff = (Enabled == true);
lingerval.l_linger = TimeLimit;
return setsockopt(SOL_SOCKET, SO_LINGER, (char*)&lingerval, sizeof(lingerval));
}
bool cSocket::SetSendBufferSize(int Size)
{
return setsockopt(SOL_SOCKET, SO_SNDBUF, (char*)&Size, sizeof(Size));
}
cConnection::cConnection(cSocket *Init_Socket, Connect_Callback InitCallback, bool InitReading)
:Socket(Init_Socket),
Callback(InitCallback),
Reading(InitReading)
{
BufferReset = false;
}
cConnection::~cConnection(void)
{
if (Socket)
{
delete Socket;
}
}
void cConnection::Print(char *Format, ...)
{
char temp[1024];
va_list argptr;
int size;
va_start (argptr, Format);
size = _vsnprintf (temp, sizeof(temp), Format, argptr);
va_end (argptr);
Buffer.Add(temp, size);
}
bool cConnection::Read(void)
{
char temp[8193];
int size;
size = Socket->recv(temp, sizeof(temp)-1);
if (size >= 0)
{
Buffer.Add(temp, size);
temp[size] = 0;
}
if (Buffer.Get() && strstr(Buffer.Get(), "\r\n\r\n"))
{ // found the blank line
temp[0] = 0;
Buffer.Add(temp, 1);
Reading = false;
Buffer.FreeBeforeNextAdd();
if (Callback)
{
Callback(this);
}
return ReadCallback();
}
return false;
}
bool cConnection::Write(void)
{
int size;
if (!BufferReset)
{
BufferReset = true;
Buffer.Read();
}
size = Socket->send(Buffer.GetWithPos(), Buffer.GetRemaining() );
if (size != SOCKET_ERROR)
{
if (!Buffer.Read(size))
{
return WriteCallback();
}
}
return false;
}
bool cConnection::Handle(void)
{
if (Reading)
{
return Read();
}
else
{
return Write();
}
}
cWinsock::cWinsock(void)
{
WinsockStarted = false;
}
cWinsock::~cWinsock(void)
{
Shutdown();
}
void cWinsock::Init(void)
{
WSADATA dat;
int rv;
if (WinsockStarted)
{
return;
}
#ifdef _USE_WINSOCK2_
rv = WSAStartup(MAKEWORD(2,0), &dat);
#else
rv = WSAStartup(MAKEWORD(1,1), &dat);
#endif
if (rv == 0)
{
WinsockStarted = true;
}
}
void cWinsock::Shutdown(void)
{
if (WinsockStarted)
{
WSACleanup();
WinsockStarted = false;
}
}
struct servent FAR *cWinsock::getservbyname(const char FAR *name, const char FAR *proto)
{
return ::getservbyname(name, proto);
}
u_short cWinsock::htons(u_short hostshort)
{
return ::htons(hostshort);
}
struct hostent FAR *cWinsock::gethostbyaddr(const char FAR *addr, int len, int type)
{
return ::gethostbyaddr(addr, len, type);
}
#endif

View File

@@ -0,0 +1,95 @@
#ifndef __SOCKETS_H
#define __SOCKETS_H
#include <windows.h>
#include <winsock.h>
#include "buffer.h"
class cSocket
{
private:
SOCKET Socket;
public:
cSocket(void);
cSocket(SOCKET InitSocket);
~cSocket(void);
const SOCKET GetSocket(void) { return Socket; }
void Free(void);
// straight winsock commands
bool socket(int af = PF_INET, int type = SOCK_STREAM, int protocol = IPPROTO_TCP);
bool bind(const struct sockaddr FAR *name, int namelen);
bool listen(int backlog = 5);
SOCKET accept(struct sockaddr FAR *addr = NULL, int FAR *addrlen = 0);
bool connect(struct sockaddr FAR *addr, int FAR addrlen);
int recv(char FAR *buf, int len, int flags = 0);
int send(const char FAR *buf, int len, int flags = 0);
bool ioctlsocket(long cmd, u_long FAR *argp);
bool setsockopt(int level, int optname, const char FAR *optval, int optlen);
int getsockopt(int level, int optname, char FAR *optval, int FAR *optlen);
bool getpeername(struct sockaddr FAR *name, int FAR *namelen);
bool getpeername(struct sockaddr_in FAR *name, int FAR *namelen)
{
return getpeername((struct sockaddr FAR *)name, namelen);
}
// convience functions
bool Create(u_short Port);
bool Connect(unsigned char u1, unsigned char u2, unsigned char u3, unsigned char u4, unsigned short port);
cSocket *GetConnection(void);
bool SetBlocking(bool Enabled = false);
bool SetKeepAlive(bool Enabled = false);
bool SetLinger(bool Enabled = true, u_short TimeLimit = 0);
bool SetSendBufferSize(int Size);
};
class cConnection;
typedef void (*Connect_Callback)(cConnection *);
class cConnection
{
protected:
cSocket *Socket;
bool Reading;
bool BufferReset;
cBuffer Buffer;
Connect_Callback Callback;
public:
cConnection(cSocket *Init_Socket, Connect_Callback InitCallback = NULL, bool InitReading = true);
~cConnection(void);
cBuffer &GetBuffer(void) { return Buffer; }
void Print(char *Format, ...);
bool Write(void);
bool Read(void);
bool Handle(void);
virtual bool ReadCallback(void) { return true; }
virtual bool WriteCallback(void) { return true; }
};
class cWinsock
{
private:
bool WinsockStarted;
public:
cWinsock(void);
~cWinsock(void);
void Init(void);
void Shutdown(void);
struct servent FAR *getservbyname(const char FAR *name, const char FAR *proto = "tcp");
u_short htons(u_short hostshort);
struct hostent FAR *gethostbyaddr(const char FAR *addr, int len, int type = PF_INET);
};
#endif // __SOCKETS_H