[SCM] Samba Shared Repository - branch master updated

Stefan Metzmacher metze at samba.org
Mon Jan 6 18:25:04 MST 2014


The branch, master has been updated
       via  6ab9164 s3:rpc_client: send a dcerpc_sec_verification_trailer if needed
       via  f0532fe s3:rpc_client: fill alloc_hint with the remaining data not the total data.
       via  c0dc2fb dcerpc.idl: add dcerpc_sec_verification_trailer
       via  66c3942 dcerpc.idl: add documentation references
       via  b62308e librpc/ndr: add LIBNDR_FLAG_SUBCONTEXT_NO_UNREAD_BYTES
       via  523d616 s3:rpc_server: add support for DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN
       via  61bdbc2 s3:rpc_client: implement DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN
       via  f7bf7e70 s3:rpc_client: handle DCERPC_AUTH_TYPE_SCHANNEL as any other gensec backend
       via  4d3376e s3:rpc_client: add some const to rpc_api_pipe_req_send()
       via  946e29d s3:rpc_client: make rpc_api_pipe_req_send/recv static
       via  5b39a35 s3:rpc_client: talloc_zero pipe_auth_data
       via  03006d0 auth/gensec: implement GENSEC_FEATURE_SIGN_PKT_HEADER in schannel.c
       via  616cd00 auth/gensec: move libcli/auth/schannel_sign.c into schannel.c
       via  54b5b30 s4:gensec_gssapi: make sure gensec_gssapi_[un]seal_packet() rejects header signing
       via  14f6c41 s4:auth/gensec_gssapi: handle GENSEC_FEATURE_SIGN_PKT_HEADER in have_feature()
       via  64fc015 auth/ntlmssp: GENSEC_FEATURE_SIGN_PKT_HEADER is always supported
       via  661fe3c s4:rpc_server: support DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN by default
       via  7db1dc1 s4:librpc: always try to negotiate DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN
      from  e8eb47f docs: Add num-children to smbcontrol manpage

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 6ab9164c74e0ad57bdde8abb568953026b644e27
Author: Stefan Metzmacher <metze at samba.org>
Date:   Sun Jan 5 08:12:45 2014 +0100

    s3:rpc_client: send a dcerpc_sec_verification_trailer if needed
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    
    Autobuild-User(master): Stefan Metzmacher <metze at samba.org>
    Autobuild-Date(master): Tue Jan  7 02:24:42 CET 2014 on sn-devel-104

commit f0532fe0cd69aeb161088ca990d376f119102e61
Author: Stefan Metzmacher <metze at samba.org>
Date:   Sun Jan 5 07:57:51 2014 +0100

    s3:rpc_client: fill alloc_hint with the remaining data not the total data.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit c0dc2fb7e1dadcef35a132040448cb27ff1d5bfa
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Jan 2 11:18:38 2014 +0100

    dcerpc.idl: add dcerpc_sec_verification_trailer
    
    See [MS-RPCE] 2.2.2.13 Verification Trailer for details.
    
    Pair-Programmed-With: Gregor Beck <gbeck at sernet.de>
    
    Signed-off-by: Gregor Beck <gbeck at sernet.de>
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 66c39420e29e7c257d9cdc5d04c061472bbefd19
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Jan 3 15:06:23 2014 +0100

    dcerpc.idl: add documentation references
    
    To [C706 - DCE 1.1: Remote Procedure Call] and [MS-RPCE].
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit b62308ed994e9734dfd934d230531010d9e7cefa
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Jan 3 09:25:23 2014 +0100

    librpc/ndr: add LIBNDR_FLAG_SUBCONTEXT_NO_UNREAD_BYTES
    
    This lets ndr_pull_subcontext_end() make sure that all
    subcontext bytes are consumed otherwise it returns NDR_ERR_UNREAD_BYTES.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 523d616268af5f94e11c863f9acdebabace80608
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Jan 3 22:56:03 2014 +0100

    s3:rpc_server: add support for DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN
    
    If the backend supports it there's no reason to avoid it.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 61bdbc23cd09a594a63f49ff8626934c85a8e51a
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Jan 3 22:41:33 2014 +0100

    s3:rpc_client: implement DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit f7bf7e705e704d2f1702e42a8e400baff9521066
