Bug 8862 - smb2.connect fails when trying to connect to a samba server but the server has "server signing" set to "Disabled"(default value) in smb.conf
Summary: smb2.connect fails when trying to connect to a samba server but the server ha...
Status: NEEDINFO
Alias: None
Product: Samba 4.0
Classification: Unclassified
Component: smbtorture (show other bugs)
Version: unspecified
Hardware: All All
: P5 normal (vote)
Target Milestone: ---
Assignee: Stefan Metzmacher
QA Contact: samba4-qa@samba.org
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-04-12 20:04 UTC by YOUZHONG YANG
Modified: 2014-07-24 20:02 UTC (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description YOUZHONG YANG 2012-04-12 20:04:11 UTC
smb2.connect fails with error message "Bad SMB2 signature for message".

I tracked the issue down and the following could be a fix:

diff --git a/libcli/smb/smb2_signing.c b/libcli/smb/smb2_signing.c
index 43c9ba5..7448b39 100644
--- a/libcli/smb/smb2_signing.c
+++ b/libcli/smb/smb2_signing.c
@@ -107,6 +107,7 @@ NTSTATUS smb2_signing_check_pdu(DATA_BLOB signing_key,
        uint8_t res[16];
        static const uint8_t zero_sig[16] = { 0, };
        int i;
+       uint32_t flags;

        if (count < 2) {
                return NT_STATUS_INVALID_PARAMETER;
@@ -117,6 +118,11 @@ NTSTATUS smb2_signing_check_pdu(DATA_BLOB signing_key,
        }

        hdr = (const uint8_t *)vector[0].iov_base;
+       flags = IVAL(hdr, SMB2_HDR_FLAGS);
+       if(!(flags & SMB2_HDR_FLAG_SIGNED))
+       {
+               return NT_STATUS_OK;
+       }

        session_id = BVAL(hdr, SMB2_HDR_SESSION_ID);
        if (session_id == 0) {

===================================================================
NTSTATUS smb2_signing_check_pdu(DATA_BLOB signing_key,
                                enum protocol_types protocol,
                                const struct iovec *vector,
                                int count)
{
        const uint8_t *hdr;
        const uint8_t *sig;
        uint64_t session_id;
        uint8_t res[16];
        static const uint8_t zero_sig[16] = { 0, };
        int i;
        uint32_t flags;

        if (count < 2) {
                return NT_STATUS_INVALID_PARAMETER;
        }

        if (vector[0].iov_len != SMB2_HDR_BODY) {
                return NT_STATUS_INVALID_PARAMETER;
        }

        hdr = (const uint8_t *)vector[0].iov_base;
        flags = IVAL(hdr, SMB2_HDR_FLAGS);
        if(!(flags & SMB2_HDR_FLAG_SIGNED))
        {
                return NT_STATUS_OK;
        }

        session_id = BVAL(hdr, SMB2_HDR_SESSION_ID);
        if (session_id == 0) {
                /*
                 * do not sign messages with a zero session_id.
                 * See MS-SMB2 3.2.4.1.1
                 */
                return NT_STATUS_OK;
        }

        if (signing_key.length == 0) {
                /* we don't have the session key yet */
                return NT_STATUS_OK;
        }

        sig = hdr+SMB2_HDR_SIGNATURE;

        if (protocol >= PROTOCOL_SMB2_24) {
                struct aes_cmac_128_context ctx;
                uint8_t key[AES_BLOCK_SIZE];

                ZERO_STRUCT(key);
                memcpy(key, signing_key.data, MIN(signing_key.length, 16));

                aes_cmac_128_init(&ctx, key);
                aes_cmac_128_update(&ctx, hdr, SMB2_HDR_SIGNATURE);
                aes_cmac_128_update(&ctx, zero_sig, 16);
                for (i=1; i < count; i++) {
                        aes_cmac_128_update(&ctx,
                                        (const uint8_t *)vector[i].iov_base,
                                        vector[i].iov_len);
                }
                aes_cmac_128_final(&ctx, res);
        } else {
                struct HMACSHA256Context m;
                uint8_t digest[SHA256_DIGEST_LENGTH];

                ZERO_STRUCT(m);
                hmac_sha256_init(signing_key.data, MIN(signing_key.length, 16), &m);
                hmac_sha256_update(hdr, SMB2_HDR_SIGNATURE, &m);
                hmac_sha256_update(zero_sig, 16, &m);
                for (i=1; i < count; i++) {
                        hmac_sha256_update((const uint8_t *)vector[i].iov_base,
                                           vector[i].iov_len, &m);
                }
                hmac_sha256_final(digest, &m);
                memcpy(res, digest, 16);
        }

        if (memcmp(res, sig, 16) != 0) {
                DEBUG(0,("Bad SMB2 signature for message\n"));
                dump_data(0, sig, 16);
                dump_data(0, res, 16);
                return NT_STATUS_ACCESS_DENIED;
        }

        return NT_STATUS_OK;
}
Comment 1 Matthias Dieter Wallnöfer 2012-04-13 07:49:02 UTC
metze, what do you think?
Comment 2 Stefan Metzmacher 2012-04-16 11:06:45 UTC
It's related to
https://bugzilla.samba.org/show_bug.cgi?id=8749

We sh
Comment 3 Stefan Metzmacher 2012-04-16 11:09:03 UTC
I've currently some client side patches for anonymous session setups
in autobuild.
Comment 4 YOUZHONG YANG 2012-04-16 21:10:33 UTC
(In reply to comment #3)
> I've currently some client side patches for anonymous session setups
> in autobuild.

Can you attach the patches or send it to me(youzhong@gmail.com)? Thanks.
Comment 5 Stefan Metzmacher 2012-05-31 11:22:01 UTC
(In reply to comment #4)
> (In reply to comment #3)
> > I've currently some client side patches for anonymous session setups
> > in autobuild.
> 
> Can you attach the patches or send it to me(youzhong@gmail.com)? Thanks.

The best would be to just try the current master.
Comment 6 Björn Jacke 2014-07-24 20:02:37 UTC
YOUZHONG: I did you try the that out? Wondering if this bug can successfully be closed ...