diff options
-rw-r--r-- | source4/auth/ntlmssp/ntlmssp.c | 41 | ||||
-rw-r--r-- | source4/auth/ntlmssp/ntlmssp_sign.c | 54 |
2 files changed, 41 insertions, 54 deletions
diff --git a/source4/auth/ntlmssp/ntlmssp.c b/source4/auth/ntlmssp/ntlmssp.c index 1866eb56b9..e55527a51d 100644 --- a/source4/auth/ntlmssp/ntlmssp.c +++ b/source4/auth/ntlmssp/ntlmssp.c @@ -310,47 +310,6 @@ void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, } -/** - Weaken NTLMSSP keys to cope with down-level clients and servers. - - We probably should have some parameters to control this, but as - it only occours for LM_KEY connections, and this is controlled - by the client lanman auth/lanman auth parameters, it isn't too bad. -*/ - -DATA_BLOB ntlmssp_weakend_key(struct ntlmssp_state *ntlmssp_state, - TALLOC_CTX *mem_ctx) -{ - DATA_BLOB weakened_key = data_blob_talloc(mem_ctx, - ntlmssp_state->session_key.data, - ntlmssp_state->session_key.length); - /* Nothing to weaken. We certainly don't want to 'extend' the length... */ - if (weakened_key.length < 16) { - /* perhaps there was no key? */ - return weakened_key; - } - - /* Key weakening not performed on the master key for NTLM2 - and does not occour for NTLM1. Therefore we only need - to do this for the LM_KEY. - */ - if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) { - /* LM key doesn't support 128 bit crypto, so this is - * the best we can do. If you negotiate 128 bit, but - * not 56, you end up with 40 bit... */ - if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_56) { - weakened_key.data[7] = 0xa0; - weakened_key.length = 8; - } else { /* forty bits */ - weakened_key.data[5] = 0xe5; - weakened_key.data[6] = 0x38; - weakened_key.data[7] = 0xb0; - weakened_key.length = 8; - } - } - return weakened_key; -} - static bool gensec_ntlmssp_have_feature(struct gensec_security *gensec_security, uint32_t feature) { diff --git a/source4/auth/ntlmssp/ntlmssp_sign.c b/source4/auth/ntlmssp/ntlmssp_sign.c index 285369dbb3..3b25db571e 100644 --- a/source4/auth/ntlmssp/ntlmssp_sign.c +++ b/source4/auth/ntlmssp/ntlmssp_sign.c @@ -347,20 +347,12 @@ NTSTATUS ntlmssp_unseal_packet(struct ntlmssp_state *ntlmssp_state, /** Initialise the state for NTLMSSP signing. */ -/* TODO: make this non-public */ NTSTATUS ntlmssp_sign_init(struct ntlmssp_state *ntlmssp_state) { - TALLOC_CTX *mem_ctx = talloc_new(ntlmssp_state); - - if (!mem_ctx) { - return NT_STATUS_NO_MEMORY; - } - DEBUG(3, ("NTLMSSP Sign/Seal - Initialising with flags:\n")); debug_ntlmssp_flags(ntlmssp_state->neg_flags); if (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; } @@ -389,7 +381,6 @@ NTSTATUS ntlmssp_sign_init(struct ntlmssp_state *ntlmssp_state) recv_seal_const = CLI_SEAL; break; default: - talloc_free(mem_ctx); return NT_STATUS_INTERNAL_ERROR; } @@ -468,23 +459,60 @@ NTSTATUS ntlmssp_sign_init(struct ntlmssp_state *ntlmssp_state) /* RECV: seq num */ ntlmssp_state->crypt.ntlm2.recv_seq_num = 0; - } else { - DATA_BLOB weak_session_key = ntlmssp_weakend_key(ntlmssp_state, mem_ctx); + uint8_t weak_session_key[8]; + DATA_BLOB seal_session_key = ntlmssp_state->session_key; + bool do_weak = false; + DEBUG(5, ("NTLMSSP Sign/Seal - using NTLM1\n")); + /* + * Key weakening not performed on the master key for NTLM2 + * and does not occour for NTLM1. Therefore we only need + * to do this for the LM_KEY. + */ + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) { + do_weak = true; + } + + /* + * Nothing to weaken. + * We certainly don't want to 'extend' the length... + */ + if (seal_session_key.length < 16) { + /* TODO: is this really correct? */ + do_weak = false; + } + + if (do_weak) { + memcpy(weak_session_key, seal_session_key.data, 8); + seal_session_key = data_blob_const(weak_session_key, 8); + + /* + * LM key doesn't support 128 bit crypto, so this is + * the best we can do. If you negotiate 128 bit, but + * not 56, you end up with 40 bit... + */ + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_56) { + weak_session_key[7] = 0xa0; + } else { /* forty bits */ + weak_session_key[5] = 0xe5; + weak_session_key[6] = 0x38; + weak_session_key[7] = 0xb0; + } + } + ntlmssp_state->crypt.ntlm.arcfour_state = talloc(ntlmssp_state, struct arcfour_state); NT_STATUS_HAVE_NO_MEMORY(ntlmssp_state->crypt.ntlm.arcfour_state); arcfour_init(ntlmssp_state->crypt.ntlm.arcfour_state, - &weak_session_key); + &seal_session_key); dump_data_pw("NTLMSSP hash:\n", ntlmssp_state->crypt.ntlm.arcfour_state->sbox, sizeof(ntlmssp_state->crypt.ntlm.arcfour_state->sbox)); ntlmssp_state->crypt.ntlm.seq_num = 0; } - talloc_free(mem_ctx); return NT_STATUS_OK; } |