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