[SCM] Samba Shared Repository - branch master updated

Stefan Metzmacher metze at samba.org
Sat Aug 4 03:10:02 MDT 2012


The branch, master has been updated
       via  49d0432 s3:smbd: setup session->global->signing_/application_key during SPNEGO SMB1 session setups
       via  2265e46 s3:smbd: setup session->global->signing_/application_key during old SMB1 session setups
       via  3d63e4d s3:smbd: keep the "application session key" during SMB1 reauth
       via  ba864b8 s4:torture: add support for SMB_EXTENDED_SIGNATURES during SMBtconX
       via  67767de s4:libcli: add support for SMB_EXTENDED_SIGNATURES during SMBtconX
       via  c32120b s3:libsmb: add EXTENDED_SIGNATURE support in cli_tcon_andx*()
       via  97be49c libcli/smb: add smb1cli_session_protect_session_key()
       via  dbefd7d libcli/smb: add smb_key_derivation() for TREE_CONNECT_ANDX_EXTENDED_SIGNATURES support
       via  b1a0fda libcli/smb: pass hdr/len to smb_signing_check/sign_pdu() and skip the nbt header
       via  b1c5efb s3:smbd: skip nbt header in srv_check_sign_mac()
       via  d88a6c1 libcli/smb: change smb_signing to skip the NBT_HEADER_SIZE internally
       via  e8f4868 auth/ntlmssp: avoid talloc_tos() in ntlmssp_client_initial()
      from  764f2f9 s3-ctdb: return proper exit code

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


- Log -----------------------------------------------------------------
commit 49d0432efd84ef2e4bcaa85d4aad11c18d947db1
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Aug 2 18:47:48 2012 +0200

    s3:smbd: setup session->global->signing_/application_key during SPNEGO SMB1 session setups
    
    metze
    
    Autobuild-User(master): Stefan Metzmacher <metze at samba.org>
    Autobuild-Date(master): Sat Aug  4 11:09:42 CEST 2012 on sn-devel-104

commit 2265e4633a5b37ded755f6c964cb4d3a6f67a350
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Aug 2 18:47:48 2012 +0200

    s3:smbd: setup session->global->signing_/application_key during old SMB1 session setups
    
    metze

commit 3d63e4da170881f4d0381bf9e01e0ceab10c2a90
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Aug 2 18:46:09 2012 +0200

    s3:smbd: keep the "application session key" during SMB1 reauth
    
    metze

commit ba864b83fa43062a684204cbaf9bf1b0c2074533
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Aug 2 08:51:13 2012 +0200

    s4:torture: add support for SMB_EXTENDED_SIGNATURES during SMBtconX
    
    metze

commit 67767de4e9e4a3a2cac1f28b590398bd587467da
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Aug 2 08:51:13 2012 +0200

    s4:libcli: add support for SMB_EXTENDED_SIGNATURES during SMBtconX
    
    metze

commit c32120b4e93a565c12534b7614becdf573672586
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Aug 1 11:47:07 2012 +0200

    s3:libsmb: add EXTENDED_SIGNATURE support in cli_tcon_andx*()
    
    metze

commit 97be49c4d42bbc84a85383db0d5c6cf14fd077da
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Aug 1 09:01:25 2012 +0200

    libcli/smb: add smb1cli_session_protect_session_key()
    
    metze

commit dbefd7d194cc05a793a480740e9e29558ff95ad3
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Aug 1 09:28:06 2012 +0200

    libcli/smb: add smb_key_derivation() for TREE_CONNECT_ANDX_EXTENDED_SIGNATURES support
    
    metze

commit b1a0fda73d13587fd63682bc8e47f6862289f66d
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Aug 3 09:58:29 2012 +0200

    libcli/smb: pass hdr/len to smb_signing_check/sign_pdu() and skip the nbt header
    
    metze

commit b1c5efbfeab2b597d8b7878fbe47afb2d9786f10
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Aug 3 09:57:19 2012 +0200

    s3:smbd: skip nbt header in srv_check_sign_mac()
    
    metze

commit d88a6c1dc3bb90b5ac82e09eb1c96df434f6ce69
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Aug 3 09:29:20 2012 +0200

    libcli/smb: change smb_signing to skip the NBT_HEADER_SIZE internally
    
    metze

