[SCM] Samba Shared Repository - branch v4-0-test updated - release-4-0-0alpha5-230-gbde2496

Stefan Metzmacher metze at samba.org
Thu Aug 7 16:12:02 GMT 2008


The branch, v4-0-test has been updated
       via  bde2496e6b7034c99243b22434a97aebeb8f75b9 (commit)
       via  54f1fca582b1474693b5ee11b7b847086d27f75f (commit)
       via  60b3523da485d845b1d930d990688d8434d39ef3 (commit)
       via  c62e5d23a69789d23516a6d150fd3b756e270998 (commit)
       via  d7dfdbaf34843cb6783d8e686e659c53c5ac27ef (commit)
      from  8e201ecf3e86c3c8865c7276fad8dad07106efaf (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v4-0-test


- Log -----------------------------------------------------------------
commit bde2496e6b7034c99243b22434a97aebeb8f75b9
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Aug 6 22:28:04 2008 +0200

    rpc_server: add support for DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN
    
    you need "dcesrv:header signing=yes" to enable it.
    
    metze

commit 54f1fca582b1474693b5ee11b7b847086d27f75f
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Aug 6 21:35:07 2008 +0200

    librpc/rpc: add support DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN
    
    You can trigger it like this:
    
    ncacn_ip_tcp:172.31.9.234[sign,hdrsign]
    
    or
    
    ncacn_ip_tcp:172.31.9.234[seal,hdrsign]
    
    metze

commit 60b3523da485d845b1d930d990688d8434d39ef3
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Aug 6 21:34:00 2008 +0200

    librpc/rpc: pass struct dcerpc_pipe to dcerpc_auth3()
    
    metze

commit c62e5d23a69789d23516a6d150fd3b756e270998
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Aug 6 21:30:17 2008 +0200

    gensec_gssapi: add support for GENSEC_FEATURE_SIGN_PKT_HEADER
    
    This only works for sign/verify_packet() yet,
    seal/unseal_packet() doesn't work yet...
    
    metze

commit d7dfdbaf34843cb6783d8e686e659c53c5ac27ef
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Aug 6 21:26:20 2008 +0200

    gensec: add GENSEC_FEATURE_SIGN_PKT_HEADER flag
    
    metze

-----------------------------------------------------------------------

Summary of changes:
 source/auth/gensec/gensec.h        |    1 +
 source/auth/gensec/gensec_gssapi.c |   86 ++++++++++++++++++++++++++++++++++--
 source/librpc/rpc/binding.c        |    3 +-
 source/librpc/rpc/dcerpc.c         |   39 ++++++++++++++--
 source/librpc/rpc/dcerpc.h         |    3 +
 source/librpc/rpc/dcerpc_auth.c    |    6 ++-
 source/rpc_server/dcerpc_server.c  |    9 +++-
 source/rpc_server/dcerpc_server.h  |    1 +
 source/rpc_server/dcesrv_auth.c    |    5 ++
 9 files changed, 141 insertions(+), 12 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source/auth/gensec/gensec.h b/source/auth/gensec/gensec.h
index 7a1abfb..2a89e67 100644
--- a/source/auth/gensec/gensec.h
+++ b/source/auth/gensec/gensec.h
@@ -52,6 +52,7 @@ struct gensec_target {
 #define GENSEC_FEATURE_DCE_STYLE	0x00000008
 #define GENSEC_FEATURE_ASYNC_REPLIES	0x00000010
 #define GENSEC_FEATURE_DATAGRAM_MODE	0x00000020
+#define GENSEC_FEATURE_SIGN_PKT_HEADER	0x00000040
 
 /* GENSEC mode */
 enum gensec_role
diff --git a/source/auth/gensec/gensec_gssapi.c b/source/auth/gensec/gensec_gssapi.c
index bb44c75..1541c88 100644
--- a/source/auth/gensec/gensec_gssapi.c
+++ b/source/auth/gensec/gensec_gssapi.c
@@ -37,6 +37,7 @@
 #include "param/param.h"
 #include "auth/session_proto.h"
 #include <gssapi/gssapi.h>
+#include <gssapi/gssapi_krb5.h>
 
 enum gensec_gssapi_sasl_state 
 {
@@ -77,6 +78,7 @@ struct gensec_gssapi_state {
 
 	size_t max_wrap_buf_size;
 	int gss_exchange_count;
+	size_t sig_size;
 };
 
 static size_t gensec_gssapi_max_input_size(struct gensec_security *gensec_security);
@@ -191,6 +193,7 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security)
 	gensec_gssapi_state->pac = data_blob(NULL, 0);
 
 	gensec_gssapi_state->delegated_cred_handle = GSS_C_NO_CREDENTIAL;
+	gensec_gssapi_state->sig_size = 0;
 
 	talloc_set_destructor(gensec_gssapi_state, gensec_gssapi_destructor);
 
@@ -1035,8 +1038,13 @@ static NTSTATUS gensec_gssapi_sign_packet(struct gensec_security *gensec_securit
 	OM_uint32 maj_stat, min_stat;
 	gss_buffer_desc input_token, output_token;
 
-	input_token.length = length;
-	input_token.value = discard_const_p(uint8_t *, data);
+	if (gensec_security->want_features & GENSEC_FEATURE_SIGN_PKT_HEADER) {
+		input_token.length = pdu_length;
+		input_token.value = discard_const_p(uint8_t *, whole_pdu);
+	} else {
+		input_token.length = length;
+		input_token.value = discard_const_p(uint8_t *, data);
+	}
 
 	maj_stat = gss_get_mic(&min_stat,
 			    gensec_gssapi_state->gssapi_context,
@@ -1073,8 +1081,13 @@ static NTSTATUS gensec_gssapi_check_packet(struct gensec_security *gensec_securi
 
 	dump_data_pw("gensec_gssapi_seal_packet: sig\n", sig->data, sig->length);
 
-	input_message.length = length;
-	input_message.value = data;
+	if (gensec_security->want_features & GENSEC_FEATURE_SIGN_PKT_HEADER) {
+		input_message.length = pdu_length;
+		input_message.value = whole_pdu;
+	} else {
+		input_message.length = length;
+		input_message.value = data;
+	}
 
 	input_token.length = sig->length;
 	input_token.value = sig->data;
@@ -1369,6 +1382,70 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi
 	return NT_STATUS_OK;
 }
 
+size_t gensec_gssapi_sig_size(struct gensec_security *gensec_security, size_t data_size)
+{
+	struct gensec_gssapi_state *gensec_gssapi_state
+		= talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state);
+	OM_uint32 maj_stat, min_stat;
+	gss_krb5_lucid_context_v1_t *lucid = NULL;
+
+	if (gensec_gssapi_state->sig_size) {
+		return gensec_gssapi_state->sig_size;
+	}
+
+	if (gensec_gssapi_state->got_flags & GSS_C_CONF_FLAG) {
+		gensec_gssapi_state->sig_size = 45;
+	} else {
+		gensec_gssapi_state->sig_size = 37;
+	}
+
+	maj_stat = gss_krb5_export_lucid_sec_context(&min_stat,
+						     &gensec_gssapi_state->gssapi_context,
+						     1, (void **)&lucid);
+	if (maj_stat != GSS_S_COMPLETE) {
+		return gensec_gssapi_state->sig_size;
+	}
+
+	if (lucid->version != 1) {
+		return gensec_gssapi_state->sig_size;
+	}
+
+	if (lucid->protocol == 1) {
+		if (gensec_gssapi_state->got_flags & GSS_C_CONF_FLAG) {
+			/*
+			 * TODO: windows uses 76 here, but we don't know
+			 *       gss_wrap works with aes keys yet
+			 */
+			gensec_gssapi_state->sig_size = 60;
+		} else {
+			gensec_gssapi_state->sig_size = 28;
+		}
+	} else if (lucid->protocol == 0) {
+		switch (lucid->rfc1964_kd.ctx_key.type) {
+		case KEYTYPE_DES:
+		case KEYTYPE_ARCFOUR:
+		case KEYTYPE_ARCFOUR_56:
+			if (gensec_gssapi_state->got_flags & GSS_C_CONF_FLAG) {
+				gensec_gssapi_state->sig_size = 45;
+			} else {
+				gensec_gssapi_state->sig_size = 37;
+			}
+			break;
+		case KEYTYPE_DES3:
+			if (gensec_gssapi_state->got_flags & GSS_C_CONF_FLAG) {
+				gensec_gssapi_state->sig_size = 57;
+			} else {
+				gensec_gssapi_state->sig_size = 49;
+			}
+			break;
+		}
+	}
+
+	gss_krb5_free_lucid_sec_context(&min_stat, lucid);
+
+	return gensec_gssapi_state->sig_size;
+}
+
 static const char *gensec_gssapi_krb5_oids[] = { 
 	GENSEC_OID_KERBEROS5_OLD,
 	GENSEC_OID_KERBEROS5,
@@ -1415,6 +1492,7 @@ static const struct gensec_security_ops gensec_gssapi_krb5_security_ops = {
 	.update 	= gensec_gssapi_update,
 	.session_key	= gensec_gssapi_session_key,
 	.session_info	= gensec_gssapi_session_info,
+	.sig_size	= gensec_gssapi_sig_size,
 	.sign_packet	= gensec_gssapi_sign_packet,
 	.check_packet	= gensec_gssapi_check_packet,
 	.seal_packet	= gensec_gssapi_seal_packet,
diff --git a/source/librpc/rpc/binding.c b/source/librpc/rpc/binding.c
index ae88dce..bfe62c4 100644
--- a/source/librpc/rpc/binding.c
+++ b/source/librpc/rpc/binding.c
@@ -83,7 +83,8 @@ static const struct {
 	{"print", DCERPC_DEBUG_PRINT_BOTH},
 	{"padcheck", DCERPC_DEBUG_PAD_CHECK},
 	{"bigendian", DCERPC_PUSH_BIGENDIAN},
-	{"smb2", DCERPC_SMB2}
+	{"smb2", DCERPC_SMB2},
+	{"hdrsign", DCERPC_HEADER_SIGNING}
 };
 
 const char *epm_floor_string(TALLOC_CTX *mem_ctx, struct epm_floor *epm_floor)
diff --git a/source/librpc/rpc/dcerpc.c b/source/librpc/rpc/dcerpc.c
index 4758189..a6c7e00 100644
--- a/source/librpc/rpc/dcerpc.c
+++ b/source/librpc/rpc/dcerpc.c
@@ -658,6 +658,16 @@ static void dcerpc_bind_recv_handler(struct rpc_request *req,
 	conn->srv_max_xmit_frag = pkt->u.bind_ack.max_xmit_frag;
 	conn->srv_max_recv_frag = pkt->u.bind_ack.max_recv_frag;
 
+	if ((req->p->binding->flags & DCERPC_CONCURRENT_MULTIPLEX) &&
+	    (pkt->pfc_flags & DCERPC_PFC_FLAG_CONC_MPX)) {
+		conn->flags |= DCERPC_CONCURRENT_MULTIPLEX;
+	}
+
+	if ((req->p->binding->flags & DCERPC_HEADER_SIGNING) &&
+	    (pkt->pfc_flags & DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN)) {
+		conn->flags |= DCERPC_HEADER_SIGNING;
+	}
+
 	/* the bind_ack might contain a reply set of credentials */
 	if (conn->security_state.auth_info &&
 	    pkt->u.bind_ack.auth_info.length) {
@@ -731,6 +741,10 @@ struct composite_context *dcerpc_bind_send(struct dcerpc_pipe *p,
 		pkt.pfc_flags |= DCERPC_PFC_FLAG_CONC_MPX;
 	}
 
+	if (p->binding->flags & DCERPC_HEADER_SIGNING) {
+		pkt.pfc_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN;
+	}
+
 	pkt.u.bind.max_xmit_frag = 5840;
 	pkt.u.bind.max_recv_frag = 5840;
 	pkt.u.bind.assoc_group_id = p->binding->assoc_group_id;
@@ -790,30 +804,41 @@ NTSTATUS dcerpc_bind_recv(struct composite_context *ctx)
 /* 
    perform a continued bind (and auth3)
 */
-NTSTATUS dcerpc_auth3(struct dcerpc_connection *c, 
+NTSTATUS dcerpc_auth3(struct dcerpc_pipe *p,
 		      TALLOC_CTX *mem_ctx)
 {
 	struct ncacn_packet pkt;
 	NTSTATUS status;
 	DATA_BLOB blob;
 
-	init_ncacn_hdr(c, &pkt);
+	init_ncacn_hdr(p->conn, &pkt);
 
 	pkt.ptype = DCERPC_PKT_AUTH3;
 	pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
-	pkt.call_id = next_call_id(c);
+	pkt.call_id = next_call_id(p->conn);
 	pkt.auth_length = 0;
 	pkt.u.auth3._pad = 0;
 	pkt.u.auth3.auth_info = data_blob(NULL, 0);
 
+	if (p->binding->flags & DCERPC_CONCURRENT_MULTIPLEX) {
+		pkt.pfc_flags |= DCERPC_PFC_FLAG_CONC_MPX;
+	}
+
+	if (p->binding->flags & DCERPC_HEADER_SIGNING) {
+		pkt.pfc_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN;
+	}
+
 	/* construct the NDR form of the packet */
-	status = ncacn_push_auth(&blob, mem_ctx, c->iconv_convenience, &pkt, c->security_state.auth_info);
+	status = ncacn_push_auth(&blob, mem_ctx,
+				 p->conn->iconv_convenience,
+				 &pkt,
+				 p->conn->security_state.auth_info);
 	if (!NT_STATUS_IS_OK(status)) {
 		return status;
 	}
 
 	/* send it on its way */
-	status = c->transport.send_request(c, &blob, false);
+	status = p->conn->transport.send_request(p->conn, &blob, false);
 	if (!NT_STATUS_IS_OK(status)) {
 		return status;
 	}
@@ -1627,6 +1652,10 @@ struct composite_context *dcerpc_alter_context_send(struct dcerpc_pipe *p,
 		pkt.pfc_flags |= DCERPC_PFC_FLAG_CONC_MPX;
 	}
 
+	if (p->binding->flags & DCERPC_HEADER_SIGNING) {
+		pkt.pfc_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN;
+	}
+
 	pkt.u.alter.max_xmit_frag = 5840;
 	pkt.u.alter.max_recv_frag = 5840;
 	pkt.u.alter.assoc_group_id = p->binding->assoc_group_id;
diff --git a/source/librpc/rpc/dcerpc.h b/source/librpc/rpc/dcerpc.h
index 487f9f2..1fd56cb 100644
--- a/source/librpc/rpc/dcerpc.h
+++ b/source/librpc/rpc/dcerpc.h
@@ -163,6 +163,9 @@ struct dcerpc_pipe {
 /* this triggers the DCERPC_PFC_FLAG_CONC_MPX flag in the bind request */
 #define DCERPC_CONCURRENT_MULTIPLEX     (1<<19)
 
+/* this triggers the DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN flag in the bind request */
+#define DCERPC_HEADER_SIGNING          (1<<20)
+
 /* this describes a binding to a particular transport/pipe */
 struct dcerpc_binding {
 	enum dcerpc_transport_t transport;
diff --git a/source/librpc/rpc/dcerpc_auth.c b/source/librpc/rpc/dcerpc_auth.c
index f990029..49fc3d9 100644
--- a/source/librpc/rpc/dcerpc_auth.c
+++ b/source/librpc/rpc/dcerpc_auth.c
@@ -137,6 +137,10 @@ static void bind_auth_next_step(struct composite_context *c)
 
 	if (!composite_is_ok(c)) return;
 
+	if (state->pipe->conn->flags & DCERPC_HEADER_SIGNING) {
+		gensec_want_feature(sec->generic_state, GENSEC_FEATURE_SIGN_PKT_HEADER);
+	}
+
 	if (state->credentials.length == 0) {
 		composite_done(c);
 		return;
@@ -146,7 +150,7 @@ static void bind_auth_next_step(struct composite_context *c)
 
 	if (!more_processing) {
 		/* NO reply expected, so just send it */
-		c->status = dcerpc_auth3(state->pipe->conn, state);
+		c->status = dcerpc_auth3(state->pipe, state);
 		if (!composite_is_ok(c)) return;
 
 		composite_done(c);
diff --git a/source/rpc_server/dcerpc_server.c b/source/rpc_server/dcerpc_server.c
index 9558949..a336ddb 100644
--- a/source/rpc_server/dcerpc_server.c
+++ b/source/rpc_server/dcerpc_server.c
@@ -544,6 +544,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
 	uint32_t result=0, reason=0;
 	uint32_t context_id;
 	const struct dcesrv_interface *iface;
+	uint32_t extra_flags = 0;
 
 	/*
 	 * Association groups allow policy handles to be shared across
@@ -617,6 +618,12 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
 		call->conn->cli_max_recv_frag = call->pkt.u.bind.max_recv_frag;
 	}
 
+	if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN) &&
+	    lp_parm_bool(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv","header signing", false)) {
+		call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_HEADER_SIGNING;
+		extra_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN;
+	}
+
 	/* handle any authentication that is being requested */
 	if (!dcesrv_auth_bind(call)) {
 		return dcesrv_bind_nak(call, DCERPC_BIND_REASON_INVALID_AUTH_TYPE);
@@ -627,7 +634,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
 	pkt.auth_length = 0;
 	pkt.call_id = call->pkt.call_id;
 	pkt.ptype = DCERPC_PKT_BIND_ACK;
-	pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
+	pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
 	pkt.u.bind_ack.max_xmit_frag = 0x2000;
 	pkt.u.bind_ack.max_recv_frag = 0x2000;
 	/* we need to send a non zero assoc_group_id here to make longhorn happy, it also matches samba3 */
diff --git a/source/rpc_server/dcerpc_server.h b/source/rpc_server/dcerpc_server.h
index 058dfe3..b5672b4 100644
--- a/source/rpc_server/dcerpc_server.h
+++ b/source/rpc_server/dcerpc_server.h
@@ -101,6 +101,7 @@ struct dcesrv_call_state {
 	 */
 #define DCESRV_CALL_STATE_FLAG_ASYNC (1<<0)
 #define DCESRV_CALL_STATE_FLAG_MAY_ASYNC (1<<1)
+#define DCESRV_CALL_STATE_FLAG_HEADER_SIGNING (1<<2)
 	uint32_t state_flags;
 
 	/* the time the request arrived in the server */
diff --git a/source/rpc_server/dcesrv_auth.c b/source/rpc_server/dcesrv_auth.c
index 1d89441..64f42ee 100644
--- a/source/rpc_server/dcesrv_auth.c
+++ b/source/rpc_server/dcesrv_auth.c
@@ -124,6 +124,11 @@ NTSTATUS dcesrv_auth_bind_ack(struct dcesrv_call_state *call, struct ncacn_packe
 			return status;
 		}
 
+		if (dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_HEADER_SIGNING) {
+			gensec_want_feature(dce_conn->auth_state.gensec_security,
+					    GENSEC_FEATURE_SIGN_PKT_HEADER);
+		}
+
 		/* Now that we are authenticated, go back to the generic session key... */
 		dce_conn->auth_state.session_key = dcesrv_generic_session_key;
 		return NT_STATUS_OK;


-- 
Samba Shared Repository


More information about the samba-cvs mailing list