1--- a/source/libsmb/asn1.c 2+++ b/source/libsmb/asn1.c 3@@ -261,6 +261,36 @@ 4 return asn1_read(data, v, 1); 5 } 6 7+/* peek to see if a tag is present */ 8+/* this was not ported from samba and may not be identical to libsmb mainline */ 9+BOOL asn1_peek_tag(ASN1_DATA *data, uint8 tag) 10+{ 11+ uint8 curtag; 12+ 13+ if (data->has_error) 14+ return False; 15+ 16+ // overflow checking 17+ if (data->ofs + 1 < data->ofs || data->ofs + 1 < 1) { 18+ return False; 19+ } 20+ 21+ // boundary checking 22+ if (data->ofs + 1 > data->length) { 23+ return False; 24+ } 25+ 26+ memcpy( (void*)&curtag, data->data + data->ofs, 1); 27+ 28+ // don't move cursor 29+ // don't set error 30+ 31+ if( tag != curtag ) 32+ return False; 33+ 34+ return True; 35+} 36+ 37 /* start reading a nested asn1 structure */ 38 BOOL asn1_start_tag(ASN1_DATA *data, uint8 tag) 39 { 40--- a/source/libsmb/clispnego.c 41+++ b/source/libsmb/clispnego.c 42@@ -135,9 +135,16 @@ 43 44 asn1_start_tag(&data,ASN1_APPLICATION(0)); 45 asn1_check_OID(&data,OID_SPNEGO); 46+ 47+ /* negTokenInit [0] NegTokenInit */ 48 asn1_start_tag(&data,ASN1_CONTEXT(0)); 49 asn1_start_tag(&data,ASN1_SEQUENCE(0)); 50 51+ /* mechTypes [0] MechTypeList OPTIONAL */ 52+ 53+ /* Not really optional, we depend on this to decide 54+ * what mechanisms we have to work with. */ 55+ 56 asn1_start_tag(&data,ASN1_CONTEXT(0)); 57 asn1_start_tag(&data,ASN1_SEQUENCE(0)); 58 for (i=0; asn1_tag_remaining(&data) > 0 && i < ASN1_MAX_OIDS-1; i++) { 59@@ -150,7 +157,39 @@ 60 asn1_end_tag(&data); 61 62 *principal = NULL; 63- if (asn1_tag_remaining(&data) > 0) { 64+ 65+ /* 66+ Win7 + Live Sign-in Assistant attaches a mechToken 67+ ASN1_CONTEXT(2) to the negTokenInit packet 68+ which breaks our negotiation if we just assume 69+ the next tag is ASN1_CONTEXT(3). 70+ */ 71+ 72+ if (asn1_peek_tag(&data, ASN1_CONTEXT(1))) { 73+ uint8 flags; 74+ 75+ /* reqFlags [1] ContextFlags OPTIONAL */ 76+ asn1_start_tag(&data, ASN1_CONTEXT(1)); 77+ asn1_start_tag(&data, ASN1_BITFIELD); 78+ while (asn1_tag_remaining(&data) > 0) { 79+ asn1_read_uint8(&data, &flags); 80+ } 81+ asn1_end_tag(&data); 82+ asn1_end_tag(&data); 83+ } 84+ 85+ if (asn1_peek_tag(&data, ASN1_CONTEXT(2))) { 86+ /* mechToken [2] OCTET STRING OPTIONAL */ 87+ DATA_BLOB token; 88+ asn1_start_tag(&data, ASN1_CONTEXT(2)); 89+ asn1_read_OctetString(&data, &token); 90+ asn1_end_tag(&data); 91+ /* Throw away the token - not used. */ 92+ data_blob_free(&token); 93+ } 94+ 95+ if (asn1_peek_tag(&data, ASN1_CONTEXT(3))) { 96+ /* mechListMIC [3] OCTET STRING OPTIONAL */ 97 asn1_start_tag(&data, ASN1_CONTEXT(3)); 98 asn1_start_tag(&data, ASN1_SEQUENCE(0)); 99 asn1_start_tag(&data, ASN1_CONTEXT(0)); 100