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