From 6f5cc45f93c8c4f15b258c63db3d5da8995a4904 Mon Sep 17 00:00:00 2001 From: Andrew Lawrence Date: Fri, 9 Feb 2018 23:32:28 +0000 Subject: [PATCH] ITS#8639 remove LANMAN hashed passwords --- configure.in | 16 -- libraries/liblutil/passwd.c | 334 +----------------------------------- 2 files changed, 3 insertions(+), 347 deletions(-) diff --git a/configure.in b/configure.in index 69dc0903c5..c4f9dbe3dd 100644 --- a/configure.in +++ b/configure.in @@ -271,7 +271,6 @@ OL_ARG_ENABLE(dynacl,[ --enable-dynacl enable run-time loadable ACL support OL_ARG_ENABLE(aci,[ --enable-aci enable per-object ACIs (experimental)], no, [no yes mod])dnl OL_ARG_ENABLE(cleartext,[ --enable-cleartext enable cleartext passwords], yes)dnl OL_ARG_ENABLE(crypt,[ --enable-crypt enable crypt(3) passwords], no)dnl -OL_ARG_ENABLE(lmpasswd,[ --enable-lmpasswd enable LAN Manager passwords], no)dnl OL_ARG_ENABLE(spasswd,[ --enable-spasswd enable (Cyrus) SASL password verification], no)dnl OL_ARG_ENABLE(modules,[ --enable-modules enable dynamic module support], no)dnl OL_ARG_ENABLE(rewrite,[ --enable-rewrite enable DN rewriting in back-ldap and rwm overlay], auto)dnl @@ -507,12 +506,6 @@ if test $ol_enable_asyncmeta/$ol_enable_ldap = yes/no ; then AC_MSG_ERROR([--enable-asyncmeta requires --enable-ldap]) fi -if test $ol_enable_lmpasswd = yes ; then - if test $ol_with_tls = no ; then - AC_MSG_ERROR([LAN Manager passwords require OpenSSL]) - fi -fi - if test $ol_enable_spasswd = yes ; then if test $ol_with_cyrus_sasl = no ; then AC_MSG_ERROR([options require --with-cyrus-sasl]) @@ -1293,15 +1286,6 @@ else AC_MSG_WARN([TLS data protection not supported!]) fi -dnl ---------------------------------------------------------------- -dnl LAN Manger password checking requires DES from OpenSSL -if test $ol_enable_lmpasswd != no; then - if test $ol_link_tls != yes ; then - AC_MSG_ERROR([LAN Manager passwords require OpenSSL]) - fi - - AC_DEFINE(SLAPD_LMHASH, 1, [define to support LAN Manager passwords]) -fi dnl ---------------------------------------------------------------- dnl Threads? diff --git a/libraries/liblutil/passwd.c b/libraries/liblutil/passwd.c index 68bb41b19d..85418d24be 100644 --- a/libraries/liblutil/passwd.c +++ b/libraries/liblutil/passwd.c @@ -32,36 +32,6 @@ #include #include #include - -#if defined(SLAPD_LMHASH) -#if defined(HAVE_OPENSSL) -# include - - -typedef DES_cblock des_key; -typedef DES_cblock des_data_block; -typedef DES_key_schedule des_context[1]; -#define des_failed(encrypted) 0 -#define des_finish(key, schedule) - -#elif defined(HAVE_MOZNSS) -/* - hack hack hack - We need to define this here so that nspr/obsolete/protypes.h will not be included - if that file is included, it will create a uint32 typedef that will cause the - one in lutil_sha1.h to blow up -*/ -#define PROTYPES_H 1 -# include -typedef PK11SymKey *des_key; -typedef unsigned char des_data_block[8]; -typedef PK11Context *des_context[1]; -#define DES_ENCRYPT CKA_ENCRYPT - -#endif - -#endif /* SLAPD_LMHASH */ - #include #ifdef SLAPD_CRYPT @@ -130,10 +100,6 @@ static LUTIL_PASSWD_HASH_FUNC hash_sha1; static LUTIL_PASSWD_HASH_FUNC hash_ssha1; #endif -#ifdef SLAPD_LMHASH -static LUTIL_PASSWD_CHK_FUNC chk_lanman; -static LUTIL_PASSWD_HASH_FUNC hash_lanman; -#endif #ifdef SLAPD_CRYPT static LUTIL_PASSWD_CHK_FUNC chk_crypt; @@ -163,10 +129,6 @@ static const struct pw_scheme pw_schemes_default[] = { BER_BVC("{SMD5}"), chk_smd5, hash_smd5 }, { BER_BVC("{MD5}"), chk_md5, hash_md5 }, -#ifdef SLAPD_LMHASH - { BER_BVC("{LANMAN}"), chk_lanman, hash_lanman }, -#endif /* SLAPD_LMHASH */ - #ifdef SLAPD_CRYPT { BER_BVC("{CRYPT}"), chk_crypt, hash_crypt }, # if defined( HAVE_GETPWNAM ) && defined( HAVE_STRUCT_PASSWD_PW_PASSWD ) @@ -399,8 +361,8 @@ int lutil_passwd_hash( return (sc->hash_fn)( &sc->name, passwd, hash, text ); } -/* pw_string is only called when SLAPD_LMHASH or SLAPD_CRYPT is defined */ -#if defined(SLAPD_LMHASH) || defined(SLAPD_CRYPT) +/* pw_string is only called when SLAPD_CRYPT is defined */ +#if defined(SLAPD_CRYPT) static int pw_string( const struct berval *sc, struct berval *passwd ) @@ -422,7 +384,7 @@ static int pw_string( return LUTIL_PASSWD_OK; } -#endif /* SLAPD_LMHASH || SLAPD_CRYPT */ +#endif /* SLAPD_CRYPT */ int lutil_passwd_string64( const struct berval *sc, @@ -656,245 +618,6 @@ static int chk_md5( return rc ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK; } -#ifdef SLAPD_LMHASH - -#if defined(HAVE_OPENSSL) - -/* - * abstract away setting the parity. - */ -static void -des_set_key_and_parity( des_key *key, unsigned char *keyData) -{ - memcpy(key, keyData, 8); - DES_set_odd_parity( key ); -} - - -#elif defined(HAVE_MOZNSS) - -/* - * implement MozNSS wrappers for the openSSL calls - */ -static void -des_set_key_and_parity( des_key *key, unsigned char *keyData) -{ - SECItem keyDataItem; - PK11SlotInfo *slot; - *key = NULL; - - keyDataItem.data = keyData; - keyDataItem.len = 8; - - slot = PK11_GetBestSlot(CKM_DES_ECB, NULL); - if (slot == NULL) { - return; - } - - /* NOTE: this will not work in FIPS mode. In order to make lmhash - * work in fips mode we need to define a LMHASH pbe mechanism and - * do the fulll key derivation inside the token */ - *key = PK11_ImportSymKey(slot, CKM_DES_ECB, PK11_OriginGenerated, - CKA_ENCRYPT, &keyDataItem, NULL); -} - -static void -DES_set_key_unchecked( des_key *key, des_context ctxt ) -{ - ctxt[0] = NULL; - - /* handle error conditions from previous call */ - if (!*key) { - return; - } - - ctxt[0] = PK11_CreateContextBySymKey(CKM_DES_ECB, CKA_ENCRYPT, *key, NULL); -} - -static void -DES_ecb_encrypt( des_data_block *plain, des_data_block *encrypted, - des_context ctxt, int op) -{ - SECStatus rv; - int size; - - if (ctxt[0] == NULL) { - /* need to fail here... */ - memset(encrypted, 0, sizeof(des_data_block)); - return; - } - rv = PK11_CipherOp(ctxt[0], (unsigned char *)&encrypted[0], - &size, sizeof(des_data_block), - (unsigned char *)&plain[0], sizeof(des_data_block)); - if (rv != SECSuccess) { - /* signal failure */ - memset(encrypted, 0, sizeof(des_data_block)); - return; - } - return; -} - -static int -des_failed(des_data_block *encrypted) -{ - static const des_data_block zero = { 0 }; - return memcmp(encrypted, zero, sizeof(zero)) == 0; -} - -static void -des_finish(des_key *key, des_context ctxt) -{ - if (*key) { - PK11_FreeSymKey(*key); - *key = NULL; - } - if (ctxt[0]) { - PK11_Finalize(ctxt[0]); - PK11_DestroyContext(ctxt[0], PR_TRUE); - ctxt[0] = NULL; - } -} - -#endif - -/* pseudocode from RFC2433 - * A.2 LmPasswordHash() - * - * LmPasswordHash( - * IN 0-to-14-oem-char Password, - * OUT 16-octet PasswordHash ) - * { - * Set UcasePassword to the uppercased Password - * Zero pad UcasePassword to 14 characters - * - * DesHash( 1st 7-octets of UcasePassword, - * giving 1st 8-octets of PasswordHash ) - * - * DesHash( 2nd 7-octets of UcasePassword, - * giving 2nd 8-octets of PasswordHash ) - * } - * - * - * A.3 DesHash() - * - * DesHash( - * IN 7-octet Clear, - * OUT 8-octet Cypher ) - * { - * * - * * Make Cypher an irreversibly encrypted form of Clear by - * * encrypting known text using Clear as the secret key. - * * The known text consists of the string - * * - * * KGS!@#$% - * * - * - * Set StdText to "KGS!@#$%" - * DesEncrypt( StdText, Clear, giving Cypher ) - * } - * - * - * A.4 DesEncrypt() - * - * DesEncrypt( - * IN 8-octet Clear, - * IN 7-octet Key, - * OUT 8-octet Cypher ) - * { - * * - * * Use the DES encryption algorithm [4] in ECB mode [9] - * * to encrypt Clear into Cypher such that Cypher can - * * only be decrypted back to Clear by providing Key. - * * Note that the DES algorithm takes as input a 64-bit - * * stream where the 8th, 16th, 24th, etc. bits are - * * parity bits ignored by the encrypting algorithm. - * * Unless you write your own DES to accept 56-bit input - * * without parity, you will need to insert the parity bits - * * yourself. - * * - * } - */ - -static void lmPasswd_to_key( - const char *lmPasswd, - des_key *key) -{ - const unsigned char *lpw = (const unsigned char *) lmPasswd; - unsigned char k[8]; - - /* make room for parity bits */ - k[0] = lpw[0]; - k[1] = ((lpw[0] & 0x01) << 7) | (lpw[1] >> 1); - k[2] = ((lpw[1] & 0x03) << 6) | (lpw[2] >> 2); - k[3] = ((lpw[2] & 0x07) << 5) | (lpw[3] >> 3); - k[4] = ((lpw[3] & 0x0F) << 4) | (lpw[4] >> 4); - k[5] = ((lpw[4] & 0x1F) << 3) | (lpw[5] >> 5); - k[6] = ((lpw[5] & 0x3F) << 2) | (lpw[6] >> 6); - k[7] = ((lpw[6] & 0x7F) << 1); - - des_set_key_and_parity( key, k ); -} - -static int chk_lanman( - const struct berval *scheme, - const struct berval *passwd, - const struct berval *cred, - const char **text ) -{ - ber_len_t i; - char UcasePassword[15]; - des_key key; - des_context schedule; - des_data_block StdText = "KGS!@#$%"; - des_data_block PasswordHash1, PasswordHash2; - char PasswordHash[33], storedPasswordHash[33]; - - for( i=0; ibv_len; i++) { - if(cred->bv_val[i] == '\0') { - return LUTIL_PASSWD_ERR; /* NUL character in password */ - } - } - - if( cred->bv_val[i] != '\0' ) { - return LUTIL_PASSWD_ERR; /* passwd must behave like a string */ - } - - strncpy( UcasePassword, cred->bv_val, 14 ); - UcasePassword[14] = '\0'; - ldap_pvt_str2upper( UcasePassword ); - - lmPasswd_to_key( UcasePassword, &key ); - DES_set_key_unchecked( &key, schedule ); - DES_ecb_encrypt( &StdText, &PasswordHash1, schedule , DES_ENCRYPT ); - - if (des_failed(&PasswordHash1)) { - return LUTIL_PASSWD_ERR; - } - - lmPasswd_to_key( &UcasePassword[7], &key ); - DES_set_key_unchecked( &key, schedule ); - DES_ecb_encrypt( &StdText, &PasswordHash2, schedule , DES_ENCRYPT ); - if (des_failed(&PasswordHash2)) { - return LUTIL_PASSWD_ERR; - } - - des_finish( &key, schedule ); - - sprintf( PasswordHash, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", - PasswordHash1[0],PasswordHash1[1],PasswordHash1[2],PasswordHash1[3], - PasswordHash1[4],PasswordHash1[5],PasswordHash1[6],PasswordHash1[7], - PasswordHash2[0],PasswordHash2[1],PasswordHash2[2],PasswordHash2[3], - PasswordHash2[4],PasswordHash2[5],PasswordHash2[6],PasswordHash2[7] ); - - /* as a precaution convert stored password hash to lower case */ - strncpy( storedPasswordHash, passwd->bv_val, 32 ); - storedPasswordHash[32] = '\0'; - ldap_pvt_str2lower( storedPasswordHash ); - - return memcmp( PasswordHash, storedPasswordHash, 32) ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK; -} -#endif /* SLAPD_LMHASH */ - #ifdef SLAPD_CRYPT static int lutil_crypt( const char *key, @@ -1129,57 +852,6 @@ static int hash_md5( ; } -#ifdef SLAPD_LMHASH -static int hash_lanman( - const struct berval *scheme, - const struct berval *passwd, - struct berval *hash, - const char **text ) -{ - - ber_len_t i; - char UcasePassword[15]; - des_key key; - des_context schedule; - des_data_block StdText = "KGS!@#$%"; - des_data_block PasswordHash1, PasswordHash2; - char PasswordHash[33]; - - for( i=0; ibv_len; i++) { - if(passwd->bv_val[i] == '\0') { - return LUTIL_PASSWD_ERR; /* NUL character in password */ - } - } - - if( passwd->bv_val[i] != '\0' ) { - return LUTIL_PASSWD_ERR; /* passwd must behave like a string */ - } - - strncpy( UcasePassword, passwd->bv_val, 14 ); - UcasePassword[14] = '\0'; - ldap_pvt_str2upper( UcasePassword ); - - lmPasswd_to_key( UcasePassword, &key ); - DES_set_key_unchecked( &key, schedule ); - DES_ecb_encrypt( &StdText, &PasswordHash1, schedule , DES_ENCRYPT ); - - lmPasswd_to_key( &UcasePassword[7], &key ); - DES_set_key_unchecked( &key, schedule ); - DES_ecb_encrypt( &StdText, &PasswordHash2, schedule , DES_ENCRYPT ); - - sprintf( PasswordHash, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", - PasswordHash1[0],PasswordHash1[1],PasswordHash1[2],PasswordHash1[3], - PasswordHash1[4],PasswordHash1[5],PasswordHash1[6],PasswordHash1[7], - PasswordHash2[0],PasswordHash2[1],PasswordHash2[2],PasswordHash2[3], - PasswordHash2[4],PasswordHash2[5],PasswordHash2[6],PasswordHash2[7] ); - - hash->bv_val = PasswordHash; - hash->bv_len = 32; - - return pw_string( scheme, hash ); -} -#endif /* SLAPD_LMHASH */ - #ifdef SLAPD_CRYPT static int hash_crypt( const struct berval *scheme,