diff options
author | Simo Sorce <simo@redhat.com> | 2014-08-06 10:50:24 -0400 |
---|---|---|
committer | Simo Sorce <simo@redhat.com> | 2014-08-07 12:44:47 -0400 |
commit | d4e920b8e0cabbb0f8978c25c946036f644d2155 (patch) | |
tree | 4c48824469e8ebc2a0ba520fdcc9091cc330bc1f | |
parent | d46909d5058cc08c61da39e8e8ff135b9b665a73 (diff) | |
download | gss-ntlmssp-d4e920b8e0cabbb0f8978c25c946036f644d2155.tar.gz gss-ntlmssp-d4e920b8e0cabbb0f8978c25c946036f644d2155.tar.xz gss-ntlmssp-d4e920b8e0cabbb0f8978c25c946036f644d2155.zip |
Add support for NTLMv1 auth to the server
Fixes also condition on when to test for a LM Response on the server.
-rw-r--r-- | src/gss_auth.c | 90 | ||||
-rw-r--r-- | src/gss_ntlmssp.h | 2 | ||||
-rw-r--r-- | src/gss_sec_ctx.c | 9 |
3 files changed, 77 insertions, 24 deletions
diff --git a/src/gss_auth.c b/src/gss_auth.c index 9874431..e48b1dd 100644 --- a/src/gss_auth.c +++ b/src/gss_auth.c @@ -309,6 +309,12 @@ done: } +bool is_ntlm_v1(struct ntlm_buffer *nt_chal_resp) +{ + return (nt_chal_resp->length == 24); +} + + uint32_t gssntlm_srv_auth(uint32_t *minor, struct gssntlm_ctx *ctx, struct gssntlm_cred *cred, @@ -316,10 +322,13 @@ uint32_t gssntlm_srv_auth(uint32_t *minor, struct ntlm_buffer *lm_chal_resp, struct ntlm_key *key_exchange_key) { + struct ntlm_key session_base_key = { .length = 16 }; struct ntlm_key ntlmv2_key = { .length = 16 }; struct ntlm_buffer nt_proof = { 0 }; uint32_t retmaj, retmin; const char *domstr; + bool ntlm_v1; + bool ext_sec; int retries; if (key_exchange_key->length != 16) { @@ -327,10 +336,37 @@ uint32_t gssntlm_srv_auth(uint32_t *minor, return GSS_S_FAILURE; } + ntlm_v1 = is_ntlm_v1(nt_chal_resp); + + if (ntlm_v1 && !(ctx->sec_req & (SEC_DC_LM_OK | SEC_DC_NTLM_OK))) { + *minor = EPERM; + return GSS_S_FAILURE; + } + + ext_sec = (ctx->neg_flags & NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY); + switch (cred->type) { case GSSNTLM_CRED_USER: - for (retries = 2; retries > 0; retries--) { + if (ntlm_v1) { + uint8_t client_chal[8] = { 0 }; + + if (ext_sec) { + memcpy(client_chal, lm_chal_resp->data, 8); + } + + retmin = ntlm_verify_nt_response(nt_chal_resp, + &cred->cred.user.nt_hash, + ext_sec, ctx->server_chal, + client_chal); + if (retmin && ctx->sec_req & SEC_DC_LM_OK) { + retmin = ntlm_verify_lm_response(lm_chal_resp, + &cred->cred.user.lm_hash, + ext_sec, ctx->server_chal, + client_chal); + } + + } else for (retries = 2; retries > 0; retries--) { if (retries == 2) { domstr = cred->cred.user.user.data.user.domain; @@ -351,24 +387,30 @@ uint32_t gssntlm_srv_auth(uint32_t *minor, retmin = ntlmv2_verify_nt_response(nt_chal_resp, &ntlmv2_key, ctx->server_chal); - if (retmin == 0) { - break; - } else { - if (ctx->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) { - /* LMv2 Response */ - retmin = ntlmv2_verify_lm_response(lm_chal_resp, - &ntlmv2_key, - ctx->server_chal); - if (retmin == 0) { - break; - } - } + if (retmin && ctx->sec_req & SEC_DC_LM_OK) { + /* LMv2 Response */ + retmin = ntlmv2_verify_lm_response(lm_chal_resp, + &ntlmv2_key, + ctx->server_chal); } - if (retmin && retries < 2) { + if (retmin == 0) break; + } + + if (retmin) { + retmaj = GSS_S_FAILURE; + goto done; + } + + if (ntlm_v1) { + retmin = ntlm_session_base_key(&cred->cred.user.nt_hash, + &session_base_key); + if (retmin) { retmaj = GSS_S_FAILURE; goto done; } + break; } + /* The NT proof is the first 16 bytes */ nt_proof.data = nt_chal_resp->data; nt_proof.length = 16; @@ -376,7 +418,7 @@ uint32_t gssntlm_srv_auth(uint32_t *minor, /* The Session Base Key */ /* In NTLMv2 the Key Exchange Key is the Session Base Key */ retmin = ntlmv2_session_base_key(&ntlmv2_key, &nt_proof, - key_exchange_key); + &session_base_key); if (retmin) { retmaj = GSS_S_FAILURE; goto done; @@ -385,7 +427,7 @@ uint32_t gssntlm_srv_auth(uint32_t *minor, case GSSNTLM_CRED_EXTERNAL: retmin = external_srv_auth(ctx, cred, nt_chal_resp, lm_chal_resp, - key_exchange_key); + &session_base_key); if (retmin) { retmaj = GSS_S_FAILURE; goto done; @@ -398,6 +440,22 @@ uint32_t gssntlm_srv_auth(uint32_t *minor, goto done; } + if (ntlm_v1) { + retmin = KXKEY(ctx->ntlm, ext_sec, + (ctx->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY), + (ctx->neg_flags & NTLMSSP_REQUEST_NON_NT_SESSION_KEY), + ctx->server_chal, &cred->cred.user.lm_hash, + &session_base_key, lm_chal_resp, + key_exchange_key); + if (retmin) { + retmaj = GSS_S_FAILURE; + goto done; + } + } else { + memcpy(key_exchange_key->data, + session_base_key.data, session_base_key.length); + } + retmaj = GSS_S_COMPLETE; retmin = 0; diff --git a/src/gss_ntlmssp.h b/src/gss_ntlmssp.h index a0689c7..8c594aa 100644 --- a/src/gss_ntlmssp.h +++ b/src/gss_ntlmssp.h @@ -186,6 +186,8 @@ uint32_t external_srv_auth(struct gssntlm_ctx *ctx, uint32_t netbios_get_names(char *computer_name, char **netbios_host, char **netbios_domain); +bool is_ntlm_v1(struct ntlm_buffer *nt_chal_resp); + uint32_t gssntlm_cli_auth(uint32_t *minor, struct gssntlm_ctx *ctx, struct gssntlm_cred *cred, diff --git a/src/gss_sec_ctx.c b/src/gss_sec_ctx.c index 05d352f..fefbf6d 100644 --- a/src/gss_sec_ctx.c +++ b/src/gss_sec_ctx.c @@ -857,11 +857,9 @@ uint32_t gssntlm_accept_sec_context(uint32_t *minor_status, retmin = EINVAL; retmaj = GSS_S_FAILURE; goto done; - } - if (ctx->sec_req & SEC_V2_ONLY) { + } else { - /* ### NTLMv2 ### */ char useratdom[1024]; size_t ulen, dlen, uadlen; gss_buffer_desc usrname; @@ -925,11 +923,6 @@ uint32_t gssntlm_accept_sec_context(uint32_t *minor_status, &nt_chal_resp, &lm_chal_resp, &key_exchange_key); if (retmaj) goto done; - - } else { - /* ### NTLMv1 ### */ - retmaj = GSS_S_FAILURE; - goto done; } if (ctx->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { |