/* Tony Watson (aka Alascom) 11 Nov 2003

   Spoofer for Call of Duty (CoD) authorization server.
   Listens on UDP 20500 for client and server requests and
   replies to server requests to authorize a client IP.
   Not sure if its all implemented correctly, but it appears to
   be working good.  All the clients can use the same valid CD-Key
   or multiple valid CD-Keys.  

   INSTALL:  compile and run this program on any Unix system.  Then
   add a static host entry on the server in the
   \%SystemRoot%\SYSTEM32\DRIVERS\ETC\HOSTS file pointing
   codauthorize.activision.com to your Unix box's IP address.
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/uio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

void parse(char *buf);
void command(char *buf, char *s,int * rval);

int udpSocket = 0, clientLength = 0;
struct sockaddr_in serverName = { 0 },
                   clientName = { 0 };

int main(int argc, char *argv[])
{
        int myPort = 0,
            status = 0,
            size = 0,
            i = 0,
            c = 0,
            check = 0,
	    rc = 0,
	    val = 0;
	char mesgin[1024000] = "";
	char * mesginptr = mesgin;
	char mesgout[1024000] = "";
	char * mesgoutptr = mesgout;
	char serial[128] = "NULL";
        char * pserial = serial;

	myPort = 20500;
	clientLength = sizeof(clientName);
	udpSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	memset(&serverName, 0, sizeof(serverName));
	memset(&clientName, 0, sizeof(clientName));
	serverName.sin_family = AF_INET;
	serverName.sin_addr.s_addr = htonl(INADDR_ANY);
	serverName.sin_port = htons(myPort);
	status = bind(udpSocket, (struct sockaddr *) &serverName,
		     sizeof(serverName));
	for(;;)
	{
	  bzero(mesgin, sizeof(mesgin));
	  size = recvfrom(udpSocket, mesgin, sizeof(mesgin), 0,
                         (struct sockaddr *) &clientName, &clientLength);
	  if ( size > 1024000 ) size = 1024000;
          parse(mesgin);
          val=0;
          command(mesgin,pserial,&val);
          bzero(mesgout, sizeof(mesgout));
          if (val<1||val>2) {
	    sprintf(mesgout,"    What-chu talk'n 'bout Willis?");
	    }
	  if (val==1) {
            sprintf(mesgout,"    ipAuthorize %s accept KEY_IS_GOOD 163122 ",serial);
            mesgout[sizeof(mesgout)]=0x00;  /*tcpdump showed trailing 0x00 */
	    }
          if (val==2) {
	    sprintf(mesgout,"    Thanks for the cd-key %s",serial);
            }
          i=strlen(mesgout);
          mesgout[0]=0xff;
          mesgout[1]=0xff;
          mesgout[2]=0xff;
          mesgout[3]=0xff;
          sendto(udpSocket, mesgout, i, 0,
	        (struct sockaddr *) &clientName, clientLength);
          printf("SENT: %s\n",mesgout);
	}
return 0;
}

void parse(char * buf)
{
int i=0;
int j=0;
int size;
char f1[128];
size=strlen(buf);
printf("GOT : ");
for(i=0;i<size;i++) {
  printf("%c",buf[i]);
  }
printf("\n");
}

void command(char *buf, char *s,int * rval)
{
int i;
int j;
int size;
char *l;
char command[128]="";
char * pcommand=command;
char getkey[128] = "    getKeyAuthorize";
char getip[128] = "    getIpAuthorize";
char * pgetkey = getkey;
char * pgetip = getip;
char f1[128];
getkey[0]=0xff;
getkey[1]=0xff;
getkey[2]=0xff;
getkey[3]=0xff;
getip[0]=0xff;
getip[1]=0xff;
getip[2]=0xff;
getip[3]=0xff;
size=strlen(buf);
l=strchr(buf,' ');
j=l-buf;
strncpy(command,buf,j);
if (strcmp(pgetip,command)) {
  *rval=2;
  }
if (strcmp(pgetkey,command)) {
  *rval=1;
  }
for(i=0;i<size;i++) { if (buf[i]==0x20) break; }
j=0;
for(i++;i<size;i++) {
  if (buf[i]!=0x20) {
    sprintf(f1+j,"%c",buf[i]);
    }
  else {
    sprintf(f1+j,"%c",0); 
    }
  j++;
  }
strcpy(s,f1);
return;
}

