From d876a22732d83ddf8e37ead89e6f23bf7aa0d69c Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Tue, 29 Oct 2013 12:19:01 +0100 Subject: Remove generation and handling of LM hashes https://fedorahosted.org/freeipa/ticket/3795 --- daemons/ipa-sam/ipa_sam.c | 21 +-- daemons/ipa-slapi-plugins/ipa-pwd-extop/common.c | 14 +- daemons/ipa-slapi-plugins/ipa-pwd-extop/encoding.c | 48 ++--- daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd.h | 3 +- daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c | 17 +- util/ipa_pwd.h | 11 +- util/ipa_pwd_ntlm.c | 210 +++++---------------- 7 files changed, 74 insertions(+), 250 deletions(-) diff --git a/daemons/ipa-sam/ipa_sam.c b/daemons/ipa-sam/ipa_sam.c index 59ddcef2e..674085d2a 100644 --- a/daemons/ipa-sam/ipa_sam.c +++ b/daemons/ipa-sam/ipa_sam.c @@ -2637,10 +2637,9 @@ static bool init_sam_from_td(struct samu *user, struct pdb_trusted_domain *td, char *name; char *trustpw = NULL; char *trustpw_utf8 = NULL; - char *trustpw_utf8_uc = NULL; char *tmp_str = NULL; int ret; - struct ntlm_keys ntlm_keys; + uint8_t nt_key[16]; size_t converted_size; bool res; char *sid_str; @@ -2706,23 +2705,13 @@ static bool init_sam_from_td(struct samu *user, struct pdb_trusted_domain *td, goto done; } - if (!push_utf8_talloc(user, &trustpw_utf8_uc, tmp_str, &converted_size)) { - res = false; - goto done; - } - - ret = encode_ntlm_keys(trustpw_utf8, trustpw_utf8_uc, true, true, - &ntlm_keys); + ret = encode_nt_key(trustpw_utf8, nt_key); if (ret != 0) { res = false; goto done; } - if (!pdb_set_lanman_passwd(user, ntlm_keys.lm, PDB_SET)) { - res = false; - goto done; - } - if (!pdb_set_nt_passwd(user, ntlm_keys.nt, PDB_SET)) { + if (!pdb_set_nt_passwd(user, nt_key, PDB_SET)) { res = false; goto done; } @@ -2741,10 +2730,6 @@ done: memset(tmp_str, 0, strlen(tmp_str)); talloc_free(tmp_str); } - if (trustpw_utf8_uc != NULL) { - memset(trustpw_utf8_uc, 0, strlen(trustpw_utf8_uc)); - talloc_free(trustpw_utf8_uc); - } return res; } diff --git a/daemons/ipa-slapi-plugins/ipa-pwd-extop/common.c b/daemons/ipa-slapi-plugins/ipa-pwd-extop/common.c index f0339c47c..2538a4094 100644 --- a/daemons/ipa-slapi-plugins/ipa-pwd-extop/common.c +++ b/daemons/ipa-slapi-plugins/ipa-pwd-extop/common.c @@ -366,7 +366,6 @@ static struct ipapwd_krbcfg *ipapwd_getConfig(void) slapi_entry_free(config_entry); /* get the ipa etc/ipaConfig entry */ - config->allow_lm_hash = false; config->allow_nt_hash = false; ret = ipapwd_getEntry(ipa_etc_config_dn, &config_entry, NULL); if (ret != LDAP_SUCCESS) { @@ -376,10 +375,6 @@ static struct ipapwd_krbcfg *ipapwd_getConfig(void) tmparray = slapi_entry_attr_get_charray(config_entry, "ipaConfigString"); for (i = 0; tmparray && tmparray[i]; i++) { - if (strcasecmp(tmparray[i], "AllowLMhash") == 0) { - config->allow_lm_hash = true; - continue; - } if (strcasecmp(tmparray[i], "AllowNThash") == 0) { config->allow_nt_hash = true; continue; @@ -928,7 +923,6 @@ int ipapwd_SetPassword(struct ipapwd_krbcfg *krbcfg, Slapi_Value **pwvals = NULL; struct tm utctime; char timestr[GENERALIZED_TIME_LENGTH+1]; - char *lm = NULL; char *nt = NULL; int is_smb = 0; int is_ipant = 0; @@ -965,7 +959,7 @@ int ipapwd_SetPassword(struct ipapwd_krbcfg *krbcfg, ret = ipapwd_gen_hashes(krbcfg, data, data->password, is_krb, is_smb, is_ipant, - &svals, &nt, &lm, &ntvals, &errMesg); + &svals, &nt, &ntvals, &errMesg); if (ret) { goto free_and_return; } @@ -1004,11 +998,6 @@ int ipapwd_SetPassword(struct ipapwd_krbcfg *krbcfg, } } - if (lm && is_smb) { - slapi_mods_add_string(smods, LDAP_MOD_REPLACE, - "sambaLMPassword", lm); - } - if (nt && is_smb) { slapi_mods_add_string(smods, LDAP_MOD_REPLACE, "sambaNTPassword", nt); @@ -1069,7 +1058,6 @@ int ipapwd_SetPassword(struct ipapwd_krbcfg *krbcfg, LOG_TRACE("<= result: %d\n", ret); free_and_return: - if (lm) slapi_ch_free((void **)&lm); if (nt) slapi_ch_free((void **)&nt); if (modtime) slapi_ch_free((void **)&modtime); slapi_mods_free(&smods); diff --git a/daemons/ipa-slapi-plugins/ipa-pwd-extop/encoding.c b/daemons/ipa-slapi-plugins/ipa-pwd-extop/encoding.c index a92eaf0da..28f164eb8 100644 --- a/daemons/ipa-slapi-plugins/ipa-pwd-extop/encoding.c +++ b/daemons/ipa-slapi-plugins/ipa-pwd-extop/encoding.c @@ -201,15 +201,13 @@ enc_error: int ipapwd_gen_hashes(struct ipapwd_krbcfg *krbcfg, struct ipapwd_data *data, char *userpw, int is_krb, int is_smb, int is_ipant, Slapi_Value ***svals, - char **nthash, char **lmhash, Slapi_Value ***ntvals, + char **nthash, Slapi_Value ***ntvals, char **errMesg) { int rc; - char *userpw_uc = NULL; *svals = NULL; *nthash = NULL; - *lmhash = NULL; *errMesg = NULL; if (is_krb) { @@ -225,40 +223,24 @@ int ipapwd_gen_hashes(struct ipapwd_krbcfg *krbcfg, } if (is_smb || is_ipant) { - char lm[33], nt[33]; - struct ntlm_keys ntlm; + char nt[33]; + uint8_t nt_key[16]; int ret; - userpw_uc = (char *) slapi_utf8StrToUpper((unsigned char *) userpw); - if (!userpw_uc) { - *errMesg = "Failed to generate upper case password\n"; - LOG_FATAL("%s", *errMesg); - rc = LDAP_OPERATIONS_ERROR; - goto done; - } - - ret = encode_ntlm_keys(userpw, - userpw_uc, - krbcfg->allow_lm_hash, - krbcfg->allow_nt_hash, - &ntlm); - memset(userpw_uc, 0, strlen(userpw_uc)); - slapi_ch_free_string(&userpw_uc); - if (ret) { - *errMesg = "Failed to generate NT/LM hashes\n"; - LOG_FATAL("%s", *errMesg); - rc = LDAP_OPERATIONS_ERROR; - goto done; - } - if (krbcfg->allow_lm_hash) { - hexbuf(lm, ntlm.lm); - lm[32] = '\0'; - *lmhash = slapi_ch_strdup(lm); - } if (krbcfg->allow_nt_hash) { - hexbuf(nt, ntlm.nt); + ret = encode_nt_key(userpw, nt_key); + if (ret) { + *errMesg = "Failed to generate NT/LM hashes\n"; + LOG_FATAL("%s", *errMesg); + rc = LDAP_OPERATIONS_ERROR; + goto done; + } + + hexbuf(nt, nt_key); nt[32] = '\0'; *nthash = slapi_ch_strdup(nt); + } else { + memset(nt_key, 0, 16); } if (is_ipant) { @@ -269,7 +251,7 @@ int ipapwd_gen_hashes(struct ipapwd_krbcfg *krbcfg, goto done; } (*ntvals)[0] = slapi_value_new(); - if (slapi_value_set((*ntvals)[0], ntlm.nt, 16) == NULL) { + if (slapi_value_set((*ntvals)[0], nt_key, 16) == NULL) { rc = LDAP_OPERATIONS_ERROR; goto done; } diff --git a/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd.h b/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd.h index 74b636276..b4087488c 100644 --- a/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd.h +++ b/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd.h @@ -132,7 +132,6 @@ struct ipapwd_krbcfg { krb5_key_salt_tuple *pref_encsalts; char **passsync_mgrs; int num_passsync_mgrs; - bool allow_lm_hash; bool allow_nt_hash; }; @@ -172,7 +171,7 @@ void ipapwd_keyset_free(struct ipapwd_keyset **pkset); int ipapwd_gen_hashes(struct ipapwd_krbcfg *krbcfg, struct ipapwd_data *data, char *userpw, int is_krb, int is_smb, int is_ipant, - Slapi_Value ***svals, char **nthash, char **lmhash, + Slapi_Value ***svals, char **nthash, Slapi_Value ***ntvals, char **errMesg); /* from prepost.c */ diff --git a/daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c b/daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c index 64a9d3140..ef37b5e17 100644 --- a/daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c +++ b/daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c @@ -325,13 +325,12 @@ static int ipapwd_pre_add(Slapi_PBlock *pb) Slapi_Value **svals = NULL; Slapi_Value **ntvals = NULL; char *nt = NULL; - char *lm = NULL; pwdop->is_krb = is_krb; rc = ipapwd_gen_hashes(krbcfg, &pwdop->pwdata, userpw, is_krb, is_smb, is_ipant, - &svals, &nt, &lm, &ntvals, &errMesg); + &svals, &nt, &ntvals, &errMesg); if (rc != LDAP_SUCCESS) { goto done; } @@ -349,11 +348,6 @@ static int ipapwd_pre_add(Slapi_PBlock *pb) ipapwd_free_slapi_value_array(&svals); } - if (lm && is_smb) { - /* set value */ - slapi_entry_attr_set_charptr(e, "sambaLMPassword", lm); - slapi_ch_free_string(&lm); - } if (nt && is_smb) { /* set value */ slapi_entry_attr_set_charptr(e, "sambaNTPassword", nt); @@ -814,11 +808,10 @@ static int ipapwd_pre_mod(Slapi_PBlock *pb) Slapi_Value **svals = NULL; Slapi_Value **ntvals = NULL; char *nt = NULL; - char *lm = NULL; rc = ipapwd_gen_hashes(krbcfg, &pwdop->pwdata, unhashedpw, gen_krb_keys, is_smb, is_ipant, - &svals, &nt, &lm, &ntvals, &errMesg); + &svals, &nt, &ntvals, &errMesg); if (rc) { goto done; } @@ -830,12 +823,6 @@ static int ipapwd_pre_mod(Slapi_PBlock *pb) ipapwd_free_slapi_value_array(&svals); } - if (lm && is_smb) { - /* replace value */ - slapi_mods_add_string(smods, LDAP_MOD_REPLACE, - "sambaLMPassword", lm); - slapi_ch_free_string(&lm); - } if (nt && is_smb) { /* replace value */ slapi_mods_add_string(smods, LDAP_MOD_REPLACE, diff --git a/util/ipa_pwd.h b/util/ipa_pwd.h index a6990cac6..bc07549cc 100644 --- a/util/ipa_pwd.h +++ b/util/ipa_pwd.h @@ -74,15 +74,6 @@ int ipapwd_generate_new_history(char *password, char ***new_pwd_history, int *new_pwd_hlen); -struct ntlm_keys { - uint8_t lm[16]; - uint8_t nt[16]; -}; - -int encode_ntlm_keys(char *newPasswd, - char *upperPasswd, - bool do_lm_hash, - bool do_nt_hash, - struct ntlm_keys *keys); +int encode_nt_key(char *newPasswd, uint8_t *nt_key); #endif diff --git a/util/ipa_pwd_ntlm.c b/util/ipa_pwd_ntlm.c index a3399b58e..8ffa66660 100644 --- a/util/ipa_pwd_ntlm.c +++ b/util/ipa_pwd_ntlm.c @@ -32,178 +32,70 @@ #define KTF_UTF8 "UTF-8" #define KTF_UCS2 "UCS-2LE" -static const uint8_t parity_table[128] = { - 1, 2, 4, 7, 8, 11, 13, 14, 16, 19, 21, 22, 25, 26, 28, 31, - 32, 35, 37, 38, 41, 42, 44, 47, 49, 50, 52, 55, 56, 59, 61, 62, - 64, 67, 69, 70, 73, 74, 76, 79, 81, 82, 84, 87, 88, 91, 93, 94, - 97, 98,100,103,104,107,109,110,112,115,117,118,121,122,124,127, - 128,131,133,134,137,138,140,143,145,146,148,151,152,155,157,158, - 161,162,164,167,168,171,173,174,176,179,181,182,185,186,188,191, - 193,194,196,199,200,203,205,206,208,211,213,214,217,218,220,223, - 224,227,229,230,233,234,236,239,241,242,244,247,248,251,253,254 -}; - -static void lm_shuffle(uint8_t *out, uint8_t *in) -{ - out[0] = parity_table[in[0]>>1]; - out[1] = parity_table[((in[0]<<6)|(in[1]>>2)) & 0x7F]; - out[2] = parity_table[((in[1]<<5)|(in[2]>>3)) & 0x7F]; - out[3] = parity_table[((in[2]<<4)|(in[3]>>4)) & 0x7F]; - out[4] = parity_table[((in[3]<<3)|(in[4]>>5)) & 0x7F]; - out[5] = parity_table[((in[4]<<2)|(in[5]>>6)) & 0x7F]; - out[6] = parity_table[((in[5]<<1)|(in[6]>>7)) & 0x7F]; - out[7] = parity_table[in[6] & 0x7F]; -} - -/* create the lm and nt hashes +/* create the nt hash newPassword: the clear text utf8 password - upperPasswd: upper case version of clear text utf8 password - do_lm_hash: determine if LM hash is generated - do_nt_hash: determine if NT hash is generated - keys[out]: array with generated hashes + nt_key[out]: array with generated hash */ -int encode_ntlm_keys(char *newPasswd, - char *upperPasswd, - bool do_lm_hash, - bool do_nt_hash, - struct ntlm_keys *keys) +int encode_nt_key(char *newPasswd, uint8_t *nt_key) { int ret = 0; + iconv_t cd; + size_t cs, il, ol, sl; + char *inc, *outc; + char *ucs2Passwd; + MD4_CTX md4ctx; + + /* TODO: must store the dos charset somewhere in the directory */ + cd = iconv_open(KTF_UCS2, KTF_UTF8); + if (cd == (iconv_t)(-1)) { + ret = -1; + goto done; + } - /* do lanman first */ - if (do_lm_hash) { - iconv_t cd; - size_t cs, il, ol; - char *inc, *outc; - char *asciiPasswd; - DES_key_schedule schedule; - DES_cblock deskey; - DES_cblock magic = "KGS!@#$%"; - - if (upperPasswd == NULL) { - ret = -1; - goto done; - } - il = strlen(upperPasswd); - - /* TODO: must store the dos charset somewhere in the directory */ - cd = iconv_open(KTF_DOS_CHARSET, KTF_UTF8); - if (cd == (iconv_t)(-1)) { - ret = -1; - goto done; - } - - /* an ascii string can only be smaller than or equal to an utf8 one */ - ol = il; - if (ol < 14) ol = 14; - asciiPasswd = calloc(ol+1, 1); - if (!asciiPasswd) { - iconv_close(cd); - ret = -1; - goto done; - } - - inc = upperPasswd; - outc = asciiPasswd; - cs = iconv(cd, &inc, &il, &outc, &ol); - if (cs == -1) { - ret = -1; - free(asciiPasswd); - iconv_close(cd); - goto done; - } + il = strlen(newPasswd); - /* done with these */ + /* an ucs2 string can be at most double than an utf8 one */ + sl = ol = (il+1)*2; + ucs2Passwd = calloc(ol, 1); + if (!ucs2Passwd) { + ret = -1; iconv_close(cd); - - /* we are interested only in the first 14 ASCII chars for lanman */ - if (strlen(asciiPasswd) > 14) { - asciiPasswd[14] = '\0'; - } - - /* first half */ - lm_shuffle(deskey, (uint8_t *)asciiPasswd); - - DES_set_key_unchecked(&deskey, &schedule); - DES_ecb_encrypt(&magic, (DES_cblock *)keys->lm, - &schedule, DES_ENCRYPT); - - /* second half */ - lm_shuffle(deskey, (uint8_t *)&asciiPasswd[7]); - - DES_set_key_unchecked(&deskey, &schedule); - DES_ecb_encrypt(&magic, (DES_cblock *)&(keys->lm[8]), - &schedule, DES_ENCRYPT); - - /* done with it */ - free(asciiPasswd); - - } else { - memset(keys->lm, 0, 16); + goto done; } - if (do_nt_hash) { - iconv_t cd; - size_t cs, il, ol, sl; - char *inc, *outc; - char *ucs2Passwd; - MD4_CTX md4ctx; - - /* TODO: must store the dos charset somewhere in the directory */ - cd = iconv_open(KTF_UCS2, KTF_UTF8); - if (cd == (iconv_t)(-1)) { - ret = -1; - goto done; - } - - il = strlen(newPasswd); - - /* an ucs2 string can be at most double than an utf8 one */ - sl = ol = (il+1)*2; - ucs2Passwd = calloc(ol, 1); - if (!ucs2Passwd) { - ret = -1; - iconv_close(cd); - goto done; - } - - inc = newPasswd; - outc = ucs2Passwd; - cs = iconv(cd, &inc, &il, &outc, &ol); - if (cs == -1) { - ret = -1; - free(ucs2Passwd); - iconv_close(cd); - goto done; - } - - /* done with it */ + inc = newPasswd; + outc = ucs2Passwd; + cs = iconv(cd, &inc, &il, &outc, &ol); + if (cs == -1) { + ret = -1; + free(ucs2Passwd); iconv_close(cd); + goto done; + } - /* get the final ucs2 string length */ - sl -= ol; + /* done with it */ + iconv_close(cd); - ret = MD4_Init(&md4ctx); - if (ret == 0) { - ret = -1; - free(ucs2Passwd); - goto done; - } - ret = MD4_Update(&md4ctx, ucs2Passwd, sl); - if (ret == 0) { - ret = -1; - free(ucs2Passwd); - goto done; - } - ret = MD4_Final(keys->nt, &md4ctx); - if (ret == 0) { - ret = -1; - free(ucs2Passwd); - goto done; - } + /* get the final ucs2 string length */ + sl -= ol; - } else { - memset(keys->nt, 0, 16); + ret = MD4_Init(&md4ctx); + if (ret == 0) { + ret = -1; + free(ucs2Passwd); + goto done; + } + ret = MD4_Update(&md4ctx, ucs2Passwd, sl); + if (ret == 0) { + ret = -1; + free(ucs2Passwd); + goto done; + } + ret = MD4_Final(nt_key, &md4ctx); + if (ret == 0) { + ret = -1; + free(ucs2Passwd); + goto done; } ret = 0; -- cgit