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 <[email protected]>
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 <[email protected]>
    Autobuild-Date(master): Sat Aug  4 11:09:42 CEST 2012 on sn-devel-104

commit 2265e4633a5b37ded755f6c964cb4d3a6f67a350
Author: Stefan Metzmacher <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
Date:   Wed Aug 1 09:01:25 2012 +0200

    libcli/smb: add smb1cli_session_protect_session_key()
    
    metze

commit dbefd7d194cc05a793a480740e9e29558ff95ad3
Author: Stefan Metzmacher <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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

Reply via email to