/*
 * ----------------------------------------------------------------------------
 * "THE BEER-WARE LICENSE" (Revision 42):
 * <phk@login.dknet.dk> wrote this file.  As long as you retain this 
 * notice you can do whatever you want with this stuff. If we meet some 
 * day, and you think this stuff is worth it, you can buy me a beer in 
 * return.   Poul-Henning Kamp
 * ----------------------------------------------------------------------------
 */

#include "includes.h"

#if defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT)
#include <openssl/md5.h>

RCSID("$Id: md5crypt.c,v 1.6 2003/05/18 14:46:46 djm Exp $");

/* 0 ... 63 => ascii - 64 */
static unsigned char itoa64[] =
    "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

static char *magic = "$1$";

static char *
to64(unsigned long v, int n)
{
	static char buf[5];
	char *s = buf;

	if (n > 4)
		return (NULL);

	memset(buf, '\0', sizeof(buf));
	while (--n >= 0) {
		*s++ = itoa64[v&0x3f];
		v >>= 6;
	}
	
	return (buf);
}

int
is_md5_salt(const char *salt)
{
	return (strncmp(salt, magic, strlen(magic)) == 0);
}

char *
md5_crypt(const char *pw, const char *salt)
{
	static char passwd[120], salt_copy[9], *p;
	static const char *sp, *ep;
	unsigned char final[16];
	int sl, pl, i, j;
	MD5_CTX	ctx, ctx1;
	unsigned long l;

	/* Refine the Salt first */
	sp = salt;

	/* If it starts with the magic string, then skip that */
	if(strncmp(sp, magic, strlen(magic)) == 0)
		sp += strlen(magic);

	/* It stops at the first '$', max 8 chars */
	for (ep = sp; *ep != '$'; ep++) {
		if (*ep == '\0' || ep >= (sp + 8))
			return (NULL);
	}

	/* get the length of the true salt */
	sl = ep - sp;

	/* Stash the salt */
	memcpy(salt_copy, sp, sl);
	salt_copy[sl] = '\0';

	MD5_Init(&ctx);

	/* The password first, since that is what is most unknown */
	MD5_Update(&ctx, pw, strlen(pw));

	/* Then our magic string */
	MD5_Update(&ctx, magic, strlen(magic));

	/* Then the raw salt */
	MD5_Update(&ctx, sp, sl);

	/* Then just as many characters of the MD5(pw, salt, pw) */
	MD5_Init(&ctx1);
	MD5_Update(&ctx1, pw, strlen(pw));
	MD5_Update(&ctx1, sp, sl);
	MD5_Update(&ctx1, pw, strlen(pw));
	MD5_Final(final, &ctx1);

	for(pl = strlen(pw); pl > 0; pl -= 16)
		MD5_Update(&ctx, final, pl > 16 ? 16 : pl);

	/* Don't leave anything around in vm they could use. */
	memset(final, '\0', sizeof final);

	/* Then something really weird... */
	for (j = 0, i = strlen(pw); i != 0; i >>= 1)
		if (i & 1)
			MD5_Update(&ctx, final + j, 1);
		else
			MD5_Update(&ctx, pw + j, 1);

	/* Now make the output string */
	snprintf(passwd, sizeof(passwd), "%s%s$", magic, salt_copy);

	MD5_Final(final, &ctx);

	/*
	 * and now, just to make sure things don't run too fast
	 * On a 60 Mhz Pentium this takes 34 msec, so you would
	 * need 30 seconds to build a 1000 entry dictionary...
	 */
	for(i = 0; i < 1000; i++) {
		MD5_Init(&ctx1);
		if (i & 1)
			MD5_Update(&ctx1, pw, strlen(pw));
		else
			MD5_Update(&ctx1, final, 16);

		if (i % 3)
			MD5_Update(&ctx1, sp, sl);

		if (i % 7)
			MD5_Update(&ctx1, pw, strlen(pw));

		if (i & 1)
			MD5_Update(&ctx1, final, 16);
		else
			MD5_Update(&ctx1, pw, strlen(pw));

		MD5_Final(final, &ctx1);
	}

	p = passwd + strlen(passwd);

	l = (final[ 0]<<16) | (final[ 6]<<8) | final[12];
	strlcat(passwd, to64(l, 4), sizeof(passwd));
	l = (final[ 1]<<16) | (final[ 7]<<8) | final[13];
	strlcat(passwd, to64(l, 4), sizeof(passwd));
	l = (final[ 2]<<16) | (final[ 8]<<8) | final[14];
	strlcat(passwd, to64(l, 4), sizeof(passwd));
	l = (final[ 3]<<16) | (final[ 9]<<8) | final[15];
	strlcat(passwd, to64(l, 4), sizeof(passwd));
	l = (final[ 4]<<16) | (final[10]<<8) | final[ 5];
	strlcat(passwd, to64(l, 4), sizeof(passwd));
	l =                    final[11]                ;
	strlcat(passwd, to64(l, 2), sizeof(passwd));

	/* Don't leave anything around in vm they could use. */
	memset(final, 0, sizeof(final));
	memset(salt_copy, 0, sizeof(salt_copy));
	memset(&ctx, 0, sizeof(ctx));
	memset(&ctx1, 0, sizeof(ctx1));
	(void)to64(0, 4)

	return (passwd);
}

#endif /* defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) */