Author: Stefan Metzmacher <metze at samba.org>
Date:   Sun Jan 5 08:26:15 2014 +0100

    s3:rpc_client: handle DCERPC_AUTH_TYPE_SCHANNEL as any other gensec backend
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 4d3376e919b5c33f272b3a584d8172729a7468e0
Author: Stefan Metzmacher <metze at samba.org>
Date:   Sun Jan 5 07:56:20 2014 +0100

    s3:rpc_client: add some const to rpc_api_pipe_req_send()
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 946e29dbc148d40fadbee81d4d530a36c0f2f1e6
Author: Stefan Metzmacher <metze at samba.org>
Date:   Sun Jan 5 06:31:44 2014 +0100

    s3:rpc_client: make rpc_api_pipe_req_send/recv static
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 5b39a351a8ceb3bec04236ceb4b2fe10651958a9
Author: Stefan Metzmacher <metze at samba.org>
Date:   Sun Jan 5 06:16:03 2014 +0100

    s3:rpc_client: talloc_zero pipe_auth_data
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 03006d0e4471465f071517097145806fbe46fdba
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Dec 31 10:11:18 2013 +0100

    auth/gensec: implement GENSEC_FEATURE_SIGN_PKT_HEADER in schannel.c
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 616cd009955b1722e6749019e2c1cac8bbb94e52
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Dec 31 09:42:36 2013 +0100

    auth/gensec: move libcli/auth/schannel_sign.c into schannel.c
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 54b5b3067f5b7a0eb6dd9f1326c903f9fe4a5592
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Jan 3 15:30:46 2014 +0100

    s4:gensec_gssapi: make sure gensec_gssapi_[un]seal_packet() rejects header signing
    
    If header signing is requested we should error out instead of
    silently ignoring it, our peer would hopefully reject it,
    but we should also do that.
    
    TODO: we should implement header signing using gss_wrap_iov().
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 14f6c41754960d73f46aca1bade2266b7e934d03
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Dec 31 09:54:54 2013 +0100

    s4:auth/gensec_gssapi: handle GENSEC_FEATURE_SIGN_PKT_HEADER in have_feature()
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 64fc015a85f9b5ed74f3dabe05dbdff185093278
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Dec 31 09:53:55 2013 +0100

    auth/ntlmssp: GENSEC_FEATURE_SIGN_PKT_HEADER is always supported
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 661fe3cf890b91f8750872b0f5a09da536f76ae2
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Jan 3 08:39:12 2014 +0100

    s4:rpc_server: support DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN by default
    
    If the gensec backend supports it there's no reason to disable it.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 7db1dc13b0149441a2beebca65b75f6e11af13a3
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Jan 3 08:35:27 2014 +0100

    s4:librpc: always try to negotiate DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN
    
    If the gensec backend supports it there's no reason not sign the header.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

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

Summary of changes:
 auth/gensec/schannel.c              |  428 ++++++++++++++++++++++++++++++++++-
 auth/ntlmssp/gensec_ntlmssp.c       |    4 +
 libcli/auth/schannel_proto.h        |   14 --
 libcli/auth/schannel_sign.c         |  404 ---------------------------------
 libcli/auth/wscript_build           |    2 +-
 librpc/idl/dcerpc.idl               |   80 +++++++-
 librpc/idl/idl_types.h              |    2 +
 librpc/ndr/libndr.h                 |    6 +
 librpc/ndr/ndr.c                    |   20 ++
 librpc/ndr/ndr_dcerpc.c             |   66 ++++++
 librpc/rpc/binding.c                |    1 -
 librpc/rpc/rpc_common.h             |    5 +-
 librpc/wscript_build                |    2 +-
 source3/librpc/rpc/dcerpc.h         |    5 +-
 source3/rpc_client/cli_pipe.c       |  264 +++++++++++++++++++--
 source3/rpc_client/cli_pipe.h       |   10 -
 source3/rpc_client/rpc_client.h     |    1 +
 source3/rpc_server/srv_pipe.c       |   25 ++-
 source4/auth/gensec/gensec_gssapi.c |   24 ++
 source4/librpc/rpc/dcerpc.c         |   12 +-
 source4/librpc/rpc/dcerpc_auth.c    |   14 +-
 source4/rpc_server/dcerpc_server.c  |    6 -
 source4/rpc_server/dcesrv_auth.c    |   37 +++-
 23 files changed, 938 insertions(+), 494 deletions(-)
 delete mode 100644 libcli/auth/schannel_sign.c
 create mode 100644 librpc/ndr/ndr_dcerpc.c


