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