#include #include #include #include #include #include #include #include "crypto.h" static IDEA_KEY key; static IDEA_KEY dkey; static int have_dkey = 0; /* The principal constraint here is that NCSET^NENC must be >= 256^32. This gives us the following table: NENC NCSET 32 256..306 33 217..255 34 185..216 35 160..184 36 139..159 37 122..138 38 107..121 39 95..106 40 85..94 41 76..84 42 69..75 43 62..68 But with only 95 printable ASCII chars, three of which go to syntax (space, [, ]) and three more avoided so that the results can go in an RFC822 comment without mangling ((, ), \), NCSET above 89 is unworkable, which means we can't get NENC below 40. We could pick NCSET=85, as the smallest value which still lets us achieve NENC=40, but by accepting three more characters in encoded tokens, we can get NCSET down to 62, at which point we can avoid anything even the least bit dubious: letters and digits already make 62. */ #define NCSET 62 #define NENC 43 static char cset[NCSET] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; static char txt[ #if NENC > 128 NENC #else 128 #endif +1]; static void settwo(void *vp, unsigned long int v) { ((unsigned char *)vp)[0] = (v >> 8) & 0xff; ((unsigned char *)vp)[1] = v & 0xff; } static void setfour(void *vp, unsigned long int v) { ((unsigned char *)vp)[0] = (v >> 24) & 0xff; ((unsigned char *)vp)[1] = (v >> 16) & 0xff; ((unsigned char *)vp)[2] = (v >> 8) & 0xff; ((unsigned char *)vp)[3] = v & 0xff; } static unsigned long int gettwo(const void *vp) { return( (((const unsigned char *)vp)[0] * 0x0100UL) + (((const unsigned char *)vp)[1] ) ); } static unsigned long int getfour(const void *vp) { return( (((const unsigned char *)vp)[0] * 0x01000000UL) + (((const unsigned char *)vp)[1] * 0x00010000UL) + (((const unsigned char *)vp)[2] * 0x00000100UL) + (((const unsigned char *)vp)[3] ) ); } void init_encryption(const char *keystring) { void *h; char b[20]; struct timeval tv; int i; int j; h = sha1_init(); sha1_process_bytes(h,keystring,strlen(keystring)); sha1_result(h,&b[0]); b[0] ^= b[16]; b[1] ^= b[17]; b[2] ^= b[18]; b[3] ^= b[19]; idea_setkey_e(&b[0],&key); gettimeofday(&tv,0); h = sha1_init(); sha1_process_bytes(h,keystring,strlen(keystring)); sha1_process_bytes(h,&b[0],20); sha1_result(h,&b[0]); for (i=0;is_addr)); setfour(&d[8],ntohl(fa->s_addr)); settwo(&d[12],lp); settwo(&d[14],fp); setfour(&d[16],uid); setfour(&d[20],0); hh = sha1_init(); sha1_process_bytes(hh,&d[0],24); sha1_result(hh,&h[0]); bzero(&h[20],4); setfour(&e[0],0); setfour(&e[4],tv.tv_usec); for (i=0;i<24;i+=8) { idea_crypt(&e[0],&key,&e[0]); for (j=0;j<8;j++) e[j] ^= h[i+j]; } idea_crypt(&e[0],&key,&e[0]); bcopy(&e[0],&bin[0],8); for (i=0;i<24;i+=8) { for (j=0;j<8;j++) e[j] ^= d[i+j]; idea_crypt(&e[0],&key,&e[0]); bcopy(&e[0],&bin[i+8],8); } k = 31; for (i=0;i=0;j--) { r = (r * 256) + bin[j]; bin[j] = r / NCSET; r %= NCSET; } txt[i] = cset[r]; if ((k >= 0) && !bin[k]) k --; } if (k != -1) { fprintf(stderr,"panic: NENC too small (256^32 vs %d^%d)\n",NCSET,NENC); abort(); } txt[NENC] = '\0'; return(&txt[0]); } const char *crack_packet(const char *s) { int l; int i; int j; int k; unsigned char bin[32]; char e[8]; char d[24]; int p; char *cp; char h[24]; void *hh; time_t tt; struct tm *tm; char ltxt[64]; char ftxt[64]; struct in_addr ia; if (! have_dkey) { idea_keycvt_e_to_d(&key,&dkey); have_dkey = 1; } l = strlen(s); if ((l == NENC+2) && (s[0] == '[') && (s[l-1] == ']')) { s ++; } else if (l != NENC) { return("length wrong"); } for (i=0;i=0;i--) { p = txt[i]; for (j=0;j>= 8; } if (p) { if (k >= 32) return("overflow"); bin[k++] = p; } } for (;k<32;k++) bin[k] = 0; for (i=16;i>=0;i-=8) { idea_crypt(&bin[i+8],&dkey,&e[0]); for (j=0;j<8;j++) d[i+j] = e[j] ^ bin[i+j]; } if (getfour(&d[20])) return("checksum 1 wrong"); idea_crypt(&bin[0],&dkey,&e[0]); hh = sha1_init(); sha1_process_bytes(hh,&d[0],24); sha1_result(hh,&h[0]); bzero(&h[20],4); for (i=16;i>=0;i-=8) { for (j=0;j<8;j++) e[j] ^= h[i+j]; idea_crypt(&e[0],&dkey,&e[0]); } if (getfour(&e[0])) return("checksum 2 wrong"); ia.s_addr = htonl(getfour(&d[4])); strcpy(<xt[0],inet_ntoa(ia)); ia.s_addr = htonl(getfour(&d[8])); strcpy(&ftxt[0],inet_ntoa(ia)); tt = getfour(&d[0]); tm = localtime(&tt); i = strftime(&txt[0],sizeof(txt),"%Y-%m-%d %H:%M:%S",tm); i += snprintf(&txt[i],sizeof(txt)-i,".%06lu %lu %s/%lu %s/%lu",getfour(&e[4]),getfour(&d[16]),<xt[0],gettwo(&d[12]),&ftxt[0],gettwo(&d[14])); if (i >= sizeof(txt)) return("buffer overflow"); txt[i] = '\0'; return(&txt[0]); }