CVE-2016-2110: auth/gensec: add gensec_may_reset_crypto() infrastructure
authorStefan Metzmacher <metze@samba.org>
Tue, 17 Dec 2013 10:49:31 +0000 (11:49 +0100)
committerStefan Metzmacher <metze@samba.org>
Tue, 12 Apr 2016 17:25:23 +0000 (19:25 +0200)
[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 <metze@samba.org>
Reviewed-by: G√ľnther Deschner <gd@samba.org>
auth/gensec/gensec.c
auth/gensec/gensec_internal.h
auth/gensec/spnego.c

index e3b13521ed2b4b2cad308f0cf9cebb706a7ec095..2a8bba8bc0bd138d6679ff837a06b116850688c3 100644 (file)
 #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
 */
index 27511966ca9ad17fd64d49454a78b178b0400886..55352417e99a5e7b29f6603e0916b09a1914ff66 100644 (file)
@@ -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__ */
index f47221a212829770243976ad37708395f5c920da..2922478ab179498975b1d5eaee4c6d8e51b1fcc1 100644 (file)
@@ -1431,7 +1431,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)) {