1/* $OpenLDAP$ */
2/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3 *
4 * Copyright 1998-2011 The OpenLDAP Foundation.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted only as authorized by the OpenLDAP
9 * Public License.
10 *
11 * A copy of this license is available in the file LICENSE in the
12 * top-level directory of the distribution or, alternatively, at
13 * <http://www.OpenLDAP.org/license.html>.
14 */
15
16#include <unistd.h>
17
18#include <lber.h>
19#include <lber_pvt.h>
20#include "lutil.h"
21#include "lutil_md5.h"
22#include <ac/string.h>
23
24static LUTIL_PASSWD_CHK_FUNC chk_ns_mta_md5;
25static const struct berval scheme = BER_BVC("{NS-MTA-MD5}");
26
27#define NS_MTA_MD5_PASSLEN	64
28static int chk_ns_mta_md5(
29	const struct berval *scheme,
30	const struct berval *passwd,
31	const struct berval *cred,
32	const char **text )
33{
34	lutil_MD5_CTX MD5context;
35	unsigned char MD5digest[LUTIL_MD5_BYTES], c;
36	char buffer[LUTIL_MD5_BYTES*2];
37	int i;
38
39	if( passwd->bv_len != NS_MTA_MD5_PASSLEN ) {
40		return LUTIL_PASSWD_ERR;
41	}
42
43	/* hash credentials with salt */
44	lutil_MD5Init(&MD5context);
45	lutil_MD5Update(&MD5context,
46		(const unsigned char *) &passwd->bv_val[32],
47		32 );
48
49	c = 0x59;
50	lutil_MD5Update(&MD5context,
51		(const unsigned char *) &c,
52		1 );
53
54	lutil_MD5Update(&MD5context,
55		(const unsigned char *) cred->bv_val,
56		cred->bv_len );
57
58	c = 0xF7;
59	lutil_MD5Update(&MD5context,
60		(const unsigned char *) &c,
61		1 );
62
63	lutil_MD5Update(&MD5context,
64		(const unsigned char *) &passwd->bv_val[32],
65		32 );
66
67	lutil_MD5Final(MD5digest, &MD5context);
68
69	for( i=0; i < sizeof( MD5digest ); i++ ) {
70		buffer[i+i]   = "0123456789abcdef"[(MD5digest[i]>>4) & 0x0F];
71		buffer[i+i+1] = "0123456789abcdef"[ MD5digest[i] & 0x0F];
72	}
73
74	/* compare */
75	return memcmp((char *)passwd->bv_val,
76		(char *)buffer, sizeof(buffer)) ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK;
77}
78
79int init_module(int argc, char *argv[]) {
80	return lutil_passwd_add( (struct berval *)&scheme, chk_ns_mta_md5, NULL );
81}
82