From 0fdc34167baad1d1e130227eacfc16f7745f81f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Love=20H=C3=B6rnquist=20=C3=85strand?= Date: Thu, 1 Feb 2007 20:19:53 +0000 Subject: [PATCH] Check the digest response in the KDC. git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@20118 ec53bebd-3082-4978-b11e-865c3cabbd6b --- kdc/digest.c | 68 ++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 53 insertions(+), 15 deletions(-) diff --git a/kdc/digest.c b/kdc/digest.c index 211e66df9..ab75e00c5 100644 --- a/kdc/digest.c +++ b/kdc/digest.c @@ -595,6 +595,7 @@ _kdc_do_digest(krb5_context context, if (strcasecmp(ireq.u.digestRequest.type, "CHAP") == 0) { MD5_CTX ctx; unsigned char md[MD5_DIGEST_LENGTH]; + char *mdx; char id; if ((config->digests_allowed & CHAP_MD5) == 0) { @@ -621,16 +622,30 @@ _kdc_do_digest(krb5_context context, MD5_Update(&ctx, serverNonce.data, serverNonce.length); MD5_Final(md, &ctx); - r.element = choice_DigestRepInner_response; - hex_encode(md, sizeof(md), &r.u.response.responseData); - if (r.u.response.responseData == NULL) { + hex_encode(md, sizeof(md), &mdx); + if (mdx == NULL) { krb5_clear_error_string(context); ret = ENOMEM; goto out; } + + ret = strcmp(mdx, ireq.u.digestRequest.responseData); + free(mdx); + if (ret != 0) { + krb5_set_error_string(context, + "CHAP reply mismatch for %s", + ireq.u.digestRequest.username); + ret = EINVAL; + goto out; + } + + r.element = choice_DigestRepInner_response; + r.u.response.success = TRUE; + } else if (strcasecmp(ireq.u.digestRequest.type, "SASL-DIGEST-MD5") == 0) { MD5_CTX ctx; unsigned char md[MD5_DIGEST_LENGTH]; + char *mdx; char *A1, *A2; if ((config->digests_allowed & DIGEST_MD5) == 0) { @@ -717,20 +732,32 @@ _kdc_do_digest(krb5_context context, MD5_Final(md, &ctx); - r.element = choice_DigestRepInner_response; - hex_encode(md, sizeof(md), &r.u.response.responseData); - free(A1); free(A2); - if (r.u.response.responseData == NULL) { - krb5_set_error_string(context, "out of memory"); + hex_encode(md, sizeof(md), &mdx); + if (mdx == NULL) { + krb5_clear_error_string(context); ret = ENOMEM; goto out; } + ret = strcmp(mdx, ireq.u.digestRequest.responseData); + free(mdx); + if (ret != 0) { + krb5_set_error_string(context, + "Digest-MD5 reply mismatch for %s", + ireq.u.digestRequest.username); + ret = EINVAL; + goto out; + } + + r.element = choice_DigestRepInner_response; + r.u.response.success = TRUE; + } else if (strcasecmp(ireq.u.digestRequest.type, "MS-CHAP-V2") == 0) { unsigned char md[SHA_DIGEST_LENGTH], challange[SHA_DIGEST_LENGTH]; + char *mdx; const char *username; struct ntlm_buf answer; Key *key = NULL; @@ -823,15 +850,27 @@ _kdc_do_digest(krb5_context context, goto out; } - r.element = choice_DigestRepInner_response; - hex_encode(answer.data, answer.length, &r.u.response.responseData); - if (r.u.response.responseData == NULL) { - free(answer.data); + hex_encode(md, sizeof(md), &mdx); + if (mdx == NULL) { krb5_clear_error_string(context); ret = ENOMEM; goto out; } + ret = strcmp(mdx, ireq.u.digestRequest.responseData); + free(mdx); + if (ret != 0) { + free(answer.data); + krb5_set_error_string(context, + "MS-CHAP-V2 reply mismatch for %s", + ireq.u.digestRequest.username); + ret = EINVAL; + goto out; + } + + r.element = choice_DigestRepInner_response; + r.u.response.success = TRUE; + /* GenerateAuthenticatorResponse */ SHA1_Init(&ctx); SHA1_Update(&ctx, key->key.keyvalue.data, key->key.keyvalue.length); @@ -854,7 +893,7 @@ _kdc_do_digest(krb5_context context, } hex_encode(md, sizeof(md), r.u.response.rsp); - if (r.u.response.responseData == NULL) { + if (r.u.response.rsp == NULL) { krb5_clear_error_string(context); ret = ENOMEM; goto out; @@ -862,7 +901,7 @@ _kdc_do_digest(krb5_context context, } else { r.element = choice_DigestRepInner_error; - asprintf(&r.u.error.reason, "unsupported digest type %s", + asprintf(&r.u.error.reason, "Unsupported digest type %s", ireq.u.digestRequest.type); if (r.u.error.reason == NULL) { krb5_set_error_string(context, "out of memory"); @@ -884,7 +923,6 @@ _kdc_do_digest(krb5_context context, goto out; } - r.element = choice_DigestRepInner_ntlmInitReply; r.u.ntlmInitReply.flags = NTLM_NEG_UNICODE;