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