Remove generation and handling of LM hashes

https://fedorahosted.org/freeipa/ticket/3795
This commit is contained in:
Sumit Bose 2013-10-29 12:19:01 +01:00 committed by Martin Kosek
parent b5e60c2020
commit d876a22732
7 changed files with 75 additions and 251 deletions

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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 */

View File

@ -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,

View File

@ -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

View File

@ -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;
/* 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;
}
/* done with these */
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);
/* 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;
}
if (do_nt_hash) {
iconv_t cd;
size_t cs, il, ol, sl;
char *inc, *outc;
char *ucs2Passwd;
MD4_CTX md4ctx;
il = strlen(newPasswd);
/* 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 */
/* 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;
}
/* get the final ucs2 string length */
sl -= ol;
inc = newPasswd;
outc = ucs2Passwd;
cs = iconv(cd, &inc, &il, &outc, &ol);
if (cs == -1) {
ret = -1;
free(ucs2Passwd);
iconv_close(cd);
goto done;
}
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;
}
/* done with it */
iconv_close(cd);
} else {
memset(keys->nt, 0, 16);
/* get the final ucs2 string length */
sl -= ol;
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;