1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
diff -r -u samba-3.0.37-clean/source/libsmb/asn1.c samba-3.0.37/source/libsmb/asn1.c
--- samba-3.0.37-clean/source/libsmb/asn1.c 2009-09-30 05:21:56.000000000 -0700
+++ samba-3.0.37/source/libsmb/asn1.c 2010-11-18 12:40:06.981517350 -0800
@@ -261,6 +261,36 @@
return asn1_read(data, v, 1);
}
+/* peek to see if a tag is present */
+/* this was not ported from samba and may not be identical to libsmb mainline */
+BOOL asn1_peek_tag(ASN1_DATA *data, uint8 tag)
+{
+ uint8 curtag;
+
+ if (data->has_error)
+ return False;
+
+ // overflow checking
+ if (data->ofs + 1 < data->ofs || data->ofs + 1 < 1) {
+ return False;
+ }
+
+ // boundary checking
+ if (data->ofs + 1 > data->length) {
+ return False;
+ }
+
+ memcpy( (void*)&curtag, data->data + data->ofs, 1);
+
+ // don't move cursor
+ // don't set error
+
+ if( tag != curtag )
+ return False;
+
+ return True;
+}
+
/* start reading a nested asn1 structure */
BOOL asn1_start_tag(ASN1_DATA *data, uint8 tag)
{
diff -r -u samba-3.0.37-clean/source/libsmb/clispnego.c samba-3.0.37/source/libsmb/clispnego.c
--- samba-3.0.37-clean/source/libsmb/clispnego.c 2009-09-30 05:21:56.000000000 -0700
+++ samba-3.0.37/source/libsmb/clispnego.c 2010-11-18 12:52:54.833518134 -0800
@@ -135,9 +135,16 @@
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++) {
@@ -150,7 +157,39 @@
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_BITFIELD);
+ 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, &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));
|