commit e8f486883fb13c1e5bb9cb63196f798370b4abb8
Author: Stefan Metzmacher <metze at samba.org>
Date:   Sat Aug 4 09:07:24 2012 +0200

    auth/ntlmssp: avoid talloc_tos() in ntlmssp_client_initial()
    
    This avoids a smb_panic at log level = 10.
    If we don't have a talloc stackframe yet.
    
    metze

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

Summary of changes:
 auth/ntlmssp/ntlmssp_client.c          |    2 +-
 libcli/smb/smbXcli_base.c              |   50 ++++++++++--
 libcli/smb/smbXcli_base.h              |    1 +
 libcli/smb/smb_signing.c               |   93 +++++++++++++++++-----
 libcli/smb/smb_signing.h               |    8 ++-
 source3/libsmb/cliconnect.c            |    5 +
 source3/smbd/sesssetup.c               |  135 ++++++++++++++++++++++++++++++--
 source3/smbd/signing.c                 |   24 ++++--
 source4/libcli/cliconnect.c            |    6 ++
 source4/libcli/smb_composite/connect.c |    6 ++
 source4/libcli/util/clilsa.c           |    6 ++
 source4/torture/rpc/samba3rpc.c        |    7 ++
 source4/torture/util_smb.c             |    8 ++-
 13 files changed, 304 insertions(+), 47 deletions(-)


Changeset truncated at 500 lines:

diff --git a/auth/ntlmssp/ntlmssp_client.c b/auth/ntlmssp/ntlmssp_client.c
index f51a1ed..fc66a8d 100644
--- a/auth/ntlmssp/ntlmssp_client.c
+++ b/auth/ntlmssp/ntlmssp_client.c
@@ -96,7 +96,7 @@ NTSTATUS ntlmssp_client_initial(struct gensec_security *gensec_security,
 
 	if (DEBUGLEVEL >= 10) {
 		struct NEGOTIATE_MESSAGE *negotiate = talloc(
-			talloc_tos(), struct NEGOTIATE_MESSAGE);
+			ntlmssp_state, struct NEGOTIATE_MESSAGE);
 		if (negotiate != NULL) {
 			status = ntlmssp_pull_NEGOTIATE_MESSAGE(
 				out, negotiate, negotiate);
diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c
index 37c738e..c6e3b2a 100644
--- a/libcli/smb/smbXcli_base.c
+++ b/libcli/smb/smbXcli_base.c
@@ -149,6 +149,7 @@ struct smbXcli_session {
 	struct {
 		uint16_t session_id;
 		DATA_BLOB application_key;
+		bool protected_key;
 	} smb1;
 
 	struct smb2cli_session *smb2;
@@ -633,7 +634,10 @@ bool smb1cli_conn_activate_signing(struct smbXcli_conn *conn,
 bool smb1cli_conn_check_signing(struct smbXcli_conn *conn,
 				const uint8_t *buf, uint32_t seqnum)
 {
-	return smb_signing_check_pdu(conn->smb1.signing, buf, seqnum);
+	const uint8_t *hdr = buf + NBT_HDR_SIZE;
+	size_t len = smb_len_nbt(buf);
+
+	return smb_signing_check_pdu(conn->smb1.signing, hdr, len, seqnum);
 }
 
 bool smb1cli_conn_signing_is_active(struct smbXcli_conn *conn)
@@ -1339,15 +1343,17 @@ static NTSTATUS smb1cli_conn_signv(struct smbXcli_conn *conn,
 
 	frame = talloc_stackframe();
 
-	buf = smbXcli_iov_concat(frame, iov, iov_count);
+	buf = smbXcli_iov_concat(frame, &iov[1], iov_count - 1);
 	if (buf == NULL) {
 		return NT_STATUS_NO_MEMORY;
 	}
 
 	*seqnum = smb_signing_next_seqnum(conn->smb1.signing,
 					  one_way_seqnum);
-	smb_signing_sign_pdu(conn->smb1.signing, buf, *seqnum);
-	memcpy(iov[1].iov_base, buf+4, iov[1].iov_len);
+	smb_signing_sign_pdu(conn->smb1.signing,
+			     buf, talloc_get_size(buf),
+			     *seqnum);
+	memcpy(iov[1].iov_base, buf, iov[1].iov_len);
 
 	TALLOC_FREE(frame);
 	return NT_STATUS_OK;
@@ -1776,7 +1782,8 @@ static NTSTATUS smb1cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
 	uint8_t cmd;
 	uint16_t mid;
 	bool oplock_break;
-	const uint8_t *inhdr = inbuf + NBT_HDR_SIZE;
+	uint8_t *inhdr = inbuf + NBT_HDR_SIZE;
+	size_t len = smb_len_nbt(inbuf);
 	struct iovec *iov = NULL;
 	int num_iov = 0;
 	struct tevent_req **chain = NULL;
@@ -1804,8 +1811,8 @@ static NTSTATUS smb1cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
 			}
 		}
 
-		state->smb1.recv_iov[0].iov_base = (void *)(inbuf + NBT_HDR_SIZE);
-		state->smb1.recv_iov[0].iov_len = smb_len_nbt(inbuf);
+		state->smb1.recv_iov[0].iov_base = (void *)(inhdr);
+		state->smb1.recv_iov[0].iov_len = len;
 		ZERO_STRUCT(state->smb1.recv_iov[1]);
 		ZERO_STRUCT(state->smb1.recv_iov[2]);
 
@@ -1852,6 +1859,8 @@ static NTSTATUS smb1cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
 				   nt_errstr(status)));
 			return status;
 		}
