summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimo Sorce <simo@redhat.com>2014-08-06 10:50:24 -0400
committerSimo Sorce <simo@redhat.com>2014-08-07 12:44:47 -0400
commitd4e920b8e0cabbb0f8978c25c946036f644d2155 (patch)
tree4c48824469e8ebc2a0ba520fdcc9091cc330bc1f
parentd46909d5058cc08c61da39e8e8ff135b9b665a73 (diff)
downloadgss-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.c90
-rw-r--r--src/gss_ntlmssp.h2
-rw-r--r--src/gss_sec_ctx.c9
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) {