X-Git-Url: http://git.pk910.de/?a=blobdiff_plain;f=ircd%2Fircd_crypt_smd5.c;h=439c08988de0f71a1f500267ffe07e01f69d0270;hb=refs%2Fheads%2Fupstream-ssl;hp=a5d3650697ce681c60f39a042c009bb2ac74f5f9;hpb=9276d79355f1fbcd8644594b2d1c1d19beb91e73;p=ircu2.10.12-pk.git diff --git a/ircd/ircd_crypt_smd5.c b/ircd/ircd_crypt_smd5.c index a5d3650..439c089 100644 --- a/ircd/ircd_crypt_smd5.c +++ b/ircd/ircd_crypt_smd5.c @@ -15,25 +15,17 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id$ */ -#include "config.h" -#include "ircd_crypt.h" -#include "ircd_crypt_smd5.h" -#include "ircd_md5.h" -#include "s_debug.h" -#include "ircd_alloc.h" - -#include -#include -#include - -/* + +/** + * @file + * @brief Routines for Salted MD5 passwords + * @version $Id$ + * * ircd_crypt_smd5 is largely taken from md5_crypt.c from the Linux PAM * source code. it's been modified to fit in with ircu and some of the - * undeeded code has been removed. the source file md5_crypt.c has the - * following licence, so if any of our opers or admins are in Denmark + * unneeded code has been removed. the source file md5_crypt.c has the + * following license, so if any of our opers or admins are in Denmark * they better go buy them a drink ;) -- hikari * * ---------------------------------------------------------------------------- @@ -44,10 +36,31 @@ * ---------------------------------------------------------------------------- * */ +#include "config.h" +#include "ircd_crypt.h" +#include "ircd_crypt_smd5.h" +#include "ircd_log.h" +#include "ircd_md5.h" +#include "s_debug.h" +#include "ircd_alloc.h" + +/* #include -- Now using assert in ircd_log.h */ +#include +#include static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */ "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; +/** Converts a binary value into a BASE64 encoded string. + * @param s Pointer to the output string + * @param v The unsigned long we're working on + * @param n The number of bytes we're working with + * + * This is used to produce the normal MD5 hash everyone is familiar with. + * It takes the value v and converts n bytes of it it into an ASCII string in + * 6-bit chunks, the resulting string is put at the address pointed to by s. + * + */ static void to64(char *s, unsigned long v, int n) { while (--n >= 0) { @@ -56,10 +69,23 @@ static void to64(char *s, unsigned long v, int n) } } +/** Produces a Salted MD5 crypt of a password using the supplied salt + * @param key The password we're encrypting + * @param salt The salt we're using to encrypt it + * @return The Salted MD5 password of key and salt + * + * Erm does exactly what the brief comment says. If you think I'm writing a + * description of how MD5 works, you have another think coming. Go and read + * Applied Cryptography by Bruce Schneier. The only difference is we use a + * salt at the beginning of the password to perturb it so that the same password + * doesn't always produce the same hash. + * + */ const char* ircd_crypt_smd5(const char* key, const char* salt) { const char *magic = "$1$"; -char *passwd, *p; +static char passwd[120]; +char *p; const char *sp, *ep; unsigned char final[16]; int sl, pl, i, j; @@ -75,36 +101,31 @@ unsigned long l; /* Refine the Salt first */ ep = sp = salt; - if(NULL == (passwd = (char *)MyMalloc(120))) - return NULL; - - memset(passwd, 0, 120); - for (ep = sp; *ep && *ep != '$' && ep < (sp + 8); ep++) continue; /* get the length of the true salt */ sl = ep - sp; - MD5Name(MD5Init)(&ctx); + MD5Init(&ctx); /* The password first, since that is what is most unknown */ - MD5Name(MD5Update)(&ctx,(unsigned const char *)key,strlen(key)); + MD5Update(&ctx,(unsigned const char *)key,strlen(key)); /* Then our magic string */ - MD5Name(MD5Update)(&ctx,(unsigned const char *)magic,strlen(magic)); + MD5Update(&ctx,(unsigned const char *)magic,strlen(magic)); /* Then the raw salt */ - MD5Name(MD5Update)(&ctx,(unsigned const char *)sp,sl); + MD5Update(&ctx,(unsigned const char *)sp,sl); /* Then just as many characters of the MD5(key,salt,key) */ - MD5Name(MD5Init)(&ctx1); - MD5Name(MD5Update)(&ctx1,(unsigned const char *)key,strlen(key)); - MD5Name(MD5Update)(&ctx1,(unsigned const char *)sp,sl); - MD5Name(MD5Update)(&ctx1,(unsigned const char *)key,strlen(key)); - MD5Name(MD5Final)(final,&ctx1); + MD5Init(&ctx1); + MD5Update(&ctx1,(unsigned const char *)key,strlen(key)); + MD5Update(&ctx1,(unsigned const char *)sp,sl); + MD5Update(&ctx1,(unsigned const char *)key,strlen(key)); + MD5Final(final,&ctx1); for (pl = strlen(key); pl > 0; pl -= 16) - MD5Name(MD5Update)(&ctx,(unsigned const char *)final,pl>16 ? 16 : pl); + MD5Update(&ctx,(unsigned const char *)final,pl>16 ? 16 : pl); /* Don't leave anything around in vm they could use. */ memset(final, 0, sizeof final); @@ -112,17 +133,16 @@ unsigned long l; /* Then something really weird... */ for (j = 0, i = strlen(key); i; i >>= 1) if (i & 1) - MD5Name(MD5Update)(&ctx, (unsigned const char *)final+j, 1); + MD5Update(&ctx, (unsigned const char *)final+j, 1); else - MD5Name(MD5Update)(&ctx, (unsigned const char *)key+j, 1); + MD5Update(&ctx, (unsigned const char *)key+j, 1); - /* Now make the output string - strcpy(passwd, magic); - strncat(passwd, sp, sl); */ + /* Now make the output string. */ + memset(passwd, 0, 120); strncpy(passwd, sp, sl); strcat(passwd, "$"); - MD5Name(MD5Final)(final,&ctx); + MD5Final(final,&ctx); /* * and now, just to make sure things don't run too fast @@ -130,31 +150,33 @@ unsigned long l; * need 30 seconds to build a 1000 entry dictionary... */ for (i = 0; i < 1000; i++) { - MD5Name(MD5Init)(&ctx1); + MD5Init(&ctx1); if (i & 1) - MD5Name(MD5Update)(&ctx1,(unsigned const char *)key,strlen(key)); + MD5Update(&ctx1,(unsigned const char *)key,strlen(key)); else - MD5Name(MD5Update)(&ctx1,(unsigned const char *)final,16); + MD5Update(&ctx1,(unsigned const char *)final,16); if (i % 3) - MD5Name(MD5Update)(&ctx1,(unsigned const char *)sp,sl); + MD5Update(&ctx1,(unsigned const char *)sp,sl); if (i % 7) - MD5Name(MD5Update)(&ctx1,(unsigned const char *)key,strlen(key)); + MD5Update(&ctx1,(unsigned const char *)key,strlen(key)); if (i & 1) - MD5Name(MD5Update)(&ctx1,(unsigned const char *)final,16); + MD5Update(&ctx1,(unsigned const char *)final,16); else - MD5Name(MD5Update)(&ctx1,(unsigned const char *)key,strlen(key)); + MD5Update(&ctx1,(unsigned const char *)key,strlen(key)); - MD5Name(MD5Final)(final,&ctx1); + MD5Final(final,&ctx1); } p = passwd + strlen(passwd); Debug((DEBUG_DEBUG, "passwd = %s", passwd)); + /* Turn the encrypted binary data into a BASE64 encoded string we can read + * and display -- hikari */ l = (final[0] << 16) | (final[6] << 8) | final[12]; to64(p, l, 4); p += 4; @@ -183,7 +205,11 @@ return passwd; /* end borrowed code */ -/* register ourself with the list of crypt mechanisms */ +/** Register ourself with the list of crypt mechanisms + * Registers the SMD5 mechanism in the list of available crypt mechanisms. When + * we're modular this will be the entry function for the module. + * + */ void ircd_register_crypt_smd5(void) { crypt_mech_t* crypt_mech;