[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