|
21 | 21 | #include "ksmbd_spnego_negtokeninit.asn1.h" |
22 | 22 | #include "ksmbd_spnego_negtokentarg.asn1.h" |
23 | 23 |
|
24 | | -#define SPNEGO_OID_LEN 7 |
25 | 24 | #define NTLMSSP_OID_LEN 10 |
26 | | -#define KRB5_OID_LEN 7 |
27 | | -#define KRB5U2U_OID_LEN 8 |
28 | | -#define MSKRB5_OID_LEN 7 |
29 | | -static unsigned long SPNEGO_OID[7] = { 1, 3, 6, 1, 5, 5, 2 }; |
30 | | -static unsigned long NTLMSSP_OID[10] = { 1, 3, 6, 1, 4, 1, 311, 2, 2, 10 }; |
31 | | -static unsigned long KRB5_OID[7] = { 1, 2, 840, 113554, 1, 2, 2 }; |
32 | | -static unsigned long KRB5U2U_OID[8] = { 1, 2, 840, 113554, 1, 2, 2, 3 }; |
33 | | -static unsigned long MSKRB5_OID[7] = { 1, 2, 840, 48018, 1, 2, 2 }; |
34 | 25 |
|
35 | 26 | static char NTLMSSP_OID_STR[NTLMSSP_OID_LEN] = { 0x2b, 0x06, 0x01, 0x04, 0x01, |
36 | 27 | 0x82, 0x37, 0x02, 0x02, 0x0a }; |
37 | 28 |
|
38 | | -static bool |
39 | | -asn1_subid_decode(const unsigned char **begin, const unsigned char *end, |
40 | | - unsigned long *subid) |
41 | | -{ |
42 | | - const unsigned char *ptr = *begin; |
43 | | - unsigned char ch; |
44 | | - |
45 | | - *subid = 0; |
46 | | - |
47 | | - do { |
48 | | - if (ptr >= end) |
49 | | - return false; |
50 | | - |
51 | | - ch = *ptr++; |
52 | | - *subid <<= 7; |
53 | | - *subid |= ch & 0x7F; |
54 | | - } while ((ch & 0x80) == 0x80); |
55 | | - |
56 | | - *begin = ptr; |
57 | | - return true; |
58 | | -} |
59 | | - |
60 | | -static bool asn1_oid_decode(const unsigned char *value, size_t vlen, |
61 | | - unsigned long **oid, size_t *oidlen) |
62 | | -{ |
63 | | - const unsigned char *iptr = value, *end = value + vlen; |
64 | | - unsigned long *optr; |
65 | | - unsigned long subid; |
66 | | - |
67 | | - vlen += 1; |
68 | | - if (vlen < 2 || vlen > UINT_MAX / sizeof(unsigned long)) |
69 | | - goto fail_nullify; |
70 | | - |
71 | | - *oid = kmalloc(vlen * sizeof(unsigned long), GFP_KERNEL); |
72 | | - if (!*oid) |
73 | | - return false; |
74 | | - |
75 | | - optr = *oid; |
76 | | - |
77 | | - if (!asn1_subid_decode(&iptr, end, &subid)) |
78 | | - goto fail; |
79 | | - |
80 | | - if (subid < 40) { |
81 | | - optr[0] = 0; |
82 | | - optr[1] = subid; |
83 | | - } else if (subid < 80) { |
84 | | - optr[0] = 1; |
85 | | - optr[1] = subid - 40; |
86 | | - } else { |
87 | | - optr[0] = 2; |
88 | | - optr[1] = subid - 80; |
89 | | - } |
90 | | - |
91 | | - *oidlen = 2; |
92 | | - optr += 2; |
93 | | - |
94 | | - while (iptr < end) { |
95 | | - if (++(*oidlen) > vlen) |
96 | | - goto fail; |
97 | | - |
98 | | - if (!asn1_subid_decode(&iptr, end, optr++)) |
99 | | - goto fail; |
100 | | - } |
101 | | - return true; |
102 | | - |
103 | | -fail: |
104 | | - kfree(*oid); |
105 | | -fail_nullify: |
106 | | - *oid = NULL; |
107 | | - return false; |
108 | | -} |
109 | | - |
110 | | -static bool oid_eq(unsigned long *oid1, unsigned int oid1len, |
111 | | - unsigned long *oid2, unsigned int oid2len) |
112 | | -{ |
113 | | - if (oid1len != oid2len) |
114 | | - return false; |
115 | | - |
116 | | - return memcmp(oid1, oid2, oid1len) == 0; |
117 | | -} |
118 | | - |
119 | 29 | int |
120 | 30 | ksmbd_decode_negTokenInit(unsigned char *security_blob, int length, |
121 | 31 | struct ksmbd_conn *conn) |
@@ -252,64 +162,50 @@ int build_spnego_ntlmssp_auth_blob(unsigned char **pbuffer, u16 *buflen, |
252 | 162 | int ksmbd_gssapi_this_mech(void *context, size_t hdrlen, unsigned char tag, |
253 | 163 | const void *value, size_t vlen) |
254 | 164 | { |
255 | | - unsigned long *oid; |
256 | | - size_t oidlen; |
257 | | - int err = 0; |
258 | | - |
259 | | - if (!asn1_oid_decode(value, vlen, &oid, &oidlen)) { |
260 | | - err = -EBADMSG; |
261 | | - goto out; |
262 | | - } |
| 165 | + enum OID oid; |
263 | 166 |
|
264 | | - if (!oid_eq(oid, oidlen, SPNEGO_OID, SPNEGO_OID_LEN)) |
265 | | - err = -EBADMSG; |
266 | | - kfree(oid); |
267 | | -out: |
268 | | - if (err) { |
| 167 | + oid = look_up_OID(value, vlen); |
| 168 | + if (oid != OID_spnego) { |
269 | 169 | char buf[50]; |
270 | 170 |
|
271 | 171 | sprint_oid(value, vlen, buf, sizeof(buf)); |
272 | 172 | ksmbd_debug(AUTH, "Unexpected OID: %s\n", buf); |
| 173 | + return -EBADMSG; |
273 | 174 | } |
274 | | - return err; |
| 175 | + |
| 176 | + return 0; |
275 | 177 | } |
276 | 178 |
|
277 | 179 | int ksmbd_neg_token_init_mech_type(void *context, size_t hdrlen, |
278 | 180 | unsigned char tag, const void *value, |
279 | 181 | size_t vlen) |
280 | 182 | { |
281 | 183 | struct ksmbd_conn *conn = context; |
282 | | - unsigned long *oid; |
283 | | - size_t oidlen; |
| 184 | + enum OID oid; |
284 | 185 | int mech_type; |
285 | | - char buf[50]; |
286 | 186 |
|
287 | | - if (!asn1_oid_decode(value, vlen, &oid, &oidlen)) |
288 | | - goto fail; |
289 | | - |
290 | | - if (oid_eq(oid, oidlen, NTLMSSP_OID, NTLMSSP_OID_LEN)) |
| 187 | + oid = look_up_OID(value, vlen); |
| 188 | + if (oid == OID_ntlmssp) { |
291 | 189 | mech_type = KSMBD_AUTH_NTLMSSP; |
292 | | - else if (oid_eq(oid, oidlen, MSKRB5_OID, MSKRB5_OID_LEN)) |
| 190 | + } else if (oid == OID_mskrb5) { |
293 | 191 | mech_type = KSMBD_AUTH_MSKRB5; |
294 | | - else if (oid_eq(oid, oidlen, KRB5_OID, KRB5_OID_LEN)) |
| 192 | + } else if (oid == OID_krb5) { |
295 | 193 | mech_type = KSMBD_AUTH_KRB5; |
296 | | - else if (oid_eq(oid, oidlen, KRB5U2U_OID, KRB5U2U_OID_LEN)) |
| 194 | + } else if (oid == OID_krb5u2u) { |
297 | 195 | mech_type = KSMBD_AUTH_KRB5U2U; |
298 | | - else |
299 | | - goto fail; |
| 196 | + } else { |
| 197 | + char buf[50]; |
| 198 | + |
| 199 | + sprint_oid(value, vlen, buf, sizeof(buf)); |
| 200 | + ksmbd_debug(AUTH, "Unexpected OID: %s\n", buf); |
| 201 | + return -EBADMSG; |
| 202 | + } |
300 | 203 |
|
301 | 204 | conn->auth_mechs |= mech_type; |
302 | 205 | if (conn->preferred_auth_mech == 0) |
303 | 206 | conn->preferred_auth_mech = mech_type; |
304 | 207 |
|
305 | | - kfree(oid); |
306 | 208 | return 0; |
307 | | - |
308 | | -fail: |
309 | | - kfree(oid); |
310 | | - sprint_oid(value, vlen, buf, sizeof(buf)); |
311 | | - ksmbd_debug(AUTH, "Unexpected OID: %s\n", buf); |
312 | | - return -EBADMSG; |
313 | 209 | } |
314 | 210 |
|
315 | 211 | int ksmbd_neg_token_init_mech_token(void *context, size_t hdrlen, |
|
0 commit comments