00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 #include <stdio.h>
00029 #include <string.h>
00030 #include <stdlib.h>
00031 
00032 #include <sys/utsname.h>  
00033 #include <sys/time.h>     
00034 #include <unistd.h>
00035 #include <ctype.h>
00036 
00037 typedef unsigned char *POINTER;   
00038 typedef unsigned short int UINT2; 
00039 typedef unsigned long int UINT4;  
00040 
00041 
00042 
00043 typedef struct {
00044   UINT4 state[4];                                        
00045   UINT4 count[2];             
00046   unsigned char buffer[64];                              
00047 } MD5_CTX;
00048 
00049 
00050 
00051 
00052 static void MD5Init (MD5_CTX *);
00053 static void MD5Update (MD5_CTX *, unsigned char *, unsigned int);
00054 static void MD5Final (unsigned char [16], MD5_CTX *);
00055 
00056 static void MD5Transform (UINT4 [4], unsigned char [64]);
00057 static void Encode (unsigned char *, UINT4 *, unsigned int);
00058 static void Decode (UINT4 *, unsigned char *, unsigned int);
00059 
00060 
00061 
00062 #define S11 7
00063 #define S12 12
00064 #define S13 17
00065 #define S14 22
00066 #define S21 5
00067 #define S22 9
00068 #define S23 14
00069 #define S24 20
00070 #define S31 4
00071 #define S32 11
00072 #define S33 16
00073 #define S34 23
00074 #define S41 6
00075 #define S42 10
00076 #define S43 15
00077 #define S44 21
00078 
00079 static unsigned char PADDING[64] = {
00080   0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00081   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00082   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00083 };
00084 
00085 
00086 
00087 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
00088 #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
00089 #define H(x, y, z) ((x) ^ (y) ^ (z))
00090 #define I(x, y, z) ((y) ^ ((x) | (~z)))
00091 
00092 
00093 
00094 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
00095 
00096 
00097 
00098 
00099 #define FF(a, b, c, d, x, s, ac) { \
00100  (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
00101  (a) = ROTATE_LEFT ((a), (s)); \
00102  (a) += (b); \
00103   }
00104 
00105 #define GG(a, b, c, d, x, s, ac) { \
00106  (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
00107  (a) = ROTATE_LEFT ((a), (s)); \
00108  (a) += (b); \
00109   }
00110 
00111 #define HH(a, b, c, d, x, s, ac) { \
00112  (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
00113  (a) = ROTATE_LEFT ((a), (s)); \
00114  (a) += (b); \
00115   }
00116 
00117 #define II(a, b, c, d, x, s, ac) { \
00118  (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
00119  (a) = ROTATE_LEFT ((a), (s)); \
00120  (a) += (b); \
00121   }
00122 
00123 
00124 
00125 
00126 
00127 static void MD5Init (MD5_CTX * context)
00128 {
00129   context->count[0] = context->count[1] = 0;
00130 
00131   
00132 
00133   context->state[0] = 0x67452301;
00134   context->state[1] = 0xefcdab89;
00135   context->state[2] = 0x98badcfe;
00136   context->state[3] = 0x10325476;
00137 }
00138 
00139 
00140 
00141 
00142 
00143 
00144 
00145 static void MD5Update (MD5_CTX * context, unsigned char * input,
00146                                           unsigned int inputLen  )
00147 {
00148   unsigned int i, index, partLen;
00149 
00150   
00151 
00152   index = (unsigned int)((context->count[0] >> 3) & 0x3F);
00153 
00154   
00155 
00156   if( (context->count[0] += ((UINT4)inputLen << 3)) < ((UINT4)inputLen << 3) )
00157     context->count[1]++;
00158 
00159   context->count[1] += ((UINT4)inputLen >> 29);
00160 
00161   partLen = 64 - index;
00162 
00163   
00164 
00165   if (inputLen >= partLen) {
00166 
00167    memcpy ((POINTER)&context->buffer[index], (POINTER)input, partLen);
00168 
00169    MD5Transform (context->state, context->buffer);
00170 
00171    for (i = partLen; i + 63 < inputLen; i += 64)
00172      MD5Transform (context->state, &input[i]);
00173 
00174    index = 0;
00175   }
00176   else
00177    i = 0;
00178 
00179   
00180 
00181   memcpy ((POINTER)&context->buffer[index], (POINTER)&input[i],
00182           inputLen-i);
00183 }
00184 
00185 
00186 
00187 
00188 
00189 
00190 static void MD5Final (unsigned char digest[16], MD5_CTX * context)
00191 {
00192   unsigned char bits[8];
00193   unsigned int index, padLen;
00194 
00195   
00196 
00197   Encode (bits, context->count, 8);
00198 
00199   
00200 
00201   index = (unsigned int)((context->count[0] >> 3) & 0x3f);
00202   padLen = (index < 56) ? (56 - index) : (120 - index);
00203   MD5Update (context, PADDING, padLen);
00204 
00205   
00206 
00207   MD5Update (context, bits, 8);
00208 
00209   
00210 
00211   Encode (digest, context->state, 16);
00212 
00213   
00214 
00215   memset ((POINTER)context, 0, sizeof (*context));
00216 }
00217 
00218 
00219 
00220 
00221 
00222 static void MD5Transform (UINT4 state[4], unsigned char block[64])
00223 {
00224   UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
00225 
00226   Decode (x, block, 64);
00227 
00228   
00229 
00230   FF (a, b, c, d, x[ 0], S11, 0xd76aa478); 
00231   FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); 
00232   FF (c, d, a, b, x[ 2], S13, 0x242070db); 
00233   FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); 
00234   FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); 
00235   FF (d, a, b, c, x[ 5], S12, 0x4787c62a); 
00236   FF (c, d, a, b, x[ 6], S13, 0xa8304613); 
00237   FF (b, c, d, a, x[ 7], S14, 0xfd469501); 
00238   FF (a, b, c, d, x[ 8], S11, 0x698098d8); 
00239   FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); 
00240   FF (c, d, a, b, x[10], S13, 0xffff5bb1); 
00241   FF (b, c, d, a, x[11], S14, 0x895cd7be); 
00242   FF (a, b, c, d, x[12], S11, 0x6b901122); 
00243   FF (d, a, b, c, x[13], S12, 0xfd987193); 
00244   FF (c, d, a, b, x[14], S13, 0xa679438e); 
00245   FF (b, c, d, a, x[15], S14, 0x49b40821); 
00246 
00247   
00248 
00249   GG (a, b, c, d, x[ 1], S21, 0xf61e2562); 
00250   GG (d, a, b, c, x[ 6], S22, 0xc040b340); 
00251   GG (c, d, a, b, x[11], S23, 0x265e5a51); 
00252   GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); 
00253   GG (a, b, c, d, x[ 5], S21, 0xd62f105d); 
00254   GG (d, a, b, c, x[10], S22,  0x2441453); 
00255   GG (c, d, a, b, x[15], S23, 0xd8a1e681); 
00256   GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); 
00257   GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); 
00258   GG (d, a, b, c, x[14], S22, 0xc33707d6); 
00259   GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); 
00260   GG (b, c, d, a, x[ 8], S24, 0x455a14ed); 
00261   GG (a, b, c, d, x[13], S21, 0xa9e3e905); 
00262   GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); 
00263   GG (c, d, a, b, x[ 7], S23, 0x676f02d9); 
00264   GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); 
00265 
00266   
00267 
00268   HH (a, b, c, d, x[ 5], S31, 0xfffa3942); 
00269   HH (d, a, b, c, x[ 8], S32, 0x8771f681); 
00270   HH (c, d, a, b, x[11], S33, 0x6d9d6122); 
00271   HH (b, c, d, a, x[14], S34, 0xfde5380c); 
00272   HH (a, b, c, d, x[ 1], S31, 0xa4beea44); 
00273   HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); 
00274   HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); 
00275   HH (b, c, d, a, x[10], S34, 0xbebfbc70); 
00276   HH (a, b, c, d, x[13], S31, 0x289b7ec6); 
00277   HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); 
00278   HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); 
00279   HH (b, c, d, a, x[ 6], S34,  0x4881d05); 
00280   HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); 
00281   HH (d, a, b, c, x[12], S32, 0xe6db99e5); 
00282   HH (c, d, a, b, x[15], S33, 0x1fa27cf8); 
00283   HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); 
00284 
00285   
00286 
00287   II (a, b, c, d, x[ 0], S41, 0xf4292244); 
00288   II (d, a, b, c, x[ 7], S42, 0x432aff97); 
00289   II (c, d, a, b, x[14], S43, 0xab9423a7); 
00290   II (b, c, d, a, x[ 5], S44, 0xfc93a039); 
00291   II (a, b, c, d, x[12], S41, 0x655b59c3); 
00292   II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); 
00293   II (c, d, a, b, x[10], S43, 0xffeff47d); 
00294   II (b, c, d, a, x[ 1], S44, 0x85845dd1); 
00295   II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); 
00296   II (d, a, b, c, x[15], S42, 0xfe2ce6e0); 
00297   II (c, d, a, b, x[ 6], S43, 0xa3014314); 
00298   II (b, c, d, a, x[13], S44, 0x4e0811a1); 
00299   II (a, b, c, d, x[ 4], S41, 0xf7537e82); 
00300   II (d, a, b, c, x[11], S42, 0xbd3af235); 
00301   II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); 
00302   II (b, c, d, a, x[ 9], S44, 0xeb86d391); 
00303 
00304   state[0] += a;
00305   state[1] += b;
00306   state[2] += c;
00307   state[3] += d;
00308 
00309   
00310 
00311   memset ((POINTER)x, 0, sizeof (x));
00312 }
00313 
00314 
00315 
00316 
00317 
00318 
00319 static void Encode (unsigned char *output, UINT4 *input, unsigned int len)
00320 {
00321   unsigned int i, j;
00322 
00323   for (i = 0, j = 0; j < len; i++, j += 4) {
00324     output[j] = (unsigned char)(input[i] & 0xff);
00325     output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
00326     output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
00327     output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
00328   }
00329 }
00330 
00331 
00332 
00333 
00334 
00335 
00336 static void Decode (UINT4 *output, unsigned char *input, unsigned int len)
00337 {
00338   unsigned int i, j;
00339 
00340   for (i = 0, j = 0; j < len; i++, j += 4)
00341     output[i] = ((UINT4)input[j])          | (((UINT4)input[j+1]) << 8) |
00342                (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24) ;
00343 }
00344 
00345 
00346 
00347 
00348 
00349 
00350 
00351 
00352 
00353 static char * MD5_static_printf( unsigned char digest[16] )
00354 {
00355   static char st[33] ;
00356 
00357   sprintf(st,
00358           "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" ,
00359           digest[0] , digest[1] , digest[2] , digest[3] , digest[4] ,
00360           digest[5] , digest[6] , digest[7] , digest[8] , digest[9] ,
00361           digest[10], digest[11], digest[12], digest[13], digest[14],
00362           digest[15]
00363          ) ;
00364 
00365   return st ;
00366 }
00367 
00368 
00369 
00370 
00371 
00372 char * MD5_static_array( int n , char * bytes )
00373 {
00374    MD5_CTX context;
00375    unsigned char digest[16];
00376 
00377    if( n < 0 || bytes == NULL ) return NULL ;
00378 
00379    MD5Init( &context ) ;
00380    MD5Update( &context, bytes, n ) ;
00381    MD5Final( digest, &context ) ;
00382 
00383    return MD5_static_printf(digest) ;
00384 }
00385 
00386 char * MD5_malloc_array( int n , char * bytes )
00387 {
00388    char *st , *dy ;
00389    st = MD5_static_array( n , bytes ) ;
00390    if( st == NULL ) return NULL ;
00391    dy = (char *) malloc(33) ; strcpy(dy,st) ; return dy ;
00392 }
00393 
00394 
00395 
00396 char * MD5_static_string( char * string )
00397 {
00398    if( string == NULL ) return NULL ;
00399    return MD5_static_array( strlen(string) , string ) ;
00400 }
00401 
00402 char * MD5_malloc_string( char * string )
00403 {
00404    if( string == NULL ) return NULL ;
00405    return (char*)MD5_malloc_array( strlen(string) , string ) ;
00406 }
00407 
00408 
00409 
00410 
00411 
00412 char * MD5_static_file(char * filename)
00413 {
00414   FILE *file;
00415   MD5_CTX context;
00416   int len;
00417   unsigned char buffer[1024] ;
00418   unsigned char digest[16] ;
00419 
00420   if( (file = fopen (filename, "rb")) == NULL ) return NULL ;
00421 
00422   MD5Init( &context ) ;
00423 
00424   while( len = fread(buffer, 1, 1024, file) )
00425       MD5Update( &context, buffer, len ) ;
00426 
00427   MD5Final( digest, &context );
00428   fclose (file);
00429 
00430   return MD5_static_printf( digest ) ;
00431 }
00432 
00433 char * MD5_malloc_file(char * filename)
00434 {
00435    char *st , *dy ;
00436 
00437    st = MD5_static_file( filename ) ;
00438    if( st == NULL ) return NULL ;
00439    dy = (char *) malloc(33) ; strcpy(dy,st) ; return dy ;
00440 }
00441 
00442 
00443 
00444 
00445 
00446 
00447 
00448 
00449 
00450 extern void B64_to_base64( int, char *, int *, char ** ) ; 
00451 
00452 static char * MD5_to_B64( unsigned char digest[16] )
00453 {
00454    int nb64=0 ; char *b64=NULL ;
00455 
00456    B64_to_base64( 16 , (char *)digest , &nb64 , &b64 ) ;  
00457    if( nb64 <= 0 || b64 == NULL ) return NULL ;
00458    b64[nb64-3] = '\0' ;                           
00459    return b64 ;
00460 }
00461 
00462 char * MD5_B64_array( int n , char * bytes )
00463 {
00464    MD5_CTX context;
00465    unsigned char digest[16];
00466 
00467    if( n < 0 || bytes == NULL ) return NULL ;
00468 
00469    MD5Init( &context ) ;
00470    MD5Update( &context, bytes, n ) ;
00471    MD5Final( digest, &context ) ;
00472 
00473    return MD5_to_B64( digest ) ;
00474 }
00475 
00476 char * MD5_B64_string( char * string )
00477 {
00478    if( string == NULL ) return NULL ;
00479    return MD5_B64_array( strlen(string) , string ) ;
00480 }
00481 
00482 char * MD5_B64_file(char * filename)
00483 {
00484   FILE *file;
00485   MD5_CTX context;
00486   int len;
00487   unsigned char buffer[1024] ;
00488   unsigned char digest[16] ;
00489 
00490   if( (file = fopen (filename, "rb")) == NULL ) return NULL ;
00491 
00492   MD5Init( &context ) ;
00493 
00494   while( len = fread(buffer, 1, 1024, file) )
00495       MD5Update( &context, buffer, len ) ;
00496 
00497   MD5Final( digest, &context );
00498   fclose (file);
00499 
00500   return MD5_to_B64( digest ) ;
00501 }
00502 
00503 
00504 
00505 
00506 
00507 
00508 
00509 
00510 
00511 
00512 
00513 
00514 
00515 
00516 char * UNIQ_idcode(void)
00517 {
00518    struct utsname ubuf ;
00519    struct timeval tv ;
00520    int    nn , ii ;
00521    int  nbuf ;
00522    char *buf , *idc , *eee ;
00523    static int ncall=0 ;                
00524 
00525    
00526 
00527    nn = uname( &ubuf ) ;               
00528    if( nn == -1 ){                     
00529       strcpy( ubuf.nodename , "E" ) ;
00530       strcpy( ubuf.sysname  , "L" ) ;
00531       strcpy( ubuf.release  , "V" ) ;
00532       strcpy( ubuf.version  , "I" ) ;
00533       strcpy( ubuf.machine  , "S" ) ;
00534    }
00535 
00536    
00537 
00538    nbuf = strlen(ubuf.nodename)+strlen(ubuf.sysname)
00539          +strlen(ubuf.release )+strlen(ubuf.version)+strlen(ubuf.machine) ;
00540 
00541    buf = AFMALL(char, nbuf+64) ;      
00542    strcpy(buf,ubuf.nodename) ;
00543    strcat(buf,ubuf.sysname ) ;
00544    strcat(buf,ubuf.release ) ;
00545    strcat(buf,ubuf.version ) ;
00546    strcat(buf,ubuf.machine ) ;
00547 
00548    idc = AFMALL(char, 32) ;         
00549 
00550    
00551 
00552    nn = gettimeofday( &tv , NULL ) ;
00553    if( nn == -1 ){              
00554       tv.tv_sec  = (long) buf ;
00555       tv.tv_usec = (long) idc ;
00556    }
00557 
00558    sprintf(buf+nbuf,"%d%d%d%d",
00559           (int)tv.tv_sec,(int)tv.tv_usec,(int)getpid(),ncall) ;
00560    ncall++ ;
00561 
00562    
00563 
00564    eee = getenv("IDCODE_PREFIX") ;
00565    if( eee != NULL && isalpha(eee[0]) ){
00566      for( ii=0 ; ii < 3 && isalnum(eee[ii]) ; ii++ )
00567        idc[ii] = eee[ii] ;
00568    } else {
00569      strcpy(idc,"NIH") ;
00570    }
00571    strcat(idc,"_") ;  
00572 
00573    
00574 
00575    eee = MD5_B64_string( buf ) ;
00576    if( eee != NULL ){                     
00577       int nn = strlen(eee) ;
00578       for( ii=0 ; ii < nn ; ii++ ){
00579               if( eee[ii] == '/' ) eee[ii] = '-' ;  
00580          else if( eee[ii] == '+' ) eee[ii] = '_' ;  
00581       }
00582       strcat(idc,eee) ;
00583    } else {                               
00584      nn = strlen(idc) ;
00585      sprintf(idc+nn,"%d_%d",(int)tv.tv_sec,(int)tv.tv_usec) ;
00586    }
00587 
00588    
00589 
00590    if( eee != NULL ) free(eee) ;
00591    free(buf) ; return idc ;
00592 }
00593 
00594 
00595 
00596 
00597 
00598 void UNIQ_idcode_fill( char *idc )
00599 {
00600    char *bbb ;
00601    if( idc == NULL ) return ;
00602    bbb = UNIQ_idcode() ;
00603    strcpy(idc,bbb) ; free(bbb) ; return ;
00604 }
00605 
00606