1 /* $NetBSD: passwd.c,v 1.9 2021/08/14 16:14:58 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 /*
19 * int lutil_passwd(
20 * const struct berval *passwd,
21 * const struct berval *cred,
22 * const char **schemes )
23 *
24 * Returns true if user supplied credentials (cred) matches
25 * the stored password (passwd).
26 *
27 * Due to the use of the crypt(3) function
28 * this routine is NOT thread-safe.
29 */
30
31 #include <sys/cdefs.h>
32 __RCSID("$NetBSD: passwd.c,v 1.9 2021/08/14 16:14:58 christos Exp $");
33
34 #include "portable.h"
35
36 #include <stdio.h>
37 #include <ac/stdlib.h>
38 #include <ac/string.h>
39 #include <ac/time.h>
40 #include <ac/unistd.h>
41 #include <ac/param.h>
42
43 #ifdef SLAPD_CRYPT
44 # include <ac/crypt.h>
45
46 # if defined( HAVE_GETPWNAM ) && defined( HAVE_STRUCT_PASSWD_PW_PASSWD )
47 # ifdef HAVE_SHADOW_H
48 # include <shadow.h>
49 # endif
50 # ifdef HAVE_PWD_H
51 # include <pwd.h>
52 # endif
53 # ifdef HAVE_AIX_SECURITY
54 # include <userpw.h>
55 # endif
56 # endif
57 #endif
58
59 #include <lber.h>
60
61 #include "ldap_pvt.h"
62 #include "lber_pvt.h"
63
64 #include "lutil_md5.h"
65 #include "lutil_sha1.h"
66 #include "lutil.h"
67
68 static const unsigned char crypt64[] =
69 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890./";
70
71 #ifdef SLAPD_CRYPT
72 static char *salt_format = NULL;
73 static lutil_cryptfunc lutil_crypt;
74 lutil_cryptfunc *lutil_cryptptr = lutil_crypt;
75 #endif
76
77 /* KLUDGE:
78 * chk_fn is NULL iff name is {CLEARTEXT}
79 * otherwise, things will break
80 */
81 struct pw_scheme {
82 struct berval name;
83 LUTIL_PASSWD_CHK_FUNC *chk_fn;
84 LUTIL_PASSWD_HASH_FUNC *hash_fn;
85 };
86
87 struct pw_slist {
88 struct pw_slist *next;
89 struct pw_scheme s;
90 };
91
92 /* password check routines */
93
94 #define SALT_SIZE 4
95
96 static LUTIL_PASSWD_CHK_FUNC chk_md5;
97 static LUTIL_PASSWD_CHK_FUNC chk_smd5;
98 static LUTIL_PASSWD_HASH_FUNC hash_smd5;
99 static LUTIL_PASSWD_HASH_FUNC hash_md5;
100
101
102 #ifdef LUTIL_SHA1_BYTES
103 static LUTIL_PASSWD_CHK_FUNC chk_ssha1;
104 static LUTIL_PASSWD_CHK_FUNC chk_sha1;
105 static LUTIL_PASSWD_HASH_FUNC hash_sha1;
106 static LUTIL_PASSWD_HASH_FUNC hash_ssha1;
107 #endif
108
109
110 #ifdef SLAPD_CRYPT
111 static LUTIL_PASSWD_CHK_FUNC chk_crypt;
112 static LUTIL_PASSWD_HASH_FUNC hash_crypt;
113
114 #if defined( HAVE_GETPWNAM ) && defined( HAVE_STRUCT_PASSWD_PW_PASSWD )
115 static LUTIL_PASSWD_CHK_FUNC chk_unix;
116 #endif
117 #endif
118
119 /* password hash routines */
120
121 #ifdef SLAPD_CLEARTEXT
122 static LUTIL_PASSWD_HASH_FUNC hash_clear;
123 #endif
124
125 static struct pw_slist *pw_schemes;
126 static int pw_inited;
127
128 static const struct pw_scheme pw_schemes_default[] =
129 {
130 #ifdef LUTIL_SHA1_BYTES
131 { BER_BVC("{SSHA}"), chk_ssha1, hash_ssha1 },
132 { BER_BVC("{SHA}"), chk_sha1, hash_sha1 },
133 #endif
134
135 { BER_BVC("{SMD5}"), chk_smd5, hash_smd5 },
136 { BER_BVC("{MD5}"), chk_md5, hash_md5 },
137
138 #ifdef SLAPD_CRYPT
139 { BER_BVC("{CRYPT}"), chk_crypt, hash_crypt },
140 # if defined( HAVE_GETPWNAM ) && defined( HAVE_STRUCT_PASSWD_PW_PASSWD )
141 { BER_BVC("{UNIX}"), chk_unix, NULL },
142 # endif
143 #endif
144
145 #ifdef SLAPD_CLEARTEXT
146 /* pseudo scheme */
147 { BER_BVC("{CLEARTEXT}"), NULL, hash_clear },
148 #endif
149
150 { BER_BVNULL, NULL, NULL }
151 };
152
lutil_passwd_add(struct berval * scheme,LUTIL_PASSWD_CHK_FUNC * chk,LUTIL_PASSWD_HASH_FUNC * hash)153 int lutil_passwd_add(
154 struct berval *scheme,
155 LUTIL_PASSWD_CHK_FUNC *chk,
156 LUTIL_PASSWD_HASH_FUNC *hash )
157 {
158 struct pw_slist *ptr;
159
160 if (!pw_inited) lutil_passwd_init();
161
162 ptr = ber_memalloc( sizeof( struct pw_slist ));
163 if (!ptr) return -1;
164 ptr->next = pw_schemes;
165 ptr->s.name = *scheme;
166 ptr->s.chk_fn = chk;
167 ptr->s.hash_fn = hash;
168 pw_schemes = ptr;
169 return 0;
170 }
171
lutil_passwd_init()172 void lutil_passwd_init()
173 {
174 struct pw_scheme *s;
175
176 pw_inited = 1;
177
178 for( s=(struct pw_scheme *)pw_schemes_default; s->name.bv_val; s++) {
179 if ( lutil_passwd_add( &s->name, s->chk_fn, s->hash_fn ) ) break;
180 }
181 }
182
lutil_passwd_destroy()183 void lutil_passwd_destroy()
184 {
185 struct pw_slist *ptr, *next;
186
187 for( ptr=pw_schemes; ptr; ptr=next ) {
188 next = ptr->next;
189 ber_memfree( ptr );
190 }
191 }
192
get_scheme(const char * scheme)193 static const struct pw_scheme *get_scheme(
194 const char* scheme )
195 {
196 struct pw_slist *pws;
197 struct berval bv;
198
199 if (!pw_inited) lutil_passwd_init();
200
201 bv.bv_val = strchr( scheme, '}' );
202 if ( !bv.bv_val )
203 return NULL;
204
205 bv.bv_len = bv.bv_val - scheme + 1;
206 bv.bv_val = (char *) scheme;
207
208 for( pws=pw_schemes; pws; pws=pws->next ) {
209 if ( ber_bvstrcasecmp(&bv, &pws->s.name ) == 0 ) {
210 return &(pws->s);
211 }
212 }
213
214 return NULL;
215 }
216
lutil_passwd_scheme(const char * scheme)217 int lutil_passwd_scheme(
218 const char* scheme )
219 {
220 if( scheme == NULL ) {
221 return 0;
222 }
223
224 return get_scheme(scheme) != NULL;
225 }
226
227
is_allowed_scheme(const char * scheme,const char ** schemes)228 static int is_allowed_scheme(
229 const char* scheme,
230 const char** schemes )
231 {
232 int i;
233
234 if( schemes == NULL ) return 1;
235
236 for( i=0; schemes[i] != NULL; i++ ) {
237 if( strcasecmp( scheme, schemes[i] ) == 0 ) {
238 return 1;
239 }
240 }
241 return 0;
242 }
243
passwd_scheme(const struct pw_scheme * scheme,const struct berval * passwd,struct berval * bv,const char ** allowed)244 static struct berval *passwd_scheme(
245 const struct pw_scheme *scheme,
246 const struct berval * passwd,
247 struct berval *bv,
248 const char** allowed )
249 {
250 if( !is_allowed_scheme( scheme->name.bv_val, allowed ) ) {
251 return NULL;
252 }
253
254 if( passwd->bv_len >= scheme->name.bv_len ) {
255 if( strncasecmp( passwd->bv_val, scheme->name.bv_val, scheme->name.bv_len ) == 0 ) {
256 bv->bv_val = &passwd->bv_val[scheme->name.bv_len];
257 bv->bv_len = passwd->bv_len - scheme->name.bv_len;
258
259 return bv;
260 }
261 }
262
263 return NULL;
264 }
265
266 /*
267 * Return 0 if creds are good.
268 */
269 int
lutil_passwd(const struct berval * passwd,const struct berval * cred,const char ** schemes,const char ** text)270 lutil_passwd(
271 const struct berval *passwd, /* stored passwd */
272 const struct berval *cred, /* user cred */
273 const char **schemes,
274 const char **text )
275 {
276 struct pw_slist *pws;
277
278 if ( text ) *text = NULL;
279
280 if (cred == NULL || cred->bv_len == 0 ||
281 passwd == NULL || passwd->bv_len == 0 )
282 {
283 return -1;
284 }
285
286 if (!pw_inited) lutil_passwd_init();
287
288 for( pws=pw_schemes; pws; pws=pws->next ) {
289 if( pws->s.chk_fn ) {
290 struct berval x;
291 struct berval *p = passwd_scheme( &(pws->s),
292 passwd, &x, schemes );
293
294 if( p != NULL ) {
295 return (pws->s.chk_fn)( &(pws->s.name), p, cred, text );
296 }
297 }
298 }
299
300 #ifdef SLAPD_CLEARTEXT
301 /* Do we think there is a scheme specifier here that we
302 * didn't recognize? Assume a scheme name is at least 1 character.
303 */
304 if (( passwd->bv_val[0] == '{' ) &&
305 ( ber_bvchr( passwd, '}' ) > passwd->bv_val+1 ))
306 {
307 return 1;
308 }
309 if( is_allowed_scheme("{CLEARTEXT}", schemes ) ) {
310 return ( passwd->bv_len == cred->bv_len ) ?
311 memcmp( passwd->bv_val, cred->bv_val, passwd->bv_len )
312 : 1;
313 }
314 #endif
315 return 1;
316 }
317
lutil_passwd_generate(struct berval * pw,ber_len_t len)318 int lutil_passwd_generate( struct berval *pw, ber_len_t len )
319 {
320
321 if( len < 1 ) return -1;
322
323 pw->bv_len = len;
324 pw->bv_val = ber_memalloc( len + 1 );
325
326 if( pw->bv_val == NULL ) {
327 return -1;
328 }
329
330 if( lutil_entropy( (unsigned char *) pw->bv_val, pw->bv_len) < 0 ) {
331 return -1;
332 }
333
334 for( len = 0; len < pw->bv_len; len++ ) {
335 pw->bv_val[len] = crypt64[
336 pw->bv_val[len] % (sizeof(crypt64)-1) ];
337 }
338
339 pw->bv_val[len] = '\0';
340
341 return 0;
342 }
343
lutil_passwd_hash(const struct berval * passwd,const char * method,struct berval * hash,const char ** text)344 int lutil_passwd_hash(
345 const struct berval * passwd,
346 const char * method,
347 struct berval *hash,
348 const char **text )
349 {
350 const struct pw_scheme *sc = get_scheme( method );
351
352 hash->bv_val = NULL;
353 hash->bv_len = 0;
354
355 if( sc == NULL ) {
356 if( text ) *text = "scheme not recognized";
357 return -1;
358 }
359
360 if( ! sc->hash_fn ) {
361 if( text ) *text = "scheme provided no hash function";
362 return -1;
363 }
364
365 if( text ) *text = NULL;
366
367 return (sc->hash_fn)( &sc->name, passwd, hash, text );
368 }
369
370 /* pw_string is only called when SLAPD_CRYPT is defined */
371 #if defined(SLAPD_CRYPT)
pw_string(const struct berval * sc,struct berval * passwd)372 static int pw_string(
373 const struct berval *sc,
374 struct berval *passwd )
375 {
376 struct berval pw;
377
378 pw.bv_len = sc->bv_len + passwd->bv_len;
379 pw.bv_val = ber_memalloc( pw.bv_len + 1 );
380
381 if( pw.bv_val == NULL ) {
382 return LUTIL_PASSWD_ERR;
383 }
384
385 AC_MEMCPY( pw.bv_val, sc->bv_val, sc->bv_len );
386 AC_MEMCPY( &pw.bv_val[sc->bv_len], passwd->bv_val, passwd->bv_len );
387
388 pw.bv_val[pw.bv_len] = '\0';
389 *passwd = pw;
390
391 return LUTIL_PASSWD_OK;
392 }
393 #endif /* SLAPD_CRYPT */
394
lutil_passwd_string64(const struct berval * sc,const struct berval * hash,struct berval * b64,const struct berval * salt)395 int lutil_passwd_string64(
396 const struct berval *sc,
397 const struct berval *hash,
398 struct berval *b64,
399 const struct berval *salt )
400 {
401 int rc;
402 struct berval string;
403 size_t b64len;
404
405 if( salt ) {
406 /* need to base64 combined string */
407 string.bv_len = hash->bv_len + salt->bv_len;
408 string.bv_val = ber_memalloc( string.bv_len + 1 );
409
410 if( string.bv_val == NULL ) {
411 return LUTIL_PASSWD_ERR;
412 }
413
414 AC_MEMCPY( string.bv_val, hash->bv_val,
415 hash->bv_len );
416 AC_MEMCPY( &string.bv_val[hash->bv_len], salt->bv_val,
417 salt->bv_len );
418 string.bv_val[string.bv_len] = '\0';
419
420 } else {
421 string = *hash;
422 }
423
424 b64len = LUTIL_BASE64_ENCODE_LEN( string.bv_len ) + 1;
425 b64->bv_len = b64len + sc->bv_len;
426 b64->bv_val = ber_memalloc( b64->bv_len + 1 );
427
428 if( b64->bv_val == NULL ) {
429 if( salt ) ber_memfree( string.bv_val );
430 return LUTIL_PASSWD_ERR;
431 }
432
433 AC_MEMCPY(b64->bv_val, sc->bv_val, sc->bv_len);
434
435 rc = lutil_b64_ntop(
436 (unsigned char *) string.bv_val, string.bv_len,
437 &b64->bv_val[sc->bv_len], b64len );
438
439 if( salt ) ber_memfree( string.bv_val );
440
441 if( rc < 0 ) {
442 return LUTIL_PASSWD_ERR;
443 }
444
445 /* recompute length */
446 b64->bv_len = sc->bv_len + rc;
447 assert( strlen(b64->bv_val) == b64->bv_len );
448 return LUTIL_PASSWD_OK;
449 }
450
451 /* PASSWORD CHECK ROUTINES */
452
453 #ifdef LUTIL_SHA1_BYTES
chk_ssha1(const struct berval * sc,const struct berval * passwd,const struct berval * cred,const char ** text)454 static int chk_ssha1(
455 const struct berval *sc,
456 const struct berval * passwd,
457 const struct berval * cred,
458 const char **text )
459 {
460 lutil_SHA1_CTX SHA1context;
461 unsigned char SHA1digest[LUTIL_SHA1_BYTES];
462 int rc;
463 unsigned char *orig_pass = NULL;
464 size_t decode_len = LUTIL_BASE64_DECODE_LEN(passwd->bv_len);
465
466 /* safety check -- must have some salt */
467 if (decode_len <= sizeof(SHA1digest)) {
468 return LUTIL_PASSWD_ERR;
469 }
470
471 /* decode base64 password */
472 orig_pass = (unsigned char *) ber_memalloc(decode_len + 1);
473
474 if( orig_pass == NULL ) return LUTIL_PASSWD_ERR;
475
476 rc = lutil_b64_pton(passwd->bv_val, orig_pass, decode_len);
477
478 /* safety check -- must have some salt */
479 if (rc <= (int)(sizeof(SHA1digest))) {
480 ber_memfree(orig_pass);
481 return LUTIL_PASSWD_ERR;
482 }
483
484 /* hash credentials with salt */
485 lutil_SHA1Init(&SHA1context);
486 lutil_SHA1Update(&SHA1context,
487 (const unsigned char *) cred->bv_val, cred->bv_len);
488 lutil_SHA1Update(&SHA1context,
489 (const unsigned char *) &orig_pass[sizeof(SHA1digest)],
490 rc - sizeof(SHA1digest));
491 lutil_SHA1Final(SHA1digest, &SHA1context);
492
493 /* compare */
494 rc = memcmp((char *)orig_pass, (char *)SHA1digest, sizeof(SHA1digest));
495 ber_memfree(orig_pass);
496 return rc ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK;
497 }
498
chk_sha1(const struct berval * sc,const struct berval * passwd,const struct berval * cred,const char ** text)499 static int chk_sha1(
500 const struct berval *sc,
501 const struct berval * passwd,
502 const struct berval * cred,
503 const char **text )
504 {
505 lutil_SHA1_CTX SHA1context;
506 unsigned char SHA1digest[LUTIL_SHA1_BYTES];
507 int rc;
508 unsigned char *orig_pass = NULL;
509 size_t decode_len = LUTIL_BASE64_DECODE_LEN(passwd->bv_len);
510
511 /* safety check */
512 if (decode_len < sizeof(SHA1digest)) {
513 return LUTIL_PASSWD_ERR;
514 }
515
516 /* base64 un-encode password */
517 orig_pass = (unsigned char *) ber_memalloc(decode_len + 1);
518
519 if( orig_pass == NULL ) return LUTIL_PASSWD_ERR;
520
521 rc = lutil_b64_pton(passwd->bv_val, orig_pass, decode_len);
522
523 if( rc != sizeof(SHA1digest) ) {
524 ber_memfree(orig_pass);
525 return LUTIL_PASSWD_ERR;
526 }
527
528 /* hash credentials with salt */
529 lutil_SHA1Init(&SHA1context);
530 lutil_SHA1Update(&SHA1context,
531 (const unsigned char *) cred->bv_val, cred->bv_len);
532 lutil_SHA1Final(SHA1digest, &SHA1context);
533
534 /* compare */
535 rc = memcmp((char *)orig_pass, (char *)SHA1digest, sizeof(SHA1digest));
536 ber_memfree(orig_pass);
537 return rc ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK;
538 }
539 #endif
540
chk_smd5(const struct berval * sc,const struct berval * passwd,const struct berval * cred,const char ** text)541 static int chk_smd5(
542 const struct berval *sc,
543 const struct berval * passwd,
544 const struct berval * cred,
545 const char **text )
546 {
547 lutil_MD5_CTX MD5context;
548 unsigned char MD5digest[LUTIL_MD5_BYTES];
549 int rc;
550 unsigned char *orig_pass = NULL;
551 size_t decode_len = LUTIL_BASE64_DECODE_LEN(passwd->bv_len);
552
553 /* safety check */
554 if (decode_len <= sizeof(MD5digest)) {
555 return LUTIL_PASSWD_ERR;
556 }
557
558 /* base64 un-encode password */
559 orig_pass = (unsigned char *) ber_memalloc(decode_len + 1);
560
561 if( orig_pass == NULL ) return LUTIL_PASSWD_ERR;
562
563 rc = lutil_b64_pton(passwd->bv_val, orig_pass, decode_len);
564
565 if (rc <= (int)(sizeof(MD5digest))) {
566 ber_memfree(orig_pass);
567 return LUTIL_PASSWD_ERR;
568 }
569
570 /* hash credentials with salt */
571 lutil_MD5Init(&MD5context);
572 lutil_MD5Update(&MD5context,
573 (const unsigned char *) cred->bv_val,
574 cred->bv_len );
575 lutil_MD5Update(&MD5context,
576 &orig_pass[sizeof(MD5digest)],
577 rc - sizeof(MD5digest));
578 lutil_MD5Final(MD5digest, &MD5context);
579
580 /* compare */
581 rc = memcmp((char *)orig_pass, (char *)MD5digest, sizeof(MD5digest));
582 ber_memfree(orig_pass);
583 return rc ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK;
584 }
585
chk_md5(const struct berval * sc,const struct berval * passwd,const struct berval * cred,const char ** text)586 static int chk_md5(
587 const struct berval *sc,
588 const struct berval * passwd,
589 const struct berval * cred,
590 const char **text )
591 {
592 lutil_MD5_CTX MD5context;
593 unsigned char MD5digest[LUTIL_MD5_BYTES];
594 int rc;
595 unsigned char *orig_pass = NULL;
596 size_t decode_len = LUTIL_BASE64_DECODE_LEN(passwd->bv_len);
597
598 /* safety check */
599 if (decode_len < sizeof(MD5digest)) {
600 return LUTIL_PASSWD_ERR;
601 }
602
603 /* base64 un-encode password */
604 orig_pass = (unsigned char *) ber_memalloc(decode_len + 1);
605
606 if( orig_pass == NULL ) return LUTIL_PASSWD_ERR;
607
608 rc = lutil_b64_pton(passwd->bv_val, orig_pass, decode_len);
609 if ( rc != sizeof(MD5digest) ) {
610 ber_memfree(orig_pass);
611 return LUTIL_PASSWD_ERR;
612 }
613
614 /* hash credentials with salt */
615 lutil_MD5Init(&MD5context);
616 lutil_MD5Update(&MD5context,
617 (const unsigned char *) cred->bv_val,
618 cred->bv_len );
619 lutil_MD5Final(MD5digest, &MD5context);
620
621 /* compare */
622 rc = memcmp((char *)orig_pass, (char *)MD5digest, sizeof(MD5digest));
623 ber_memfree(orig_pass);
624 return rc ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK;
625 }
626
627 #ifdef SLAPD_CRYPT
lutil_crypt(const char * key,const char * salt,char ** hash)628 static int lutil_crypt(
629 const char *key,
630 const char *salt,
631 char **hash )
632 {
633 char *cr = crypt( key, salt );
634 int rc;
635
636 if( cr == NULL || cr[0] == '\0' ) {
637 /* salt must have been invalid */
638 rc = LUTIL_PASSWD_ERR;
639 } else {
640 if ( hash ) {
641 *hash = ber_strdup( cr );
642 rc = LUTIL_PASSWD_OK;
643 } else {
644 rc = strcmp( salt, cr ) ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK;
645 }
646 }
647 return rc;
648 }
649
chk_crypt(const struct berval * sc,const struct berval * passwd,const struct berval * cred,const char ** text)650 static int chk_crypt(
651 const struct berval *sc,
652 const struct berval * passwd,
653 const struct berval * cred,
654 const char **text )
655 {
656 unsigned int i;
657
658 for( i=0; i<cred->bv_len; i++) {
659 if(cred->bv_val[i] == '\0') {
660 return LUTIL_PASSWD_ERR; /* NUL character in password */
661 }
662 }
663
664 if( cred->bv_val[i] != '\0' ) {
665 return LUTIL_PASSWD_ERR; /* cred must behave like a string */
666 }
667
668 if( passwd->bv_len < 2 ) {
669 return LUTIL_PASSWD_ERR; /* passwd must be at least two characters long */
670 }
671
672 for( i=0; i<passwd->bv_len; i++) {
673 if(passwd->bv_val[i] == '\0') {
674 return LUTIL_PASSWD_ERR; /* NUL character in password */
675 }
676 }
677
678 if( passwd->bv_val[i] != '\0' ) {
679 return LUTIL_PASSWD_ERR; /* passwd must behave like a string */
680 }
681
682 return lutil_cryptptr( cred->bv_val, passwd->bv_val, NULL );
683 }
684
685 # 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)686 static int chk_unix(
687 const struct berval *sc,
688 const struct berval * passwd,
689 const struct berval * cred,
690 const char **text )
691 {
692 unsigned int i;
693 char *pw;
694
695 for( i=0; i<cred->bv_len; i++) {
696 if(cred->bv_val[i] == '\0') {
697 return LUTIL_PASSWD_ERR; /* NUL character in password */
698 }
699 }
700 if( cred->bv_val[i] != '\0' ) {
701 return LUTIL_PASSWD_ERR; /* cred must behave like a string */
702 }
703
704 for( i=0; i<passwd->bv_len; i++) {
705 if(passwd->bv_val[i] == '\0') {
706 return LUTIL_PASSWD_ERR; /* NUL character in password */
707 }
708 }
709
710 if( passwd->bv_val[i] != '\0' ) {
711 return LUTIL_PASSWD_ERR; /* passwd must behave like a string */
712 }
713
714 {
715 struct passwd *pwd = getpwnam(passwd->bv_val);
716
717 if(pwd == NULL) {
718 return LUTIL_PASSWD_ERR; /* not found */
719 }
720
721 pw = pwd->pw_passwd;
722 }
723 # ifdef HAVE_GETSPNAM
724 {
725 struct spwd *spwd = getspnam(passwd->bv_val);
726
727 if(spwd != NULL) {
728 pw = spwd->sp_pwdp;
729 }
730 }
731 # endif
732 # ifdef HAVE_AIX_SECURITY
733 {
734 struct userpw *upw = getuserpw(passwd->bv_val);
735
736 if (upw != NULL) {
737 pw = upw->upw_passwd;
738 }
739 }
740 # endif
741
742 if( pw == NULL || pw[0] == '\0' || pw[1] == '\0' ) {
743 /* password must must be at least two characters long */
744 return LUTIL_PASSWD_ERR;
745 }
746
747 return lutil_cryptptr( cred->bv_val, pw, NULL );
748 }
749 # endif
750 #endif
751
752 /* PASSWORD GENERATION ROUTINES */
753
754 #ifdef LUTIL_SHA1_BYTES
hash_ssha1(const struct berval * scheme,const struct berval * passwd,struct berval * hash,const char ** text)755 static int hash_ssha1(
756 const struct berval *scheme,
757 const struct berval *passwd,
758 struct berval *hash,
759 const char **text )
760 {
761 lutil_SHA1_CTX SHA1context;
762 unsigned char SHA1digest[LUTIL_SHA1_BYTES];
763 char saltdata[SALT_SIZE];
764 struct berval digest;
765 struct berval salt;
766
767 digest.bv_val = (char *) SHA1digest;
768 digest.bv_len = sizeof(SHA1digest);
769 salt.bv_val = saltdata;
770 salt.bv_len = sizeof(saltdata);
771
772 if( lutil_entropy( (unsigned char *) salt.bv_val, salt.bv_len) < 0 ) {
773 return LUTIL_PASSWD_ERR;
774 }
775
776 lutil_SHA1Init( &SHA1context );
777 lutil_SHA1Update( &SHA1context,
778 (const unsigned char *)passwd->bv_val, passwd->bv_len );
779 lutil_SHA1Update( &SHA1context,
780 (const unsigned char *)salt.bv_val, salt.bv_len );
781 lutil_SHA1Final( SHA1digest, &SHA1context );
782
783 return lutil_passwd_string64( scheme, &digest, hash, &salt);
784 }
785
hash_sha1(const struct berval * scheme,const struct berval * passwd,struct berval * hash,const char ** text)786 static int hash_sha1(
787 const struct berval *scheme,
788 const struct berval *passwd,
789 struct berval *hash,
790 const char **text )
791 {
792 lutil_SHA1_CTX SHA1context;
793 unsigned char SHA1digest[LUTIL_SHA1_BYTES];
794 struct berval digest;
795 digest.bv_val = (char *) SHA1digest;
796 digest.bv_len = sizeof(SHA1digest);
797
798 lutil_SHA1Init( &SHA1context );
799 lutil_SHA1Update( &SHA1context,
800 (const unsigned char *)passwd->bv_val, passwd->bv_len );
801 lutil_SHA1Final( SHA1digest, &SHA1context );
802
803 return lutil_passwd_string64( scheme, &digest, hash, NULL);
804 }
805 #endif
806
hash_smd5(const struct berval * scheme,const struct berval * passwd,struct berval * hash,const char ** text)807 static int hash_smd5(
808 const struct berval *scheme,
809 const struct berval *passwd,
810 struct berval *hash,
811 const char **text )
812 {
813 lutil_MD5_CTX MD5context;
814 unsigned char MD5digest[LUTIL_MD5_BYTES];
815 char saltdata[SALT_SIZE];
816 struct berval digest;
817 struct berval salt;
818
819 digest.bv_val = (char *) MD5digest;
820 digest.bv_len = sizeof(MD5digest);
821 salt.bv_val = saltdata;
822 salt.bv_len = sizeof(saltdata);
823
824 if( lutil_entropy( (unsigned char *) salt.bv_val, salt.bv_len) < 0 ) {
825 return LUTIL_PASSWD_ERR;
826 }
827
828 lutil_MD5Init( &MD5context );
829 lutil_MD5Update( &MD5context,
830 (const unsigned char *) passwd->bv_val, passwd->bv_len );
831 lutil_MD5Update( &MD5context,
832 (const unsigned char *) salt.bv_val, salt.bv_len );
833 lutil_MD5Final( MD5digest, &MD5context );
834
835 return lutil_passwd_string64( scheme, &digest, hash, &salt );
836 }
837
hash_md5(const struct berval * scheme,const struct berval * passwd,struct berval * hash,const char ** text)838 static int hash_md5(
839 const struct berval *scheme,
840 const struct berval *passwd,
841 struct berval *hash,
842 const char **text )
843 {
844 lutil_MD5_CTX MD5context;
845 unsigned char MD5digest[LUTIL_MD5_BYTES];
846
847 struct berval digest;
848
849 digest.bv_val = (char *) MD5digest;
850 digest.bv_len = sizeof(MD5digest);
851
852 lutil_MD5Init( &MD5context );
853 lutil_MD5Update( &MD5context,
854 (const unsigned char *) passwd->bv_val, passwd->bv_len );
855 lutil_MD5Final( MD5digest, &MD5context );
856
857 return lutil_passwd_string64( scheme, &digest, hash, NULL );
858 ;
859 }
860
861 #ifdef SLAPD_CRYPT
hash_crypt(const struct berval * scheme,const struct berval * passwd,struct berval * hash,const char ** text)862 static int hash_crypt(
863 const struct berval *scheme,
864 const struct berval *passwd,
865 struct berval *hash,
866 const char **text )
867 {
868 unsigned char salt[32]; /* salt suitable for most anything */
869 unsigned int i;
870 char *save;
871 int rc;
872
873 for( i=0; i<passwd->bv_len; i++) {
874 if(passwd->bv_val[i] == '\0') {
875 return LUTIL_PASSWD_ERR; /* NUL character in password */
876 }
877 }
878
879 if( passwd->bv_val[i] != '\0' ) {
880 return LUTIL_PASSWD_ERR; /* passwd must behave like a string */
881 }
882
883 if( lutil_entropy( salt, sizeof( salt ) ) < 0 ) {
884 return LUTIL_PASSWD_ERR;
885 }
886
887 for( i=0; i< ( sizeof(salt) - 1 ); i++ ) {
888 salt[i] = crypt64[ salt[i] % (sizeof(crypt64)-1) ];
889 }
890 salt[sizeof( salt ) - 1 ] = '\0';
891
892 if( salt_format != NULL ) {
893 /* copy the salt we made into entropy before snprintfing
894 it back into the salt */
895 char entropy[sizeof(salt)];
896 strcpy( entropy, (char *) salt );
897 snprintf( (char *) salt, sizeof(entropy), salt_format, entropy );
898 }
899
900 rc = lutil_cryptptr( passwd->bv_val, (char *) salt, &hash->bv_val );
901 if ( rc != LUTIL_PASSWD_OK ) return rc;
902
903 if( hash->bv_val == NULL ) return -1;
904
905 hash->bv_len = strlen( hash->bv_val );
906
907 save = hash->bv_val;
908
909 if( hash->bv_len == 0 ) {
910 rc = LUTIL_PASSWD_ERR;
911 } else {
912 rc = pw_string( scheme, hash );
913 }
914 ber_memfree( save );
915 return rc;
916 }
917 #endif
918
lutil_salt_format(const char * format)919 int lutil_salt_format(const char *format)
920 {
921 #ifdef SLAPD_CRYPT
922 ber_memfree( salt_format );
923
924 salt_format = format != NULL ? ber_strdup( format ) : NULL;
925 #endif
926
927 return 0;
928 }
929
930 #ifdef SLAPD_CLEARTEXT
hash_clear(const struct berval * scheme,const struct berval * passwd,struct berval * hash,const char ** text)931 static int hash_clear(
932 const struct berval *scheme,
933 const struct berval *passwd,
934 struct berval *hash,
935 const char **text )
936 {
937 ber_dupbv( hash, (struct berval *)passwd );
938 return LUTIL_PASSWD_OK;
939 }
940 #endif
941
942