// Arminius' protocol utilities ver 0.1 // // Any questions and bugs, mailto: arminius@mail.hwaei.com.tw // ------------------------------------------------------------------- // The following definitions is to define game-dependent codes. // Before compiling, remove the "//". #define __STONEAGE #include "version.h" #include <stdio.h> #include <stdlib.h> #include "autil.h" #include "char.h" #ifdef __STONEAGE #include "lssproto_util.h" #include "common.h" #endif // Nuke 0701 fix char *MesgSlice[SLICE_MAX]; int SliceCount; char PersonalKey[1024*4]; // ------------------------------------------------------------------- // Initialize utilities // BOOL util_Init( void) { int i; for (i=0; i<SLICE_MAX; i++){ MesgSlice[i] = (char *) calloc( 1,SLICE_SIZE); if(MesgSlice[i]==NULL) return FALSE; } SliceCount = 0; strcpysafe(PersonalKey,sizeof( PersonalKey ), getDefaultKey(-1)); return TRUE; } // ------------------------------------------------------------------- // Split up a message into slices by spearator. Store those slices // into a global buffer "char **MesgSlice" // // arg: source=message string; separator=message separator (1 byte) // ret: (none) // WON ADD //void util_SplitMessage(char *source, char *separator) BOOL util_SplitMessage(char *source, char *separator) { if (source && separator) { // NULL input is invalid. char *ptr; char *head = source; // Nuke 1006 : Bug fix while ((ptr = (char *) strstr(head, separator)) && (SliceCount<SLICE_MAX) && (SliceCount>=0)) { ptr[0] = '\0'; if (strlen(head)<SLICE_SIZE) { // discard slices too large // Nuke 0701 // if (*MesgSlice != *dumb) { //print("Warning! Mem may be broken\n"); //} /* if (MesgSlice[SliceCount]==0xffffffff) { print("MesgSlice[%d] broken\n",SliceCount); return FALSE; } else { */ strcpy(MesgSlice[SliceCount], head); SliceCount++; //} } head = ptr+1; } strcpy(source, head); // remove splited slices } return TRUE; } // ------------------------------------------------------------------- // Encode the message // // arg: dst=output src=input // ret: (none) void util_EncodeMessage(char *dst, char *src) { // strcpy(dst, src); // util_xorstring(dst, src); int rn = rand() % 99; int t1, t2; char t3[1024*64], tz[1024*64]; util_swapint(&t1, &rn, "2413"); t2 = t1 ^ 0xffffffff; util_256to64(tz, (char *) &t2, sizeof(int), DEFAULTTABLE); util_shlstring(t3, src, rn); strcat(tz, t3); util_xorstring(dst, tz); } // ------------------------------------------------------------------- // Decode the message // // arg: dst=output src=input // ret: (none) void util_DecodeMessage(char *dst, char *src) { // strcpy(dst, src); // util_xorstring(dst, src); #define INTCODESIZE (sizeof(int)*8+5)/6 int rn; int *t1, t2; char t3[1024*4], t4[1024*4]; // This buffer is enough for an integer. char tz[1024*64]; if (src[strlen(src)-1]=='\n') src[strlen(src)-1]='\0'; util_xorstring(tz, src); // get seed strncpy(t4, tz, INTCODESIZE); t4[INTCODESIZE] = '\0'; util_64to256(t3, t4, DEFAULTTABLE); t1 = (int *) t3; t2 = *t1 ^ 0xffffffff; util_swapint(&rn, &t2, "3142"); util_shrstring(dst, tz + INTCODESIZE, rn); } // ------------------------------------------------------------------- // Get a function information from MesgSlice. A function is a complete // and identifiable message received, beginned at DEFAULTFUNCBEGIN and // ended at DEFAULTFUNCEND. This routine will return the function ID // (Action ID) and how many fields this function have. // // arg: func=return function ID fieldcount=return fields of the function // ret: 1=success 0=failed (function not complete) int util_GetFunctionFromSlice(int *func, int *fieldcount) { char t1[1024*16]; int i; // if (strcmp(MesgSlice[0], DEFAULTFUNCBEGIN)!=0) util_DiscardMessage(); strcpy(t1, MesgSlice[1]); // Robin adjust //*func=atoi(t1); *func=atoi(t1)-13; for (i=0; i<SLICE_MAX; i++) if (strcmp(MesgSlice[i], DEFAULTFUNCEND)==0) { *fieldcount=i-2; // - "&" - "#" - "func" 3 fields return 1; } return 0; // failed: message not complete } void util_DiscardMessage(void) { SliceCount=0; } extern int clisendfunc; void _util_SendMesg(char *file, int line, int fd, int func, char *buffer) { //print("\nfunc=%d,buff=%s\n",func,buffer); // char t1[16384], t2[16384]; char t1[1024*32], t2[1024*32]; clisendfunc=func; // WON ADD if( fd < 0 ){ //print("\n SendMesg fd err %s:%d!! ==> func(%d)\n", file, line, func); return; } // Robin adjust //sprintf(t1, "&;%d%s;#;", func, buffer); sprintf(t1, "&;%d%s;#;", func+23, buffer); util_EncodeMessage(t2, t1); #ifdef __STONEAGE lssproto_Send(fd, t2); #endif } int util_256to64(char *dst, char *src, int len, char *table) { unsigned int dw,dwcounter,i; if (!dst || !src || !table) return 0; dw=0; dwcounter=0; for (i=0; i<len; i++) { dw = ( ((unsigned int)src[i] & 0xff) << ((i%3)*2) ) | dw; dst[ dwcounter++ ] = table[ dw & 0x3f ]; dw = ( dw >> 6 ); if (i%3==2) { dst[ dwcounter++ ] = table[ dw & 0x3f ]; dw = 0; } } if (dw) dst[ dwcounter++ ] = table[ dw ]; dst[ dwcounter ] = '\0'; return dwcounter; } // ------------------------------------------------------------------- // Convert 6-bit strings into 8-bit strings, buffers that store these strings // must have enough space. // // arg: dst=6-bit string; src=8-bit string; table=mapping table // ret: 0=failed >0=bytes converted int util_64to256(char *dst, char *src, char *table) { unsigned int dw,dwcounter,i; char *ptr = NULL; dw=0; dwcounter=0; if (!dst || !src || !table) return 0; for (i=0; i<strlen(src); i++) { ptr = (char *) index(table, src[i]); if (!ptr) return 0; if (i%4) { dw = ((unsigned int)(ptr-table) & 0x3f) << ((4-(i%4))*2) | dw; dst[ dwcounter++ ] = dw & 0xff; dw = dw >> 8; } else { dw = (unsigned int)(ptr-table) & 0x3f; } } if (dw) dst[ dwcounter++ ] = dw & 0xff; dst[ dwcounter ] = '\0'; return dwcounter; } // ------------------------------------------------------------------- // This basically is a 256to64 encoder. But it shifts the result by key. // // arg: dst=6-bit string; src=8-bit string; len=src strlen; // table=mapping table; key=rotate key; // ret: 0=failed >0=bytes converted int util_256to64_shr(char *dst, char *src, int len, char *table, char *key) { unsigned int dw,dwcounter,i,j; if (!dst || !src || !table || !key) return 0; if (strlen(key)<1) return 0; // key can't be empty. dw=0; dwcounter=0; j=0; for (i=0; i<len; i++) { dw = ( ((unsigned int)src[i] & 0xff) << ((i%3)*2) ) | dw; dst[ dwcounter++ ] = table[ ((dw & 0x3f) + key[j]) % 64 ]; // check! j++; if (!key[j]) j=0; dw = ( dw >> 6 ); if (i%3==2) { dst[ dwcounter++ ] = table[ ((dw & 0x3f) + key[j]) % 64 ];// check! j++; if (!key[j]) j=0; dw = 0; } } if (dw) dst[ dwcounter++ ] = table[ (dw + key[j]) % 64 ]; // check! dst[ dwcounter ] = '\0'; return dwcounter; } // ------------------------------------------------------------------- // Decoding function of util_256to64_shr. // // arg: dst=8-bit string; src=6-bit string; table=mapping table; // key=rotate key; // ret: 0=failed >0=bytes converted int util_shl_64to256(char *dst, char *src, char *table, char *key) { unsigned int dw,dwcounter,i,j; char *ptr = NULL; if (!key || (strlen(key)<1)) return 0; // must have key dw=0; dwcounter=0; j=0; if (!dst || !src || !table) return 0; for (i=0; i<strlen(src); i++) { ptr = (char *) index(table, src[i]); if (!ptr) return 0; if (i%4) { // check! dw = ((((unsigned int)(ptr-table) & 0x3f) + 64 - key[j]) % 64) << ((4-(i%4))*2) | dw; j++; if (!key[j]) j=0; dst[ dwcounter++ ] = dw & 0xff; dw = dw >> 8; } else { // check! dw = (((unsigned int)(ptr-table) & 0x3f) + 64 - key[j]) % 64; j++; if (!key[j]) j=0; } } if (dw) dst[ dwcounter++ ] = dw & 0xff; dst[ dwcounter ] = '\0'; return dwcounter; } // ------------------------------------------------------------------- // This basically is a 256to64 encoder. But it shifts the result by key. // // arg: dst=6-bit string; src=8-bit string; len=src strlen; // table=mapping table; key=rotate key; // ret: 0=failed >0=bytes converted int util_256to64_shl(char *dst, char *src, int len, char *table, char *key) { unsigned int dw,dwcounter,i,j; if (!dst || !src || !table || !key) return 0; if (strlen(key)<1) return 0; // key can't be empty. dw=0; dwcounter=0; j=0; for (i=0; i<len; i++) { dw = ( ((unsigned int)src[i] & 0xff) << ((i%3)*2) ) | dw; dst[ dwcounter++ ] = table[ ((dw & 0x3f) + 64 - key[j]) % 64 ]; // check! j++; if (!key[j]) j=0; dw = ( dw >> 6 ); if (i%3==2) { dst[ dwcounter++ ] = table[ ((dw & 0x3f) + 64 - key[j]) % 64 ]; // check! j++; if (!key[j]) j=0; dw = 0; } } if (dw) dst[ dwcounter++ ] = table[ (dw + 64 - key[j]) % 64 ]; // check! dst[ dwcounter ] = '\0'; return dwcounter; } // ------------------------------------------------------------------- // Decoding function of util_256to64_shl. // // arg: dst=8-bit string; src=6-bit string; table=mapping table; // key=rotate key; // ret: 0=failed >0=bytes converted int util_shr_64to256(char *dst, char *src, char *table, char *key) { unsigned int dw,dwcounter,i,j; char *ptr = NULL; if (!key || (strlen(key)<1)) return 0; // must have key dw=0; dwcounter=0; j=0; if (!dst || !src || !table) return 0; for (i=0; i<strlen(src); i++) { ptr = (char *) index(table, src[i]); if (!ptr) return 0; if (i%4) { // check! dw = ((((unsigned int)(ptr-table) & 0x3f) + key[j]) % 64) << ((4-(i%4))*2) | dw; j++; if (!key[j]) j=0; dst[ dwcounter++ ] = dw & 0xff; dw = dw >> 8; } else { // check! dw = (((unsigned int)(ptr-table) & 0x3f) + key[j]) % 64; j++; if (!key[j]) j=0; } } if (dw) dst[ dwcounter++ ] = dw & 0xff; dst[ dwcounter ] = '\0'; return dwcounter; } // ------------------------------------------------------------------- // Swap a integer (4 byte). // The value "rule" indicates the swaping rule. It's a 4 byte string // such as "1324" or "2431". // void util_swapint(int *dst, int *src, char *rule) { char *ptr, *qtr; int i; ptr = (char *) src; qtr = (char *) dst; for (i=0; i<4; i++) qtr[rule[i]-'1']=ptr[i]; } // ------------------------------------------------------------------- // Xor a string. Be careful that your string contains '0xff'. Your // data may lose. // void util_xorstring(char *dst, char *src) { int i; if (strlen(src)>1024*64) return; for (i=0; i<strlen(src); i++){ dst[i]=src[i]^255; } dst[i]='\0'; } // ------------------------------------------------------------------- // Shift the string right. // void util_shrstring(char *dst, char *src, int offs) { char *ptr; if (!dst || !src || (strlen(src)<1)) return; offs = strlen(src) - (offs % strlen(src)); ptr = src+offs; strcpy(dst, ptr); strncat(dst, src, offs); dst[strlen(src)]='\0'; } // ------------------------------------------------------------------- // Shift the string left. // void util_shlstring(char *dst, char *src, int offs) { char *ptr; if (!dst || !src || (strlen(src)<1)) return; offs = offs % strlen(src); ptr = src+offs; strcpy(dst, ptr); strncat(dst, src, offs); dst[strlen(src)]='\0'; } // ------------------------------------------------------------------- // Convert a message slice into integer. Return a checksum. // // arg: sliceno=slice index in MesgSlice value=result // ret: checksum, this value must match the one generated by util_mkint int util_deint(int fd,int sliceno, int *value) { int *t1, t2; char t3[1024*4]; // This buffer is enough for an integer. if (strlen(PersonalKey)==0) strcpy(PersonalKey, getDefaultKey(fd)); util_shl_64to256(t3, MesgSlice[sliceno], DEFAULTTABLE, PersonalKey); t1 = (int *) t3; t2 = *t1 ^ 0xffffffff; util_swapint(value, &t2, "2413"); return *value; } int util_mkint(int fd,char *buffer, int value) { int t1, t2; char t3[1024*4]; if (strlen(PersonalKey)==0) strcpy(PersonalKey, getDefaultKey(fd)); util_swapint(&t1, &value, "3142"); t2 = t1 ^ 0xffffffff; util_256to64_shr(t3, (char *) &t2, sizeof(int), DEFAULTTABLE, PersonalKey); strcat(buffer, ";"); strcat(buffer, t3); return value; } // ------------------------------------------------------------------- // Convert a message slice into string. Return a checksum. // // arg: sliceno=slice index in MesgSlice value=result // ret: checksum, this value must match the one generated by util_mkstring int util_destring(int fd,int sliceno, char *value) { if (strlen(PersonalKey)==0) strcpy(PersonalKey, getDefaultKey(fd)); util_shr_64to256(value, MesgSlice[sliceno], DEFAULTTABLE, PersonalKey); return strlen(value); } // ------------------------------------------------------------------- // Convert a string into buffer (a string). Return a checksum. // // arg: buffer=output value=data to pack // ret: checksum, this value must match the one generated by util_destring int util_mkstring(int fd,char *buffer, char *value) { char t1[SLICE_SIZE]; if (strlen(PersonalKey)==0) strcpy(PersonalKey, getDefaultKey(fd)); util_256to64_shl(t1, value, strlen(value), DEFAULTTABLE, PersonalKey); strcat(buffer, ";"); // It's important to append a SEPARATOR between fields strcat(buffer, t1); return strlen(value); } #ifdef _FIX_LSSP_S_BUG int is_digit(char *str) { uint len = strlen(str); while(len > 0) { if (*str < '0' || *str > '9') { return -1; } str++; len--; } return 0; } #endif