[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