1 /* $OpenLDAP$ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3  *
4  * Copyright 1998-2021 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 /*
17  * int lutil_passwd(
18  *	const struct berval *passwd,
19  *	const struct berval *cred,
20  *	const char **schemes )
21  *
22  * Returns true if user supplied credentials (cred) matches
23  * the stored password (passwd).
24  *
25  * Due to the use of the crypt(3) function
26  * this routine is NOT thread-safe.
27  */
28 
29 #include "portable.h"
30 
31 #include <stdio.h>
32 #include <ac/stdlib.h>
33 #include <ac/string.h>
34 #include <ac/unistd.h>
35 
36 #if defined(SLAPD_LMHASH)
37 #if defined(HAVE_OPENSSL)
38 #	include <openssl/des.h>
39 
40 
41 typedef DES_cblock des_key;
42 typedef DES_cblock des_data_block;
43 typedef DES_key_schedule des_context[1];
44 #define des_failed(encrypted) 0
45 #define des_finish(key, schedule)
46 
47 #elif defined(HAVE_MOZNSS)
48 /*
49   hack hack hack
50   We need to define this here so that nspr/obsolete/protypes.h will not be included
51   if that file is included, it will create a uint32 typedef that will cause the
52   one in lutil_sha1.h to blow up
53 */
54 #define PROTYPES_H 1
55 #	include <nss/pk11pub.h>
56 typedef PK11SymKey *des_key;
57 typedef unsigned char des_data_block[8];
58 typedef PK11Context *des_context[1];
59 #define DES_ENCRYPT CKA_ENCRYPT
60 
61 #endif
62 
63 #endif /* SLAPD_LMHASH */
64 
65 #include <ac/param.h>
66 
67 #ifdef SLAPD_CRYPT
68 # include <ac/crypt.h>
69 
70 # if defined( HAVE_GETPWNAM ) && defined( HAVE_STRUCT_PASSWD_PW_PASSWD )
71 #  ifdef HAVE_SHADOW_H
72 #	include <shadow.h>
73 #  endif
74 #  ifdef HAVE_PWD_H
75 #	include <pwd.h>
76 #  endif
77 #  ifdef HAVE_AIX_SECURITY
78 #	include <userpw.h>
79 #  endif
80 # endif
81 #endif
82 
83 #include <lber.h>
84 
85 #include "ldap_pvt.h"
86 #include "lber_pvt.h"
87 
88 #include "lutil_md5.h"
89 #include "lutil_sha1.h"
90 #include "lutil.h"
91 
92 static const unsigned char crypt64[] =
93 	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890./";
94 
95 #ifdef SLAPD_CRYPT
96 static char *salt_format = NULL;
97 static lutil_cryptfunc lutil_crypt;
98 lutil_cryptfunc *lutil_cryptptr = lutil_crypt;
99 #endif
100 
101 /* KLUDGE:
102  *  chk_fn is NULL iff name is {CLEARTEXT}
103  *	otherwise, things will break
104  */
105 struct pw_scheme {
106 	struct berval name;
107 	LUTIL_PASSWD_CHK_FUNC *chk_fn;
108 	LUTIL_PASSWD_HASH_FUNC *hash_fn;
109 };
110 
111 struct pw_slist {
112 	struct pw_slist *next;
113 	struct pw_scheme s;
114 };
115 
116 /* password check routines */
117 
118 #define	SALT_SIZE	4
119 
120 static LUTIL_PASSWD_CHK_FUNC chk_md5;
121 static LUTIL_PASSWD_CHK_FUNC chk_smd5;
122 static LUTIL_PASSWD_HASH_FUNC hash_smd5;
123 static LUTIL_PASSWD_HASH_FUNC hash_md5;
124 
125 
126 #ifdef LUTIL_SHA1_BYTES
127 static LUTIL_PASSWD_CHK_FUNC chk_ssha1;
128 static LUTIL_PASSWD_CHK_FUNC chk_sha1;
129 static LUTIL_PASSWD_HASH_FUNC hash_sha1;
130 static LUTIL_PASSWD_HASH_FUNC hash_ssha1;
131 #endif
132 
133 #ifdef SLAPD_LMHASH
134 static LUTIL_PASSWD_CHK_FUNC chk_lanman;
135 static LUTIL_PASSWD_HASH_FUNC hash_lanman;
136 #endif
137 
138 #ifdef SLAPD_CRYPT
139 static LUTIL_PASSWD_CHK_FUNC chk_crypt;
140 static LUTIL_PASSWD_HASH_FUNC hash_crypt;
141 
142 #if defined( HAVE_GETPWNAM ) && defined( HAVE_STRUCT_PASSWD_PW_PASSWD )
143 static LUTIL_PASSWD_CHK_FUNC chk_unix;
144 #endif
145 #endif
146 
147 /* password hash routines */
148 
149 #ifdef SLAPD_CLEARTEXT
150 static LUTIL_PASSWD_HASH_FUNC hash_clear;
151 #endif
152 
153 static struct pw_slist *pw_schemes;
154 static int pw_inited;
155 
156 static const struct pw_scheme pw_schemes_default[] =
157 {
158 #ifdef LUTIL_SHA1_BYTES
159 	{ BER_BVC("{SSHA}"),		chk_ssha1, hash_ssha1 },
160 	{ BER_BVC("{SHA}"),			chk_sha1, hash_sha1 },
161 #endif
162 
163 	{ BER_BVC("{SMD5}"),		chk_smd5, hash_smd5 },
164 	{ BER_BVC("{MD5}"),			chk_md5, hash_md5 },
165 
166 #ifdef SLAPD_LMHASH
167 	{ BER_BVC("{LANMAN}"),		chk_lanman, hash_lanman },
168 #endif /* SLAPD_LMHASH */
169 
170 #ifdef SLAPD_CRYPT
171 	{ BER_BVC("{CRYPT}"),		chk_crypt, hash_crypt },
172 # if defined( HAVE_GETPWNAM ) && defined( HAVE_STRUCT_PASSWD_PW_PASSWD )
173 	{ BER_BVC("{UNIX}"),		chk_unix, NULL },
174 # endif
175 #endif
176 
177 #ifdef SLAPD_CLEARTEXT
178 	/* pseudo scheme */
179 	{ BER_BVC("{CLEARTEXT}"),	NULL, hash_clear },
180 #endif
181 
182 	{ BER_BVNULL, NULL, NULL }
183 };
184 
lutil_passwd_add(struct berval * scheme,LUTIL_PASSWD_CHK_FUNC * chk,LUTIL_PASSWD_HASH_FUNC * hash)185 int lutil_passwd_add(
186 	struct berval *scheme,
187 	LUTIL_PASSWD_CHK_FUNC *chk,
188 	LUTIL_PASSWD_HASH_FUNC *hash )
189 {
190 	struct pw_slist *ptr;
191 
192 	if (!pw_inited) lutil_passwd_init();
193 
194 	ptr = ber_memalloc( sizeof( struct pw_slist ));
195 	if (!ptr) return -1;
196 	ptr->next = pw_schemes;
197 	ptr->s.name = *scheme;
198 	ptr->s.chk_fn = chk;
199 	ptr->s.hash_fn = hash;
200 	pw_schemes = ptr;
201 	return 0;
202 }
203 
lutil_passwd_init()204 void lutil_passwd_init()
205 {
206 	struct pw_scheme *s;
207 
208 	pw_inited = 1;
209 
210 	for( s=(struct pw_scheme *)pw_schemes_default; s->name.bv_val; s++) {
211 		if ( lutil_passwd_add( &s->name, s->chk_fn, s->hash_fn ) ) break;
212 	}
213 }
214 
lutil_passwd_destroy()215 void lutil_passwd_destroy()
216 {
217 	struct pw_slist *ptr, *next;
218 
219 	for( ptr=pw_schemes; ptr; ptr=next ) {
220 		next = ptr->next;
221 		ber_memfree( ptr );
222 	}
223 }
224 
get_scheme(const char * scheme)225 static const struct pw_scheme *get_scheme(
226 	const char* scheme )
227 {
228 	struct pw_slist *pws;
229 	struct berval bv;
230 
231 	if (!pw_inited) lutil_passwd_init();
232 
233 	bv.bv_val = strchr( scheme, '}' );
234 	if ( !bv.bv_val )
235 		return NULL;
236 
237 	bv.bv_len = bv.bv_val - scheme + 1;
238 	bv.bv_val = (char *) scheme;
239 
240 	for( pws=pw_schemes; pws; pws=pws->next ) {
241 		if ( ber_bvstrcasecmp(&bv, &pws->s.name ) == 0 ) {
242 			return &(pws->s);
243 		}
244 	}
245 
246 	return NULL;
247 }
248 
lutil_passwd_scheme(const char * scheme)249 int lutil_passwd_scheme(
250 	const char* scheme )
251 {
252 	if( scheme == NULL ) {
253 		return 0;
254 	}
255 
256 	return get_scheme(scheme) != NULL;
257 }
258 
259 
is_allowed_scheme(const char * scheme,const char ** schemes)260 static int is_allowed_scheme(
261 	const char* scheme,
262 	const char** schemes )
263 {
264 	int i;
265 
266 	if( schemes == NULL ) return 1;
267 
268 	for( i=0; schemes[i] != NULL; i++ ) {
269 		if( strcasecmp( scheme, schemes[i] ) == 0 ) {
270 			return 1;
271 		}
272 	}
273 	return 0;
274 }
275 
passwd_scheme(const struct pw_scheme * scheme,const struct berval * passwd,struct berval * bv,const char ** allowed)276 static struct berval *passwd_scheme(
277 	const struct pw_scheme *scheme,
278 	const struct berval * passwd,
279 	struct berval *bv,
280 	const char** allowed )
281 {
282 	if( !is_allowed_scheme( scheme->name.bv_val, allowed ) ) {
283 		return NULL;
284 	}
285 
286 	if( passwd->bv_len >= scheme->name.bv_len ) {
287 		if( strncasecmp( passwd->bv_val, scheme->name.bv_val, scheme->name.bv_len ) == 0 ) {
288 			bv->bv_val = &passwd->bv_val[scheme->name.bv_len];
289 			bv->bv_len = passwd->bv_len - scheme->name.bv_len;
290 
291 			return bv;
292 		}
293 	}
294 
295 	return NULL;
296 }
297 
298 /*
299  * Return 0 if creds are good.
300  */
301 int
lutil_passwd(const struct berval * passwd,const struct berval * cred,const char ** schemes,const char ** text)302 lutil_passwd(
303 	const struct berval *passwd,	/* stored passwd */
304 	const struct berval *cred,		/* user cred */
305 	const char **schemes,
306 	const char **text )
307 {
308 	struct pw_slist *pws;
309 
310 	if ( text ) *text = NULL;
311 
312 	if (cred == NULL || cred->bv_len == 0 ||
313 		passwd == NULL || passwd->bv_len == 0 )
314 	{
315 		return -1;
316 	}
317 
318 	if (!pw_inited) lutil_passwd_init();
319 
320 	for( pws=pw_schemes; pws; pws=pws->next ) {
321 		if( pws->s.chk_fn ) {
322 			struct berval x;
323 			struct berval *p = passwd_scheme( &(pws->s),
324 				passwd, &x, schemes );
325 
326 			if( p != NULL ) {
327 				return (pws->s.chk_fn)( &(pws->s.name), p, cred, text );
328 			}
329 		}
330 	}
331 
332 #ifdef SLAPD_CLEARTEXT
333 	/* Do we think there is a scheme specifier here that we
334 	 * didn't recognize? Assume a scheme name is at least 1 character.
335 	 */
336 	if (( passwd->bv_val[0] == '{' ) &&
337 		( ber_bvchr( passwd, '}' ) > passwd->bv_val+1 ))
338 	{
339 		return 1;
340 	}
341 	if( is_allowed_scheme("{CLEARTEXT}", schemes ) ) {
342 		return ( passwd->bv_len == cred->bv_len ) ?
343 			memcmp( passwd->bv_val, cred->bv_val, passwd->bv_len )
344 			: 1;
345 	}
346 #endif
347 	return 1;
348 }
349 
lutil_passwd_generate(struct berval * pw,ber_len_t len)350 int lutil_passwd_generate( struct berval *pw, ber_len_t len )
351 {
352 
353 	if( len < 1 ) return -1;
354 
355 	pw->bv_len = len;
356 	pw->bv_val = ber_memalloc( len + 1 );
357 
358 	if( pw->bv_val == NULL ) {
359 		return -1;
360 	}
361 
362 	if( lutil_entropy( (unsigned char *) pw->bv_val, pw->bv_len) < 0 ) {
363 		return -1;
364 	}
365 
366 	for( len = 0; len < pw->bv_len; len++ ) {
367 		pw->bv_val[len] = crypt64[
368 			pw->bv_val[len] % (sizeof(crypt64)-1) ];
369 	}
370 
371 	pw->bv_val[len] = '\0';
372 
373 	return 0;
374 }
375 
lutil_passwd_hash(const struct berval * passwd,const char * method,struct berval * hash,const char ** text)376 int lutil_passwd_hash(
377 	const struct berval * passwd,
378 	const char * method,
379 	struct berval *hash,
380 	const char **text )
381 {
382 	const struct pw_scheme *sc = get_scheme( method );
383 
384 	hash->bv_val = NULL;
385 	hash->bv_len = 0;
386 
387 	if( sc == NULL ) {
388 		if( text ) *text = "scheme not recognized";
389 		return -1;
390 	}
391 
392 	if( ! sc->hash_fn ) {
393 		if( text ) *text = "scheme provided no hash function";
394 		return -1;
395 	}
396 
397 	if( text ) *text = NULL;
398 
399 	return (sc->hash_fn)( &sc->name, passwd, hash, text );
400 }
401 
402 /* pw_string is only called when SLAPD_LMHASH or SLAPD_CRYPT is defined */
403 #if defined(SLAPD_LMHASH) || defined(SLAPD_CRYPT)
pw_string(const struct berval * sc,struct berval * passwd)404 static int pw_string(
405 	const struct berval *sc,
406 	struct berval *passwd )
407 {
408 	struct berval pw;
409 
410 	pw.bv_len = sc->bv_len + passwd->bv_len;
411 	pw.bv_val = ber_memalloc( pw.bv_len + 1 );
412 
413 	if( pw.bv_val == NULL ) {
414 		return LUTIL_PASSWD_ERR;
415 	}
416 
417 	AC_MEMCPY( pw.bv_val, sc->bv_val, sc->bv_len );
418 	AC_MEMCPY( &pw.bv_val[sc->bv_len], passwd->bv_val, passwd->bv_len );
419 
420 	pw.bv_val[pw.bv_len] = '\0';
421 	*passwd = pw;
422 
423 	return LUTIL_PASSWD_OK;
424 }
425 #endif /* SLAPD_LMHASH || SLAPD_CRYPT */
426 
lutil_passwd_string64(const struct berval * sc,const struct berval * hash,struct berval * b64,const struct berval * salt)427 int lutil_passwd_string64(
428 	const struct berval *sc,
429 	const struct berval *hash,
430 	struct berval *b64,
431 	const struct berval *salt )
432 {
433 	int rc;
434 	struct berval string;
435 	size_t b64len;
436 
437 	if( salt ) {
438 		/* need to base64 combined string */
439 		string.bv_len = hash->bv_len + salt->bv_len;
440 		string.bv_val = ber_memalloc( string.bv_len + 1 );
441 
442 		if( string.bv_val == NULL ) {
443 			return LUTIL_PASSWD_ERR;
444 		}
445 
446 		AC_MEMCPY( string.bv_val, hash->bv_val,
447 			hash->bv_len );
448 		AC_MEMCPY( &string.bv_val[hash->bv_len], salt->bv_val,
449 			salt->bv_len );
450 		string.bv_val[string.bv_len] = '\0';
451 
452 	} else {
453 		string = *hash;
454 	}
455 
456 	b64len = LUTIL_BASE64_ENCODE_LEN( string.bv_len ) + 1;
457 	b64->bv_len = b64len + sc->bv_len;
458 	b64->bv_val = ber_memalloc( b64->bv_len + 1 );
459 
460 	if( b64->bv_val == NULL ) {
461 		if( salt ) ber_memfree( string.bv_val );
462 		return LUTIL_PASSWD_ERR;
463 	}
464 
465 	AC_MEMCPY(b64->bv_val, sc->bv_val, sc->bv_len);
466 
467 	rc = lutil_b64_ntop(
468 		(unsigned char *) string.bv_val, string.bv_len,
469 		&b64->bv_val[sc->bv_len], b64len );
470 
471 	if( salt ) ber_memfree( string.bv_val );
472 
473 	if( rc < 0 ) {
474 		return LUTIL_PASSWD_ERR;
475 	}
476 
477 	/* recompute length */
478 	b64->bv_len = sc->bv_len + rc;
479 	assert( strlen(b64->bv_val) == b64->bv_len );
480 	return LUTIL_PASSWD_OK;
481 }
482 
483 /* PASSWORD CHECK ROUTINES */
484 
485 #ifdef LUTIL_SHA1_BYTES
chk_ssha1(const struct berval * sc,const struct berval * passwd,const struct berval * cred,const char ** text)486 static int chk_ssha1(
487 	const struct berval *sc,
488 	const struct berval * passwd,
489 	const struct berval * cred,
490 	const char **text )
491 {
492 	lutil_SHA1_CTX SHA1context;
493 	unsigned char SHA1digest[LUTIL_SHA1_BYTES];
494 	int rc;
495 	unsigned char *orig_pass = NULL;
496 	size_t decode_len = LUTIL_BASE64_DECODE_LEN(passwd->bv_len);
497 
498 	/* safety check -- must have some salt */
499 	if (decode_len <= sizeof(SHA1digest)) {
500 		return LUTIL_PASSWD_ERR;
501 	}
502 
503 	/* decode base64 password */
504 	orig_pass = (unsigned char *) ber_memalloc(decode_len + 1);
505 
506 	if( orig_pass == NULL ) return LUTIL_PASSWD_ERR;
507 
508 	rc = lutil_b64_pton(passwd->bv_val, orig_pass, decode_len);
509 
510 	/* safety check -- must have some salt */
511 	if (rc <= (int)(sizeof(SHA1digest))) {
512 		ber_memfree(orig_pass);
513 		return LUTIL_PASSWD_ERR;
514 	}
515 
516 	/* hash credentials with salt */
517 	lutil_SHA1Init(&SHA1context);
518 	lutil_SHA1Update(&SHA1context,
519 		(const unsigned char *) cred->bv_val, cred->bv_len);
520 	lutil_SHA1Update(&SHA1context,
521 		(const unsigned char *) &orig_pass[sizeof(SHA1digest)],
522 		rc - sizeof(SHA1digest));
523 	lutil_SHA1Final(SHA1digest, &SHA1context);
524 
525 	/* compare */
526 	rc = memcmp((char *)orig_pass, (char *)SHA1digest, sizeof(SHA1digest));
527 	ber_memfree(orig_pass);
528 	return rc ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK;
529 }
530 
chk_sha1(const struct berval * sc,const struct berval * passwd,const struct berval * cred,const char ** text)531 static int chk_sha1(
532 	const struct berval *sc,
533 	const struct berval * passwd,
534 	const struct berval * cred,
535 	const char **text )
536 {
537 	lutil_SHA1_CTX SHA1context;
538 	unsigned char SHA1digest[LUTIL_SHA1_BYTES];
539 	int rc;
540 	unsigned char *orig_pass = NULL;
541 	size_t decode_len = LUTIL_BASE64_DECODE_LEN(passwd->bv_len);
542 
543 	/* safety check */
544 	if (decode_len < sizeof(SHA1digest)) {
545 		return LUTIL_PASSWD_ERR;
546 	}
547 
548 	/* base64 un-encode password */
549 	orig_pass = (unsigned char *) ber_memalloc(decode_len + 1);
550 
551 	if( orig_pass == NULL ) return LUTIL_PASSWD_ERR;
552 
553 	rc = lutil_b64_pton(passwd->bv_val, orig_pass, decode_len);
554 
555 	if( rc != sizeof(SHA1digest) ) {
556 		ber_memfree(orig_pass);
557 		return LUTIL_PASSWD_ERR;
558 	}
559 
560 	/* hash credentials with salt */
561 	lutil_SHA1Init(&SHA1context);
562 	lutil_SHA1Update(&SHA1context,
563 		(const unsigned char *) cred->bv_val, cred->bv_len);
564 	lutil_SHA1Final(SHA1digest, &SHA1context);
565 
566 	/* compare */
567 	rc = memcmp((char *)orig_pass, (char *)SHA1digest, sizeof(SHA1digest));
568 	ber_memfree(orig_pass);
569 	return rc ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK;
570 }
571 #endif
572 
chk_smd5(const struct berval * sc,const struct berval * passwd,const struct berval * cred,const char ** text)573 static int chk_smd5(
574 	const struct berval *sc,
575 	const struct berval * passwd,
576 	const struct berval * cred,
577 	const char **text )
578 {
579 	lutil_MD5_CTX MD5context;
580 	unsigned char MD5digest[LUTIL_MD5_BYTES];
581 	int rc;
582 	unsigned char *orig_pass = NULL;
583 	size_t decode_len = LUTIL_BASE64_DECODE_LEN(passwd->bv_len);
584 
585 	/* safety check */
586 	if (decode_len <= sizeof(MD5digest)) {
587 		return LUTIL_PASSWD_ERR;
588 	}
589 
590 	/* base64 un-encode password */
591 	orig_pass = (unsigned char *) ber_memalloc(decode_len + 1);
592 
593 	if( orig_pass == NULL ) return LUTIL_PASSWD_ERR;
594 
595 	rc = lutil_b64_pton(passwd->bv_val, orig_pass, decode_len);
596 
597 	if (rc <= (int)(sizeof(MD5digest))) {
598 		ber_memfree(orig_pass);
599 		return LUTIL_PASSWD_ERR;
600 	}
601 
602 	/* hash credentials with salt */
603 	lutil_MD5Init(&MD5context);
604 	lutil_MD5Update(&MD5context,
605 		(const unsigned char *) cred->bv_val,
606 		cred->bv_len );
607 	lutil_MD5Update(&MD5context,
608 		&orig_pass[sizeof(MD5digest)],
609 		rc - sizeof(MD5digest));
610 	lutil_MD5Final(MD5digest, &MD5context);
611 
612 	/* compare */
613 	rc = memcmp((char *)orig_pass, (char *)MD5digest, sizeof(MD5digest));
614 	ber_memfree(orig_pass);
615 	return rc ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK;
616 }
617 
chk_md5(const struct berval * sc,const struct berval * passwd,const struct berval * cred,const char ** text)618 static int chk_md5(
619 	const struct berval *sc,
620 	const struct berval * passwd,
621 	const struct berval * cred,
622 	const char **text )
623 {
624 	lutil_MD5_CTX MD5context;
625 	unsigned char MD5digest[LUTIL_MD5_BYTES];
626 	int rc;
627 	unsigned char *orig_pass = NULL;
628 	size_t decode_len = LUTIL_BASE64_DECODE_LEN(passwd->bv_len);
629 
630 	/* safety check */
631 	if (decode_len < sizeof(MD5digest)) {
632 		return LUTIL_PASSWD_ERR;
633 	}
634 
635 	/* base64 un-encode password */
636 	orig_pass = (unsigned char *) ber_memalloc(decode_len + 1);
637 
638 	if( orig_pass == NULL ) return LUTIL_PASSWD_ERR;
639 
640 	rc = lutil_b64_pton(passwd->bv_val, orig_pass, decode_len);
641 	if ( rc != sizeof(MD5digest) ) {
642 		ber_memfree(orig_pass);
643 		return LUTIL_PASSWD_ERR;
644 	}
645 
646 	/* hash credentials with salt */
647 	lutil_MD5Init(&MD5context);
648 	lutil_MD5Update(&MD5context,
649 		(const unsigned char *) cred->bv_val,
650 		cred->bv_len );
651 	lutil_MD5Final(MD5digest, &MD5context);
652 
653 	/* compare */
654 	rc = memcmp((char *)orig_pass, (char *)MD5digest, sizeof(MD5digest));
655 	ber_memfree(orig_pass);
656 	return rc ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK;
657 }
658 
659 #ifdef SLAPD_LMHASH
660 
661 #if defined(HAVE_OPENSSL)
662 
663 /*
664  * abstract away setting the parity.
665  */
666 static void
des_set_key_and_parity(des_key * key,unsigned char * keyData)667 des_set_key_and_parity( des_key *key, unsigned char *keyData)
668 {
669     memcpy(key, keyData, 8);
670     DES_set_odd_parity( key );
671 }
672 
673 
674 #elif defined(HAVE_MOZNSS)
675 
676 /*
677  * implement MozNSS wrappers for the openSSL calls
678  */
679 static void
des_set_key_and_parity(des_key * key,unsigned char * keyData)680 des_set_key_and_parity( des_key *key, unsigned char *keyData)
681 {
682     SECItem keyDataItem;
683     PK11SlotInfo *slot;
684     *key = NULL;
685 
686     keyDataItem.data = keyData;
687     keyDataItem.len = 8;
688 
689     slot = PK11_GetBestSlot(CKM_DES_ECB, NULL);
690     if (slot == NULL) {
691 	return;
692     }
693 
694     /* NOTE: this will not work in FIPS mode. In order to make lmhash
695      * work in fips mode we need to define a LMHASH pbe mechanism and
696      * do the fulll key derivation inside the token */
697     *key = PK11_ImportSymKey(slot, CKM_DES_ECB, PK11_OriginGenerated,
698 		CKA_ENCRYPT, &keyDataItem, NULL);
699 }
700 
701 static void
DES_set_key_unchecked(des_key * key,des_context ctxt)702 DES_set_key_unchecked( des_key *key, des_context ctxt )
703 {
704     ctxt[0] = NULL;
705 
706     /* handle error conditions from previous call */
707     if (!*key) {
708 	return;
709     }
710 
711     ctxt[0] = PK11_CreateContextBySymKey(CKM_DES_ECB, CKA_ENCRYPT, *key, NULL);
712 }
713 
714 static void
DES_ecb_encrypt(des_data_block * plain,des_data_block * encrypted,des_context ctxt,int op)715 DES_ecb_encrypt( des_data_block *plain, des_data_block *encrypted,
716 			des_context ctxt, int op)
717 {
718     SECStatus rv;
719     int size;
720 
721     if (ctxt[0] == NULL) {
722 	/* need to fail here...  */
723 	memset(encrypted, 0, sizeof(des_data_block));
724 	return;
725     }
726     rv = PK11_CipherOp(ctxt[0], (unsigned char *)&encrypted[0],
727 			&size, sizeof(des_data_block),
728 			(unsigned char *)&plain[0], sizeof(des_data_block));
729     if (rv != SECSuccess) {
730 	/* signal failure */
731 	memset(encrypted, 0, sizeof(des_data_block));
732 	return;
733     }
734     return;
735 }
736 
737 static int
des_failed(des_data_block * encrypted)738 des_failed(des_data_block *encrypted)
739 {
740    static const des_data_block zero = { 0 };
741    return memcmp(encrypted, zero, sizeof(zero)) == 0;
742 }
743 
744 static void
des_finish(des_key * key,des_context ctxt)745 des_finish(des_key *key, des_context ctxt)
746 {
747      if (*key) {
748 	PK11_FreeSymKey(*key);
749 	*key = NULL;
750      }
751      if (ctxt[0]) {
752 	PK11_Finalize(ctxt[0]);
753 	PK11_DestroyContext(ctxt[0], PR_TRUE);
754 	ctxt[0] = NULL;
755      }
756 }
757 
758 #endif
759 
760 /* pseudocode from RFC2433
761  * A.2 LmPasswordHash()
762  *
763  *    LmPasswordHash(
764  *    IN  0-to-14-oem-char Password,
765  *    OUT 16-octet         PasswordHash )
766  *    {
767  *       Set UcasePassword to the uppercased Password
768  *       Zero pad UcasePassword to 14 characters
769  *
770  *       DesHash( 1st 7-octets of UcasePassword,
771  *                giving 1st 8-octets of PasswordHash )
772  *
773  *       DesHash( 2nd 7-octets of UcasePassword,
774  *                giving 2nd 8-octets of PasswordHash )
775  *    }
776  *
777  *
778  * A.3 DesHash()
779  *
780  *    DesHash(
781  *    IN  7-octet Clear,
782  *    OUT 8-octet Cypher )
783  *    {
784  *        *
785  *        * Make Cypher an irreversibly encrypted form of Clear by
786  *        * encrypting known text using Clear as the secret key.
787  *        * The known text consists of the string
788  *        *
789  *        *              KGS!@#$%
790  *        *
791  *
792  *       Set StdText to "KGS!@#$%"
793  *       DesEncrypt( StdText, Clear, giving Cypher )
794  *    }
795  *
796  *
797  * A.4 DesEncrypt()
798  *
799  *    DesEncrypt(
800  *    IN  8-octet Clear,
801  *    IN  7-octet Key,
802  *    OUT 8-octet Cypher )
803  *    {
804  *        *
805  *        * Use the DES encryption algorithm [4] in ECB mode [9]
806  *        * to encrypt Clear into Cypher such that Cypher can
807  *        * only be decrypted back to Clear by providing Key.
808  *        * Note that the DES algorithm takes as input a 64-bit
809  *        * stream where the 8th, 16th, 24th, etc.  bits are
810  *        * parity bits ignored by the encrypting algorithm.
811  *        * Unless you write your own DES to accept 56-bit input
812  *        * without parity, you will need to insert the parity bits
813  *        * yourself.
814  *        *
815  *    }
816  */
817 
lmPasswd_to_key(const char * lmPasswd,des_key * key)818 static void lmPasswd_to_key(
819 	const char *lmPasswd,
820 	des_key *key)
821 {
822 	const unsigned char *lpw = (const unsigned char *) lmPasswd;
823 	unsigned char k[8];
824 
825 	/* make room for parity bits */
826 	k[0] = lpw[0];
827 	k[1] = ((lpw[0] & 0x01) << 7) | (lpw[1] >> 1);
828 	k[2] = ((lpw[1] & 0x03) << 6) | (lpw[2] >> 2);
829 	k[3] = ((lpw[2] & 0x07) << 5) | (lpw[3] >> 3);
830 	k[4] = ((lpw[3] & 0x0F) << 4) | (lpw[4] >> 4);
831 	k[5] = ((lpw[4] & 0x1F) << 3) | (lpw[5] >> 5);
832 	k[6] = ((lpw[5] & 0x3F) << 2) | (lpw[6] >> 6);
833 	k[7] = ((lpw[6] & 0x7F) << 1);
834 
835 	des_set_key_and_parity( key, k );
836 }
837 
chk_lanman(const struct berval * scheme,const struct berval * passwd,const struct berval * cred,const char ** text)838 static int chk_lanman(
839 	const struct berval *scheme,
840 	const struct berval *passwd,
841 	const struct berval *cred,
842 	const char **text )
843 {
844 	ber_len_t i;
845 	char UcasePassword[15];
846 	des_key key;
847 	des_context schedule;
848 	des_data_block StdText = "KGS!@#$%";
849 	des_data_block PasswordHash1, PasswordHash2;
850 	char PasswordHash[33], storedPasswordHash[33];
851 
852 	for( i=0; i<cred->bv_len; i++) {
853 		if(cred->bv_val[i] == '\0') {
854 			return LUTIL_PASSWD_ERR;	/* NUL character in password */
855 		}
856 	}
857 
858 	if( cred->bv_val[i] != '\0' ) {
859 		return LUTIL_PASSWD_ERR;	/* passwd must behave like a string */
860 	}
861 
862 	strncpy( UcasePassword, cred->bv_val, 14 );
863 	UcasePassword[14] = '\0';
864 	ldap_pvt_str2upper( UcasePassword );
865 
866 	lmPasswd_to_key( UcasePassword, &key );
867 	DES_set_key_unchecked( &key, schedule );
868 	DES_ecb_encrypt( &StdText, &PasswordHash1, schedule , DES_ENCRYPT );
869 
870 	if (des_failed(&PasswordHash1)) {
871 	    return LUTIL_PASSWD_ERR;
872 	}
873 
874 	lmPasswd_to_key( &UcasePassword[7], &key );
875 	DES_set_key_unchecked( &key, schedule );
876 	DES_ecb_encrypt( &StdText, &PasswordHash2, schedule , DES_ENCRYPT );
877 	if (des_failed(&PasswordHash2)) {
878 	    return LUTIL_PASSWD_ERR;
879 	}
880 
881 	des_finish( &key, schedule );
882 
883 	sprintf( PasswordHash, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
884 		PasswordHash1[0],PasswordHash1[1],PasswordHash1[2],PasswordHash1[3],
885 		PasswordHash1[4],PasswordHash1[5],PasswordHash1[6],PasswordHash1[7],
886 		PasswordHash2[0],PasswordHash2[1],PasswordHash2[2],PasswordHash2[3],
887 		PasswordHash2[4],PasswordHash2[5],PasswordHash2[6],PasswordHash2[7] );
888 
889 	/* as a precaution convert stored password hash to lower case */
890 	strncpy( storedPasswordHash, passwd->bv_val, 32 );
891 	storedPasswordHash[32] = '\0';
892 	ldap_pvt_str2lower( storedPasswordHash );
893 
894 	return memcmp( PasswordHash, storedPasswordHash, 32) ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK;
895 }
896 #endif /* SLAPD_LMHASH */
897 
898 #ifdef SLAPD_CRYPT
lutil_crypt(const char * key,const char * salt,char ** hash)899 static int lutil_crypt(
900 	const char *key,
901 	const char *salt,
902 	char **hash )
903 {
904 	char *cr = crypt( key, salt );
905 	int rc;
906 
907 	if( cr == NULL || cr[0] == '\0' ) {
908 		/* salt must have been invalid */
909 		rc = LUTIL_PASSWD_ERR;
910 	} else {
911 		if ( hash ) {
912 			*hash = ber_strdup( cr );
913 			rc = LUTIL_PASSWD_OK;
914 		} else {
915 			rc = strcmp( salt, cr ) ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK;
916 		}
917 	}
918 	return rc;
919 }
920 
chk_crypt(const struct berval * sc,const struct berval * passwd,const struct berval * cred,const char ** text)921 static int chk_crypt(
922 	const struct berval *sc,
923 	const struct berval * passwd,
924 	const struct berval * cred,
925 	const char **text )
926 {
927 	unsigned int i;
928 
929 	for( i=0; i<cred->bv_len; i++) {
930 		if(cred->bv_val[i] == '\0') {
931 			return LUTIL_PASSWD_ERR;	/* NUL character in password */
932 		}
933 	}
934 
935 	if( cred->bv_val[i] != '\0' ) {
936 		return LUTIL_PASSWD_ERR;	/* cred must behave like a string */
937 	}
938 
939 	if( passwd->bv_len < 2 ) {
940 		return LUTIL_PASSWD_ERR;	/* passwd must be at least two characters long */
941 	}
942 
943 	for( i=0; i<passwd->bv_len; i++) {
944 		if(passwd->bv_val[i] == '\0') {
945 			return LUTIL_PASSWD_ERR;	/* NUL character in password */
946 		}
947 	}
948 
949 	if( passwd->bv_val[i] != '\0' ) {
950 		return LUTIL_PASSWD_ERR;	/* passwd must behave like a string */
951 	}
952 
953 	return lutil_cryptptr( cred->bv_val, passwd->bv_val, NULL );
954 }
955 
956 # if defined( HAVE_GETPWNAM ) && defined( HAVE_STRUCT_PASSWD_PW_PASSWD )
chk_unix(const struct berval * sc,const struct berval * passwd,const struct berval * cred,const char ** text)957 static int chk_unix(
958 	const struct berval *sc,
959 	const struct berval * passwd,
960 	const struct berval * cred,
961 	const char **text )
962 {
963 	unsigned int i;
964 	char *pw;
965 
966 	for( i=0; i<cred->bv_len; i++) {
967 		if(cred->bv_val[i] == '\0') {
968 			return LUTIL_PASSWD_ERR;	/* NUL character in password */
969 		}
970 	}
971 	if( cred->bv_val[i] != '\0' ) {
972 		return LUTIL_PASSWD_ERR;	/* cred must behave like a string */
973 	}
974 
975 	for( i=0; i<passwd->bv_len; i++) {
976 		if(passwd->bv_val[i] == '\0') {
977 			return LUTIL_PASSWD_ERR;	/* NUL character in password */
978 		}
979 	}
980 
981 	if( passwd->bv_val[i] != '\0' ) {
982 		return LUTIL_PASSWD_ERR;	/* passwd must behave like a string */
983 	}
984 
985 	{
986 		struct passwd *pwd = getpwnam(passwd->bv_val);
987 
988 		if(pwd == NULL) {
989 			return LUTIL_PASSWD_ERR;	/* not found */
990 		}
991 
992 		pw = pwd->pw_passwd;
993 	}
994 #  ifdef HAVE_GETSPNAM
995 	{
996 		struct spwd *spwd = getspnam(passwd->bv_val);
997 
998 		if(spwd != NULL) {
999 			pw = spwd->sp_pwdp;
1000 		}
1001 	}
1002 #  endif
1003 #  ifdef HAVE_AIX_SECURITY
1004 	{
1005 		struct userpw *upw = getuserpw(passwd->bv_val);
1006 
1007 		if (upw != NULL) {
1008 			pw = upw->upw_passwd;
1009 		}
1010 	}
1011 #  endif
1012 
1013 	if( pw == NULL || pw[0] == '\0' || pw[1] == '\0' ) {
1014 		/* password must must be at least two characters long */
1015 		return LUTIL_PASSWD_ERR;
1016 	}
1017 
1018 	return lutil_cryptptr( cred->bv_val, pw, NULL );
1019 }
1020 # endif
1021 #endif
1022 
1023 /* PASSWORD GENERATION ROUTINES */
1024 
1025 #ifdef LUTIL_SHA1_BYTES
hash_ssha1(const struct berval * scheme,const struct berval * passwd,struct berval * hash,const char ** text)1026 static int hash_ssha1(
1027 	const struct berval *scheme,
1028 	const struct berval  *passwd,
1029 	struct berval *hash,
1030 	const char **text )
1031 {
1032 	lutil_SHA1_CTX  SHA1context;
1033 	unsigned char   SHA1digest[LUTIL_SHA1_BYTES];
1034 	char            saltdata[SALT_SIZE];
1035 	struct berval digest;
1036 	struct berval salt;
1037 
1038 	digest.bv_val = (char *) SHA1digest;
1039 	digest.bv_len = sizeof(SHA1digest);
1040 	salt.bv_val = saltdata;
1041 	salt.bv_len = sizeof(saltdata);
1042 
1043 	if( lutil_entropy( (unsigned char *) salt.bv_val, salt.bv_len) < 0 ) {
1044 		return LUTIL_PASSWD_ERR;
1045 	}
1046 
1047 	lutil_SHA1Init( &SHA1context );
1048 	lutil_SHA1Update( &SHA1context,
1049 		(const unsigned char *)passwd->bv_val, passwd->bv_len );
1050 	lutil_SHA1Update( &SHA1context,
1051 		(const unsigned char *)salt.bv_val, salt.bv_len );
1052 	lutil_SHA1Final( SHA1digest, &SHA1context );
1053 
1054 	return lutil_passwd_string64( scheme, &digest, hash, &salt);
1055 }
1056 
hash_sha1(const struct berval * scheme,const struct berval * passwd,struct berval * hash,const char ** text)1057 static int hash_sha1(
1058 	const struct berval *scheme,
1059 	const struct berval  *passwd,
1060 	struct berval *hash,
1061 	const char **text )
1062 {
1063 	lutil_SHA1_CTX  SHA1context;
1064 	unsigned char   SHA1digest[LUTIL_SHA1_BYTES];
1065 	struct berval digest;
1066 	digest.bv_val = (char *) SHA1digest;
1067 	digest.bv_len = sizeof(SHA1digest);
1068 
1069 	lutil_SHA1Init( &SHA1context );
1070 	lutil_SHA1Update( &SHA1context,
1071 		(const unsigned char *)passwd->bv_val, passwd->bv_len );
1072 	lutil_SHA1Final( SHA1digest, &SHA1context );
1073 
1074 	return lutil_passwd_string64( scheme, &digest, hash, NULL);
1075 }
1076 #endif
1077 
hash_smd5(const struct berval * scheme,const struct berval * passwd,struct berval * hash,const char ** text)1078 static int hash_smd5(
1079 	const struct berval *scheme,
1080 	const struct berval  *passwd,
1081 	struct berval *hash,
1082 	const char **text )
1083 {
1084 	lutil_MD5_CTX   MD5context;
1085 	unsigned char   MD5digest[LUTIL_MD5_BYTES];
1086 	char            saltdata[SALT_SIZE];
1087 	struct berval digest;
1088 	struct berval salt;
1089 
1090 	digest.bv_val = (char *) MD5digest;
1091 	digest.bv_len = sizeof(MD5digest);
1092 	salt.bv_val = saltdata;
1093 	salt.bv_len = sizeof(saltdata);
1094 
1095 	if( lutil_entropy( (unsigned char *) salt.bv_val, salt.bv_len) < 0 ) {
1096 		return LUTIL_PASSWD_ERR;
1097 	}
1098 
1099 	lutil_MD5Init( &MD5context );
1100 	lutil_MD5Update( &MD5context,
1101 		(const unsigned char *) passwd->bv_val, passwd->bv_len );
1102 	lutil_MD5Update( &MD5context,
1103 		(const unsigned char *) salt.bv_val, salt.bv_len );
1104 	lutil_MD5Final( MD5digest, &MD5context );
1105 
1106 	return lutil_passwd_string64( scheme, &digest, hash, &salt );
1107 }
1108 
hash_md5(const struct berval * scheme,const struct berval * passwd,struct berval * hash,const char ** text)1109 static int hash_md5(
1110 	const struct berval *scheme,
1111 	const struct berval  *passwd,
1112 	struct berval *hash,
1113 	const char **text )
1114 {
1115 	lutil_MD5_CTX   MD5context;
1116 	unsigned char   MD5digest[LUTIL_MD5_BYTES];
1117 
1118 	struct berval digest;
1119 
1120 	digest.bv_val = (char *) MD5digest;
1121 	digest.bv_len = sizeof(MD5digest);
1122 
1123 	lutil_MD5Init( &MD5context );
1124 	lutil_MD5Update( &MD5context,
1125 		(const unsigned char *) passwd->bv_val, passwd->bv_len );
1126 	lutil_MD5Final( MD5digest, &MD5context );
1127 
1128 	return lutil_passwd_string64( scheme, &digest, hash, NULL );
1129 ;
1130 }
1131 
1132 #ifdef SLAPD_LMHASH
hash_lanman(const struct berval * scheme,const struct berval * passwd,struct berval * hash,const char ** text)1133 static int hash_lanman(
1134 	const struct berval *scheme,
1135 	const struct berval *passwd,
1136 	struct berval *hash,
1137 	const char **text )
1138 {
1139 
1140 	ber_len_t i;
1141 	char UcasePassword[15];
1142 	des_key key;
1143 	des_context schedule;
1144 	des_data_block StdText = "KGS!@#$%";
1145 	des_data_block PasswordHash1, PasswordHash2;
1146 	char PasswordHash[33];
1147 
1148 	for( i=0; i<passwd->bv_len; i++) {
1149 		if(passwd->bv_val[i] == '\0') {
1150 			return LUTIL_PASSWD_ERR;	/* NUL character in password */
1151 		}
1152 	}
1153 
1154 	if( passwd->bv_val[i] != '\0' ) {
1155 		return LUTIL_PASSWD_ERR;	/* passwd must behave like a string */
1156 	}
1157 
1158 	strncpy( UcasePassword, passwd->bv_val, 14 );
1159 	UcasePassword[14] = '\0';
1160 	ldap_pvt_str2upper( UcasePassword );
1161 
1162 	lmPasswd_to_key( UcasePassword, &key );
1163 	DES_set_key_unchecked( &key, schedule );
1164 	DES_ecb_encrypt( &StdText, &PasswordHash1, schedule , DES_ENCRYPT );
1165 
1166 	lmPasswd_to_key( &UcasePassword[7], &key );
1167 	DES_set_key_unchecked( &key, schedule );
1168 	DES_ecb_encrypt( &StdText, &PasswordHash2, schedule , DES_ENCRYPT );
1169 
1170 	sprintf( PasswordHash, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
1171 		PasswordHash1[0],PasswordHash1[1],PasswordHash1[2],PasswordHash1[3],
1172 		PasswordHash1[4],PasswordHash1[5],PasswordHash1[6],PasswordHash1[7],
1173 		PasswordHash2[0],PasswordHash2[1],PasswordHash2[2],PasswordHash2[3],
1174 		PasswordHash2[4],PasswordHash2[5],PasswordHash2[6],PasswordHash2[7] );
1175 
1176 	hash->bv_val = PasswordHash;
1177 	hash->bv_len = 32;
1178 
1179 	return pw_string( scheme, hash );
1180 }
1181 #endif /* SLAPD_LMHASH */
1182 
1183 #ifdef SLAPD_CRYPT
hash_crypt(const struct berval * scheme,const struct berval * passwd,struct berval * hash,const char ** text)1184 static int hash_crypt(
1185 	const struct berval *scheme,
1186 	const struct berval *passwd,
1187 	struct berval *hash,
1188 	const char **text )
1189 {
1190 	unsigned char salt[32];	/* salt suitable for most anything */
1191 	unsigned int i;
1192 	char *save;
1193 	int rc;
1194 
1195 	for( i=0; i<passwd->bv_len; i++) {
1196 		if(passwd->bv_val[i] == '\0') {
1197 			return LUTIL_PASSWD_ERR;	/* NUL character in password */
1198 		}
1199 	}
1200 
1201 	if( passwd->bv_val[i] != '\0' ) {
1202 		return LUTIL_PASSWD_ERR;	/* passwd must behave like a string */
1203 	}
1204 
1205 	if( lutil_entropy( salt, sizeof( salt ) ) < 0 ) {
1206 		return LUTIL_PASSWD_ERR;
1207 	}
1208 
1209 	for( i=0; i< ( sizeof(salt) - 1 ); i++ ) {
1210 		salt[i] = crypt64[ salt[i] % (sizeof(crypt64)-1) ];
1211 	}
1212 	salt[sizeof( salt ) - 1 ] = '\0';
1213 
1214 	if( salt_format != NULL ) {
1215 		/* copy the salt we made into entropy before snprintfing
1216 		   it back into the salt */
1217 		char entropy[sizeof(salt)];
1218 		strcpy( entropy, (char *) salt );
1219 		snprintf( (char *) salt, sizeof(entropy), salt_format, entropy );
1220 	}
1221 
1222 	rc = lutil_cryptptr( passwd->bv_val, (char *) salt, &hash->bv_val );
1223 	if ( rc != LUTIL_PASSWD_OK ) return rc;
1224 
1225 	if( hash->bv_val == NULL ) return -1;
1226 
1227 	hash->bv_len = strlen( hash->bv_val );
1228 
1229 	save = hash->bv_val;
1230 
1231 	if( hash->bv_len == 0 ) {
1232 		rc = LUTIL_PASSWD_ERR;
1233 	} else {
1234 		rc = pw_string( scheme, hash );
1235 	}
1236 	ber_memfree( save );
1237 	return rc;
1238 }
1239 #endif
1240 
lutil_salt_format(const char * format)1241 int lutil_salt_format(const char *format)
1242 {
1243 #ifdef SLAPD_CRYPT
1244 	ber_memfree( salt_format );
1245 
1246 	salt_format = format != NULL ? ber_strdup( format ) : NULL;
1247 #endif
1248 
1249 	return 0;
1250 }
1251 
1252 #ifdef SLAPD_CLEARTEXT
hash_clear(const struct berval * scheme,const struct berval * passwd,struct berval * hash,const char ** text)1253 static int hash_clear(
1254 	const struct berval *scheme,
1255 	const struct berval  *passwd,
1256 	struct berval *hash,
1257 	const char **text )
1258 {
1259 	ber_dupbv( hash, (struct berval *)passwd );
1260 	return LUTIL_PASSWD_OK;
1261 }
1262 #endif
1263 
1264