+		inhdr = inbuf + NBT_HDR_SIZE;
+		len = smb_len_nbt(inbuf);
 	}
 
 	mid = SVAL(inhdr, HDR_MID);
@@ -1873,7 +1882,7 @@ static NTSTATUS smb1cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
 		/*
 		 * Paranoia checks that this is really an oplock break request.
 		 */
-		oplock_break = (smb_len_nbt(inbuf) == 51); /* hdr + 8 words */
+		oplock_break = (len == 51); /* hdr + 8 words */
 		oplock_break &= ((CVAL(inhdr, HDR_FLG) & FLAG_REPLY) == 0);
 		oplock_break &= (CVAL(inhdr, HDR_COM) == SMBlockingX);
 		oplock_break &= (SVAL(inhdr, HDR_VWV+VWV(6)) == 0);
@@ -1890,7 +1899,7 @@ static NTSTATUS smb1cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
 
 	if (!oplock_break /* oplock breaks are not signed */
 	    && !smb_signing_check_pdu(conn->smb1.signing,
-				      inbuf, state->smb1.seqnum+1)) {
+				      inhdr, len, state->smb1.seqnum+1)) {
 		DEBUG(10, ("cli_check_sign_mac failed\n"));
 		return NT_STATUS_ACCESS_DENIED;
 	}
@@ -4352,6 +4361,7 @@ NTSTATUS smb1cli_session_set_session_key(struct smbXcli_session *session,
 		 * return NT_STATUS_INVALID_PARAMETER_MIX;
 		 */
 		data_blob_clear_free(&session->smb1.application_key);
+		session->smb1.protected_key = false;
 	}
 
 	if (_session_key.length == 0) {
@@ -4370,6 +4380,28 @@ NTSTATUS smb1cli_session_set_session_key(struct smbXcli_session *session,
 		return NT_STATUS_NO_MEMORY;
 	}
 
+	session->smb1.protected_key = false;
+
+	return NT_STATUS_OK;
+}
+
+NTSTATUS smb1cli_session_protect_session_key(struct smbXcli_session *session)
+{
+	if (session->smb1.protected_key) {
+		/* already protected */
+		return NT_STATUS_OK;
+	}
+
+	if (session->smb1.application_key.length != 16) {
+		return NT_STATUS_INVALID_PARAMETER_MIX;
+	}
+
+	smb_key_derivation(session->smb1.application_key.data,
+			   session->smb1.application_key.length,
+			   session->smb1.application_key.data);
+
+	session->smb1.protected_key = true;
+
 	return NT_STATUS_OK;
 }
 
diff --git a/libcli/smb/smbXcli_base.h b/libcli/smb/smbXcli_base.h
index 3f78cd5..689369e 100644
--- a/libcli/smb/smbXcli_base.h
+++ b/libcli/smb/smbXcli_base.h
@@ -256,6 +256,7 @@ void smb1cli_session_set_id(struct smbXcli_session* session,
 			    uint16_t session_id);
 NTSTATUS smb1cli_session_set_session_key(struct smbXcli_session *session,
 					 const DATA_BLOB _session_key);
