/* Copyright 1989, 1990 by James Aspnes, David Applegate, and Bennet Yee */ /* See the file COPYING for distribution information */ #include "db.h" const char *alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./"; #ifdef USE_UNIX_CRYPT extern const char *crypt(const char *, const char *); #define do_crypt crypt #else /* USE_UNIX_CRYPT */ #define mask(x) ((1 << (x)) - 1) #define extract0(p) alphabet[bits[p] & mask(6)] /* don't even try to understand it */ /* and don't use it outside bits2alpha */ /* WARNING: Dec 3100 (pmax) cc botches the constant-folding in this macro! */ #define extract(p, shift) \ alphabet[((bits[(p)] >> (shift)) & mask(8 - (shift))) \ | ((bits[(p)+1] << ((shift) - 4)) \ & (mask(10 - (shift)) << ((shift) - 4)))] /* converts 64 bits to 11 characters of the 6-bit code */ static const char *bits2alpha(unsigned const char *bits) { static char alpha[12]; alpha[0] = extract0(0); alpha[1] = extract(0, 6); alpha[2] = extract(1, 4); alpha[3] = extract(2, 2); alpha[4] = extract0(3); alpha[5] = extract(3, 6); alpha[6] = extract(4, 4); alpha[7] = extract(5, 2); alpha[8] = extract0(6); alpha[9] = extract(6, 6); alpha[10] = alphabet[(bits[7] >> 4) & 0xf]; alpha[11] = '\0'; return alpha; } static const char *do_crypt(const char *password, const char *salt) { static int initialized = 0; /* already called desinit */ int i; unsigned char cbuf[8]; /* thing to encrypt */ char key[8]; /* key */ static char buf[14]; /* 2 bytes of salt + 11 bytes of text + term */ for(i = 0; i < 8; i+= 2) { cbuf[i] = salt[0]; cbuf[i+1] = salt[1]; } for(i = 0; i < 8 && password[i]; i++) { key[i] = password[i] << 1; } while(i < 8) key[i++] = 0; if(!initialized) { desinit(1); /* ignore initial and final permutations */ initialized = 1; } setkey(key); endes(cbuf); /* construct the salted string in buf */ buf[0] = salt[0]; buf[1] = salt[1]; strcpy(buf + 2, bits2alpha(cbuf)); return buf; } #endif /* USE_UNIX_CRYPT */ const char *encrypt_password(const char *password) { char salt[3]; salt[0] = alphabet[RAND() % 64]; salt[1] = alphabet[RAND() % 64]; salt[2] = '\0'; return do_crypt(password, salt); } int check_password(const char *clear, const char *encrypted) { return !strcmp(encrypted, do_crypt(clear, encrypted)); }