Print this page
12513 SMB 3.1.1 support for server
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/fs/smbsrv/smb2_negotiate.c
+++ new/usr/src/uts/common/fs/smbsrv/smb2_negotiate.c
1 1 /*
2 2 * This file and its contents are supplied under the terms of the
3 3 * Common Development and Distribution License ("CDDL"), version 1.0.
↓ open down ↓ |
3 lines elided |
↑ open up ↑ |
4 4 * You may only use this file in accordance with the terms of version
5 5 * 1.0 of the CDDL.
6 6 *
7 7 * A full copy of the text of the CDDL should have accompanied this
8 8 * source. A copy of the CDDL is also available via the Internet at
9 9 * http://www.illumos.org/license/CDDL.
10 10 */
11 11
12 12 /*
13 13 * Copyright 2019 Nexenta Systems, Inc. All rights reserved.
14 - * Copyright 2019 RackTop Systems.
14 + * Copyright 2020 RackTop Systems, Inc.
15 15 */
16 16
17 17 /*
18 18 * Dispatch function for SMB2_NEGOTIATE
19 19 */
20 20
21 21 #include <smbsrv/smb2_kproto.h>
22 22 #include <smbsrv/smb2.h>
23 +#include <sys/random.h>
23 24
24 25 /*
25 26 * Note from [MS-SMB2] Sec. 2.2.3: Windows servers return
26 27 * invalid parameter if the dialect count is greater than 64
27 28 * This is here (and not in smb2.h) because this is technically
28 29 * an implementation detail, not protocol specification.
29 30 */
30 31 #define SMB2_NEGOTIATE_MAX_DIALECTS 64
31 32
32 33 static int smb2_negotiate_common(smb_request_t *, uint16_t);
33 34
34 35 /* List of supported capabilities. Can be patched for testing. */
35 36 uint32_t smb2srv_capabilities =
36 37 SMB2_CAP_DFS |
37 38 SMB2_CAP_LEASING |
38 39 SMB2_CAP_LARGE_MTU |
39 40 SMB2_CAP_PERSISTENT_HANDLES |
40 41 SMB2_CAP_ENCRYPTION;
41 42
42 43 /* These are the only capabilities defined for SMB2.X */
43 44 #define SMB_2X_CAPS (SMB2_CAP_DFS | SMB2_CAP_LEASING | SMB2_CAP_LARGE_MTU)
44 45
45 46 /*
46 47 * These are not intended as customer tunables, but dev. & test folks
47 48 * might want to adjust them (with caution).
48 49 *
49 50 * smb2_tcp_bufsize is the TCP buffer size, applied to the network socket
50 51 * with setsockopt SO_SNDBUF, SO_RCVBUF. These set the TCP window size.
51 52 * This is also used as a "sanity limit" for internal send/reply message
52 53 * allocations. Note that with compounding SMB2 messages may contain
53 54 * multiple requests/responses. This size should be large enough for
54 55 * at least a few SMB2 requests, and at least 2X smb2_max_rwsize.
55 56 *
56 57 * smb2_max_rwsize is what we put in the SMB2 negotiate response to tell
57 58 * the client the largest read and write request size we'll support.
58 59 * For now, we're using contiguous allocations, so keep this at 64KB
59 60 * so that (even with message overhead) allocations stay below 128KB,
60 61 * avoiding kmem_alloc -> page_create_va thrashing.
61 62 *
62 63 * smb2_max_trans is the largest "transact" send or receive, which is
63 64 * used for directory listings and info set/get operations.
64 65 */
65 66 uint32_t smb2_tcp_bufsize = (1<<22); /* 4MB */
66 67 uint32_t smb2_max_rwsize = (1<<16); /* 64KB */
67 68 uint32_t smb2_max_trans = (1<<16); /* 64KB */
68 69
69 70 /*
70 71 * With clients (e.g. HP scanners) that don't advertise SMB2_CAP_LARGE_MTU
71 72 * (including all clients using dialect < SMB 2.1), use a "conservative" value
72 73 * for max r/w size because some older clients misbehave with larger values.
73 74 * 64KB is recommended in the [MS-SMB2] spec. (3.3.5.3.1 SMB 2.1 or SMB 3.x
74 75 * Support) as the minimum so we'll use that.
75 76 */
76 77 uint32_t smb2_old_rwsize = (1<<16); /* 64KB */
77 78
↓ open down ↓ |
45 lines elided |
↑ open up ↑ |
78 79 /*
79 80 * List of all SMB2 versions we implement. Note that the
80 81 * versions we support may be limited by the
81 82 * _cfg.skc_max_protocol and min_protocol settings.
82 83 */
83 84 static uint16_t smb2_versions[] = {
84 85 0x202, /* SMB 2.002 */
85 86 0x210, /* SMB 2.1 */
86 87 0x300, /* SMB 3.0 */
87 88 0x302, /* SMB 3.02 */
89 + 0x311, /* SMB 3.11 */
88 90 };
89 91 static uint16_t smb2_nversions =
90 92 sizeof (smb2_versions) / sizeof (smb2_versions[0]);
91 93
92 94 static boolean_t
93 95 smb2_supported_version(smb_session_t *s, uint16_t version)
94 96 {
95 97 int i;
96 98
97 99 if (version > s->s_cfg.skc_max_protocol ||
98 100 version < s->s_cfg.skc_min_protocol)
99 101 return (B_FALSE);
100 102 for (i = 0; i < smb2_nversions; i++)
101 103 if (version == smb2_versions[i])
102 104 return (B_TRUE);
103 105 return (B_FALSE);
104 106 }
105 107
106 108 /*
107 109 * Helper for the (SMB1) smb_com_negotiate(). This is the
108 110 * very unusual protocol interaction where an SMB1 negotiate
109 111 * gets an SMB2 negotiate response. This is the normal way
110 112 * clients first find out if the server supports SMB2.
111 113 *
112 114 * Note: This sends an SMB2 reply _itself_ and then returns
113 115 * SDRC_NO_REPLY so the caller will not send an SMB1 reply.
114 116 * Also, this is called directly from the reader thread, so
115 117 * we know this is the only thread using this session.
116 118 *
117 119 * The caller frees this request.
118 120 */
119 121 smb_sdrc_t
120 122 smb1_negotiate_smb2(smb_request_t *sr)
121 123 {
122 124 smb_session_t *s = sr->session;
123 125 smb_arg_negotiate_t *negprot = sr->sr_negprot;
124 126 uint16_t smb2_version;
125 127
126 128 /*
127 129 * Note: In the SMB1 negotiate command handler, we
128 130 * agreed with one of the SMB2 dialects. If that
129 131 * dialect was "SMB 2.002", we'll respond here with
130 132 * version 0x202 and negotiation is done. If that
131 133 * dialect was "SMB 2.???", we'll respond here with
132 134 * the "wildcard" version 0x2FF, and the client will
133 135 * come back with an SMB2 negotiate.
134 136 */
135 137 switch (negprot->ni_dialect) {
136 138 case DIALECT_SMB2002: /* SMB 2.002 (a.k.a. SMB2.0) */
137 139 smb2_version = SMB_VERS_2_002;
138 140 s->dialect = smb2_version;
139 141 s->s_state = SMB_SESSION_STATE_NEGOTIATED;
140 142 /* Allow normal SMB2 requests now. */
141 143 s->newrq_func = smb2sr_newrq;
142 144 break;
143 145 case DIALECT_SMB2XXX: /* SMB 2.??? (wildcard vers) */
144 146 /*
145 147 * Expecting an SMB2 negotiate next, so keep the
146 148 * initial s->newrq_func.
147 149 */
148 150 smb2_version = 0x2FF;
149 151 break;
150 152 default:
151 153 return (SDRC_DROP_VC);
152 154 }
153 155
154 156 /*
155 157 * We did not decode an SMB2 header, so make sure
156 158 * the SMB2 header fields are initialized.
157 159 * (Most are zero from smb_request_alloc.)
158 160 * Also, the SMB1 common dispatch code reserved space
159 161 * for an SMB1 header, which we need to undo here.
160 162 */
161 163 sr->smb2_reply_hdr = sr->reply.chain_offset = 0;
162 164 sr->smb2_cmd_code = SMB2_NEGOTIATE;
163 165 sr->smb2_hdr_flags = SMB2_FLAGS_SERVER_TO_REDIR;
164 166
165 167 (void) smb2_encode_header(sr, B_FALSE);
166 168 if (smb2_negotiate_common(sr, smb2_version) != 0)
167 169 sr->smb2_status = NT_STATUS_INTERNAL_ERROR;
168 170 if (sr->smb2_status != 0)
169 171 smb2sr_put_error(sr, sr->smb2_status);
170 172 (void) smb2_encode_header(sr, B_TRUE);
171 173
172 174 smb2_send_reply(sr);
173 175
174 176 /*
175 177 * We sent the reply, so tell the SMB1 dispatch
176 178 * it should NOT (also) send a reply.
177 179 */
178 180 return (SDRC_NO_REPLY);
179 181 }
180 182
181 183 static uint16_t
182 184 smb2_find_best_dialect(smb_session_t *s, uint16_t cl_versions[],
183 185 uint16_t version_cnt)
184 186 {
185 187 uint16_t best_version = 0;
186 188 int i;
187 189
188 190 for (i = 0; i < version_cnt; i++)
189 191 if (smb2_supported_version(s, cl_versions[i]) &&
190 192 best_version < cl_versions[i])
191 193 best_version = cl_versions[i];
192 194
193 195 return (best_version);
194 196 }
195 197
196 198 /*
197 199 * SMB2 Negotiate gets special handling. This is called directly by
198 200 * the reader thread (see smbsr_newrq_initial) with what _should_ be
199 201 * an SMB2 Negotiate. Only the "\feSMB" header has been checked
200 202 * when this is called, so this needs to check the SMB command,
201 203 * if it's Negotiate execute it, then send the reply, etc.
202 204 *
↓ open down ↓ |
105 lines elided |
↑ open up ↑ |
203 205 * Since this is called directly from the reader thread, we
204 206 * know this is the only thread currently using this session.
205 207 * This has to duplicate some of what smb2sr_work does as a
206 208 * result of bypassing the normal dispatch mechanism.
207 209 *
208 210 * The caller always frees this request.
209 211 *
210 212 * Return value is 0 for success, and anything else will
211 213 * terminate the reader thread (drop the connection).
212 214 */
215 +typedef struct smb31_preauth_integrity_caps_ctx {
216 + uint16_t hash_count;
217 + uint16_t salt_len;
218 + char *salt;
219 +} smb31_preauth_integrity_caps_ctx_t;
220 +
221 +typedef struct smb31_encryption_caps_ctx {
222 + uint16_t cipher_count;
223 +} smb31_encrypt_caps_ctx_t;
224 +
225 +enum smb3_neg_ctx_type {
226 + SMB31_PREAUTH_INTEGRITY_CAPS = 1,
227 + SMB31_ENCRYPTION_CAPS = 2
228 +};
229 +
230 +typedef struct smb3_negotiate_context {
231 + uint16_t type;
232 + uint16_t datalen;
233 + uint32_t _resrvd;
234 + char data[];
235 +} smb3_neg_ctx_t;
236 +
237 +typedef struct smb3_negotiate_context_info {
238 + uint32_t offset;
239 + uint16_t count;
240 + uint16_t _resrvd;
241 +} smb3_neg_ctx_info_t;
242 +
243 +#define NEG_CTX_INFO_OFFSET (SMB2_HDR_SIZE + 28)
244 +#define STATUS_SMB_NO_PREAUTH_INEGRITY_HASH_OVERLAP (0xC05D0000)
245 +
246 +#define STATUS_PREAUTH_HASH_OVERLAP \
247 + STATUS_SMB_NO_PREAUTH_INEGRITY_HASH_OVERLAP
248 +
249 +/*
250 + * This function should be called only for dialect >= 0x311
251 + * Negotiate context list should contain exactly one
252 + * smb31_preauth_INTEGRITY_CAPS context.
253 + * Otherwise STATUS_INVALID_PARAMETER.
254 + * It should contain at least 1 hash algorith what server does support.
255 + * Otehrwise STATUS_SMB_NO_PREAUTH_INEGRITY_HASH_OVERLAP.
256 + */
257 +static uint32_t
258 +smb31_decode_neg_ctxs(smb_request_t *sr, smb_session_t *s)
259 +{
260 + uint32_t status = 0;
261 + int found_preauth_ctx = 0;
262 + boolean_t preauth_sha512_enabled = B_FALSE;
263 + boolean_t encrypt_ccm_enabled = B_FALSE;
264 + boolean_t encrypt_gcm_enabled = B_FALSE;
265 + uint16_t cipher = sr->sr_server->sv_cfg.skc_encrypt_cipher;
266 + smb3_neg_ctx_info_t neg_ctx_info;
267 + int cnt, i;
268 + int rc;
269 +
270 + sr->command.chain_offset = NEG_CTX_INFO_OFFSET;
271 +
272 + rc = smb_mbc_decodef(&sr->command, "lw2.",
273 + &neg_ctx_info.offset, /* l */
274 + &neg_ctx_info.count); /* w */
275 + if (rc != 0) {
276 + status = NT_STATUS_INVALID_PARAMETER;
277 + goto errout;
278 + }
279 +
280 + /*
281 + * There should be exactly 1 SMB31_PREAUTH_INTEGRITY_CAPS negotiate ctx.
282 + * SMB31_ENCRYPTION_CAPS is optional one.
283 + */
284 + cnt = neg_ctx_info.count;
285 + if (cnt < 1) {
286 + status = NT_STATUS_INVALID_PARAMETER;
287 + goto errout;
288 + }
289 +
290 + sr->command.chain_offset = neg_ctx_info.offset;
291 +
292 + /*
293 + * Parse negotiate contexts.
294 + */
295 + for (i = 0; i < cnt; i++) {
296 + smb3_neg_ctx_t neg_ctx;
297 +
298 + sr->command.chain_offset =
299 + P2ROUNDUP(sr->command.chain_offset, 8);
300 +
301 + rc = smb_mbc_decodef(
302 + &sr->command, "ww4.",
303 + &neg_ctx.type, /* w */
304 + &neg_ctx.datalen); /* w */
305 + if (rc != 0) {
306 + status = NT_STATUS_INVALID_PARAMETER;
307 + goto errout;
308 + }
309 +
310 + if (neg_ctx.type == SMB31_PREAUTH_INTEGRITY_CAPS) {
311 + smb31_preauth_integrity_caps_ctx_t pic_ctx;
312 +
313 + if (found_preauth_ctx++ != 0) {
314 + status = NT_STATUS_INVALID_PARAMETER;
315 + goto errout;
316 + }
317 +
318 + rc = smb_mbc_decodef(
319 + &sr->command, "ww",
320 + &pic_ctx.hash_count, /* w */
321 + &pic_ctx.salt_len); /* w */
322 + if (rc != 0) {
323 + status = NT_STATUS_INVALID_PARAMETER;
324 + goto errout;
325 + }
326 +
327 + /*
328 + * In SMB 0x311 there should be exactly 1 preauth
329 + * negotiate context, and there should be exactly 1
330 + * hash value in the list - SHA512.
331 + */
332 + if (pic_ctx.hash_count != 1) {
333 + status = NT_STATUS_INVALID_PARAMETER;
334 + goto errout;
335 + }
336 +
337 + for (int k = 0; k < pic_ctx.hash_count; k++) {
338 + uint16_t hash_id;
339 +
340 + rc = smb_mbc_decodef(
341 + &sr->command, "w",
342 + &hash_id); /* w */
343 +
344 + switch (hash_id) {
345 + case SMB3_HASH_SHA512:
346 + preauth_sha512_enabled = B_TRUE;
347 + break;
348 + default:
349 + ;
350 + }
351 + }
352 +
353 + rc = smb_mbc_decodef(
354 + &sr->command, "#.",
355 + pic_ctx.salt_len);
356 +
357 + } else if (neg_ctx.type == SMB31_ENCRYPTION_CAPS) {
358 + smb31_encrypt_caps_ctx_t enc_ctx;
359 +
360 + rc = smb_mbc_decodef(
361 + &sr->command, "w",
362 + &enc_ctx.cipher_count); /* w */
363 + if (rc != 0) {
364 + status = NT_STATUS_INVALID_PARAMETER;
365 + goto errout;
366 + }
367 +
368 + for (int k = 0; k < enc_ctx.cipher_count; k++) {
369 + uint16_t cipher_id;
370 +
371 + rc = smb_mbc_decodef(
372 + &sr->command, "w",
373 + &cipher_id); /* w */
374 +
375 + switch (cipher_id) {
376 + case SMB3_CIPHER_AES128_CCM:
377 + encrypt_ccm_enabled = B_TRUE;
378 + break;
379 + case SMB3_CIPHER_AES128_GCM:
380 + encrypt_gcm_enabled = B_TRUE;
381 + break;
382 + default:
383 + ;
384 + }
385 + }
386 + } else {
387 + /* Skip unsupported context */
388 + ASSERT0(smb_mbc_decodef(
389 + &sr->command, "#.",
390 + neg_ctx.datalen));
391 + }
392 + }
393 +
394 + /* Not found mandatory SMB31_PREAUTH_INTEGRITY_CAPS ctx */
395 + if (!found_preauth_ctx)
396 + status = NT_STATUS_INVALID_PARAMETER;
397 +
398 + if (!preauth_sha512_enabled) {
399 + status = STATUS_PREAUTH_HASH_OVERLAP;
400 + goto errout;
401 + }
402 +
403 + s->smb31_preauth_hashid = SMB3_HASH_SHA512;
404 +
405 + switch (cipher) {
406 + case SMB3_CIPHER_AES128_GCM:
407 + if (encrypt_gcm_enabled) {
408 + s->smb31_enc_cipherid = cipher;
409 + break;
410 + }
411 + /* FALLTHROUGH */
412 + case SMB3_CIPHER_AES128_CCM:
413 + if (encrypt_ccm_enabled) {
414 + s->smb31_enc_cipherid = cipher;
415 + break;
416 + }
417 + /* FALLTHROUGH */
418 + default:
419 + s->smb31_enc_cipherid = 0;
420 + }
421 +
422 +errout:
423 + return (status);
424 +}
425 +
426 +#define SMB31_PREAUTH_CTX_SALT_LEN 32
427 +
428 +static int
429 +smb31_encode_neg_ctxs(smb_request_t *sr, smb_session_t *s)
430 +{
431 + uint8_t salt[SMB31_PREAUTH_CTX_SALT_LEN];
432 + uint16_t salt_len = SMB31_PREAUTH_CTX_SALT_LEN;
433 + uint32_t preauth_ctx_len = 6 + salt_len;
434 + uint32_t enc_ctx_len = 4;
435 + uint32_t neg_ctx_off = SMB2_HDR_SIZE + 64 +
436 + P2ROUNDUP(sr->sr_cfg->skc_negtok_len, 8);
437 + uint32_t rc;
438 +
439 + sr->reply.chain_offset = P2ROUNDUP(sr->reply.chain_offset, 8);
440 +
441 + ASSERT3S(neg_ctx_off, ==, sr->reply.chain_offset);
442 +
443 + (void) random_get_pseudo_bytes(salt, sizeof (salt));
444 +
445 + rc = smb_mbc_encodef(
446 + &sr->reply, "ww4.",
447 + SMB31_PREAUTH_INTEGRITY_CAPS,
448 + preauth_ctx_len
449 + /* 4. */); /* reserverd */
450 +
451 + ASSERT0(rc);
452 + rc = smb_mbc_encodef(
453 + &sr->reply, "www#c",
454 + 1, /* hash algo count */
455 + salt_len, /* salt length */
456 + s->smb31_preauth_hashid, /* hash id */
457 + salt_len, /* salt length */
458 + salt);
459 +
460 + /* aligned on 8-bytes boundary */
461 + if (rc != 0 || s->smb31_enc_cipherid == 0) {
462 + cmn_err(CE_NOTE, "Encryption is not supported");
463 + return (rc);
464 + }
465 +
466 + if (sr->reply.chain_offset % 8 != 0) {
467 + sr->reply.chain_offset = P2ROUNDUP(sr->reply.chain_offset, 8);
468 + }
469 +
470 + rc = smb_mbc_encodef(
471 + &sr->reply, "ww4.",
472 + SMB31_ENCRYPTION_CAPS,
473 + enc_ctx_len
474 + /* 4. */); /* reserverd */
475 +
476 + rc = smb_mbc_encodef(
477 + &sr->reply, "ww",
478 + 1, /* cipher count */
479 + s->smb31_enc_cipherid); /* encrypt. cipher id */
480 +
481 + return (rc);
482 +}
483 +
213 484 int
214 485 smb2_newrq_negotiate(smb_request_t *sr)
215 486 {
216 487 smb_session_t *s = sr->session;
217 488 int rc;
218 489 uint32_t status = 0;
219 490 uint16_t struct_size;
220 491 uint16_t best_version;
221 492 uint16_t version_cnt;
222 493 uint16_t cl_versions[SMB2_NEGOTIATE_MAX_DIALECTS];
223 494
224 495 sr->smb2_cmd_hdr = sr->command.chain_offset;
225 496 rc = smb2_decode_header(sr);
226 497 if (rc != 0)
227 498 return (rc);
228 499
229 500 if (sr->smb2_hdr_flags & SMB2_FLAGS_SERVER_TO_REDIR)
230 501 return (-1);
231 502
232 503 if ((sr->smb2_cmd_code != SMB2_NEGOTIATE) ||
233 504 (sr->smb2_next_command != 0))
234 505 return (-1);
235 506
236 507 /*
237 508 * Decode SMB2 Negotiate (fixed-size part)
238 509 */
239 510 rc = smb_mbc_decodef(
240 511 &sr->command, "www..l16c8.",
241 512 &struct_size, /* w */
242 513 &version_cnt, /* w */
243 514 &s->cli_secmode, /* w */
244 515 /* reserved (..) */
245 516 &s->capabilities, /* l */
246 517 s->clnt_uuid); /* 16c */
247 518 /* start_time 8. */
248 519 if (rc != 0)
249 520 return (rc);
250 521 if (struct_size != 36)
251 522 return (-1);
252 523
253 524 /*
254 525 * Decode SMB2 Negotiate (variable part)
255 526 *
↓ open down ↓ |
33 lines elided |
↑ open up ↑ |
256 527 * Be somewhat tolerant while decoding the variable part
257 528 * so we can return errors instead of dropping the client.
258 529 * Will limit decoding to the size of cl_versions here,
259 530 * and do the error checks on version_cnt after the
260 531 * dtrace start probe.
261 532 */
262 533 if (version_cnt > 0 &&
263 534 version_cnt <= SMB2_NEGOTIATE_MAX_DIALECTS &&
264 535 smb_mbc_decodef(&sr->command, "#w", version_cnt,
265 536 cl_versions) != 0) {
266 - /* decode error; force an error below */
267 - version_cnt = 0;
537 + /* decode error; force an error below */
538 + version_cnt = 0;
268 539 }
269 540
270 541 DTRACE_SMB2_START(op__Negotiate, smb_request_t *, sr);
271 542
272 543 sr->smb2_hdr_flags |= SMB2_FLAGS_SERVER_TO_REDIR;
273 544 (void) smb2_encode_header(sr, B_FALSE);
274 545
275 546 /*
276 547 * [MS-SMB2] 3.3.5.2.4 Verifying the Signature
277 548 * "If the SMB2 header of the SMB2 NEGOTIATE request has the
278 549 * SMB2_FLAGS_SIGNED bit set in the Flags field, the server
279 550 * MUST fail the request with STATUS_INVALID_PARAMETER."
280 551 */
281 552 if ((sr->smb2_hdr_flags & SMB2_FLAGS_SIGNED) != 0) {
282 553 sr->smb2_hdr_flags &= ~SMB2_FLAGS_SIGNED;
283 554 status = NT_STATUS_INVALID_PARAMETER;
284 555 goto errout;
285 556 }
286 557
287 558 /*
288 559 * [MS-SMB2] 3.3.5.4 Receiving an SMB2 NEGOTIATE Request
289 560 * "If the DialectCount of the SMB2 NEGOTIATE Request is 0, the
290 561 * server MUST fail the request with STATUS_INVALID_PARAMETER."
291 562 */
292 563 if (version_cnt == 0 ||
293 564 version_cnt > SMB2_NEGOTIATE_MAX_DIALECTS) {
294 565 status = NT_STATUS_INVALID_PARAMETER;
295 566 goto errout;
296 567 }
297 568
298 569 /*
299 570 * The client offers an array of protocol versions it
300 571 * supports, which we have decoded into cl_versions[].
301 572 * We walk the array and pick the highest supported.
↓ open down ↓ |
24 lines elided |
↑ open up ↑ |
302 573 *
303 574 * [MS-SMB2] 3.3.5.4 Receiving an SMB2 NEGOTIATE Request
304 575 * "If a common dialect is not found, the server MUST fail
305 576 * the request with STATUS_NOT_SUPPORTED."
306 577 */
307 578 best_version = smb2_find_best_dialect(s, cl_versions, version_cnt);
308 579 if (best_version == 0) {
309 580 status = NT_STATUS_NOT_SUPPORTED;
310 581 goto errout;
311 582 }
583 + if (best_version >= 0x311) {
584 + if ((status = smb31_decode_neg_ctxs(sr, s)) != 0)
585 + goto errout;
586 + }
587 +
312 588 s->dialect = best_version;
313 589
314 590 /* Allow normal SMB2 requests now. */
315 591 s->s_state = SMB_SESSION_STATE_NEGOTIATED;
316 592 s->newrq_func = smb2sr_newrq;
317 593
318 594 if (smb2_negotiate_common(sr, best_version) != 0)
319 595 status = NT_STATUS_INTERNAL_ERROR;
320 596
321 597 errout:
322 598 sr->smb2_status = status;
323 599 DTRACE_SMB2_DONE(op__Negotiate, smb_request_t *, sr);
324 600
325 601 if (sr->smb2_status != 0)
326 602 smb2sr_put_error(sr, sr->smb2_status);
327 603 (void) smb2_encode_header(sr, B_TRUE);
328 604
605 + if (s->dialect >= SMB_VERS_3_11) {
606 + ASSERT3U(s->smb31_preauth_hashid, !=, 0);
607 + (void) smb31_preauth_sha512_calc(sr, &sr->reply,
608 + s->smb31_preauth_hashval);
609 + }
610 +
329 611 smb2_send_reply(sr);
330 612
331 613 return (rc);
332 614 }
333 615
334 616 /*
335 617 * Common parts of SMB2 Negotiate, used for both the
336 618 * SMB1-to-SMB2 style, and straight SMB2 style.
337 619 * Do negotiation decisions and encode the reply.
338 620 * The caller does the network send.
339 621 *
↓ open down ↓ |
1 lines elided |
↑ open up ↑ |
340 622 * Return value is 0 for success, else error.
341 623 */
342 624 static int
343 625 smb2_negotiate_common(smb_request_t *sr, uint16_t version)
344 626 {
345 627 timestruc_t boot_tv, now_tv;
346 628 smb_session_t *s = sr->session;
347 629 int rc;
348 630 uint32_t max_rwsize;
349 631 uint16_t secmode;
632 + uint16_t neg_ctx_cnt = 0;
633 + uint32_t neg_ctx_off = 0;
350 634
351 635 /*
352 636 * Negotiation itself. First the Security Mode.
353 637 */
354 638 secmode = SMB2_NEGOTIATE_SIGNING_ENABLED;
355 639 if (sr->sr_cfg->skc_signing_required)
356 640 secmode |= SMB2_NEGOTIATE_SIGNING_REQUIRED;
357 641 s->srv_secmode = secmode;
358 642
359 643 s->cmd_max_bytes = smb2_tcp_bufsize;
360 644 s->reply_max_bytes = smb2_tcp_bufsize;
361 645
362 646 /*
363 647 * "The number of credits held by the client MUST be considered
364 648 * as 1 when the connection is established." [MS-SMB2]
365 649 * We leave credits at 1 until the first successful
366 650 * session setup is completed.
367 651 */
368 652 s->s_cur_credits = s->s_max_credits = 1;
369 653 sr->smb2_credit_response = 1;
370 654
371 655 boot_tv.tv_sec = smb_get_boottime();
↓ open down ↓ |
12 lines elided |
↑ open up ↑ |
372 656 boot_tv.tv_nsec = 0;
373 657 now_tv.tv_sec = gethrestime_sec();
374 658 now_tv.tv_nsec = 0;
375 659
376 660 /*
377 661 * If the version is 0x2FF, we haven't completed negotiate.
378 662 * Don't initialize until we have our final request.
379 663 */
380 664 if (version != 0x2FF)
381 665 smb2_sign_init_mech(s);
666 + if (version >= 0x311)
667 + smb31_preauth_init_mech(s);
382 668
383 669 /*
384 670 * [MS-SMB2] 3.3.5.4 Receiving an SMB2 NEGOTIATE Request
385 671 *
386 672 * The SMB2.x capabilities are returned without regard for
387 673 * what capabilities the client provided in the request.
388 674 * The SMB3.x capabilities returned are the traditional
389 675 * logical AND of server and client capabilities.
390 676 *
391 677 * One additional check: If KCF is missing something we
392 678 * require for encryption, turn off that capability.
393 679 */
394 680 if (s->dialect < SMB_VERS_2_1) {
395 681 /* SMB 2.002 */
396 682 s->srv_cap = smb2srv_capabilities & SMB2_CAP_DFS;
↓ open down ↓ |
5 lines elided |
↑ open up ↑ |
397 683 } else if (s->dialect < SMB_VERS_3_0) {
398 684 /* SMB 2.x */
399 685 s->srv_cap = smb2srv_capabilities & SMB_2X_CAPS;
400 686 } else {
401 687 /* SMB 3.0 or later */
402 688 s->srv_cap = smb2srv_capabilities &
403 689 (SMB_2X_CAPS | s->capabilities);
404 690 if ((s->srv_cap & SMB2_CAP_ENCRYPTION) != 0 &&
405 691 smb3_encrypt_init_mech(s) != 0) {
406 692 s->srv_cap &= ~SMB2_CAP_ENCRYPTION;
693 + s->smb31_enc_cipherid = 0;
694 + }
695 +
696 + if (s->dialect >= SMB_VERS_3_11) {
697 + neg_ctx_cnt = s->smb31_enc_cipherid == 0 ? 1 : 2;
698 + neg_ctx_off = SMB2_HDR_SIZE + 64 +
699 + P2ROUNDUP(sr->sr_cfg->skc_negtok_len, 8);
700 +
701 + ASSERT3U(s->smb31_preauth_hashid, !=, 0);
702 + (void) smb31_preauth_sha512_calc(sr, &sr->command,
703 + s->smb31_preauth_hashval);
407 704 }
408 705 }
409 706
410 707 /*
411 708 * See notes above smb2_max_rwsize, smb2_old_rwsize
412 709 */
413 710 if (s->capabilities & SMB2_CAP_LARGE_MTU)
414 711 max_rwsize = smb2_max_rwsize;
415 712 else
416 713 max_rwsize = smb2_old_rwsize;
417 714
418 715 rc = smb_mbc_encodef(
419 716 &sr->reply,
420 717 "wwww#cllllTTwwl#c",
421 718 65, /* StructSize */ /* w */
422 719 s->srv_secmode, /* w */
423 720 version, /* w */
424 - 0, /* reserved */ /* w */
721 + neg_ctx_cnt, /* w */
425 722 UUID_LEN, /* # */
426 723 &s->s_cfg.skc_machine_uuid, /* c */
427 724 s->srv_cap, /* l */
428 725 smb2_max_trans, /* l */
429 726 max_rwsize, /* l */
430 727 max_rwsize, /* l */
431 728 &now_tv, /* T */
432 729 &boot_tv, /* T */
433 730 128, /* SecBufOff */ /* w */
434 731 sr->sr_cfg->skc_negtok_len, /* w */
435 - 0, /* reserved */ /* l */
732 + neg_ctx_off, /* l */
436 733 sr->sr_cfg->skc_negtok_len, /* # */
437 734 sr->sr_cfg->skc_negtok); /* c */
735 +
736 +
737 +
738 + if (neg_ctx_cnt) {
739 + rc = smb31_encode_neg_ctxs(sr, s);
740 + }
438 741
439 742 /* smb2_send_reply(sr); in caller */
440 743
441 744 (void) ksocket_setsockopt(s->sock, SOL_SOCKET,
442 745 SO_SNDBUF, (const void *)&smb2_tcp_bufsize,
443 746 sizeof (smb2_tcp_bufsize), CRED());
444 747 (void) ksocket_setsockopt(s->sock, SOL_SOCKET,
445 748 SO_RCVBUF, (const void *)&smb2_tcp_bufsize,
446 749 sizeof (smb2_tcp_bufsize), CRED());
447 750
448 751 return (rc);
449 752 }
450 753
451 754 /*
452 755 * SMB2 Dispatch table handler, which will run if we see an
453 756 * SMB2_NEGOTIATE after the initial negotiation is done.
454 757 * That would be a protocol error.
455 758 */
456 759 smb_sdrc_t
457 760 smb2_negotiate(smb_request_t *sr)
458 761 {
459 762 sr->smb2_status = NT_STATUS_INVALID_PARAMETER;
460 763 return (SDRC_ERROR);
461 764 }
462 765
463 766 /*
464 767 * VALIDATE_NEGOTIATE_INFO [MS-SMB2] 2.2.32.6
465 768 */
466 769 uint32_t
467 770 smb2_nego_validate(smb_request_t *sr, smb_fsctl_t *fsctl)
468 771 {
469 772 smb_session_t *s = sr->session;
470 773 int rc;
471 774
472 775 /*
473 776 * The spec. says to parse the VALIDATE_NEGOTIATE_INFO here
474 777 * and verify that the original negotiate was not modified.
475 778 * The request MUST be signed, and we MUST validate the signature.
476 779 *
477 780 * One interesting requirement here is that we MUST reply
478 781 * with exactly the same information as we returned in our
479 782 * original reply to the SMB2 negotiate on this session.
480 783 * If we don't the client closes the connection.
481 784 */
482 785
483 786 /* dialects[8] taken from cl_versions[8] in smb2_newrq_negotiate */
484 787 uint32_t capabilities;
485 788 uint16_t secmode, num_dialects, dialects[8];
486 789 uint8_t clnt_guid[16];
487 790
488 791 if ((sr->smb2_hdr_flags & SMB2_FLAGS_SIGNED) == 0)
489 792 goto drop;
490 793
491 794 if (fsctl->InputCount < 24)
492 795 goto drop;
493 796
494 797 (void) smb_mbc_decodef(fsctl->in_mbc, "l16cww",
495 798 &capabilities, /* l */
496 799 &clnt_guid, /* 16c */
497 800 &secmode, /* w */
498 801 &num_dialects); /* w */
499 802
500 803 if (num_dialects == 0 || num_dialects > 8)
501 804 goto drop;
502 805 if (secmode != s->cli_secmode)
503 806 goto drop;
504 807 if (capabilities != s->capabilities)
505 808 goto drop;
506 809 if (memcmp(clnt_guid, s->clnt_uuid, sizeof (clnt_guid)) != 0)
507 810 goto drop;
508 811
509 812 if (fsctl->InputCount < (24 + num_dialects * sizeof (*dialects)))
510 813 goto drop;
511 814
512 815 rc = smb_mbc_decodef(fsctl->in_mbc, "#w", num_dialects, dialects);
513 816 if (rc != 0)
514 817 goto drop;
515 818
516 819 if (smb2_find_best_dialect(s, dialects, num_dialects) != s->dialect)
517 820 goto drop;
518 821
519 822 rc = smb_mbc_encodef(
520 823 fsctl->out_mbc, "l#cww",
521 824 s->srv_cap, /* l */
522 825 UUID_LEN, /* # */
523 826 &s->s_cfg.skc_machine_uuid, /* c */
524 827 s->srv_secmode, /* w */
525 828 s->dialect); /* w */
526 829 if (rc == 0)
527 830 return (rc);
528 831
529 832 drop:
530 833 smb_session_disconnect(s);
531 834 return (NT_STATUS_ACCESS_DENIED);
532 835 }
↓ open down ↓ |
85 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX