summaryrefslogtreecommitdiff
path: root/source4/auth/ntlmssp
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2006-02-12 12:42:37 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:51:54 -0500
commite218c8442db38bcfcac9e9425e8d0e32f61c840f (patch)
treef5079c7ad9f532c648a1e44f02085dcd7d9e048d /source4/auth/ntlmssp
parentba04ff6736c0551da06d112af28d42b351c10481 (diff)
downloadsamba-e218c8442db38bcfcac9e9425e8d0e32f61c840f.tar.gz
samba-e218c8442db38bcfcac9e9425e8d0e32f61c840f.tar.bz2
samba-e218c8442db38bcfcac9e9425e8d0e32f61c840f.zip
r13470: Thanks to a report from VL:
We were causing mayhem by weakening the keys at the wrong point in time. I think this is the correct place to do it. The session key for SMB signing, and the 'smb session key' (used for encrypting password sets) is never weakened. The session key used for bulk data encryption/signing is weakened. This also makes more sense, when we look at the NTLM2 code. Andrew Bartlett (This used to be commit 3fd32a12094ff2b6df52f5ab2af7c0ffceb5a4a0)
Diffstat (limited to 'source4/auth/ntlmssp')
-rw-r--r--source4/auth/ntlmssp/ntlmssp.c30
-rw-r--r--source4/auth/ntlmssp/ntlmssp_client.c3
-rw-r--r--source4/auth/ntlmssp/ntlmssp_server.c3
-rw-r--r--source4/auth/ntlmssp/ntlmssp_sign.c28
4 files changed, 39 insertions, 25 deletions
diff --git a/source4/auth/ntlmssp/ntlmssp.c b/source4/auth/ntlmssp/ntlmssp.c
index e1c748c558..d4edfb97aa 100644
--- a/source4/auth/ntlmssp/ntlmssp.c
+++ b/source4/auth/ntlmssp/ntlmssp.c
@@ -64,6 +64,8 @@ void debug_ntlmssp_flags(uint32_t neg_flags)
DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SIGN\n"));
if (neg_flags & NTLMSSP_NEGOTIATE_SEAL)
DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SEAL\n"));
+ if (neg_flags & NTLMSSP_NEGOTIATE_DATAGRAM_STYLE)
+ DEBUGADD(4, (" NTLMSSP_NEGOTIATE_DATAGRAM_STYLE\n"));
if (neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
DEBUGADD(4, (" NTLMSSP_NEGOTIATE_LM_KEY\n"));
if (neg_flags & NTLMSSP_NEGOTIATE_NETWARE)
@@ -78,6 +80,10 @@ void debug_ntlmssp_flags(uint32_t neg_flags)
DEBUGADD(4, (" NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL\n"));
if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)
DEBUGADD(4, (" NTLMSSP_NEGOTIATE_ALWAYS_SIGN\n"));
+ if (neg_flags & NTLMSSP_CHAL_ACCEPT_RESPONSE)
+ DEBUGADD(4, (" NTLMSSP_CHAL_ACCEPT_RESPONSE\n"));
+ if (neg_flags & NTLMSSP_CHAL_NON_NT_SESSION_KEY)
+ DEBUGADD(4, (" NTLMSSP_CHAL_NON_NT_SESSION_KEY\n"));
if (neg_flags & NTLMSSP_NEGOTIATE_NTLM2)
DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NTLM2\n"));
if (neg_flags & NTLMSSP_CHAL_TARGET_INFO)
@@ -86,6 +92,8 @@ void debug_ntlmssp_flags(uint32_t neg_flags)
DEBUGADD(4, (" NTLMSSP_NEGOTIATE_128\n"));
if (neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)
DEBUGADD(4, (" NTLMSSP_NEGOTIATE_KEY_EXCH\n"));
+ if (neg_flags & NTLMSSP_NEGOTIATE_56)
+ DEBUGADD(4, (" NTLMSSP_NEGOTIATE_56\n"));
}
static NTSTATUS gensec_ntlmssp_magic(struct gensec_security *gensec_security,
@@ -277,11 +285,16 @@ void ntlmssp_handle_neg_flags(struct gensec_ntlmssp_state *gensec_ntlmssp_state,
by the client lanman auth/lanman auth parameters, it isn't too bad.
*/
-void ntlmssp_weaken_keys(struct gensec_ntlmssp_state *gensec_ntlmssp_state)
+DATA_BLOB ntlmssp_weakend_key(struct gensec_ntlmssp_state *gensec_ntlmssp_state,
+ TALLOC_CTX *mem_ctx)
{
+ DATA_BLOB weakened_key = data_blob_talloc(mem_ctx,
+ gensec_ntlmssp_state->session_key.data,
+ gensec_ntlmssp_state->session_key.length);
/* Nothing to weaken. We certainly don't want to 'extend' the length... */
- if (gensec_ntlmssp_state->session_key.length < 8) {
- return;
+ if (weakened_key.length < 16) {
+ /* perhaps there was no key? */
+ return weakened_key;
}
/* Key weakening not performed on the master key for NTLM2
@@ -292,14 +305,15 @@ void ntlmssp_weaken_keys(struct gensec_ntlmssp_state *gensec_ntlmssp_state)
if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_128) {
} else if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_56) {
- gensec_ntlmssp_state->session_key.data[7] = 0xa0;
+ weakened_key.data[7] = 0xa0;
} else { /* forty bits */
- gensec_ntlmssp_state->session_key.data[5] = 0xe5;
- gensec_ntlmssp_state->session_key.data[6] = 0x38;
- gensec_ntlmssp_state->session_key.data[7] = 0xb0;
+ weakened_key.data[5] = 0xe5;
+ weakened_key.data[6] = 0x38;
+ weakened_key.data[7] = 0xb0;
}
- gensec_ntlmssp_state->session_key.length = 8;
+ weakened_key.length = 8;
}
+ return weakened_key;
}
static BOOL gensec_ntlmssp_have_feature(struct gensec_security *gensec_security,
diff --git a/source4/auth/ntlmssp/ntlmssp_client.c b/source4/auth/ntlmssp/ntlmssp_client.c
index d058b84a28..c2a1e1cde8 100644
--- a/source4/auth/ntlmssp/ntlmssp_client.c
+++ b/source4/auth/ntlmssp/ntlmssp_client.c
@@ -259,9 +259,6 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security,
talloc_steal(out_mem_ctx, out->data);
- /* The client might be using 56 or 40 bit weakened keys */
- ntlmssp_weaken_keys(gensec_ntlmssp_state);
-
gensec_ntlmssp_state->chal = challenge_blob;
gensec_ntlmssp_state->lm_resp = lm_response;
talloc_steal(gensec_ntlmssp_state->lm_resp.data, lm_response.data);
diff --git a/source4/auth/ntlmssp/ntlmssp_server.c b/source4/auth/ntlmssp/ntlmssp_server.c
index de44d40a50..65956d0580 100644
--- a/source4/auth/ntlmssp/ntlmssp_server.c
+++ b/source4/auth/ntlmssp/ntlmssp_server.c
@@ -554,9 +554,6 @@ static NTSTATUS ntlmssp_server_postauth(struct gensec_security *gensec_security,
/* keep the session key around on the new context */
talloc_steal(gensec_ntlmssp_state, session_key.data);
- /* The server might need us to use a partial-strength session key */
- ntlmssp_weaken_keys(gensec_ntlmssp_state);
-
if ((gensec_security->want_features & GENSEC_FEATURE_SIGN)
|| (gensec_security->want_features & GENSEC_FEATURE_SEAL)) {
nt_status = ntlmssp_sign_init(gensec_ntlmssp_state);
diff --git a/source4/auth/ntlmssp/ntlmssp_sign.c b/source4/auth/ntlmssp/ntlmssp_sign.c
index 41075cd25b..de1720be4c 100644
--- a/source4/auth/ntlmssp/ntlmssp_sign.c
+++ b/source4/auth/ntlmssp/ntlmssp_sign.c
@@ -299,13 +299,17 @@ NTSTATUS gensec_ntlmssp_unseal_packet(struct gensec_security *gensec_security,
*/
NTSTATUS ntlmssp_sign_init(struct gensec_ntlmssp_state *gensec_ntlmssp_state)
{
- uint8_t p24[24];
- ZERO_STRUCT(p24);
+ TALLOC_CTX *mem_ctx = talloc_new(gensec_ntlmssp_state);
+
+ if (!mem_ctx) {
+ return NT_STATUS_NO_MEMORY;
+ }
DEBUG(3, ("NTLMSSP Sign/Seal - Initialising with flags:\n"));
debug_ntlmssp_flags(gensec_ntlmssp_state->neg_flags);
- if (!gensec_ntlmssp_state->session_key.length) {
+ if (gensec_ntlmssp_state->session_key.length < 8) {
+ talloc_free(mem_ctx);
DEBUG(3, ("NO session key, cannot intialise signing\n"));
return NT_STATUS_NO_USER_SESSION_KEY;
}
@@ -335,6 +339,7 @@ NTSTATUS ntlmssp_sign_init(struct gensec_ntlmssp_state *gensec_ntlmssp_state)
recv_seal_const = CLI_SEAL;
break;
default:
+ talloc_free(mem_ctx);
return NT_STATUS_INTERNAL_ERROR;
}
@@ -368,7 +373,7 @@ NTSTATUS ntlmssp_sign_init(struct gensec_ntlmssp_state *gensec_ntlmssp_state)
weak_session_key.data,
weak_session_key.length);
- /* SEND */
+ /* SEND: sign key */
calc_ntlmv2_key(gensec_ntlmssp_state,
&gensec_ntlmssp_state->crypt.ntlm2.send_sign_key,
gensec_ntlmssp_state->session_key, send_sign_const);
@@ -376,21 +381,20 @@ NTSTATUS ntlmssp_sign_init(struct gensec_ntlmssp_state *gensec_ntlmssp_state)
gensec_ntlmssp_state->crypt.ntlm2.send_sign_key.data,
gensec_ntlmssp_state->crypt.ntlm2.send_sign_key.length);
- calc_ntlmv2_key(gensec_ntlmssp_state,
+ /* SEND: seal ARCFOUR pad */
+ calc_ntlmv2_key(mem_ctx,
&send_seal_key,
weak_session_key, send_seal_const);
dump_data_pw("NTLMSSP send seal key:\n",
send_seal_key.data,
send_seal_key.length);
-
arcfour_init(gensec_ntlmssp_state->crypt.ntlm2.send_seal_arcfour_state,
&send_seal_key);
-
dump_data_pw("NTLMSSP send sesl hash:\n",
gensec_ntlmssp_state->crypt.ntlm2.send_seal_arcfour_state->sbox,
sizeof(gensec_ntlmssp_state->crypt.ntlm2.send_seal_arcfour_state->sbox));
- /* RECV */
+ /* RECV: sign key */
calc_ntlmv2_key(gensec_ntlmssp_state,
&gensec_ntlmssp_state->crypt.ntlm2.recv_sign_key,
gensec_ntlmssp_state->session_key, recv_sign_const);
@@ -398,7 +402,8 @@ NTSTATUS ntlmssp_sign_init(struct gensec_ntlmssp_state *gensec_ntlmssp_state)
gensec_ntlmssp_state->crypt.ntlm2.recv_sign_key.data,
gensec_ntlmssp_state->crypt.ntlm2.recv_sign_key.length);
- calc_ntlmv2_key(gensec_ntlmssp_state,
+ /* RECV: seal ARCFOUR pad */
+ calc_ntlmv2_key(mem_ctx,
&recv_seal_key,
weak_session_key, recv_seal_const);
dump_data_pw("NTLMSSP recv seal key:\n",
@@ -406,7 +411,6 @@ NTSTATUS ntlmssp_sign_init(struct gensec_ntlmssp_state *gensec_ntlmssp_state)
recv_seal_key.length);
arcfour_init(gensec_ntlmssp_state->crypt.ntlm2.recv_seal_arcfour_state,
&recv_seal_key);
-
dump_data_pw("NTLMSSP receive seal hash:\n",
gensec_ntlmssp_state->crypt.ntlm2.recv_seal_arcfour_state->sbox,
sizeof(gensec_ntlmssp_state->crypt.ntlm2.recv_seal_arcfour_state->sbox));
@@ -415,19 +419,21 @@ NTSTATUS ntlmssp_sign_init(struct gensec_ntlmssp_state *gensec_ntlmssp_state)
gensec_ntlmssp_state->crypt.ntlm2.recv_seq_num = 0;
} else {
+ DATA_BLOB weak_session_key = ntlmssp_weakend_key(gensec_ntlmssp_state, mem_ctx);
DEBUG(5, ("NTLMSSP Sign/Seal - using NTLM1\n"));
gensec_ntlmssp_state->crypt.ntlm.arcfour_state = talloc(gensec_ntlmssp_state, struct arcfour_state);
NT_STATUS_HAVE_NO_MEMORY(gensec_ntlmssp_state->crypt.ntlm.arcfour_state);
arcfour_init(gensec_ntlmssp_state->crypt.ntlm.arcfour_state,
- &gensec_ntlmssp_state->session_key);
+ &weak_session_key);
dump_data_pw("NTLMSSP hash:\n", gensec_ntlmssp_state->crypt.ntlm.arcfour_state->sbox,
sizeof(gensec_ntlmssp_state->crypt.ntlm.arcfour_state->sbox));
gensec_ntlmssp_state->crypt.ntlm.seq_num = 0;
}
+ talloc_free(mem_ctx);
return NT_STATUS_OK;
}