[SCM] Samba Shared Repository - branch v4-0-test updated - release-4-0-0alpha5-185-g73964f0

Stefan Metzmacher metze at samba.org
Mon Jul 28 14:39:08 GMT 2008


The branch, v4-0-test has been updated
       via  73964f069056f46f2f27fc690e42e5c91ae1fe19 (commit)
       via  0c6d988f2083067e1ac7b07a492f88cefd3ba906 (commit)
       via  2844e361730a6bc640ea89d0e10059deca1ca867 (commit)
       via  5b3ba3f3556e8031133128853cd2324ee3852aa1 (commit)
       via  8bc12dc77a59e792830d96e84a4e8d1b2c651505 (commit)
       via  93203e8e318dd10b9e7096e586187eb271d42134 (commit)
       via  35ee165b146b9157b0cff49e1139a0cb37d98926 (commit)
      from  4b137085c8b89773d4639372bbffd516a41dfc8f (commit)

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


- Log -----------------------------------------------------------------
commit 73964f069056f46f2f27fc690e42e5c91ae1fe19
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Jul 28 16:11:30 2008 +0200

    gensec_gssapi: use gsskrb5_get_subkey() to make smb2 signing with aes keys work
    
    SMB signing with aes doesn't work, but still works with
    arcfour-hmac-md5, des-cbc-md5 and des-cbc-crc.
    
    metze

commit 0c6d988f2083067e1ac7b07a492f88cefd3ba906
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Jul 28 15:49:46 2008 +0200

    libcli/smb2: the session key for SMB2 signing is truncated to 16 bytes
    
    To make that work (as a client) with aes128 and aes256 krb5 keys
    we need to use gsskrb5_get_subkey().
    
    metze

commit 2844e361730a6bc640ea89d0e10059deca1ca867
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Jun 9 21:57:05 2008 +0200

    smb2srv: sign SMB2 Logoff replies
    
    metze

commit 5b3ba3f3556e8031133128853cd2324ee3852aa1
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Jun 9 21:45:19 2008 +0200

    smb2srv: correctly hold the signing state per session
    
    metze

commit 8bc12dc77a59e792830d96e84a4e8d1b2c651505
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Jun 9 21:57:41 2008 +0200

    libcli/smb2: fix per session signing state
    
    metze

commit 93203e8e318dd10b9e7096e586187eb271d42134
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Jun 9 21:41:55 2008 +0200

    SMB2-CONNECT: remove reference to req->session before calling smb2_logoff_recv() on the invalid session
    
    metze

commit 35ee165b146b9157b0cff49e1139a0cb37d98926
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Jun 9 21:41:06 2008 +0200

    libcli/smb2: sign SMB2 Logoff requests
    
    metze

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

Summary of changes:
 source/auth/gensec/gensec_gssapi.c |    6 +++---
 source/libcli/smb2/connect.c       |    8 ++++----
 source/libcli/smb2/logoff.c        |    2 ++
 source/libcli/smb2/session.c       |   10 +++++-----
 source/libcli/smb2/signing.c       |    9 ++++-----
 source/libcli/smb2/smb2.h          |    9 +++------
 source/libcli/smb2/transport.c     |    6 ++----
 source/smb_server/smb2/negprot.c   |    2 +-
 source/smb_server/smb2/receive.c   |   21 +++++++++++----------
 source/smb_server/smb2/sesssetup.c |   34 ++++++++++++++++++++++++++++++----
 source/smb_server/smb_server.h     |    7 ++++++-
 source/torture/smb2/connect.c      |   11 ++++++++++-
 12 files changed, 81 insertions(+), 44 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source/auth/gensec/gensec_gssapi.c b/source/auth/gensec/gensec_gssapi.c
index 205d8a0..c20cf4f 100644
--- a/source/auth/gensec/gensec_gssapi.c
+++ b/source/auth/gensec/gensec_gssapi.c
@@ -1152,9 +1152,9 @@ static NTSTATUS gensec_gssapi_session_key(struct gensec_security *gensec_securit
 		return NT_STATUS_OK;
 	}
 
