th_mask.c

Go to the documentation of this file.
00001 
00027 #include <string.h>
00028 
00029 #include "../../dprint.h"
00030 #include "../../md5.h"
00031 #include "../../crc.h"
00032 #include "../../mem/mem.h"
00033 #include "th_mask.h"
00034 
00035 #define TH_EB64I \
00036                 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.-"
00037 
00038 char _th_EB64[65];
00039 int _th_DB64[256];
00040 char *_th_PD64 = "*";
00041 
00042 extern str _th_key;
00043 
00044 void th_shuffle(char *in, int size)
00045 {
00046         char tmp;
00047         int last;
00048         unsigned int r;
00049         unsigned char md5[16];
00050         unsigned int *md5i;
00051         unsigned int crc;
00052         MD5_CTX ctx;
00053 
00054         MD5Init(&ctx);
00055         MD5Update(&ctx, _th_key.s, _th_key.len);
00056         MD5Update(&ctx, _th_key.s, _th_key.len);
00057         U_MD5Final(md5, &ctx);
00058 
00059         md5i = (unsigned int*)md5;
00060 
00061         crc = (unsigned int)crcitt_string(_th_key.s, _th_key.len);
00062         for (last = size; last > 1; last--)
00063         {
00064                 r = (md5i[(crc+last+_th_key.len)%4]
00065                                 + _th_key.s[(crc+last+_th_key.len)%_th_key.len]) % last;
00066                 tmp = in[r];
00067                 in[r] = in[last - 1];
00068                 in[last - 1] = tmp;
00069         }
00070 }
00071 
00072 void th_mask_init(void)
00073 {
00074         int i;
00075 
00076         _th_key.len = strlen(_th_key.s);
00077         memcpy(_th_EB64, TH_EB64I, sizeof(TH_EB64I));
00078         th_shuffle(_th_EB64, 64);
00079         LM_ERR("+++ %s\n", TH_EB64I);
00080         LM_ERR("+++ %s\n", _th_EB64);
00081         for(i=0; i<256; i++)
00082                 _th_DB64[i] = -1;
00083         for(i=0; i<64; i++)
00084                 _th_DB64[(int)_th_EB64[i]] = i;
00085 
00086         return;
00087 }
00088 
00089 char* th_mask_encode(char *in, int ilen, str *prefix, int *olen)
00090 {
00091         char *out;
00092         int  left;
00093         int  idx;
00094         int  i;
00095         int  r;
00096         char *p;
00097         int  block;
00098 
00099         *olen = (((ilen+2)/3)<<2) + ((prefix!=NULL&&prefix->len>0)?prefix->len:0);
00100         out = (char*)pkg_malloc((*olen+1)*sizeof(char));
00101         if(out==NULL)
00102         {
00103                 LM_ERR("no more pkg\n");
00104                 *olen = 0;
00105                 return NULL;
00106         }
00107         memset(out, 0, (*olen+1)*sizeof(char));
00108         if(prefix!=NULL&&prefix->len>0)
00109                 memcpy(out, prefix->s, prefix->len);
00110 
00111         p = out + (int)((prefix!=NULL&&prefix->len>0)?prefix->len:0);
00112         for(idx=0; idx<ilen; idx+=3)
00113         {
00114                 left = ilen - idx - 1 ;
00115                 left = (left>1)?2:left;
00116 
00117                 block = 0;
00118                 for(i=0, r=16; i<=left; i++, r-=8)
00119                         block += ((unsigned char)in[idx+i]) << r;
00120 
00121                 *(p++) = _th_EB64[(block >> 18) & 0x3f];
00122                 *(p++) = _th_EB64[(block >> 12) & 0x3f];
00123                 *(p++) = (left>0)?_th_EB64[(block >> 6) & 0x3f]:_th_PD64[0];
00124                 *(p++) = (left>1)?_th_EB64[block & 0x3f]:_th_PD64[0];
00125         }
00126 
00127         return out;
00128 }
00129 
00130 char* th_mask_decode(char *in, int ilen, str *prefix, int extra, int *olen)
00131 {
00132         char *out;
00133         int n;
00134         int block;
00135         int idx;
00136         int i;
00137         int j;
00138         int end;
00139         char c;
00140 
00141         for(n=0,i=ilen-1; in[i]==_th_PD64[0]; i--)
00142                 n++;
00143 
00144         *olen = (((ilen-((prefix!=NULL&&prefix->len>0)?prefix->len:0)) * 6) >> 3)
00145                                 - n;
00146         out = (char*)pkg_malloc((*olen+1+extra)*sizeof(char));
00147 
00148         if(out==NULL)
00149         {
00150                 LM_ERR("no more pkg\n");
00151                 *olen = 0;
00152                 return NULL;
00153         }
00154         memset(out, 0, (*olen+1+extra)*sizeof(char));
00155 
00156         end = ilen - n;
00157         i = (prefix!=NULL&&prefix->len>0)?prefix->len:0;
00158         for(idx=0; i<end; idx+=3)
00159         {
00160                 block = 0;
00161                 for(j=0; j<4 && i<end ; j++)
00162                 {
00163                         c = _th_DB64[(int)in[i++]];
00164                         if(c<0)
00165                         {
00166                                 LM_ERR("invalid input string\"%.*s\"\n", ilen, in);
00167                                 pkg_free(out);
00168                                 *olen = 0;
00169                                 return NULL;
00170                         }
00171                         block += c << (18 - 6*j);
00172                 }
00173 
00174                 for(j=0, n=16; j<3 && idx+j< *olen; j++, n-=8)
00175                         out[idx+j] = (char)((block >> n) & 0xff);
00176         }
00177 
00178         return out;
00179 }
00180 
00181