Changeset truncated at 500 lines:

diff --git a/auth/gensec/schannel.c b/auth/gensec/schannel.c
index eb2e100..3d30e83 100644
--- a/auth/gensec/schannel.c
+++ b/auth/gensec/schannel.c
@@ -31,6 +31,413 @@
 #include "librpc/gen_ndr/dcerpc.h"
 #include "param/param.h"
 #include "auth/gensec/gensec_toplevel_proto.h"
+#include "lib/crypto/crypto.h"
+
+struct schannel_state {
+	struct gensec_security *gensec;
+	uint64_t seq_num;
+	bool initiator;
+	struct netlogon_creds_CredentialState *creds;
+};
+
+#define SETUP_SEQNUM(state, buf, initiator) do { \
+	uint8_t *_buf = buf; \
+	uint32_t _seq_num_low = (state)->seq_num & UINT32_MAX; \
+	uint32_t _seq_num_high = (state)->seq_num >> 32; \
+	if (initiator) { \
+		_seq_num_high |= 0x80000000; \
+	} \
+	RSIVAL(_buf, 0, _seq_num_low); \
+	RSIVAL(_buf, 4, _seq_num_high); \
+} while(0)
+
+static struct schannel_state *netsec_create_state(
+				struct gensec_security *gensec,
+				struct netlogon_creds_CredentialState *creds,
+				bool initiator)
+{
+	struct schannel_state *state;
+
+	state = talloc(gensec, struct schannel_state);
+	if (state == NULL) {
+		return NULL;
+	}
+
+	state->gensec = gensec;
+	state->initiator = initiator;
+	state->seq_num = 0;
+	state->creds = netlogon_creds_copy(state, creds);
+	if (state->creds == NULL) {
+		talloc_free(state);
+		return NULL;
+	}
+
+	gensec->private_data = state;
+
+	return state;
+}
+
+static void netsec_offset_and_sizes(struct schannel_state *state,
+				    bool do_seal,
+				    uint32_t *_min_sig_size,
+				    uint32_t *_used_sig_size,
+				    uint32_t *_checksum_length,
+				    uint32_t *_confounder_ofs)
+{
+	uint32_t min_sig_size;
+	uint32_t used_sig_size;
+	uint32_t checksum_length;
+	uint32_t confounder_ofs;
+
+	if (state->creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
+		min_sig_size = 48;
+		used_sig_size = 56;
+		/*
+		 * Note: windows has a bug here and uses the old values...
+		 *
+		 * checksum_length = 32;
+		 * confounder_ofs = 48;
+		 */
+		checksum_length = 8;
+		confounder_ofs = 24;
+	} else {
+		min_sig_size = 24;
+		used_sig_size = 32;
+		checksum_length = 8;
+		confounder_ofs = 24;
+	}
+
+	if (do_seal) {
+		min_sig_size += 8;
+	}
+
+	if (_min_sig_size) {
+		*_min_sig_size = min_sig_size;
+	}
+
+	if (_used_sig_size) {
+		*_used_sig_size = used_sig_size;
+	}
+
+	if (_checksum_length) {
+		*_checksum_length = checksum_length;
+	}
+
+	if (_confounder_ofs) {
+		*_confounder_ofs = confounder_ofs;
+	}
+}
+
+/*******************************************************************
+ Encode or Decode the sequence number (which is symmetric)
+ ********************************************************************/
+static void netsec_do_seq_num(struct schannel_state *state,
+			      const uint8_t *checksum,
+			      uint32_t checksum_length,
+			      uint8_t seq_num[8])
+{
+	if (state->creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
+		AES_KEY key;
+		uint8_t iv[AES_BLOCK_SIZE];
+
+		AES_set_encrypt_key(state->creds->session_key, 128, &key);
+		ZERO_STRUCT(iv);
+		memcpy(iv+0, checksum, 8);
+		memcpy(iv+8, checksum, 8);
+
+		aes_cfb8_encrypt(seq_num, seq_num, 8, &key, iv, AES_ENCRYPT);
+	} else {
+		static const uint8_t zeros[4];
+		uint8_t sequence_key[16];
+		uint8_t digest1[16];
+
+		hmac_md5(state->creds->session_key, zeros, sizeof(zeros), digest1);
+		hmac_md5(digest1, checksum, checksum_length, sequence_key);
+		arcfour_crypt(seq_num, sequence_key, 8);
+	}
+
+	state->seq_num++;
+}
+
+static void netsec_do_seal(struct schannel_state *state,
+			   const uint8_t seq_num[8],
+			   uint8_t confounder[8],
+			   uint8_t *data, uint32_t length,
+			   bool forward)
+{
+	if (state->creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
+		AES_KEY key;
+		uint8_t iv[AES_BLOCK_SIZE];
+		uint8_t sess_kf0[16];
+		int i;
+
+		for (i = 0; i < 16; i++) {
+			sess_kf0[i] = state->creds->session_key[i] ^ 0xf0;
+		}
+
+		AES_set_encrypt_key(sess_kf0, 128, &key);
+		ZERO_STRUCT(iv);
+		memcpy(iv+0, seq_num, 8);
+		memcpy(iv+8, seq_num, 8);
+
+		if (forward) {
+			aes_cfb8_encrypt(confounder, confounder, 8, &key, iv, AES_ENCRYPT);
+			aes_cfb8_encrypt(data, data, length, &key, iv, AES_ENCRYPT);
+		} else {
+			aes_cfb8_encrypt(confounder, confounder, 8, &key, iv, AES_DECRYPT);
+			aes_cfb8_encrypt(data, data, length, &key, iv, AES_DECRYPT);
+		}
+	} else {
+		uint8_t sealing_key[16];
+		static const uint8_t zeros[4];
+		uint8_t digest2[16];
+		uint8_t sess_kf0[16];
+		int i;
+
+		for (i = 0; i < 16; i++) {
+			sess_kf0[i] = state->creds->session_key[i] ^ 0xf0;
+		}
+
+		hmac_md5(sess_kf0, zeros, 4, digest2);
+		hmac_md5(digest2, seq_num, 8, sealing_key);
+
+		arcfour_crypt(confounder, sealing_key, 8);
+		arcfour_crypt(data, sealing_key, length);
+	}
+}
+
+/*******************************************************************
+ Create a digest over the entire packet (including the data), and
+ MD5 it with the session key.
+ ********************************************************************/
+static void netsec_do_sign(struct schannel_state *state,
+			   const uint8_t *confounder,
+			   const uint8_t *data, size_t length,
+			   uint8_t header[8],
+			   uint8_t *checksum)
+{
+	if (state->creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
+		struct HMACSHA256Context ctx;
+
+		hmac_sha256_init(state->creds->session_key,
+				 sizeof(state->creds->session_key),
+				 &ctx);
+
+		if (confounder) {
+			SSVAL(header, 0, NL_SIGN_HMAC_SHA256);
+			SSVAL(header, 2, NL_SEAL_AES128);
+			SSVAL(header, 4, 0xFFFF);
+			SSVAL(header, 6, 0x0000);
+
+			hmac_sha256_update(header, 8, &ctx);
+			hmac_sha256_update(confounder, 8, &ctx);
+		} else {
+			SSVAL(header, 0, NL_SIGN_HMAC_SHA256);
+			SSVAL(header, 2, NL_SEAL_NONE);
+			SSVAL(header, 4, 0xFFFF);
+			SSVAL(header, 6, 0x0000);
+
+			hmac_sha256_update(header, 8, &ctx);
+		}
+
+		hmac_sha256_update(data, length, &ctx);
+
+		hmac_sha256_final(checksum, &ctx);
+	} else {
+		uint8_t packet_digest[16];
+		static const uint8_t zeros[4];
+		MD5_CTX ctx;
+
+		MD5Init(&ctx);
+		MD5Update(&ctx, zeros, 4);
+		if (confounder) {
+			SSVAL(header, 0, NL_SIGN_HMAC_MD5);
+			SSVAL(header, 2, NL_SEAL_RC4);
+			SSVAL(header, 4, 0xFFFF);
+			SSVAL(header, 6, 0x0000);
+
+			MD5Update(&ctx, header, 8);
+			MD5Update(&ctx, confounder, 8);
+		} else {
+			SSVAL(header, 0, NL_SIGN_HMAC_MD5);
+			SSVAL(header, 2, NL_SEAL_NONE);
+			SSVAL(header, 4, 0xFFFF);
+			SSVAL(header, 6, 0x0000);
+
+			MD5Update(&ctx, header, 8);
+		}
+		MD5Update(&ctx, data, length);
+		MD5Final(packet_digest, &ctx);
+
+		hmac_md5(state->creds->session_key,
+			 packet_digest, sizeof(packet_digest),
+			 checksum);
+	}
+}
+
+static NTSTATUS netsec_incoming_packet(struct schannel_state *state,
+				bool do_unseal,
+				uint8_t *data, size_t length,
+				const uint8_t *whole_pdu, size_t pdu_length,
+				const DATA_BLOB *sig)
+{
+	uint32_t min_sig_size = 0;
+	uint8_t header[8];
+	uint8_t checksum[32];
+	uint32_t checksum_length = sizeof(checksum_length);
+	uint8_t _confounder[8];
+	uint8_t *confounder = NULL;
+	uint32_t confounder_ofs = 0;
+	uint8_t seq_num[8];
+	int ret;
+	const uint8_t *sign_data = NULL;
+	size_t sign_length = 0;
+
+	netsec_offset_and_sizes(state,
+				do_unseal,
+				&min_sig_size,
+				NULL,
+				&checksum_length,
+				&confounder_ofs);
+
+	if (sig->length < min_sig_size) {
+		return NT_STATUS_ACCESS_DENIED;
+	}
+
+	if (do_unseal) {
+		confounder = _confounder;
+		memcpy(confounder, sig->data+confounder_ofs, 8);
+	} else {
+		confounder = NULL;
+	}
+
+	SETUP_SEQNUM(state, seq_num, !state->initiator);
+
+	if (do_unseal) {
+		netsec_do_seal(state, seq_num,
+			       confounder,
+			       data, length,
+			       false);
+	}
+
+	if (state->gensec->want_features & GENSEC_FEATURE_SIGN_PKT_HEADER) {
+		sign_data = whole_pdu;
+		sign_length = pdu_length;
+	} else {
+		sign_data = data;
+		sign_length = length;
+	}
+
+	netsec_do_sign(state, confounder,
+		       sign_data, sign_length,
+		       header, checksum);
+
+	ret = memcmp(checksum, sig->data+16, checksum_length);
+	if (ret != 0) {
+		dump_data_pw("calc digest:", checksum, checksum_length);
+		dump_data_pw("wire digest:", sig->data+16, checksum_length);
+		return NT_STATUS_ACCESS_DENIED;
+	}
+
+	netsec_do_seq_num(state, checksum, checksum_length, seq_num);
+
+	ret = memcmp(seq_num, sig->data+8, 8);
+	if (ret != 0) {
+		dump_data_pw("calc seq num:", seq_num, 8);
+		dump_data_pw("wire seq num:", sig->data+8, 8);
+		return NT_STATUS_ACCESS_DENIED;
+	}
+
+	return NT_STATUS_OK;
+}
+
+static uint32_t netsec_outgoing_sig_size(struct schannel_state *state)
+{
+	uint32_t sig_size = 0;
+
+	netsec_offset_and_sizes(state,
+				true,
+				NULL,
+				&sig_size,
+				NULL,
+				NULL);
+
+	return sig_size;
+}
+
+static NTSTATUS netsec_outgoing_packet(struct schannel_state *state,
+				TALLOC_CTX *mem_ctx,
+				bool do_seal,
+				uint8_t *data, size_t length,
+				const uint8_t *whole_pdu, size_t pdu_length,
+				DATA_BLOB *sig)
+{
+	uint32_t min_sig_size = 0;
+	uint32_t used_sig_size = 0;
+	uint8_t header[8];
+	uint8_t checksum[32];
+	uint32_t checksum_length = sizeof(checksum_length);
+	uint8_t _confounder[8];
+	uint8_t *confounder = NULL;
+	uint32_t confounder_ofs = 0;
+	uint8_t seq_num[8];
+	const uint8_t *sign_data = NULL;
+	size_t sign_length = 0;
+
+	netsec_offset_and_sizes(state,
+				do_seal,
+				&min_sig_size,
+				&used_sig_size,
+				&checksum_length,
+				&confounder_ofs);
+
+	SETUP_SEQNUM(state, seq_num, state->initiator);
+
+	if (do_seal) {
+		confounder = _confounder;
+		generate_random_buffer(confounder, 8);
+	} else {
+		confounder = NULL;
+	}
+
+	if (state->gensec->want_features & GENSEC_FEATURE_SIGN_PKT_HEADER) {
+		sign_data = whole_pdu;
+		sign_length = pdu_length;
+	} else {
+		sign_data = data;
+		sign_length = length;
+	}
+
+	netsec_do_sign(state, confounder,
+		       sign_data, sign_length,
+		       header, checksum);
+
+	if (do_seal) {
+		netsec_do_seal(state, seq_num,
+			       confounder,
+			       data, length,
+			       true);
+	}
+
+	netsec_do_seq_num(state, checksum, checksum_length, seq_num);
+
+	(*sig) = data_blob_talloc_zero(mem_ctx, used_sig_size);
+
+	memcpy(sig->data, header, 8);
+	memcpy(sig->data+8, seq_num, 8);
+	memcpy(sig->data+16, checksum, checksum_length);
+
+	if (confounder) {
+		memcpy(sig->data+confounder_ofs, confounder, 8);
+	}
+
+	dump_data_pw("signature:", sig->data+ 0, 8);
+	dump_data_pw("seq_num  :", sig->data+ 8, 8);
+	dump_data_pw("digest   :", sig->data+16, checksum_length);
+	dump_data_pw("confound :", sig->data+confounder_ofs, 8);
+
+	return NT_STATUS_OK;
+}
 
 _PUBLIC_ NTSTATUS gensec_schannel_init(void);
 
