diff options
author | Andrew Bartlett <abartlet@samba.org> | 2007-07-03 08:00:08 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 14:58:59 -0500 |
commit | ec0035c9b8e0690f3bc21f3de089c39eae660916 (patch) | |
tree | 183dddce1bc0704f0c137df03e611d255fb68e11 /source4/heimdal/kdc/digest.c | |
parent | 74b35321dc043188386d0305508b5276a5290d0d (diff) | |
download | samba-ec0035c9b8e0690f3bc21f3de089c39eae660916.tar.gz samba-ec0035c9b8e0690f3bc21f3de089c39eae660916.tar.bz2 samba-ec0035c9b8e0690f3bc21f3de089c39eae660916.zip |
r23678: Update to current lorikeet-heimdal (-r 767), which should fix the
panics on hosts without /dev/random.
Andrew Bartlett
(This used to be commit 14a4ddb131993fec72316f7e8e371638749e6f1f)
Diffstat (limited to 'source4/heimdal/kdc/digest.c')
-rw-r--r-- | source4/heimdal/kdc/digest.c | 140 |
1 files changed, 84 insertions, 56 deletions
diff --git a/source4/heimdal/kdc/digest.c b/source4/heimdal/kdc/digest.c index 811ab639f1..801449fe5e 100644 --- a/source4/heimdal/kdc/digest.c +++ b/source4/heimdal/kdc/digest.c @@ -34,7 +34,7 @@ #include "kdc_locl.h" #include <hex.h> -RCSID("$Id: digest.c 20877 2007-06-04 04:07:26Z lha $"); +RCSID("$Id: digest.c 21241 2007-06-20 11:30:19Z lha $"); #define MS_CHAP_V2 0x20 #define CHAP_MD5 0x10 @@ -160,6 +160,44 @@ static const unsigned char ms_rfc3079_magic1[27] = { * */ +static krb5_error_code +get_password_entry(krb5_context context, + krb5_kdc_configuration *config, + const char *username, + char **password) +{ + krb5_principal clientprincipal; + krb5_error_code ret; + hdb_entry_ex *user; + HDB *db; + + /* get username */ + ret = krb5_parse_name(context, username, &clientprincipal); + if (ret) + return ret; + + ret = _kdc_db_fetch(context, config, clientprincipal, + HDB_F_GET_CLIENT, &db, &user); + krb5_free_principal(context, clientprincipal); + if (ret) + return ret; + + ret = hdb_entry_get_password(context, db, &user->entry, password); + if (ret || password == NULL) { + if (ret == 0) { + ret = EINVAL; + krb5_set_error_string(context, "password missing"); + } + memset(user, 0, sizeof(*user)); + } + _kdc_free_ent (context, user); + return ret; +} + +/* + * + */ + krb5_error_code _kdc_do_digest(krb5_context context, krb5_kdc_configuration *config, @@ -461,9 +499,6 @@ _kdc_do_digest(krb5_context context, break; } case choice_DigestReqInner_digestRequest: { - krb5_principal clientprincipal; - HDB *db; - sp = krb5_storage_emem(); if (sp == NULL) { ret = ENOMEM; @@ -571,29 +606,6 @@ _kdc_do_digest(krb5_context context, } } - /* get username */ - ret = krb5_parse_name(context, - ireq.u.digestRequest.username, - &clientprincipal); - if (ret) - goto out; - - ret = _kdc_db_fetch(context, config, clientprincipal, - HDB_F_GET_CLIENT, &db, &user); - - krb5_free_principal(context, clientprincipal); - if (ret) - goto out; - - ret = hdb_entry_get_password(context, db, &user->entry, &password); - if (ret || password == NULL) { - if (ret == 0) { - ret = EINVAL; - krb5_set_error_string(context, "password missing"); - } - goto out; - } - if (strcasecmp(ireq.u.digestRequest.type, "CHAP") == 0) { MD5_CTX ctx; unsigned char md[MD5_DIGEST_LENGTH]; @@ -618,6 +630,12 @@ _kdc_do_digest(krb5_context context, goto out; } + ret = get_password_entry(context, config, + ireq.u.digestRequest.username, + &password); + if (ret) + goto out; + MD5_Init(&ctx); MD5_Update(&ctx, &id, 1); MD5_Update(&ctx, password, strlen(password)); @@ -664,6 +682,12 @@ _kdc_do_digest(krb5_context context, if (ireq.u.digestRequest.realm == NULL) goto out; + ret = get_password_entry(context, config, + ireq.u.digestRequest.username, + &password); + if (ret) + goto failed; + MD5_Init(&ctx); MD5_Update(&ctx, ireq.u.digestRequest.username, strlen(ireq.u.digestRequest.username)); @@ -692,7 +716,7 @@ _kdc_do_digest(krb5_context context, if (A1 == NULL) { krb5_set_error_string(context, "out of memory"); ret = ENOMEM; - goto out; + goto failed; } MD5_Init(&ctx); @@ -712,7 +736,7 @@ _kdc_do_digest(krb5_context context, krb5_set_error_string(context, "out of memory"); ret = ENOMEM; free(A1); - goto out; + goto failed; } MD5_Init(&ctx); @@ -758,6 +782,7 @@ _kdc_do_digest(krb5_context context, } else if (strcasecmp(ireq.u.digestRequest.type, "MS-CHAP-V2") == 0) { unsigned char md[SHA_DIGEST_LENGTH], challange[SHA_DIGEST_LENGTH]; + krb5_principal clientprincipal = NULL; char *mdx; const char *username; struct ntlm_buf answer; @@ -766,20 +791,20 @@ _kdc_do_digest(krb5_context context, if ((config->digests_allowed & MS_CHAP_V2) == 0) { kdc_log(context, config, 0, "MS-CHAP-V2 not allowed"); - goto out; + goto failed; } if (ireq.u.digestRequest.clientNonce == NULL) { krb5_set_error_string(context, "MS-CHAP-V2 clientNonce missing"); ret = EINVAL; - goto out; + goto failed; } if (serverNonce.length != 16) { krb5_set_error_string(context, "MS-CHAP-V2 serverNonce wrong length"); ret = EINVAL; - goto out; + goto failed; } /* strip of the domain component */ @@ -821,7 +846,7 @@ _kdc_do_digest(krb5_context context, /* NtPasswordHash */ ret = krb5_parse_name(context, username, &clientprincipal); if (ret) - goto out; + goto failed; ret = _kdc_db_fetch(context, config, clientprincipal, HDB_F_GET_CLIENT, NULL, &user); @@ -830,7 +855,7 @@ _kdc_do_digest(krb5_context context, krb5_set_error_string(context, "MS-CHAP-V2 user %s not in database", username); - goto out; + goto failed; } ret = hdb_enctype2key(context, &user->entry, @@ -839,7 +864,7 @@ _kdc_do_digest(krb5_context context, krb5_set_error_string(context, "MS-CHAP-V2 missing arcfour key %s", username); - goto out; + goto failed; } /* ChallengeResponse */ @@ -848,7 +873,7 @@ _kdc_do_digest(krb5_context context, challange, &answer); if (ret) { krb5_set_error_string(context, "NTLM missing arcfour key"); - goto out; + goto failed; } hex_encode(answer.data, answer.length, &mdx); @@ -861,15 +886,15 @@ _kdc_do_digest(krb5_context context, r.element = choice_DigestRepInner_response; ret = strcasecmp(mdx, ireq.u.digestRequest.responseData); - free(mdx); if (ret == 0) { r.u.response.success = TRUE; } else { kdc_log(context, config, 0, - "MS-CHAP-V2 reply mismatch for %s", + "MS-CHAP-V2 hash mismatch for %s", ireq.u.digestRequest.username); r.u.response.success = FALSE; } + free(mdx); if (r.u.response.success) { unsigned char hashhash[MD4_DIGEST_LENGTH]; @@ -958,7 +983,7 @@ _kdc_do_digest(krb5_context context, if ((config->digests_allowed & (NTLM_V1|NTLM_V1_SESSION|NTLM_V2)) == 0) { kdc_log(context, config, 0, "NTLM not allowed"); - goto out; + goto failed; } r.element = choice_DigestRepInner_ntlmInitReply; @@ -967,14 +992,14 @@ _kdc_do_digest(krb5_context context, if ((ireq.u.ntlmInit.flags & NTLM_NEG_UNICODE) == 0) { kdc_log(context, config, 0, "NTLM client have no unicode"); - goto out; + goto failed; } if (ireq.u.ntlmInit.flags & NTLM_NEG_NTLM) r.u.ntlmInitReply.flags |= NTLM_NEG_NTLM; else { kdc_log(context, config, 0, "NTLM client doesn't support NTLM"); - goto out; + goto failed; } r.u.ntlmInitReply.flags |= @@ -1095,7 +1120,7 @@ _kdc_do_digest(krb5_context context, ireq.u.ntlmRequest.username, &clientprincipal); if (ret) - goto out; + goto failed; ret = _kdc_db_fetch(context, config, clientprincipal, HDB_F_GET_CLIENT, NULL, &user); @@ -1103,20 +1128,23 @@ _kdc_do_digest(krb5_context context, if (ret) { krb5_set_error_string(context, "NTLM user %s not in database", ireq.u.ntlmRequest.username); - goto out; + goto failed; } ret = get_digest_key(context, config, server, &crypto); if (ret) - goto out; + goto failed; ret = krb5_decrypt(context, crypto, KRB5_KU_DIGEST_OPAQUE, ireq.u.ntlmRequest.opaque.data, ireq.u.ntlmRequest.opaque.length, &buf); krb5_crypto_destroy(context, crypto); crypto = NULL; - if (ret) - goto out; + if (ret) { + kdc_log(context, config, 0, + "Failed to decrypt nonce from %s", from); + goto failed; + } sp = krb5_storage_from_data(&buf); if (sp == NULL) { @@ -1185,7 +1213,7 @@ _kdc_do_digest(krb5_context context, free(targetname); if (ret) { krb5_set_error_string(context, "NTLM v2 verify failed"); - goto out; + goto failed; } /* XXX verify infotarget matches client (checksum ?) */ @@ -1205,14 +1233,14 @@ _kdc_do_digest(krb5_context context, if ((config->digests_allowed & NTLM_V1_SESSION) == 0) { kdc_log(context, config, 0, "NTLM v1-session not allowed"); ret = EINVAL; - goto out; + goto failed; } if (ireq.u.ntlmRequest.lm.length != 24) { krb5_set_error_string(context, "LM hash have wrong length " "for NTLM session key"); ret = EINVAL; - goto out; + goto failed; } MD5_Init(&md5ctx); @@ -1223,7 +1251,7 @@ _kdc_do_digest(krb5_context context, } else { if ((config->digests_allowed & NTLM_V1) == 0) { kdc_log(context, config, 0, "NTLM v1 not allowed"); - goto out; + goto failed; } } @@ -1232,7 +1260,7 @@ _kdc_do_digest(krb5_context context, challange, &answer); if (ret) { krb5_set_error_string(context, "NTLM missing arcfour key"); - goto out; + goto failed; } if (ireq.u.ntlmRequest.ntlm.length != answer.length || @@ -1241,7 +1269,7 @@ _kdc_do_digest(krb5_context context, free(answer.data); ret = EINVAL; krb5_set_error_string(context, "NTLM hash mismatch"); - goto out; + goto failed; } free(answer.data); @@ -1265,7 +1293,7 @@ _kdc_do_digest(krb5_context context, "NTLM client failed to neg key " "exchange but still sent key"); ret = EINVAL; - goto out; + goto failed; } len = ireq.u.ntlmRequest.sessionkey->length; @@ -1273,7 +1301,7 @@ _kdc_do_digest(krb5_context context, krb5_set_error_string(context, "NTLM master key wrong length: %lu", (unsigned long)len); - goto out; + goto failed; } RC4_set_key(&rc4, sizeof(sessionkey), sessionkey); @@ -1301,12 +1329,12 @@ _kdc_do_digest(krb5_context context, r.u.ntlmResponse.success = 1; kdc_log(context, config, 0, "NTLM version %d successful for %s", version, ireq.u.ntlmRequest.username); - break; } default: + failed: r.element = choice_DigestRepInner_error; - r.u.error.reason = strdup("unknown operation"); + r.u.error.reason = strdup("unknown/failed operation"); if (r.u.error.reason == NULL) { krb5_set_error_string(context, "out of memory"); ret = ENOMEM; |