samba-cvs.cvs
[Top] [All Lists]

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

Subject: [SCM] Samba Shared Repository - branch v4-0-test updated - release-4-0-0alpha5-185-g73964f0
From: metze@xxxxxxxxx (Stefan Metzmacher)
Date: Mon, 28 Jul 2008 09:39:08 -0500 (CDT)
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@xxxxxxxxx>
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@xxxxxxxxx>
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@xxxxxxxxx>
Date:   Mon Jun 9 21:57:05 2008 +0200

    smb2srv: sign SMB2 Logoff replies
    
    metze

commit 5b3ba3f3556e8031133128853cd2324ee3852aa1
Author: Stefan Metzmacher <metze@xxxxxxxxx>
Date:   Mon Jun 9 21:45:19 2008 +0200

    smb2srv: correctly hold the signing state per session
    
    metze

commit 8bc12dc77a59e792830d96e84a4e8d1b2c651505
Author: Stefan Metzmacher <metze@xxxxxxxxx>
Date:   Mon Jun 9 21:57:41 2008 +0200

    libcli/smb2: fix per session signing state
    
    metze

commit 93203e8e318dd10b9e7096e586187eb271d42134
Author: Stefan Metzmacher <metze@xxxxxxxxx>
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@xxxxxxxxx>
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

<Prev in Thread] Current Thread [Next in Thread>
  • [SCM] Samba Shared Repository - branch v4-0-test updated - release-4-0-0alpha5-185-g73964f0, Stefan Metzmacher <=