@@ -77,7 +484,6 @@ static NTSTATUS schannel_update(struct gensec_security *gensec_security, TALLOC_
 		if (state == NULL) {
 			return NT_STATUS_NO_MEMORY;
 		}
-		gensec_security->private_data = state;
 
 		bind_schannel.MessageType = NL_NEGOTIATE_REQUEST;
 #if 0
@@ -173,7 +579,6 @@ static NTSTATUS schannel_update(struct gensec_security *gensec_security, TALLOC_
 		if (state == NULL) {
 			return NT_STATUS_NO_MEMORY;
 		}
-		gensec_security->private_data = state;
 
 		bind_schannel_ack.MessageType = NL_NEGOTIATE_RESPONSE;
 		bind_schannel_ack.Flags = 0;
@@ -228,6 +633,9 @@ static bool schannel_have_feature(struct gensec_security *gensec_security,
 	if (feature & GENSEC_FEATURE_DCE_STYLE) {
 		return true;
 	}
+	if (feature & GENSEC_FEATURE_SIGN_PKT_HEADER) {
+		return true;
+	}
 	return false;
 }
 
@@ -245,7 +653,9 @@ static NTSTATUS schannel_unseal_packet(struct gensec_security *gensec_security,
 
 	return netsec_incoming_packet(state, true,
 				      discard_const_p(uint8_t, data),
-				      length, sig);
+				      length,
+				      whole_pdu, pdu_length,
+				      sig);
 }
 
 /*
@@ -262,7 +672,9 @@ static NTSTATUS schannel_check_packet(struct gensec_security *gensec_security,
 
 	return netsec_incoming_packet(state, false,
 				      discard_const_p(uint8_t, data),
-				      length, sig);
+				      length,
+				      whole_pdu, pdu_length,
+				      sig);
 }
 /*
   seal a packet
@@ -278,7 +690,9 @@ static NTSTATUS schannel_seal_packet(struct gensec_security *gensec_security,
 		struct schannel_state);
 
 	return netsec_outgoing_packet(state, mem_ctx, true,
-				      data, length, sig);
+				      data, length,
+				      whole_pdu, pdu_length,
+				      sig);
 }
 
 /*
@@ -296,7 +710,9 @@ static NTSTATUS schannel_sign_packet(struct gensec_security *gensec_security,
 
 	return netsec_outgoing_packet(state, mem_ctx, false,
 				      discard_const_p(uint8_t, data),
-				      length, sig);
+				      length,
+				      whole_pdu, pdu_length,
+				      sig);
 }
 
 static const struct gensec_security_ops gensec_schannel_security_ops = {
diff --git a/auth/ntlmssp/gensec_ntlmssp.c b/auth/ntlmssp/gensec_ntlmssp.c
index 654c0e3..5672589 100644
--- a/auth/ntlmssp/gensec_ntlmssp.c
+++ b/auth/ntlmssp/gensec_ntlmssp.c
@@ -102,6 +102,10 @@ bool gensec_ntlmssp_have_feature(struct gensec_security *gensec_security,
 			return true;
 		}
 	}
+	if (feature & GENSEC_FEATURE_SIGN_PKT_HEADER) {
+		return true;
+	}
+


-- 
Samba Shared Repository


More information about the samba-cvs mailing list