+NTSTATUS smb1cli_session_protect_session_key(struct smbXcli_session *session);
 uint8_t smb2cli_session_security_mode(struct smbXcli_session *session);
 uint64_t smb2cli_session_current_id(struct smbXcli_session *session);
 uint16_t smb2cli_session_get_flags(struct smbXcli_session *session);
diff --git a/libcli/smb/smb_signing.c b/libcli/smb/smb_signing.c
index a72760b..95c9c27 100644
--- a/libcli/smb/smb_signing.c
+++ b/libcli/smb/smb_signing.c
@@ -20,7 +20,7 @@
 */
 
 #include "includes.h"
-#include "../lib/crypto/md5.h"
+#include "../lib/crypto/crypto.h"
 #include "smb_common.h"
 #include "smb_signing.h"
 
@@ -140,10 +140,11 @@ static bool smb_signing_good(struct smb_signing_state *si,
 }
 
 static void smb_signing_md5(const DATA_BLOB *mac_key,
-			    const uint8_t *buf, uint32_t seq_number,
+			    const uint8_t *hdr, size_t len,
+			    uint32_t seq_number,
 			    uint8_t calc_md5_mac[16])
 {
-	const size_t offset_end_of_sig = (NBT_HDR_SIZE + HDR_SS_FIELD + 8);
+	const size_t offset_end_of_sig = (HDR_SS_FIELD + 8);
 	uint8_t sequence_buf[8];
 	struct MD5Context md5_ctx;
 
@@ -170,14 +171,14 @@ static void smb_signing_md5(const DATA_BLOB *mac_key,
 	MD5Update(&md5_ctx, mac_key->data, mac_key->length);
 
 	/* copy in the first bit of the SMB header */
-	MD5Update(&md5_ctx, buf + NBT_HDR_SIZE, HDR_SS_FIELD);
+	MD5Update(&md5_ctx, hdr, HDR_SS_FIELD);
 
 	/* copy in the sequence number, instead of the signature */
 	MD5Update(&md5_ctx, sequence_buf, sizeof(sequence_buf));
 
 	/* copy in the rest of the packet in, skipping the signature */
-	MD5Update(&md5_ctx, buf + offset_end_of_sig, 
-		  smb_len_nbt(buf) - (offset_end_of_sig - 4));
+	MD5Update(&md5_ctx, hdr + offset_end_of_sig,
+		  len - (offset_end_of_sig));
 
 	/* calculate the MD5 sig */
 	MD5Final(calc_md5_mac, &md5_ctx);
@@ -215,7 +216,8 @@ void smb_signing_cancel_reply(struct smb_signing_state *si, bool oneway)
 }
 
 void smb_signing_sign_pdu(struct smb_signing_state *si,
-			  uint8_t *outbuf, uint32_t seqnum)
+			  uint8_t *outhdr, size_t len,
+			  uint32_t seqnum)
 {
 	uint8_t calc_md5_mac[16];
 	uint8_t com;
@@ -228,18 +230,18 @@ void smb_signing_sign_pdu(struct smb_signing_state *si,
 	}
 
 	/* JRA Paranioa test - we should be able to get rid of this... */
-	if (smb_len_nbt(outbuf) < (HDR_SS_FIELD + 8)) {
+	if (len < (HDR_SS_FIELD + 8)) {
 		DEBUG(1,("smb_signing_sign_pdu: Logic error. "
 			 "Can't check signature on short packet! smb_len = %u\n",
-			 smb_len_nbt(outbuf)));
+			 (unsigned)len));
 		abort();
 	}
 
