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