Bug 7577 - SPNEGO auth fails when contacting Win7 system using Microsoft Live Sign-in Assistant
SPNEGO auth fails when contacting Win7 system using Microsoft Live Sign-in As...
Status: RESOLVED FIXED
Product: Samba 3.5
Classification: Unclassified
Component: File services
3.5.4
All Windows 7
: P3 major
: ---
Assigned To: Karolin Seeger
Samba QA Contact
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2010-07-19 11:06 UTC by David Kondrad
Modified: 2013-12-16 17:55 UTC (History)
1 user (show)

See Also:


Attachments
Wireshark capture of spnego session failure for win7 (791 bytes, application/octet-stream)
2010-07-19 12:12 UTC, David Kondrad
no flags Details
[PATCH] SPNEGO: Don't assume principal (ASN1_CONTEXT(3)) always follows OIDs in negTokenInit packet. (2.00 KB, patch)
2010-07-19 12:57 UTC, David Kondrad
no flags Details
Patch for 3.5.x. (2.47 KB, application/octet-stream)
2010-07-19 16:10 UTC, Jeremy Allison
no flags Details
Replacement patcg for 3.5.x. (2.49 KB, patch)
2010-07-20 12:27 UTC, Jeremy Allison
idra: review+
Details
Patch for 3.4.x. (2.26 KB, patch)
2010-07-20 12:41 UTC, Jeremy Allison
idra: review+
Details

Note You need to log in before you can comment on or make changes to this bug.
Description David Kondrad 2010-07-19 11:06:10 UTC
Win7 + Microsoft Live Sign-in Assistant includes a mechToken
in the SPNEGO response packet which seemingly all versions 
of samba 3.x.x fail to parse and always return permission denied.

Crawling through support forums, mailing lists, and MS technet, it
seems that this is an issue that is plaguing many people. Using samba
3.5.4 source, I have tracked the issue down to

libsmb/clispnego.c:164

    *principal = NULL;
    if (asn1_tag_remaining(data) > 0) {
        asn1_start_tag(data, ASN1_CONTEXT(3)); /* fails here */
        asn1_start_tag(data, ASN1_SEQUENCE(0));
        asn1_start_tag(data, ASN1_CONTEXT(0));
        asn1_read_GeneralString(data,talloc_autofree_context(),
                                 principal);
        asn1_end_tag(data);
        asn1_end_tag(data);
        asn1_end_tag(data);
    }

Looking at a Wireshark dump, it turns out that after the two OIDs
we have a mechToken [ASN1_CONTEXT(2)] instead of a principal [ASN1_CONTEXT(3)].

I have implemented a patch that checks to see what kind of object
is next in the spnego packet (if any) that I will attach as soon
as I finish cloning the master branch.

Here is the packet decode for the SMB negotiation:

SMB (Server Message Block Protocol)
    SMB Header
    Negotiate Protocol Response (0x72)
        Word Count (WCT): 17
        Dialect Index: 9: NT LM 0.12
        Security Mode: 0x03
        Max Mpx Count: 10
        Max VCs: 1
        Max Buffer Size: 4356
        Max Raw Buffer: 65536
        Session Key: 0x00000000
        Capabilities: 0x8001e3fc
        System Time: Jul 16, 2010 16:17:55.406250000
        Server Time Zone: 240 min from UTC
        Key Length: 0
        Byte Count (BCC): 336
        Server GUID: B3A217CC5F419E4D9073F8971A82E202
        Security Blob:
        6082013C06062B0601050502A08201303082012CA01A3018...
            GSS-API Generic Security Service Application Program
            Interface
                OID: 1.3.6.1.5.5.2 (SPNEGO - Simple Protected
                Negotiation)
                SPNEGO
                    negTokenInit
                        mechTypes: 2 items
                            MechType: 1.3.6.1.4.1.311.2.2.30 (SNMPv2-
                            SMI::enterprises.311.2.2.30)
                            MechType: 1.3.6.1.4.1.311.2.2.10 (NTLMSSP
                            - Microsoft NTLM Security Support
                            Provider)
                        mechToken:
                        4E45474F45585453010000000000000060000000700000
                        00...

Hex of Security BLOB: (mechToken starts at offset 00cb)

