CVE-2016-2110: auth/ntlmssp: maintain conf_flags and required_flags variables
authorStefan Metzmacher <metze@samba.org>
Tue, 1 Dec 2015 10:01:24 +0000 (11:01 +0100)
committerStefan Metzmacher <metze@samba.org>
Tue, 12 Apr 2016 17:25:22 +0000 (19:25 +0200)
We now give an error when required flags are missing.

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/ntlmssp/gensec_ntlmssp_server.c
auth/ntlmssp/ntlmssp.h
auth/ntlmssp/ntlmssp_client.c
auth/ntlmssp/ntlmssp_util.c

index 5a57413a4d2ebdfc32758a59edeab00f059fbb3a..ede6f465122da0abcc88059e36996ace9c6a0c39 100644 (file)
@@ -225,6 +225,9 @@ NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_security)
        ntlmssp_state->server.dns_domain = talloc_strdup(ntlmssp_state, dns_domain);
        NT_STATUS_HAVE_NO_MEMORY(ntlmssp_state->server.dns_domain);
 
+       ntlmssp_state->neg_flags |= ntlmssp_state->required_flags;
+       ntlmssp_state->conf_flags = ntlmssp_state->neg_flags;
+
        return NT_STATUS_OK;
 }
 
index c63c23d029cd652b813d3f4e5105d4aabd061bbe..31062e5f9195c8b1a179e76f96757c8be0b70711 100644 (file)
@@ -92,6 +92,8 @@ struct ntlmssp_state
        DATA_BLOB nt_resp;
        DATA_BLOB session_key;
 
+       uint32_t conf_flags;
+       uint32_t required_flags;
        uint32_t neg_flags; /* the current state of negotiation with the NTLMSSP partner */
 
        bool force_wrap_seal;
index bf3b8c0dd5f6e18db324aae4da26f8a2b5af118b..c8b7c432f8ac212defd5d31614eba5a964266ccc 100644 (file)
@@ -168,6 +168,9 @@ NTSTATUS gensec_ntlmssp_resume_ccache(struct gensec_security *gensec_security,
                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
        }
 
+       ntlmssp_state->neg_flags |= ntlmssp_state->required_flags;
+       ntlmssp_state->conf_flags = ntlmssp_state->neg_flags;
+
        if (DEBUGLEVEL >= 10) {
                struct NEGOTIATE_MESSAGE *negotiate = talloc(
                        ntlmssp_state, struct NEGOTIATE_MESSAGE);
@@ -669,6 +672,9 @@ NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security)
                ntlmssp_state->use_ccache = true;
        }
 
+       ntlmssp_state->neg_flags |= ntlmssp_state->required_flags;
+       ntlmssp_state->conf_flags = ntlmssp_state->neg_flags;
+
        return NT_STATUS_OK;
 }
 
index 8f11df1a3cadde39f207b65ccc03700c2ce1fe90..262bf61201c99315cb082b68415ea7b55388eaaa 100644 (file)
@@ -73,6 +73,8 @@ void debug_ntlmssp_flags(uint32_t neg_flags)
 NTSTATUS ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state,
                                  uint32_t flags, const char *name)
 {
+       uint32_t missing_flags = ntlmssp_state->required_flags;
+
        if (flags & NTLMSSP_NEGOTIATE_UNICODE) {
                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
                ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_OEM;
@@ -123,6 +125,24 @@ NTSTATUS ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state,
                ntlmssp_state->neg_flags |= NTLMSSP_REQUEST_TARGET;
        }
 
+       missing_flags &= ~ntlmssp_state->neg_flags;
+       if (missing_flags != 0) {
+               HRESULT hres = HRES_SEC_E_UNSUPPORTED_FUNCTION;
+               NTSTATUS status = NT_STATUS(HRES_ERROR_V(hres));
+               DEBUG(1, ("%s: Got %s flags[0x%08x] "
+                         "- possible downgrade detected! "
+                         "missing_flags[0x%08x] - %s\n",
+                         __func__, name,
+                         (unsigned)flags,
+                         (unsigned)missing_flags,
+                         nt_errstr(status)));
+               debug_ntlmssp_flags_raw(1, missing_flags);
+               DEBUGADD(4, ("neg_flags[0x%08x]\n",
+                            (unsigned)ntlmssp_state->neg_flags));
+               debug_ntlmssp_flags_raw(4, ntlmssp_state->neg_flags);
+               return status;
+       }
+
        return NT_STATUS_OK;
 }