-	com = SVAL(outbuf,NBT_HDR_SIZE+HDR_COM);
-	flags = SVAL(outbuf,NBT_HDR_SIZE+HDR_FLG);
+	com = SVAL(outhdr, HDR_COM);
+	flags = SVAL(outhdr, HDR_FLG);
 
 	if (!(flags & FLAG_REPLY)) {
-		uint16_t flags2 = SVAL(outbuf,NBT_HDR_SIZE+HDR_FLG2);
+		uint16_t flags2 = SVAL(outhdr, HDR_FLG2);
 		/*
 		 * If this is a request, specify what is
 		 * supported or required by the client
@@ -250,7 +252,7 @@ void smb_signing_sign_pdu(struct smb_signing_state *si,
 		if (si->negotiated && si->mandatory) {
 			flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
 		}
-		SSVAL(outbuf, NBT_HDR_SIZE+HDR_FLG2, flags2);
+		SSVAL(outhdr, HDR_FLG2, flags2);
 	}
 
 	if (si->mac_key.length == 0) {
@@ -262,21 +264,22 @@ void smb_signing_sign_pdu(struct smb_signing_state *si,
 			memset(calc_md5_mac, 0, 8);
 		}
 	} else {
-		smb_signing_md5(&si->mac_key, outbuf,
+		smb_signing_md5(&si->mac_key, outhdr, len,
 				seqnum, calc_md5_mac);
 	}
 
 	DEBUG(10, ("smb_signing_sign_pdu: sent SMB signature of\n"));
 	dump_data(10, calc_md5_mac, 8);
 
-	memcpy(&outbuf[NBT_HDR_SIZE+HDR_SS_FIELD], calc_md5_mac, 8);
+	memcpy(&outhdr[HDR_SS_FIELD], calc_md5_mac, 8);
 
-/*	outbuf[NBT_HDR_SIZE+HDR_SS_FIELD+2]=0;
+/*	outhdr[HDR_SS_FIELD+2]=0;
 	Uncomment this to test if the remote server actually verifies signatures...*/
 }
 
 bool smb_signing_check_pdu(struct smb_signing_state *si,
-			   const uint8_t *inbuf, uint32_t seqnum)
+			   const uint8_t *inhdr, size_t len,
+			   uint32_t seqnum)
 {
 	bool good;
 	uint8_t calc_md5_mac[16];
@@ -286,17 +289,17 @@ bool smb_signing_check_pdu(struct smb_signing_state *si,
 		return true;
 	}
 
-	if (smb_len_nbt(inbuf) < (HDR_SS_FIELD + 8)) {
+	if (len < (HDR_SS_FIELD + 8)) {
 		DEBUG(1,("smb_signing_check_pdu: Can't check signature "
 			 "on short packet! smb_len = %u\n",
-			 smb_len_nbt(inbuf)));
+			 (unsigned)len));
 		return false;
 	}
 
