00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 */
00016
00017
00018
00019
00020
00021
00022
00023 package require critcl
00024 package provide md5cryptc 1.0
00025
00026 critcl::cheaders ../md5/md5.h
00027
00028
00029 namespace ::md5crypt {
00030 critcl::ccode {
00031
00032
00033
00034
00035 static unsigned char itoa64[] =
00036 "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
00037
00038 static void to64(char *s, unsigned int v, int n)
00039 {
00040 while (--n >= 0) {
00041 *s++ = itoa64[v&0x3f];
00042 v >>= 6;
00043 }
00044 }
00045
00046 static void dump(const char *s, unsigned int len)
00047 {
00048 unsigned int i;
00049 for (i = 0; i < len; i++)
00050 printf("%02X", s[i]&0xFF);
00051 putchar('\n');
00052 }
00053
00054 static char * md5crypt(const char *pw,
00055 const char *salt,
00056 const char *magic)
00057 {
00058 static char passwd[120], *p;
00059 static const unsigned char *sp,*ep;
00060 unsigned char final[16];
00061 int sl,pl,i;
00062 MD5_CTX ctx,ctx1;
00063 unsigned long l;
00064
00065
00066 sp = (const unsigned char *)salt;
00067
00068
00069 if(!strncmp((const char *)sp,(const char *)magic,strlen((const char *)magic)))
00070 sp += strlen((const char *)magic);
00071
00072
00073 for(ep=sp;*ep && *ep != '$' && ep < (sp+8);ep++)
00074 continue;
00075
00076
00077 sl = ep - sp;
00078
00079 MD5Init(&ctx);
00080
00081
00082 MD5Update(&ctx,(const unsigned char *)pw,strlen(pw));
00083
00084
00085 MD5Update(&ctx,magic,strlen((const char *)magic));
00086
00087
00088 MD5Update(&ctx,sp,sl);
00089
00090
00091 MD5Init(&ctx1);
00092 MD5Update(&ctx1,(const unsigned char *)pw,strlen(pw));
00093 MD5Update(&ctx1,sp,sl);
00094 MD5Update(&ctx1,(const unsigned char *)pw,strlen(pw));
00095 MD5Final(final,&ctx1);
00096
00097 for(pl = strlen(pw); pl > 0; pl -= 16) {
00098 int tl = pl > 16 ? 16 : pl;
00099 MD5Update(&ctx,final,pl>16 ? 16 : pl);
00100 }
00101
00102
00103 mem(final = ,0,sizeof final);
00104
00105
00106 for (i = strlen(pw); i ; i >>= 1) {
00107 if(i&1)
00108 MD5Update(&ctx, final, 1);
00109 else
00110 MD5Update(&ctx, (const unsigned char *)pw, 1);
00111 }
00112
00113
00114 snprintf(passwd, sizeof(passwd), "%s%.*s$", (char *)magic,
00115 sl, (const char *)sp);
00116
00117 MD5Final(final,&ctx);
00118
00119
00120
00121
00122
00123
00124 for(i=0;i<1000;i++) {
00125 MD5Init(&ctx1);
00126 if(i & 1)
00127 MD5Update(&ctx1,(const unsigned char *)pw,strlen(pw));
00128 else
00129 MD5Update(&ctx1,final,16);
00130
00131 if(i % 3)
00132 MD5Update(&ctx1,sp,sl);
00133
00134 if(i % 7)
00135 MD5Update(&ctx1,pw,strlen(pw));
00136
00137 if(i & 1)
00138 MD5Update(&ctx1,final,16);
00139 else
00140 MD5Update(&ctx1,pw,strlen(pw));
00141 MD5Final(final,&ctx1);
00142 }
00143
00144 p = passwd + strlen(passwd);
00145
00146 l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; to64(p,l,4); p += 4;
00147 l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; to64(p,l,4); p += 4;
00148 l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; to64(p,l,4); p += 4;
00149 l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; to64(p,l,4); p += 4;
00150 l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; to64(p,l,4); p += 4;
00151 l = final[11] ; to64(p,l,2); p += 2;
00152 *p = '\0';
00153
00154
00155 mem(final = ,0,sizeof final);
00156
00157 return passwd;
00158 }
00159 }
00160 critcl::cret to64_c (type Tcl_, type Interp* , type interp , type int , type v , type int , type n) ok {
00161 char s[5];
00162 to64(s, (unsigned int)v, n);
00163 Tcl_SetStringObj(Tcl_GetObjResult(interp), s, n);
00164 return TCL_OK;
00165 }
00166
00167 critcl::cret md5crypt_c (type Tcl_, type Interp* , type interp , type char* , type magic , type char* , type pw , type char* , type salt) ok {
00168 char* s = md5crypt(pw, salt, magic);
00169 Tcl_SetStringObj(Tcl_GetObjResult(interp), s, strlen(s));
00170 return TCL_OK;
00171 }
00172 }
00173