-	maj_stat = gsskrb5_get_initiator_subkey(&min_stat, 
-						gensec_gssapi_state->gssapi_context,
-						&subkey);
+	maj_stat = gsskrb5_get_subkey(&min_stat,
+				      gensec_gssapi_state->gssapi_context,
+				      &subkey);
 	if (maj_stat != 0) {
 		DEBUG(1, ("NO session key for this mech\n"));
 		return NT_STATUS_NO_USER_SESSION_KEY;
diff --git a/source/libcli/smb2/connect.c b/source/libcli/smb2/connect.c
index cdb5e3b..c89c109 100644
--- a/source/libcli/smb2/connect.c
+++ b/source/libcli/smb2/connect.c
@@ -112,19 +112,19 @@ static void continue_negprot(struct smb2_request *req)
 			composite_error(c, NT_STATUS_ACCESS_DENIED);
 			return;
 		}
-		transport->signing.doing_signing = false;
+		transport->signing_required = false;
 		break;
 	case SMB_SIGNING_SUPPORTED:
 	case SMB_SIGNING_AUTO:
 		if (transport->negotiate.security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) {
-			transport->signing.doing_signing = true;
+			transport->signing_required = true;
 		} else {
-			transport->signing.doing_signing = false;
+			transport->signing_required = false;
 		}
 		break;
 	case SMB_SIGNING_REQUIRED:
 		if (transport->negotiate.security_mode & SMB2_NEGOTIATE_SIGNING_ENABLED) {
-			transport->signing.doing_signing = true;
+			transport->signing_required = true;
 		} else {
 			composite_error(c, NT_STATUS_ACCESS_DENIED);
 			return;
diff --git a/source/libcli/smb2/logoff.c b/source/libcli/smb2/logoff.c
index b38a08c..e3f83f2 100644
--- a/source/libcli/smb2/logoff.c
+++ b/source/libcli/smb2/logoff.c
@@ -33,6 +33,8 @@ struct smb2_request *smb2_logoff_send(struct smb2_session *session)
 	req = smb2_request_init(session->transport, SMB2_OP_LOGOFF, 0x04, false, 0);
 	if (req == NULL) return NULL;
 
+	req->session = session;
+
 	SBVAL(req->out.hdr,  SMB2_HDR_SESSION_ID, session->uid);
 
 	SSVAL(req->out.body, 0x02, 0);
diff --git a/source/libcli/smb2/session.c b/source/libcli/smb2/session.c
index 9161631..31b3e94 100644
--- a/source/libcli/smb2/session.c
+++ b/source/libcli/smb2/session.c
@@ -187,14 +187,14 @@ static void session_request_handler(struct smb2_request *req)
 		return;
 	}
 
