From 0d5de7e19c8112821269b4f5a910ee777f35d185 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 15 Oct 2011 13:17:33 +1100 Subject: gensec: Assert that we have not been subject to a downgrade attack in DCE/RPC clients Because of the calling convention, this is the best place to assert that we have not been subject to a downgrade attack on the negotiated features. (In DCE/RPC, this isn't a negotiation, the client simply specifies the level of protection that is required). Andrew Bartlett (some formatting fixes) Signed-off-by: Stefan Metzmacher --- auth/gensec/gensec.c | 46 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) (limited to 'auth/gensec/gensec.c') diff --git a/auth/gensec/gensec.c b/auth/gensec/gensec.c index 417b05cf06..c0ebc68bb5 100644 --- a/auth/gensec/gensec.c +++ b/auth/gensec/gensec.c @@ -26,6 +26,7 @@ #include "lib/tsocket/tsocket.h" #include "lib/util/tevent_ntstatus.h" #include "auth/gensec/gensec.h" +#include "librpc/rpc/dcerpc.h" /* wrappers for the gensec function pointers @@ -195,7 +196,50 @@ _PUBLIC_ NTSTATUS gensec_session_info(struct gensec_security *gensec_security, _PUBLIC_ NTSTATUS gensec_update(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, const DATA_BLOB in, DATA_BLOB *out) { - return gensec_security->ops->update(gensec_security, out_mem_ctx, in, out); + NTSTATUS status; + + status = gensec_security->ops->update(gensec_security, out_mem_ctx, + in, out); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + /* + * Because callers using the + * gensec_start_mech_by_auth_type() never call + * gensec_want_feature(), it isn't sensible for them + * to have to call gensec_have_feature() manually, and + * these are not points of negotiation, but are + * asserted by the client + */ + switch (gensec_security->dcerpc_auth_level) { + case DCERPC_AUTH_LEVEL_INTEGRITY: + if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { + DEBUG(0,("Did not manage to negotiate mandetory feature " + "SIGN for dcerpc auth_level %u\n", + gensec_security->dcerpc_auth_level)); + return NT_STATUS_ACCESS_DENIED; + } + break; + case DCERPC_AUTH_LEVEL_PRIVACY: + if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { + DEBUG(0,("Did not manage to negotiate mandetory feature " + "SIGN for dcerpc auth_level %u\n", + gensec_security->dcerpc_auth_level)); + return NT_STATUS_ACCESS_DENIED; + } + if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) { + DEBUG(0,("Did not manage to negotiate mandetory feature " + "SEAL for dcerpc auth_level %u\n", + gensec_security->dcerpc_auth_level)); + return NT_STATUS_ACCESS_DENIED; + } + break; + default: + break; + } + + return NT_STATUS_OK; } struct gensec_update_state { -- cgit