1/* $OpenLDAP$ */ 2/* This work is part of OpenLDAP Software <http://www.openldap.org/>. 3 * 4 * Copyright 1998-2011 The OpenLDAP Foundation. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted only as authorized by the OpenLDAP 9 * Public License. 10 * 11 * A copy of this license is available in the file LICENSE in the 12 * top-level directory of the distribution or, alternatively, at 13 * <http://www.OpenLDAP.org/license.html>. 14 */ 15 16/* 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 41typedef des_cblock des_key; 42typedef des_cblock des_data_block; 43typedef des_key_schedule des_context; 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> 56typedef PK11SymKey *des_key; 57typedef unsigned char des_data_block[8]; 58typedef 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 92static const unsigned char crypt64[] = 93 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890./"; 94 95#ifdef SLAPD_CRYPT 96static char *salt_format = NULL; 97static lutil_cryptfunc lutil_crypt; 98lutil_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 */ 105struct pw_scheme { 106 struct berval name; 107 LUTIL_PASSWD_CHK_FUNC *chk_fn; 108 LUTIL_PASSWD_HASH_FUNC *hash_fn; 109}; 110 111struct 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 120static LUTIL_PASSWD_CHK_FUNC chk_md5; 121static LUTIL_PASSWD_CHK_FUNC chk_smd5; 122static LUTIL_PASSWD_HASH_FUNC hash_smd5; 123static LUTIL_PASSWD_HASH_FUNC hash_md5; 124 125 126#ifdef LUTIL_SHA1_BYTES 127static LUTIL_PASSWD_CHK_FUNC chk_ssha1; 128static LUTIL_PASSWD_CHK_FUNC chk_sha1; 129static LUTIL_PASSWD_HASH_FUNC hash_sha1; 130static LUTIL_PASSWD_HASH_FUNC hash_ssha1; 131#endif 132 133#ifdef SLAPD_LMHASH 134static LUTIL_PASSWD_CHK_FUNC chk_lanman; 135static LUTIL_PASSWD_HASH_FUNC hash_lanman; 136#endif 137 138#ifdef SLAPD_CRYPT 139static LUTIL_PASSWD_CHK_FUNC chk_crypt; 140static LUTIL_PASSWD_HASH_FUNC hash_crypt; 141 142#if defined( HAVE_GETPWNAM ) && defined( HAVE_STRUCT_PASSWD_PW_PASSWD ) 143static LUTIL_PASSWD_CHK_FUNC chk_unix; 144#endif 145#endif 146 147/* password hash routines */ 148 149#ifdef SLAPD_CLEARTEXT 150static LUTIL_PASSWD_HASH_FUNC hash_clear; 151#endif 152 153static struct pw_slist *pw_schemes; 154static int pw_inited; 155 156static 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 185int 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 204void 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 215void 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 225static 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 249int 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 260static 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 276static 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 */ 301int 302lutil_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 350int 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 376int 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) 404static 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 427int 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 486static 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 497 /* safety check -- must have some salt */ 498 if (LUTIL_BASE64_DECODE_LEN(passwd->bv_len) <= sizeof(SHA1digest)) { 499 return LUTIL_PASSWD_ERR; 500 } 501 502 /* decode base64 password */ 503 orig_pass = (unsigned char *) ber_memalloc( (size_t) ( 504 LUTIL_BASE64_DECODE_LEN(passwd->bv_len) + 1) ); 505 506 if( orig_pass == NULL ) return LUTIL_PASSWD_ERR; 507 508 rc = lutil_b64_pton(passwd->bv_val, orig_pass, passwd->bv_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 531static 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 542 /* safety check */ 543 if (LUTIL_BASE64_DECODE_LEN(passwd->bv_len) < sizeof(SHA1digest)) { 544 return LUTIL_PASSWD_ERR; 545 } 546 547 /* base64 un-encode password */ 548 orig_pass = (unsigned char *) ber_memalloc( (size_t) ( 549 LUTIL_BASE64_DECODE_LEN(passwd->bv_len) + 1) ); 550 551 if( orig_pass == NULL ) return LUTIL_PASSWD_ERR; 552 553 rc = lutil_b64_pton(passwd->bv_val, orig_pass, passwd->bv_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 573static 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 584 /* safety check */ 585 if (LUTIL_BASE64_DECODE_LEN(passwd->bv_len) <= sizeof(MD5digest)) { 586 return LUTIL_PASSWD_ERR; 587 } 588 589 /* base64 un-encode password */ 590 orig_pass = (unsigned char *) ber_memalloc( (size_t) ( 591 LUTIL_BASE64_DECODE_LEN(passwd->bv_len) + 1) ); 592 593 if( orig_pass == NULL ) return LUTIL_PASSWD_ERR; 594 595 rc = lutil_b64_pton(passwd->bv_val, orig_pass, passwd->bv_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 618static 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 629 /* safety check */ 630 if (LUTIL_BASE64_DECODE_LEN(passwd->bv_len) < sizeof(MD5digest)) { 631 return LUTIL_PASSWD_ERR; 632 } 633 634 /* base64 un-encode password */ 635 orig_pass = (unsigned char *) ber_memalloc( (size_t) ( 636 LUTIL_BASE64_DECODE_LEN(passwd->bv_len) + 1) ); 637 638 if( orig_pass == NULL ) return LUTIL_PASSWD_ERR; 639 640 rc = lutil_b64_pton(passwd->bv_val, orig_pass, passwd->bv_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 */ 666static void 667des_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 */ 679static void 680des_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 701static void 702des_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 714static void 715des_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 737static int 738des_failed(des_data_block *encrypted) 739{ 740 static const des_data_block zero = { 0 }; 741 return memcmp(encrypted, zero, sizeof(zero)) == 0; 742} 743 744static void 745des_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 818static 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 838static 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 899static 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 921static 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 ) 957static 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 1026static 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 1057static 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 1078static 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 1109static 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 1133static 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 1184static 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 1241int 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 1253static 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