-	if (session->transport->signing.doing_signing) {
-		if (session->session_key.length != 16) {
-			DEBUG(2,("Wrong session key length %u for SMB2 signing\n",
+	if (session->transport->signing_required) {
+		if (session->session_key.length == 0) {
+			DEBUG(0,("Wrong session key length %u for SMB2 signing\n",
 				 (unsigned)session->session_key.length));
 			composite_error(c, NT_STATUS_ACCESS_DENIED);
 			return;
 		}
-		session->transport->signing.signing_started = true;
+		session->signing_active = true;
 	}
 
 	composite_done(c);
@@ -218,7 +218,7 @@ struct composite_context *smb2_session_setup_spnego_send(struct smb2_session *se
 
 	ZERO_STRUCT(state->io);
 	state->io.in.vc_number          = 0;
-	if (session->transport->signing.doing_signing) {
+	if (session->transport->signing_required) {
 		state->io.in.security_mode = 
 			SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED;
 	}
diff --git a/source/libcli/smb2/signing.c b/source/libcli/smb2/signing.c
index fb2c22d..0d655d1 100644
--- a/source/libcli/smb2/signing.c
+++ b/source/libcli/smb2/signing.c
@@ -46,7 +46,7 @@ NTSTATUS smb2_sign_message(struct smb2_request_buffer *buf, DATA_BLOB session_ke
 		return NT_STATUS_OK;		
 	}
 
-	if (session_key.length != 16) {
+	if (session_key.length == 0) {
 		DEBUG(2,("Wrong session key length %u for SMB2 signing\n",
 			 (unsigned)session_key.length));
 		return NT_STATUS_ACCESS_DENIED;
@@ -57,10 +57,9 @@ NTSTATUS smb2_sign_message(struct smb2_request_buffer *buf, DATA_BLOB session_ke
 	SIVAL(buf->hdr, SMB2_HDR_FLAGS, IVAL(buf->hdr, SMB2_HDR_FLAGS) | SMB2_HDR_FLAG_SIGNED);
 
 	ZERO_STRUCT(m);
-	hmac_sha256_init(session_key.data, 16, &m);
+	hmac_sha256_init(session_key.data, MIN(session_key.length, 16), &m);
 	hmac_sha256_update(buf->buffer+NBT_HDR_SIZE, buf->size-NBT_HDR_SIZE, &m);
 	hmac_sha256_final(res, &m);
-
 	DEBUG(5,("signed SMB2 message of size %u\n", (unsigned)buf->size - NBT_HDR_SIZE));
 
 	memcpy(buf->hdr + SMB2_HDR_SIGNATURE, res, 16);
@@ -95,7 +94,7 @@ NTSTATUS smb2_check_signature(struct smb2_request_buffer *buf, DATA_BLOB session
 		return NT_STATUS_OK;
 	}
 
-	if (session_key.length != 16) {
+	if (session_key.length == 0) {
 		DEBUG(2,("Wrong session key length %u for SMB2 signing\n",
 			 (unsigned)session_key.length));
 		return NT_STATUS_ACCESS_DENIED;
@@ -106,7 +105,7 @@ NTSTATUS smb2_check_signature(struct smb2_request_buffer *buf, DATA_BLOB session
 	memset(buf->hdr + SMB2_HDR_SIGNATURE, 0, 16);
 
 	ZERO_STRUCT(m);
-	hmac_sha256_init(session_key.data, 16, &m);
+	hmac_sha256_init(session_key.data, MIN(session_key.length, 16), &m);
 	hmac_sha256_update(buf->hdr, buf->size-NBT_HDR_SIZE, &m);
 	hmac_sha256_final(res, &m);
 
diff --git a/source/libcli/smb2/smb2.h b/source/libcli/smb2/smb2.h
index 2b468d3..5d6341a 100644
--- a/source/libcli/smb2/smb2.h
+++ b/source/libcli/smb2/smb2.h
@@ -27,11 +27,6 @@
 
 struct smb2_handle;
 
-struct smb2_signing_context {
-	bool doing_signing;
-	bool signing_started;
-};
-
 /*
   information returned from the negotiate process
 */
@@ -78,7 +73,8 @@ struct smb2_transport {
 	} oplock;
 
 	struct smbcli_options options;
-	struct smb2_signing_context signing;
+
+	bool signing_required;
 };
 
 
@@ -98,6 +94,7 @@ struct smb2_session {
 	struct gensec_security *gensec;
 	uint64_t uid;
 	DATA_BLOB session_key;
+	bool signing_active;
 };
 
 
diff --git a/source/libcli/smb2/transport.c b/source/libcli/smb2/transport.c
index 6e0d523..d9691be 100644
--- a/source/libcli/smb2/transport.c
+++ b/source/libcli/smb2/transport.c
@@ -235,7 +235,7 @@ static NTSTATUS smb2_transport_finish_recv(void *private, DATA_BLOB blob)
 	req->in.body_size = req->in.size - (SMB2_HDR_BODY+NBT_HDR_SIZE);
 	req->status       = NT_STATUS(IVAL(hdr, SMB2_HDR_STATUS));
 
-	if (req->session && transport->signing.doing_signing) {
+	if (req->session && req->session->signing_active) {
 		status = smb2_check_signature(&req->in, 
 					      req->session->session_key);
 		if (!NT_STATUS_IS_OK(status)) {
@@ -352,9 +352,7 @@ void smb2_transport_send(struct smb2_request *req)
 	}
 
 	/* possibly sign the message */
-	if (req->transport->signing.doing_signing && 
-	    req->transport->signing.signing_started &&
-	    req->session) {
+	if (req->session && req->session->signing_active) {
 		status = smb2_sign_message(&req->out, req->session->session_key);
 		if (!NT_STATUS_IS_OK(status)) {
 			req->state = SMB2_REQUEST_ERROR;
diff --git a/source/smb_server/smb2/negprot.c b/source/smb_server/smb2/negprot.c
index 3e6e2e1..d64b36d 100644
--- a/source/smb_server/smb2/negprot.c
+++ b/source/smb_server/smb2/negprot.c
@@ -122,7 +122,7 @@ static NTSTATUS smb2srv_negprot_backend(struct smb2srv_request *req, struct smb2
 	case SMB_SIGNING_REQUIRED:
 		io->out.security_mode = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED;
 		/* force signing on immediately */
-		req->smb_conn->doing_signing = true;
+		req->smb_conn->smb2_signing_required = true;
 		break;
 	}
 	io->out.dialect_revision   = SMB2_DIALECT_REVISION;
diff --git a/source/smb_server/smb2/receive.c b/source/smb_server/smb2/receive.c
index 2f4e9df..cfd6c1d 100644
--- a/source/smb_server/smb2/receive.c
+++ b/source/smb_server/smb2/receive.c
@@ -235,11 +235,8 @@ void smb2srv_send_reply(struct smb2srv_request *req)
 		_smb2_setlen(req->out.buffer, req->out.size - NBT_HDR_SIZE);
 	}
 
-	/* if the request was signed or doing_signing is true, then we
-	   must sign the reply */
-	if (req->session &&
-	    (req->smb_conn->doing_signing ||
-	     (IVAL(req->in.hdr, SMB2_HDR_FLAGS) & SMB2_HDR_FLAG_SIGNED))) {
+	/* if signing is active on the session then sign the packet */
+	if (req->session && req->session->smb2_signing.active) {
 		status = smb2_sign_message(&req->out, 
 					   req->session->session_info->session_key);
 		if (!NT_STATUS_IS_OK(status)) {
@@ -310,18 +307,22 @@ static NTSTATUS smb2srv_reply(struct smb2srv_request *req)
 	   should give a signed reply to any signed request */
 	if (flags & SMB2_HDR_FLAG_SIGNED) {
 		NTSTATUS status;
-		if (req->session == NULL) {
-			/* we can't check signing with no session */
-			smb2srv_send_error(req, NT_STATUS_ACCESS_DENIED);
-			return NT_STATUS_OK;			
+
+		if (!req->session) goto nosession;
+
+		if (!req->session->smb2_signing.active) {
+			/* TODO: workout the correct error code */
+			smb2srv_send_error(req, NT_STATUS_FOOBAR);
+			return NT_STATUS_OK;
 		}
+
 		status = smb2_check_signature(&req->in, 
 					      req->session->session_info->session_key);
 		if (!NT_STATUS_IS_OK(status)) {
 			smb2srv_send_error(req, status);
 			return NT_STATUS_OK;			
 		}
-	} else if (req->smb_conn->doing_signing && req->session != NULL) {
+	} else if (req->session && req->session->smb2_signing.active) {
 		/* we require signing and this request was not signed */
 		smb2srv_send_error(req, NT_STATUS_ACCESS_DENIED);
 		return NT_STATUS_OK;					
diff --git a/source/smb_server/smb2/sesssetup.c b/source/smb_server/smb2/sesssetup.c
index 9fb3220..9f8765d 100644
--- a/source/smb_server/smb2/sesssetup.c
+++ b/source/smb_server/smb2/sesssetup.c
@@ -90,6 +90,10 @@ static void smb2srv_sesssetup_callback(struct gensec_update_request *greq, void
 	}
 	req->session = smb_sess;
 
+	if (smb_sess->smb2_signing.required) {
+		/* activate smb2 signing on the session */
+		smb_sess->smb2_signing.active = true;
+	}
 done:
 	io->smb2.out.uid = smb_sess->vuid;
 failed:
@@ -182,7 +186,15 @@ static void smb2srv_sesssetup_backend(struct smb2srv_request *req, union smb_ses
 	   This is deliberate as windows does not set it even when it does 
 	   set SMB2_NEGOTIATE_SIGNING_REQUIRED */
 	if (io->smb2.in.security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) {
-		req->smb_conn->doing_signing = true;
+		smb_sess->smb2_signing.required = true;
+	} else if (req->smb_conn->smb2_signing_required) {
+		/*
+		 * if required signing was negotiates in SMB2 Negotiate
+		 * then the client made an error not using it here
+		 */
+		DEBUG(1, ("SMB2 signing required on the connection but not used on session\n"));
+		req->status = NT_STATUS_FOOBAR;
+		goto failed;
 	}
 
 	return;
@@ -212,11 +224,25 @@ void smb2srv_sesssetup_recv(struct smb2srv_request *req)
 	smb2srv_sesssetup_backend(req, io);
 }
 
-static NTSTATUS smb2srv_logoff_backend(struct smb2srv_request *req)
+static int smb2srv_cleanup_session_destructor(struct smbsrv_session **session)
 {
 	/* TODO: call ntvfs backends to close file of this session */
-	talloc_free(req->session);
-	req->session = NULL;
+	DEBUG(0,("free session[%p]\n", *session));
+	talloc_free(*session);
+	return 0;
+}
+
+static NTSTATUS smb2srv_logoff_backend(struct smb2srv_request *req)
+{
+	struct smbsrv_session **session_ptr;
+
+	/* we need to destroy the session after sending the reply */
+	session_ptr = talloc(req, struct smbsrv_session *);
+	NT_STATUS_HAVE_NO_MEMORY(session_ptr);
+
+	*session_ptr = req->session;
+	talloc_set_destructor(session_ptr, smb2srv_cleanup_session_destructor);
+
 	return NT_STATUS_OK;
 }
 
diff --git a/source/smb_server/smb_server.h b/source/smb_server/smb_server.h
index dd4ec32..4676fc3 100644
--- a/source/smb_server/smb_server.h
+++ b/source/smb_server/smb_server.h
@@ -100,6 +100,11 @@ struct smbsrv_session {
 
 	struct auth_session_info *session_info;
 
+	struct {
+		bool required;
+		bool active;
+	} smb2_signing;
+
 	/* some statistics for the management tools */
 	struct {
 		/* the time when the session setup started */
@@ -380,7 +385,7 @@ struct smbsrv_connection {
 
 	struct loadparm_context *lp_ctx;
 
-	bool doing_signing;
+	bool smb2_signing_required;
 };
 
 struct model_ops;
diff --git a/source/torture/smb2/connect.c b/source/torture/smb2/connect.c
index 826bb2d..e77e32f 100644
--- a/source/torture/smb2/connect.c
+++ b/source/torture/smb2/connect.c
@@ -193,6 +193,7 @@ bool torture_smb2_connect(struct torture_context *torture)
 {
 	TALLOC_CTX *mem_ctx = talloc_new(NULL);
 	struct smb2_tree *tree;
+	struct smb2_request *req;
 	struct smb2_handle h1, h2;
 	NTSTATUS status;
 
@@ -242,7 +243,15 @@ bool torture_smb2_connect(struct torture_context *torture)
 		return false;
 	}
 
-	status = smb2_logoff(tree->session);
+	req = smb2_logoff_send(tree->session);
+	if (!req) {
+		printf("smb2_logoff_send() failed\n");
+		return false;
+	}
+
+	req->session = NULL;
+
+	status = smb2_logoff_recv(req);
 	if (!NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
 		printf("Logoff should have disabled session - %s\n", nt_errstr(status));
 		return false;


-- 
Samba Shared Repository


More information about the samba-cvs mailing list