0090  -- -- -- -- -- -- -- -- | -- -- -- 60 82 01 3c 06
00a0  06 2b 06 01 05 05 02 a0 | 82 01 30 30 82 01 2c a0
00b0  1a 30 18 06 0a 2b 06 01 | 04 01 82 37 02 02 1e 06
00c0  0a 2b 06 01 04 01 82 37 | 02 02 0a a2 82 01 0c 04
00d0  82 01 08 4e 45 47 4f 45 | 58 54 53 01 00 00 00 00
00e0  00 00 00 60 00 00 00 70 | 00 00 00 c9 9b 9a 09 7b
00f0  48 dd a2 d3 aa 67 2a c7 | 93 b5 bc 06 02 cc 9f 8f
0100  db 1a 66 b2 68 83 9a 93 | 6c f2 16 1c 31 76 a8 a3
0110  8c 1f 8c 26 80 97 ff 0e | 8e 25 18 00 00 00 00 00
0120  00 00 00 60 00 00 00 01 | 00 00 00 00 00 00 00 00
0130  00 00 00 5c 33 53 0d ea | f9 0d 4d b2 ec 4a e3 78
0140  6e c3 08 4e 45 47 4f 45 | 58 54 53 03 00 00 00 01
0150  00 00 00 40 00 00 00 98 | 00 00 00 c9 9b 9a 09 7b
0160  48 dd a2 d3 aa 67 2a c7 | 93 b5 bc 5c 33 53 0d ea
0170  f9 0d 4d b2 ec 4a e3 78 | 6e c3 08 40 00 00 00 58
0180  00 00 00 30 56 a0 54 30 | 52 30 27 80 25 30 23 31
0190  21 30 1f 06 03 55 04 03 | 13 18 54 6f 6b 65 6e 20
01a0  53 69 67 6e 69 6e 67 20 | 50 75 62 6c 69 63 20 4b
01b0  65 79 30 27 80 25 30 23 | 31 21 30 1f 06 03 55 04
01c0  03 13 18 54 6f 6b 65 6e | 20 53 69 67 6e 69 6e 67
01d0  20 50 75 62 6c 69 63 20 | 4b 65 79

Text of Security BLOB:

