diff options
-rw-r--r-- | auth/ntlmssp/ntlmssp.c | 25 | ||||
-rw-r--r-- | auth/ntlmssp/ntlmssp.h | 2 | ||||
-rw-r--r-- | auth/ntlmssp/ntlmssp_sign.c | 40 |
3 files changed, 55 insertions, 12 deletions
diff --git a/auth/ntlmssp/ntlmssp.c b/auth/ntlmssp/ntlmssp.c index 091fdab9e4a..4abab88627a 100644 --- a/auth/ntlmssp/ntlmssp.c +++ b/auth/ntlmssp/ntlmssp.c @@ -179,6 +179,30 @@ NTSTATUS gensec_ntlmssp_update(struct gensec_security *gensec_security, return NT_STATUS_OK; } +static NTSTATUS gensec_ntlmssp_may_reset_crypto(struct gensec_security *gensec_security, + bool full_reset) +{ + struct gensec_ntlmssp_context *gensec_ntlmssp = + talloc_get_type_abort(gensec_security->private_data, + struct gensec_ntlmssp_context); + struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state; + NTSTATUS status; + bool reset_seqnums = full_reset; + + if (!gensec_ntlmssp_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { + return NT_STATUS_OK; + } + + status = ntlmssp_sign_reset(ntlmssp_state, reset_seqnums); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Could not reset NTLMSSP signing/sealing system (error was: %s)\n", + nt_errstr(status))); + return status; + } + + return NT_STATUS_OK; +} + static const char *gensec_ntlmssp_oids[] = { GENSEC_OID_NTLMSSP, NULL @@ -193,6 +217,7 @@ static const struct gensec_security_ops gensec_ntlmssp_security_ops = { .server_start = gensec_ntlmssp_server_start, .magic = gensec_ntlmssp_magic, .update = gensec_ntlmssp_update, + .may_reset_crypto= gensec_ntlmssp_may_reset_crypto, .sig_size = gensec_ntlmssp_sig_size, .sign_packet = gensec_ntlmssp_sign_packet, .check_packet = gensec_ntlmssp_check_packet, diff --git a/auth/ntlmssp/ntlmssp.h b/auth/ntlmssp/ntlmssp.h index 8c254f36e83..bb8807df425 100644 --- a/auth/ntlmssp/ntlmssp.h +++ b/auth/ntlmssp/ntlmssp.h @@ -130,6 +130,8 @@ NTSTATUS ntlmssp_unwrap(struct ntlmssp_state *ntlmssp_stae, TALLOC_CTX *out_mem_ctx, const DATA_BLOB *in, DATA_BLOB *out); +NTSTATUS ntlmssp_sign_reset(struct ntlmssp_state *ntlmssp_state, + bool reset_seqnums); NTSTATUS ntlmssp_sign_init(struct ntlmssp_state *ntlmssp_state); bool ntlmssp_blob_matches_magic(const DATA_BLOB *blob); diff --git a/auth/ntlmssp/ntlmssp_sign.c b/auth/ntlmssp/ntlmssp_sign.c index 2f8c6de75d9..a9757258803 100644 --- a/auth/ntlmssp/ntlmssp_sign.c +++ b/auth/ntlmssp/ntlmssp_sign.c @@ -503,20 +503,14 @@ NTSTATUS ntlmssp_unwrap(struct ntlmssp_state *ntlmssp_state, /** Initialise the state for NTLMSSP signing. */ -NTSTATUS ntlmssp_sign_init(struct ntlmssp_state *ntlmssp_state) +NTSTATUS ntlmssp_sign_reset(struct ntlmssp_state *ntlmssp_state, + bool reset_seqnums) { DEBUG(3, ("NTLMSSP Sign/Seal - Initialising with flags:\n")); debug_ntlmssp_flags(ntlmssp_state->neg_flags); - if (ntlmssp_state->session_key.length < 8) { - DEBUG(3, ("NO session key, cannot intialise signing\n")); - return NT_STATUS_NO_USER_SESSION_KEY; - } - - ntlmssp_state->crypt = talloc_zero(ntlmssp_state, - union ntlmssp_crypt_state); if (ntlmssp_state->crypt == NULL) { - return NT_STATUS_NO_MEMORY; + return NT_STATUS_INVALID_PARAMETER_MIX; } if (ntlmssp_state->force_wrap_seal && @@ -606,7 +600,9 @@ NTSTATUS ntlmssp_sign_init(struct ntlmssp_state *ntlmssp_state) &ntlmssp_state->crypt->ntlm2.sending.seal_state); /* SEND: seq num */ - ntlmssp_state->crypt->ntlm2.sending.seq_num = 0; + if (reset_seqnums) { + ntlmssp_state->crypt->ntlm2.sending.seq_num = 0; + } /* RECV: sign key */ calc_ntlmv2_key(ntlmssp_state->crypt->ntlm2.receiving.sign_key, @@ -626,7 +622,9 @@ NTSTATUS ntlmssp_sign_init(struct ntlmssp_state *ntlmssp_state) &ntlmssp_state->crypt->ntlm2.receiving.seal_state); /* RECV: seq num */ - ntlmssp_state->crypt->ntlm2.receiving.seq_num = 0; + if (reset_seqnums) { + ntlmssp_state->crypt->ntlm2.receiving.seq_num = 0; + } } else { uint8_t weak_session_key[8]; DATA_BLOB seal_session_key = ntlmssp_state->session_key; @@ -676,8 +674,26 @@ NTSTATUS ntlmssp_sign_init(struct ntlmssp_state *ntlmssp_state) dump_arc4_state("NTLMv1 arc4 state:\n", &ntlmssp_state->crypt->ntlm.seal_state); - ntlmssp_state->crypt->ntlm.seq_num = 0; + if (reset_seqnums) { + ntlmssp_state->crypt->ntlm.seq_num = 0; + } } return NT_STATUS_OK; } + +NTSTATUS ntlmssp_sign_init(struct ntlmssp_state *ntlmssp_state) +{ + if (ntlmssp_state->session_key.length < 8) { + DEBUG(3, ("NO session key, cannot intialise signing\n")); + return NT_STATUS_NO_USER_SESSION_KEY; + } + + ntlmssp_state->crypt = talloc_zero(ntlmssp_state, + union ntlmssp_crypt_state); + if (ntlmssp_state->crypt == NULL) { + return NT_STATUS_NO_MEMORY; + } + + return ntlmssp_sign_reset(ntlmssp_state, true); +} |