From 2e35e39fc33071c03f3b1c60641e2f87d37ef3b0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 17 Dec 2013 11:49:31 +0100 Subject: [PATCH] CVE-2016-2110: auth/gensec: add gensec_may_reset_crypto() infrastructure MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit [MS-SPNG] requires the NTLMSSP RC4 states to be reset after the SPNEGO exchange with mechListMic verification (new_spnego). This provides the infrastructure for this feature. The 'reset_full' parameter is needed to support the broken behavior that windows only resets the RC4 states but not the sequence numbers. Which means this functionality is completely useless... But we want to work against all windows versions... BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- auth/gensec/gensec.c | 10 ++++++++++ auth/gensec/gensec_internal.h | 5 +++++ auth/gensec/spnego.c | 7 +++++++ 3 files changed, 22 insertions(+) diff --git a/auth/gensec/gensec.c b/auth/gensec/gensec.c index 548091a54ea..4d0968b298f 100644 --- a/auth/gensec/gensec.c +++ b/auth/gensec/gensec.c @@ -30,6 +30,16 @@ #include "auth/gensec/gensec_internal.h" #include "librpc/gen_ndr/dcerpc.h" +_PRIVATE_ NTSTATUS gensec_may_reset_crypto(struct gensec_security *gensec_security, + bool full_reset) +{ + if (!gensec_security->ops->may_reset_crypto) { + return NT_STATUS_OK; + } + + return gensec_security->ops->may_reset_crypto(gensec_security, full_reset); +} + /* wrappers for the gensec function pointers */ diff --git a/auth/gensec/gensec_internal.h b/auth/gensec/gensec_internal.h index 27511966ca9..55352417e99 100644 --- a/auth/gensec/gensec_internal.h +++ b/auth/gensec/gensec_internal.h @@ -47,6 +47,8 @@ struct gensec_security_ops { NTSTATUS (*update_recv)(struct tevent_req *req, TALLOC_CTX *out_mem_ctx, DATA_BLOB *out); + NTSTATUS (*may_reset_crypto)(struct gensec_security *gensec_security, + bool full_reset); NTSTATUS (*seal_packet)(struct gensec_security *gensec_security, TALLOC_CTX *sig_mem_ctx, uint8_t *data, size_t length, const uint8_t *whole_pdu, size_t pdu_length, @@ -121,4 +123,7 @@ struct gensec_critical_sizes { int sizeof_gensec_security; }; +NTSTATUS gensec_may_reset_crypto(struct gensec_security *gensec_security, + bool full_reset); + #endif /* __GENSEC_H__ */ diff --git a/auth/gensec/spnego.c b/auth/gensec/spnego.c index 7978f7bcab4..1d4b172e476 100644 --- a/auth/gensec/spnego.c +++ b/auth/gensec/spnego.c @@ -1426,7 +1426,14 @@ static NTSTATUS gensec_spnego_update_wrapper(struct gensec_security *gensec_secu data_blob_free(&spnego_state->in_frag); spnego_state->in_needed = 0; if (NT_STATUS_IS_OK(status)) { + bool reset_full = true; + gensec_security->child_security = spnego_state->sub_sec_security; + + reset_full = !spnego_state->done_mic_check; + + status = gensec_may_reset_crypto(spnego_state->sub_sec_security, + reset_full); } if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { -- 2.47.2