009b             `..<.
00a0  .+........00..,.
00b0  .0...+.....7....
00c0  .+.....7........
00d0  ...NEGOEXTS.....
00e0  ...`...p.......{
00f0  H....g*.........
0100  ..f.h...l...1v..
0110  ...&.....%......
0120  ...`............
0130  ...\3S....M..J.x
0140  n..NEGOEXTS.....
0150  ...@...........{
0160  H....g*....\3S..
0170  ..M..J.xn..@...X
0180  ...0V.T0R0'.%0#1
0190  !0...U....Token
01a0  Signing Public K
01b0  ey0'.%0#1!0...U.
01c0  ...Token Signing
01d0   Public Key
Comment 1 Derrell Lipman 2010-07-19 11:22:28 UTC
corrected component
Comment 2 Jeremy Allison 2010-07-19 11:50:26 UTC
Can you attach a "raw" wireshark packet trace please ? It's easier to work with than the text versions.

Thanks,

Jeremy.
Comment 3 David Kondrad 2010-07-19 12:12:11 UTC
Created attachment 5850 [details]
Wireshark capture of spnego session failure for win7

Here is the raw wireshark capture requested by Jeremy.
Comment 4 David Kondrad 2010-07-19 12:57:55 UTC
Created attachment 5851 [details]
[PATCH] SPNEGO: Don't assume principal (ASN1_CONTEXT(3)) always follows OIDs in negTokenInit packet.

Tested against Win7 Home Premimium PC + Live Sign-in Assistant Installed.
Client platform: Davinci DM6441 ARM

Before patch (smbget -d 4):

-sh-2.05b# smbget -d 4 'smb://DEVENGWIN7/Users/Dan/Music/test.jpg'
lp_load_ex: refreshing parameters
Initialising global parameters
params.c:OpenConfFile() - Unable to open configuration file "/root/.smb/smb.conf":
        No such file or directory
pm_process() returned No
lp_load_ex: refreshing parameters
params.c:pm_process() - Processing configuration file "/usr/samba/lib/smb.conf"
Processing section "[global]"
doing parameter workgroup = UNITY
doing parameter netbios name = INTEG-000106
handle_netbios_name: set global_myname to: INTEG-000106
doing parameter server string = Legrand UNITY Module
doing parameter encrypt passwords = true
doing parameter domain master = yes
doing parameter local master = no
doing parameter preferred master = yes
doing parameter dns proxy = no
doing parameter name resolve order = bcast wins lmhosts
doing parameter level2 oplocks = yes
doing parameter read raw = no
doing parameter log file = /usr/samba/var/locks/log.%m
doing parameter max log size = 50
doing parameter enhanced browsing = no
doing parameter map to guest = Bad User
pm_process() returned Yes
lp_load_ex: refreshing parameters
params.c:OpenConfFile() - Unable to open configuration file "/root/.smb/smb.conf.append":
        No such file or directory
pm_process() returned No
added interface eth0 ip=fe80::226:ecff:fe00:106%253 bcast=fe80::ffff:ffff:ffff:ffff%253 netmask=ffff:ffff:ffff:ffff::
added interface eth0 ip=192.168.40.12 bcast=192.168.40.255 netmask=255.255.255.0
Using netbios name INTEG-000106.
Using workgroup UNITY.
Username for Users at DEVENGWIN7 [guest] Dan
Password for Users at DEVENGWIN7:
Using workgroup UNITY, user Dan
SMBC_server: server_n=[DEVENGWIN7] server=[DEVENGWIN7]
 -> server_n=[DEVENGWIN7] server=[DEVENGWIN7]
name_resolve_bcast: Attempting broadcast lookup for name DEVENGWIN7<0x20>
nmb packet from 192.168.40.90(137) header: id=1615 opcode=Query(0) response=Yes
    header: flags: bcast=No rec_avail=No rec_des=Yes trunc=No auth=Yes
    header: rcode=0 qdcount=0 ancount=1 nscount=0 arcount=0
    answers: nmb_name=DEVENGWIN7<20> rr_type=32 rr_class=1 ttl=300000
    answers   0 char ....(Z   hex 0000C0A8285A
Got a positive name query response from 192.168.40.90 ( 192.168.40.90 )
Connecting to 192.168.40.90 at port 445
 session request ok
Doing spnego session setup (blob length=336)
SPNEGO login failed: Invalid parameter
 session setup ok
smbc errno NT_STATUS_ACCESS_DENIED -> 13
You don't have enough permissions to access smb://DEVENGWIN7/Users/Dan/Music/test.jpg

After patch (smbget -d 4):

-sh-2.05b# ./smbget -d 4 'smb://DEVENGWIN7/Users/Dan/Music/test.jpg'
params.c:OpenConfFile() - Unable to open configuration file "/root/.smb/smb.conf":
        No such file or directory
params.c:OpenConfFile() - Unable to open configuration file "/root/.smb/smb.conf.append":
        No such file or directory
Using netbios name INTEG-000106.
Using workgroup UNITY.
Username for Users at DEVENGWIN7 [guest] Dan
Password for Users at DEVENGWIN7:
Using workgroup UNITY, user Dan
SMBC_server: server_n=[DEVENGWIN7] server=[DEVENGWIN7]
 -> server_n=[DEVENGWIN7] server=[DEVENGWIN7]
Connecting to 192.168.40.90 at port 445
 session request ok
Doing spnego session setup (blob length=336)
got OID=1.3.6.1.4.1.311.2.2.30
got OID=1.3.6.1.4.1.311.2.2.10
got principal=<null>
Got challenge flags:
Got NTLMSSP neg_flags=0x628a8215
  NTLMSSP_NEGOTIATE_UNICODE
  NTLMSSP_REQUEST_TARGET
  NTLMSSP_NEGOTIATE_SIGN
  NTLMSSP_NEGOTIATE_NTLM
  NTLMSSP_NEGOTIATE_ALWAYS_SIGN
  NTLMSSP_NEGOTIATE_NTLM2
  NTLMSSP_NEGOTIATE_TARGET_INFO
  NTLMSSP_NEGOTIATE_VERSION
  NTLMSSP_NEGOTIATE_128
  NTLMSSP_NEGOTIATE_KEY_EXCH
NTLMSSP: Set final flags:
Got NTLMSSP neg_flags=0x60088215
  NTLMSSP_NEGOTIATE_UNICODE
  NTLMSSP_REQUEST_TARGET
  NTLMSSP_NEGOTIATE_SIGN
  NTLMSSP_NEGOTIATE_NTLM
  NTLMSSP_NEGOTIATE_ALWAYS_SIGN
  NTLMSSP_NEGOTIATE_NTLM2
  NTLMSSP_NEGOTIATE_128
  NTLMSSP_NEGOTIATE_KEY_EXCH
NTLMSSP Sign/Seal - Initialising with flags:
Got NTLMSSP neg_flags=0x60088215
  NTLMSSP_NEGOTIATE_UNICODE
  NTLMSSP_REQUEST_TARGET
  NTLMSSP_NEGOTIATE_SIGN
  NTLMSSP_NEGOTIATE_NTLM
  NTLMSSP_NEGOTIATE_ALWAYS_SIGN
  NTLMSSP_NEGOTIATE_NTLM2
  NTLMSSP_NEGOTIATE_128
  NTLMSSP_NEGOTIATE_KEY_EXCH
 session setup ok
 tconx ok
Case sensitive: True
Server connect ok: //DEVENGWIN7/Users: 0x8f9b90
smbc_read(0x91e970, 64000)
  --> 7131
smb://DEVENGWIN7/Users/Dan/Music/test.jpg
Downloaded 6.96kb in 6 seconds
Comment 5 Jeremy Allison 2010-07-19 13:59:12 UTC
Great patch ! I think as we;re fixing this we also should correctly handle the reqFlags option from RFC 2478 as well as the mechToken option, just in case it gets changed again. Give me a little time to update with an alternate patch (based on yours).

NegTokenInit ::= SEQUENCE {
                            mechTypes       [0] MechTypeList  OPTIONAL,
                            reqFlags        [1] ContextFlags  OPTIONAL,
                            mechToken       [2] OCTET STRING  OPTIONAL,
                            mechListMIC     [3] OCTET STRING  OPTIONAL
                         }

Jeremy
Comment 6 David Kondrad 2010-07-19 14:29:02 UTC
(In reply to comment #5)

Thanks Jeremy. 

Yeah, I guess the most robust solution would be to loop while there is more tag data, call peek for tag id and switch on the tag id.

-- Dave
Comment 7 Jeremy Allison 2010-07-19 14:53:11 UTC
As it's a sequence, I don't think we need to loop - we can guarantee if any optional field is present then it'll be the next in the sequence. We just need one more if statement :-).

Jeremy.
Comment 8 David Kondrad 2010-07-19 15:01:38 UTC
Doh - what a fail... of course! Hence the SEQUENCE in the definition!


Comment 9 Jeremy Allison 2010-07-19 16:10:03 UTC
Created attachment 5852 [details]
Patch for 3.5.x.

Can you test this please to see if it fixes the problem ?
Jeremy.
Comment 10 David Kondrad 2010-07-20 09:24:53 UTC
(In reply to comment #9)

> Created an attachment (id=5852) [details]
> Patch for 3.5.x.

Just a few things I saw:

"if (asn1_tag_remaining(data) > 0)" checks aren't needed because asn1_peek_tag does this already.

If secblob or principal is NULL then will it leak memory because you didn't data_blob_free or TALLOC_FREE?

e.g.:

if (secblob) {
    *secblob = sblob;
} else {
    data_blob_free(&sblob);
}

if (principal) {
    *principal = princ; 
} else {
   TALLOC_FREE(princ);
}

> Can you test this please to see if it fixes the problem ?
> Jeremy.

Works great - thank you very much for the patch!

-- Dave
Comment 11 Jeremy Allison 2010-07-20 11:20:43 UTC
Good catch on the memory leaks and optimization. I'll update the patch and then get it pushed for 3.4.x and 3.5.x - thanks !
Jeremy.
Comment 12 Jeremy Allison 2010-07-20 12:27:30 UTC
Created attachment 5854 [details]
Replacement patcg for 3.5.x.

Please review, then I'll get it added for 3.5.x.
Jeremy.
Comment 13 Jeremy Allison 2010-07-20 12:41:30 UTC
Created attachment 5855 [details]
Patch for 3.4.x.

Please review for 3.4.x.
Jeremy.
Comment 14 Simo Sorce 2010-07-20 13:11:01 UTC
Comment on attachment 5854 [details]
Replacement patcg for 3.5.x.

Looks good to me
Comment 15 Simo Sorce 2010-07-20 13:11:47 UTC
Comment on attachment 5855 [details]
Patch for 3.4.x.

same for 3.4, good
Comment 16 Jeremy Allison 2010-07-20 13:13:52 UTC
Re-assigning to Karolin for inclusion in the next offical 3.5.x and 3.4.x releases.
Jeremy.
Comment 17 Karolin Seeger 2010-07-27 01:48:41 UTC
(In reply to comment #16)
> Re-assigning to Karolin for inclusion in the next offical 3.5.x and 3.4.x
> releases.
> Jeremy.
> 

Pushed to both branches.
Closing out bug report.

Thanks!