From f5dbdef78af9777fde64a6cfaa052613b987276d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 27 Jul 2010 08:45:46 +0200 Subject: [PATCH] s3-libsmb: Fix bug #7577. SPNEGO auth fails when contacting Win7 system using Microsoft Live Sign-in Assistant. (cherry picked from commit 97e0238d0e8b1573a408648bff29958a2e1a89e8) --- source3/libsmb/clispnego.c | 47 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 264743b2a6a..36d21d0a965 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -4,7 +4,7 @@ Copyright (C) Andrew Tridgell 2001 Copyright (C) Jim McDonough 2002 Copyright (C) Luke Howard 2003 - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or @@ -146,9 +146,16 @@ bool spnego_parse_negTokenInit(DATA_BLOB blob, asn1_start_tag(data,ASN1_APPLICATION(0)); asn1_check_OID(data,OID_SPNEGO); + + /* negTokenInit [0] NegTokenInit */ asn1_start_tag(data,ASN1_CONTEXT(0)); asn1_start_tag(data,ASN1_SEQUENCE(0)); + /* mechTypes [0] MechTypeList OPTIONAL */ + + /* Not really optional, we depend on this to decide + * what mechanisms we have to work with. */ + asn1_start_tag(data,ASN1_CONTEXT(0)); asn1_start_tag(data,ASN1_SEQUENCE(0)); for (i=0; asn1_tag_remaining(data) > 0 && i < ASN1_MAX_OIDS-1; i++) { @@ -161,11 +168,45 @@ bool spnego_parse_negTokenInit(DATA_BLOB blob, asn1_end_tag(data); *principal = NULL; - if (asn1_tag_remaining(data) > 0) { + + /* + Win7 + Live Sign-in Assistant attaches a mechToken + ASN1_CONTEXT(2) to the negTokenInit packet + which breaks our negotiation if we just assume + the next tag is ASN1_CONTEXT(3). + */ + + if (asn1_peek_tag(data, ASN1_CONTEXT(1))) { + uint8 flags; + + /* reqFlags [1] ContextFlags OPTIONAL */ + asn1_start_tag(data, ASN1_CONTEXT(1)); + asn1_start_tag(data, ASN1_BIT_STRING); + while (asn1_tag_remaining(data) > 0) { + asn1_read_uint8(data, &flags); + } + asn1_end_tag(data); + asn1_end_tag(data); + } + + if (asn1_peek_tag(data, ASN1_CONTEXT(2))) { + /* mechToken [2] OCTET STRING OPTIONAL */ + DATA_BLOB token; + asn1_start_tag(data, ASN1_CONTEXT(2)); + asn1_read_OctetString(data, talloc_autofree_context(), + &token); + asn1_end_tag(data); + /* Throw away the token - not used. */ + data_blob_free(&token); + } + + if (asn1_peek_tag(data, ASN1_CONTEXT(3))) { + /* mechListMIC [3] OCTET STRING OPTIONAL */ asn1_start_tag(data, ASN1_CONTEXT(3)); asn1_start_tag(data, ASN1_SEQUENCE(0)); asn1_start_tag(data, ASN1_CONTEXT(0)); - asn1_read_GeneralString(data,talloc_autofree_context(),principal); + asn1_read_GeneralString(data,talloc_autofree_context(), + principal); asn1_end_tag(data); asn1_end_tag(data); asn1_end_tag(data); -- 2.11.4.GIT