-	smb_signing_md5(&si->mac_key, inbuf,
+	smb_signing_md5(&si->mac_key, inhdr, len,
 			seqnum, calc_md5_mac);
 
-	reply_sent_mac = &inbuf[NBT_HDR_SIZE+HDR_SS_FIELD];
+	reply_sent_mac = &inhdr[HDR_SS_FIELD];
 	good = (memcmp(reply_sent_mac, calc_md5_mac, 8) == 0);
 
 	if (!good) {
@@ -310,7 +313,7 @@ bool smb_signing_check_pdu(struct smb_signing_state *si,
 		dump_data(5, reply_sent_mac, 8);
 
 		for (i = -sign_range; i < sign_range; i++) {
-			smb_signing_md5(&si->mac_key, inbuf,
+			smb_signing_md5(&si->mac_key, inhdr, len,
 					seqnum+i, calc_md5_mac);
 			if (memcmp(reply_sent_mac, calc_md5_mac, 8) == 0) {
 				DEBUG(0,("smb_signing_check_pdu: "
@@ -452,3 +455,49 @@ bool smb_signing_is_negotiated(struct smb_signing_state *si)
 {
 	return si->negotiated;
 }
+
+void smb_key_derivation(const uint8_t *KI, size_t KI_len,
+			uint8_t KO[16])
+{
+	static const uint8_t SSKeyHash[256] = {
+		0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79,
+		0x20, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75,
+		0x72, 0x65, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x55,
+		0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x79, 0x07,
+		0x6e, 0x28, 0x2e, 0x69, 0x88, 0x10, 0xb3, 0xdb,
+		0x01, 0x55, 0x72, 0xfb, 0x74, 0x14, 0xfb, 0xc4,
+		0xc5, 0xaf, 0x3b, 0x41, 0x65, 0x32, 0x17, 0xba,
+		0xa3, 0x29, 0x08, 0xc1, 0xde, 0x16, 0x61, 0x7e,
+		0x66, 0x98, 0xa4, 0x0b, 0xfe, 0x06, 0x83, 0x53,
+		0x4d, 0x05, 0xdf, 0x6d, 0xa7, 0x51, 0x10, 0x73,
+		0xc5, 0x50, 0xdc, 0x5e, 0xf8, 0x21, 0x46, 0xaa,
+		0x96, 0x14, 0x33, 0xd7, 0x52, 0xeb, 0xaf, 0x1f,
+		0xbf, 0x36, 0x6c, 0xfc, 0xb7, 0x1d, 0x21, 0x19,
+		0x81, 0xd0, 0x6b, 0xfa, 0x77, 0xad, 0xbe, 0x18,
+		0x78, 0xcf, 0x10, 0xbd, 0xd8, 0x78, 0xf7, 0xd3,
+		0xc6, 0xdf, 0x43, 0x32, 0x19, 0xd3, 0x9b, 0xa8,
+		0x4d, 0x9e, 0xaa, 0x41, 0xaf, 0xcb, 0xc6, 0xb9,
+		0x34, 0xe7, 0x48, 0x25, 0xd4, 0x88, 0xc4, 0x51,
+		0x60, 0x38, 0xd9, 0x62, 0xe8, 0x8d, 0x5b, 0x83,
+		0x92, 0x7f, 0xb5, 0x0e, 0x1c, 0x2d, 0x06, 0x91,
+		0xc3, 0x75, 0xb3, 0xcc, 0xf8, 0xf7, 0x92, 0x91,
+		0x0b, 0x3d, 0xa1, 0x10, 0x5b, 0xd5, 0x0f, 0xa8,
+		0x3f, 0x5d, 0x13, 0x83, 0x0a, 0x6b, 0x72, 0x93,
+		0x14, 0x59, 0xd5, 0xab, 0xde, 0x26, 0x15, 0x6d,
+		0x60, 0x67, 0x71, 0x06, 0x6e, 0x3d, 0x0d, 0xa7,
+		0xcb, 0x70, 0xe9, 0x08, 0x5c, 0x99, 0xfa, 0x0a,
+		0x5f, 0x3d, 0x44, 0xa3, 0x8b, 0xc0, 0x8d, 0xda,
+		0xe2, 0x68, 0xd0, 0x0d, 0xcd, 0x7f, 0x3d, 0xf8,
+		0x73, 0x7e, 0x35, 0x7f, 0x07, 0x02, 0x0a, 0xb5,
+		0xe9, 0xb7, 0x87, 0xfb, 0xa1, 0xbf, 0xcb, 0x32,
+		0x31, 0x66, 0x09, 0x48, 0x88, 0xcc, 0x18, 0xa3,
+		0xb2, 0x1f, 0x1f, 0x1b, 0x90, 0x4e, 0xd7, 0xe1
+	};
+	HMACMD5Context ctx;
+
+	hmac_md5_init_limK_to_64(KI, KI_len, &ctx);
+	hmac_md5_update(SSKeyHash, sizeof(SSKeyHash), &ctx);
+	hmac_md5_final(KO, &ctx);
+
+	ZERO_STRUCT(ctx);
+}
diff --git a/libcli/smb/smb_signing.h b/libcli/smb/smb_signing.h
index b5deec6..7427ada 100644
--- a/libcli/smb/smb_signing.h
+++ b/libcli/smb/smb_signing.h
@@ -37,9 +37,11 @@ struct smb_signing_state *smb_signing_init_ex(TALLOC_CTX *mem_ctx,
 uint32_t smb_signing_next_seqnum(struct smb_signing_state *si, bool oneway);
 void smb_signing_cancel_reply(struct smb_signing_state *si, bool oneway);
 void smb_signing_sign_pdu(struct smb_signing_state *si,
-			  uint8_t *outbuf, uint32_t seqnum);
+			  uint8_t *outhdr, size_t len,
+			  uint32_t seqnum);
 bool smb_signing_check_pdu(struct smb_signing_state *si,
-			   const uint8_t *inbuf, uint32_t seqnum);
+			   const uint8_t *inhdr, size_t len,
+			   uint32_t seqnum);
 bool smb_signing_activate(struct smb_signing_state *si,
 			  const DATA_BLOB user_session_key,
 			  const DATA_BLOB response);
@@ -49,5 +51,7 @@ bool smb_signing_is_mandatory(struct smb_signing_state *si);
 bool smb_signing_set_negotiated(struct smb_signing_state *si,
 				bool allowed, bool mandatory);
 bool smb_signing_is_negotiated(struct smb_signing_state *si);
+void smb_key_derivation(const uint8_t *KI, size_t KI_len,
+			uint8_t KO[16]);
 
 #endif /* _SMB_SIGNING_H_ */
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index 9850511..cd914bf 100644
--- a/source3/libsmb/cliconnect.c
+++ b/source3/libsmb/cliconnect.c
@@ -2332,6 +2332,7 @@ struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx,
 	}
 
 	tcon_flags |= TCONX_FLAG_EXTENDED_RESPONSE;
+	tcon_flags |= TCONX_FLAG_EXTENDED_SIGNATURES;
 
 	SCVAL(vwv+0, 0, 0xFF);
 	SCVAL(vwv+0, 1, 0);
@@ -2482,6 +2483,10 @@ static void cli_tcon_andx_done(struct tevent_req *subreq)
 		cli->dfsroot = true;
 	}
 
+	if (optional_support & SMB_EXTENDED_SIGNATURES) {
+		smb1cli_session_protect_session_key(cli->smb1.session);
+	}
+
 	cli_state_set_tid(cli, SVAL(inhdr, HDR_TID));
 	tevent_req_done(req);
 }
diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c
index dc3e254..cf9c2e7 100644
--- a/source3/smbd/sesssetup.c
+++ b/source3/smbd/sesssetup.c
@@ -283,6 +283,58 @@ static void reply_sesssetup_and_X_spnego(struct smb_request *req)
 			action = 1;
 		}
 
+		if (session_info->session_key.length > 0) {
+			struct smbXsrv_session *x = session;
+			uint8_t session_key[16];
+
+			/*
+			 * Note: the SMB1 signing key is not truncated to 16 byte!
+			 */
+			x->global->signing_key =
+				data_blob_dup_talloc(x->global,
+						     session_info->session_key);
+			if (x->global->signing_key.data == NULL) {
+				data_blob_free(&out_blob);
+				TALLOC_FREE(session);
+				reply_nterror(req, NT_STATUS_NO_MEMORY);
+				return;
+			}
+
+			/*
+			 * The application key is truncated/padded to 16 bytes
+			 */
+			ZERO_STRUCT(session_key);
+			memcpy(session_key, x->global->signing_key.data,
+			       MIN(x->global->signing_key.length,
+				   sizeof(session_key)));
+			x->global->application_key =
+				data_blob_talloc(x->global,
+						 session_key,
+						 sizeof(session_key));
+			ZERO_STRUCT(session_key);
+			if (x->global->application_key.data == NULL) {
+				data_blob_free(&out_blob);
+				TALLOC_FREE(session);
+				reply_nterror(req, NT_STATUS_NO_MEMORY);
+				return;
+			}
+
+			/*
+			 * Place the application key into the session_info
+			 */
+			data_blob_clear_free(&session_info->session_key);
+			session_info->session_key =
+				data_blob_dup_talloc(session_info,
+						     x->global->application_key);
+			if (session_info->session_key.data == NULL) {
+				data_blob_clear_free(&x->global->application_key);
+				data_blob_free(&out_blob);
+				TALLOC_FREE(session);
+				reply_nterror(req, NT_STATUS_NO_MEMORY);
+				return;
+			}
+		}
+
 		session->compat = talloc_zero(session, struct user_struct);
 		if (session->compat == NULL) {
 			data_blob_free(&out_blob);
@@ -312,13 +364,16 @@ static void reply_sesssetup_and_X_spnego(struct smb_request *req)
 			return;
 		}
 
-		if (srv_is_signing_negotiated(sconn) && action == 0) {
+		if (srv_is_signing_negotiated(sconn) &&
+		    action == 0 &&
+		    session->global->signing_key.length > 0)
+		{
 			/*
 			 * Try and turn on server signing on the first non-guest
 			 * sessionsetup.
 			 */
 			srv_set_signing(sconn,
-				session_info->session_key,
+				session->global->signing_key,
 				data_blob_null);
 		}
 
@@ -373,7 +428,17 @@ static void reply_sesssetup_and_X_spnego(struct smb_request *req)
 			action = 1;
 		}
 
+		/*
+		 * Keep the application key
+		 */
+		data_blob_clear_free(&session_info->session_key);
+		session_info->session_key =
+			session->global->auth_session_info->session_key;
+		talloc_steal(session_info, session_info->session_key.data);
+		TALLOC_FREE(session->global->auth_session_info);
+
 		session->compat->session_info = session_info;
+
 		session->compat->vuid = session->global->session_wire_id;
 
 		if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {


-- 
Samba Shared Repository


More information about the samba-cvs mailing list