11305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 21305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * ---------------------------------------------------------------------------- 31305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * "THE BEER-WARE LICENSE" (Revision 42): 41305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * <phk@login.dknet.dk> wrote this file. As long as you retain this 51305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * notice you can do whatever you want with this stuff. If we meet some 61305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * day, and you think this stuff is worth it, you can buy me a beer in 71305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * return. Poul-Henning Kamp 81305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * ---------------------------------------------------------------------------- 91305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "includes.h" 121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#if defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) 141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/types.h> 151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <string.h> 171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <openssl/md5.h> 191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 0 ... 63 => ascii - 64 */ 211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic unsigned char itoa64[] = 221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic char *magic = "$1$"; 251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic char * 271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodto64(unsigned long v, int n) 281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood static char buf[5]; 301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *s = buf; 311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (n > 4) 331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (NULL); 341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memset(buf, '\0', sizeof(buf)); 361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while (--n >= 0) { 371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *s++ = itoa64[v&0x3f]; 381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood v >>= 6; 391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (buf); 421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodis_md5_salt(const char *salt) 461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (strncmp(salt, magic, strlen(magic)) == 0); 481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchar * 511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodmd5_crypt(const char *pw, const char *salt) 521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood static char passwd[120], salt_copy[9], *p; 541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood static const char *sp, *ep; 551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood unsigned char final[16]; 561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int sl, pl, i, j; 571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood MD5_CTX ctx, ctx1; 581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood unsigned long l; 591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Refine the Salt first */ 611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sp = salt; 621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* If it starts with the magic string, then skip that */ 641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if(strncmp(sp, magic, strlen(magic)) == 0) 651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sp += strlen(magic); 661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* It stops at the first '$', max 8 chars */ 681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (ep = sp; *ep != '$'; ep++) { 691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (*ep == '\0' || ep >= (sp + 8)) 701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (NULL); 711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* get the length of the true salt */ 741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sl = ep - sp; 751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Stash the salt */ 771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memcpy(salt_copy, sp, sl); 781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood salt_copy[sl] = '\0'; 791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood MD5_Init(&ctx); 811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* The password first, since that is what is most unknown */ 831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood MD5_Update(&ctx, pw, strlen(pw)); 841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Then our magic string */ 861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood MD5_Update(&ctx, magic, strlen(magic)); 871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Then the raw salt */ 891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood MD5_Update(&ctx, sp, sl); 901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Then just as many characters of the MD5(pw, salt, pw) */ 921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood MD5_Init(&ctx1); 931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood MD5_Update(&ctx1, pw, strlen(pw)); 941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood MD5_Update(&ctx1, sp, sl); 951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood MD5_Update(&ctx1, pw, strlen(pw)); 961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood MD5_Final(final, &ctx1); 971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for(pl = strlen(pw); pl > 0; pl -= 16) 991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood MD5_Update(&ctx, final, pl > 16 ? 16 : pl); 1001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Don't leave anything around in vm they could use. */ 1021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memset(final, '\0', sizeof final); 1031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Then something really weird... */ 1051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (j = 0, i = strlen(pw); i != 0; i >>= 1) 1061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (i & 1) 1071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood MD5_Update(&ctx, final + j, 1); 1081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 1091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood MD5_Update(&ctx, pw + j, 1); 1101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Now make the output string */ 1121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(passwd, sizeof(passwd), "%s%s$", magic, salt_copy); 1131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood MD5_Final(final, &ctx); 1151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 1171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * and now, just to make sure things don't run too fast 1181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * On a 60 Mhz Pentium this takes 34 msec, so you would 1191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * need 30 seconds to build a 1000 entry dictionary... 1201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 1211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for(i = 0; i < 1000; i++) { 1221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood MD5_Init(&ctx1); 1231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (i & 1) 1241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood MD5_Update(&ctx1, pw, strlen(pw)); 1251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 1261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood MD5_Update(&ctx1, final, 16); 1271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (i % 3) 1291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood MD5_Update(&ctx1, sp, sl); 1301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (i % 7) 1321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood MD5_Update(&ctx1, pw, strlen(pw)); 1331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (i & 1) 1351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood MD5_Update(&ctx1, final, 16); 1361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 1371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood MD5_Update(&ctx1, pw, strlen(pw)); 1381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood MD5_Final(final, &ctx1); 1401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood p = passwd + strlen(passwd); 1431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; 1451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strlcat(passwd, to64(l, 4), sizeof(passwd)); 1461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; 1471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strlcat(passwd, to64(l, 4), sizeof(passwd)); 1481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; 1491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strlcat(passwd, to64(l, 4), sizeof(passwd)); 1501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; 1511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strlcat(passwd, to64(l, 4), sizeof(passwd)); 1521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; 1531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strlcat(passwd, to64(l, 4), sizeof(passwd)); 1541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood l = final[11] ; 1551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strlcat(passwd, to64(l, 2), sizeof(passwd)); 1561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Don't leave anything around in vm they could use. */ 1581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memset(final, 0, sizeof(final)); 1591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memset(salt_copy, 0, sizeof(salt_copy)); 1601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memset(&ctx, 0, sizeof(ctx)); 1611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memset(&ctx1, 0, sizeof(ctx1)); 1621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (void)to64(0, 4); 1631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (passwd); 1651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 1661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif /* defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) */ 168