summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2011-10-15 13:17:33 +1100
committerAndrew Bartlett <abartlet@samba.org>2011-10-18 13:13:32 +1100
commit0d5de7e19c8112821269b4f5a910ee777f35d185 (patch)
tree61b04a7c2f01fff4f72988d222b0626d1277e4b7
parent5ef4e91cf099290c8798fd12b35927eed34b2fcf (diff)
downloadsamba-0d5de7e19c8112821269b4f5a910ee777f35d185.tar.gz
samba-0d5de7e19c8112821269b4f5a910ee777f35d185.tar.bz2
samba-0d5de7e19c8112821269b4f5a910ee777f35d185.zip
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 <metze@samba.org>
-rw-r--r--auth/gensec/gensec.c46
-rw-r--r--auth/gensec/gensec.h1
-rw-r--r--auth/gensec/gensec_start.c2
3 files changed, 48 insertions, 1 deletions
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 {
diff --git a/auth/gensec/gensec.h b/auth/gensec/gensec.h
index 38f2513742..ee87a4da79 100644
--- a/auth/gensec/gensec.h
+++ b/auth/gensec/gensec.h
@@ -160,6 +160,7 @@ struct gensec_security {
enum gensec_role gensec_role;
bool subcontext;
uint32_t want_features;
+ uint8_t dcerpc_auth_level;
struct tevent_context *event_ctx;
struct tsocket_address *local_addr, *remote_addr;
struct gensec_settings *settings;
diff --git a/auth/gensec/gensec_start.c b/auth/gensec/gensec_start.c
index 10fcb67b25..aa609c9b6f 100644
--- a/auth/gensec/gensec_start.c
+++ b/auth/gensec/gensec_start.c
@@ -547,6 +547,7 @@ _PUBLIC_ NTSTATUS gensec_subcontext_start(TALLOC_CTX *mem_ctx,
(*gensec_security)->subcontext = true;
(*gensec_security)->want_features = parent->want_features;
+ (*gensec_security)->dcerpc_auth_level = parent->dcerpc_auth_level;
(*gensec_security)->event_ctx = parent->event_ctx;
(*gensec_security)->auth_context = talloc_reference(*gensec_security, parent->auth_context);
(*gensec_security)->settings = talloc_reference(*gensec_security, parent->settings);
@@ -671,6 +672,7 @@ _PUBLIC_ NTSTATUS gensec_start_mech_by_authtype(struct gensec_security *gensec_s
DEBUG(3, ("Could not find GENSEC backend for auth_type=%d\n", (int)auth_type));
return NT_STATUS_INVALID_PARAMETER;
}
+ gensec_security->dcerpc_auth_level = auth_level;
gensec_want_feature(gensec_security, GENSEC_FEATURE_DCE_STYLE);
gensec_want_feature(gensec_security, GENSEC_FEATURE_ASYNC_REPLIES);
if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {