1 /*
2 Unix SMB/Netbios implementation.
3 Version 3.0
4 handle NTLMSSP, server side
5
6 Copyright (C) Andrew Tridgell 2001
7 Copyright (C) Andrew Bartlett 2001-2010
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23 #include "includes.h"
24 #include <tevent.h>
25 #include "lib/util/tevent_ntstatus.h"
26 #include "lib/util/time_basic.h"
27 #include "auth/ntlmssp/ntlmssp.h"
28 #include "auth/ntlmssp/ntlmssp_private.h"
29 #include "../librpc/gen_ndr/ndr_ntlmssp.h"
30 #include "auth/ntlmssp/ntlmssp_ndr.h"
31 #include "../libcli/auth/libcli_auth.h"
32 #include "auth/gensec/gensec.h"
33 #include "auth/gensec/gensec_internal.h"
34 #include "auth/common_auth.h"
35 #include "param/param.h"
36 #include "param/loadparm.h"
37 #include "libcli/security/session.h"
38
39 #include "lib/crypto/gnutls_helpers.h"
40 #include <gnutls/gnutls.h>
41 #include <gnutls/crypto.h>
42
43 #undef DBGC_CLASS
44 #define DBGC_CLASS DBGC_AUTH
45
46 /**
47 * Determine correct target name flags for reply, given server role
48 * and negotiated flags
49 *
50 * @param ntlmssp_state NTLMSSP State
51 * @param neg_flags The flags from the packet
52 * @param chal_flags The flags to be set in the reply packet
53 * @return The 'target name' string.
54 */
55
ntlmssp_target_name(struct ntlmssp_state * ntlmssp_state,uint32_t neg_flags,uint32_t * chal_flags)56 const char *ntlmssp_target_name(struct ntlmssp_state *ntlmssp_state,
57 uint32_t neg_flags, uint32_t *chal_flags)
58 {
59 if (neg_flags & NTLMSSP_REQUEST_TARGET) {
60 *chal_flags |= NTLMSSP_NEGOTIATE_TARGET_INFO;
61 *chal_flags |= NTLMSSP_REQUEST_TARGET;
62 if (ntlmssp_state->server.is_standalone) {
63 *chal_flags |= NTLMSSP_TARGET_TYPE_SERVER;
64 return ntlmssp_state->server.netbios_name;
65 } else {
66 *chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN;
67 return ntlmssp_state->server.netbios_domain;
68 };
69 } else {
70 return "";
71 }
72 }
73
74 /**
75 * Next state function for the NTLMSSP Negotiate packet
76 *
77 * @param gensec_security GENSEC state
78 * @param out_mem_ctx Memory context for *out
79 * @param in The request, as a DATA_BLOB. reply.data must be NULL
80 * @param out The reply, as an allocated DATA_BLOB, caller to free.
81 * @return Errors or MORE_PROCESSING_REQUIRED if (normal) a reply is required.
82 */
83
gensec_ntlmssp_server_negotiate(struct gensec_security * gensec_security,TALLOC_CTX * out_mem_ctx,const DATA_BLOB request,DATA_BLOB * reply)84 NTSTATUS gensec_ntlmssp_server_negotiate(struct gensec_security *gensec_security,
85 TALLOC_CTX *out_mem_ctx,
86 const DATA_BLOB request, DATA_BLOB *reply)
87 {
88 struct gensec_ntlmssp_context *gensec_ntlmssp =
89 talloc_get_type_abort(gensec_security->private_data,
90 struct gensec_ntlmssp_context);
91 struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
92 struct auth4_context *auth_context = gensec_security->auth_context;
93 DATA_BLOB struct_blob;
94 uint32_t neg_flags = 0;
95 uint32_t ntlmssp_command, chal_flags;
96 uint8_t cryptkey[8];
97 const char *target_name;
98 NTSTATUS status;
99 struct timeval tv_now = timeval_current();
100 /*
101 * See [MS-NLMP]
102 *
103 * Windows NT 4.0, windows_2000: use 30 minutes,
104 * Windows XP, Windows Server 2003, Windows Vista,
105 * Windows Server 2008, Windows 7, and Windows Server 2008 R2
106 * use 36 hours.
107 *
108 * Newer systems doesn't check this, likely because the
109 * connectionless NTLMSSP is no longer supported.
110 *
111 * As we expect the AUTHENTICATION_MESSAGE to arrive
112 * directly after the NEGOTIATE_MESSAGE (typically less than
113 * as 1 second later). We use a hard timeout of 30 Minutes.
114 *
115 * We don't look at AUTHENTICATE_MESSAGE.NtChallengeResponse.TimeStamp
116 * instead we just remember our own time.
117 */
118 uint32_t max_lifetime = 30 * 60;
119 struct timeval tv_end = timeval_add(&tv_now, max_lifetime, 0);
120
121 /* parse the NTLMSSP packet */
122 #if 0
123 file_save("ntlmssp_negotiate.dat", request.data, request.length);
124 #endif
125
126 if (request.length) {
127 if (request.length > UINT16_MAX) {
128 DEBUG(1, ("ntlmssp_server_negotiate: reject large request of length %u\n",
129 (unsigned int)request.length));
130 return NT_STATUS_INVALID_PARAMETER;
131 }
132
133 if ((request.length < 16) || !msrpc_parse(ntlmssp_state, &request, "Cdd",
134 "NTLMSSP",
135 &ntlmssp_command,
136 &neg_flags)) {
137 DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP Negotiate of length %u\n",
138 (unsigned int)request.length));
139 dump_data(2, request.data, request.length);
140 return NT_STATUS_INVALID_PARAMETER;
141 }
142 debug_ntlmssp_flags(neg_flags);
143
144 if (DEBUGLEVEL >= 10) {
145 struct NEGOTIATE_MESSAGE *negotiate = talloc(
146 ntlmssp_state, struct NEGOTIATE_MESSAGE);
147 if (negotiate != NULL) {
148 status = ntlmssp_pull_NEGOTIATE_MESSAGE(
149 &request, negotiate, negotiate);
150 if (NT_STATUS_IS_OK(status)) {
151 NDR_PRINT_DEBUG(NEGOTIATE_MESSAGE,
152 negotiate);
153 }
154 TALLOC_FREE(negotiate);
155 }
156 }
157 }
158
159 status = ntlmssp_handle_neg_flags(ntlmssp_state, neg_flags, "negotiate");
160 if (!NT_STATUS_IS_OK(status)){
161 return status;
162 }
163
164 /* Ask our caller what challenge they would like in the packet */
165 if (auth_context->get_ntlm_challenge) {
166 status = auth_context->get_ntlm_challenge(auth_context, cryptkey);
167 if (!NT_STATUS_IS_OK(status)) {
168 DEBUG(1, ("gensec_ntlmssp_server_negotiate: failed to get challenge: %s\n",
169 nt_errstr(status)));
170 return status;
171 }
172 } else {
173 DEBUG(1, ("gensec_ntlmssp_server_negotiate: backend doesn't give a challenge\n"));
174 return NT_STATUS_NOT_IMPLEMENTED;
175 }
176
177 /* The flags we send back are not just the negotiated flags,
178 * they are also 'what is in this packet'. Therfore, we
179 * operate on 'chal_flags' from here on
180 */
181
182 chal_flags = ntlmssp_state->neg_flags;
183 ntlmssp_state->server.challenge_endtime = timeval_to_nttime(&tv_end);
184
185 /* get the right name to fill in as 'target' */
186 target_name = ntlmssp_target_name(ntlmssp_state,
187 neg_flags, &chal_flags);
188 if (target_name == NULL)
189 return NT_STATUS_INVALID_PARAMETER;
190
191 ntlmssp_state->chal = data_blob_talloc(ntlmssp_state, cryptkey, 8);
192 ntlmssp_state->internal_chal = data_blob_talloc(ntlmssp_state,
193 cryptkey, 8);
194
195 /* This creates the 'blob' of names that appears at the end of the packet */
196 if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) {
197 enum ndr_err_code err;
198 struct AV_PAIR *pairs = NULL;
199 uint32_t count = 5;
200
201 pairs = talloc_zero_array(ntlmssp_state, struct AV_PAIR, count + 1);
202 if (pairs == NULL) {
203 return NT_STATUS_NO_MEMORY;
204 }
205
206 pairs[0].AvId = MsvAvNbDomainName;
207 pairs[0].Value.AvNbDomainName = target_name;
208
209 pairs[1].AvId = MsvAvNbComputerName;
210 pairs[1].Value.AvNbComputerName = ntlmssp_state->server.netbios_name;
211
212 pairs[2].AvId = MsvAvDnsDomainName;
213 pairs[2].Value.AvDnsDomainName = ntlmssp_state->server.dns_domain;
214
215 pairs[3].AvId = MsvAvDnsComputerName;
216 pairs[3].Value.AvDnsComputerName= ntlmssp_state->server.dns_name;
217
218 if (!ntlmssp_state->force_old_spnego) {
219 pairs[4].AvId = MsvAvTimestamp;
220 pairs[4].Value.AvTimestamp =
221 timeval_to_nttime(&tv_now);
222 count += 1;
223
224 pairs[5].AvId = MsvAvEOL;
225 } else {
226 pairs[4].AvId = MsvAvEOL;
227 }
228
229 ntlmssp_state->server.av_pair_list.count = count;
230 ntlmssp_state->server.av_pair_list.pair = pairs;
231
232 err = ndr_push_struct_blob(&struct_blob,
233 ntlmssp_state,
234 &ntlmssp_state->server.av_pair_list,
235 (ndr_push_flags_fn_t)ndr_push_AV_PAIR_LIST);
236 if (!NDR_ERR_CODE_IS_SUCCESS(err)) {
237 return NT_STATUS_NO_MEMORY;
238 }
239 } else {
240 struct_blob = data_blob_null;
241 }
242
243 {
244 /* Marshal the packet in the right format, be it unicode or ASCII */
245 const char *gen_string;
246 const DATA_BLOB version_blob = ntlmssp_version_blob();
247
248 if (ntlmssp_state->unicode) {
249 gen_string = "CdUdbddBb";
250 } else {
251 gen_string = "CdAdbddBb";
252 }
253
254 status = msrpc_gen(out_mem_ctx, reply, gen_string,
255 "NTLMSSP",
256 NTLMSSP_CHALLENGE,
257 target_name,
258 chal_flags,
259 cryptkey, 8,
260 0, 0,
261 struct_blob.data, struct_blob.length,
262 version_blob.data, version_blob.length);
263
264 if (!NT_STATUS_IS_OK(status)) {
265 data_blob_free(&struct_blob);
266 return status;
267 }
268
269 if (DEBUGLEVEL >= 10) {
270 struct CHALLENGE_MESSAGE *challenge = talloc(
271 ntlmssp_state, struct CHALLENGE_MESSAGE);
272 if (challenge != NULL) {
273 challenge->NegotiateFlags = chal_flags;
274 status = ntlmssp_pull_CHALLENGE_MESSAGE(
275 reply, challenge, challenge);
276 if (NT_STATUS_IS_OK(status)) {
277 NDR_PRINT_DEBUG(CHALLENGE_MESSAGE,
278 challenge);
279 }
280 TALLOC_FREE(challenge);
281 }
282 }
283 }
284
285 data_blob_free(&struct_blob);
286
287 ntlmssp_state->negotiate_blob = data_blob_dup_talloc(ntlmssp_state,
288 request);
289 if (ntlmssp_state->negotiate_blob.length != request.length) {
290 return NT_STATUS_NO_MEMORY;
291 }
292
293 ntlmssp_state->challenge_blob = data_blob_dup_talloc(ntlmssp_state,
294 *reply);
295 if (ntlmssp_state->challenge_blob.length != reply->length) {
296 return NT_STATUS_NO_MEMORY;
297 }
298
299 ntlmssp_state->expected_state = NTLMSSP_AUTH;
300
301 return NT_STATUS_MORE_PROCESSING_REQUIRED;
302 }
303
304 struct ntlmssp_server_auth_state {
305 struct gensec_security *gensec_security;
306 struct gensec_ntlmssp_context *gensec_ntlmssp;
307 DATA_BLOB in;
308 struct auth_usersupplied_info *user_info;
309 DATA_BLOB user_session_key;
310 DATA_BLOB lm_session_key;
311 /* internal variables used by KEY_EXCH (client-supplied user session key */
312 DATA_BLOB encrypted_session_key;
313 bool doing_ntlm2;
314 /* internal variables used by NTLM2 */
315 uint8_t session_nonce[16];
316 };
317
318 static NTSTATUS ntlmssp_server_preauth(struct gensec_security *gensec_security,
319 struct gensec_ntlmssp_context *gensec_ntlmssp,
320 struct ntlmssp_server_auth_state *state,
321 const DATA_BLOB request);
322 static void ntlmssp_server_auth_done(struct tevent_req *subreq);
323 static NTSTATUS ntlmssp_server_postauth(struct gensec_security *gensec_security,
324 struct gensec_ntlmssp_context *gensec_ntlmssp,
325 struct ntlmssp_server_auth_state *state,
326 DATA_BLOB request);
327
ntlmssp_server_auth_send(TALLOC_CTX * mem_ctx,struct tevent_context * ev,struct gensec_security * gensec_security,const DATA_BLOB in)328 struct tevent_req *ntlmssp_server_auth_send(TALLOC_CTX *mem_ctx,
329 struct tevent_context *ev,
330 struct gensec_security *gensec_security,
331 const DATA_BLOB in)
332 {
333 struct gensec_ntlmssp_context *gensec_ntlmssp =
334 talloc_get_type_abort(gensec_security->private_data,
335 struct gensec_ntlmssp_context);
336 struct auth4_context *auth_context = gensec_security->auth_context;
337 struct tevent_req *req = NULL;
338 struct tevent_req *subreq = NULL;
339 struct ntlmssp_server_auth_state *state = NULL;
340 NTSTATUS status;
341
342 req = tevent_req_create(mem_ctx, &state,
343 struct ntlmssp_server_auth_state);
344 if (req == NULL) {
345 return NULL;
346 }
347 state->gensec_security = gensec_security;
348 state->gensec_ntlmssp = gensec_ntlmssp;
349 state->in = in;
350
351 status = ntlmssp_server_preauth(gensec_security,
352 gensec_ntlmssp,
353 state, in);
354 if (tevent_req_nterror(req, status)) {
355 return tevent_req_post(req, ev);
356 }
357
358 subreq = auth_context->check_ntlm_password_send(
359 state, ev, auth_context, state->user_info);
360 if (tevent_req_nomem(subreq, req)) {
361 return tevent_req_post(req, ev);
362 }
363 tevent_req_set_callback(subreq, ntlmssp_server_auth_done, req);
364 return req;
365 }
366
367 /**
368 * Next state function for the Authenticate packet
369 *
370 * @param ntlmssp_state NTLMSSP State
371 * @param request The request, as a DATA_BLOB
372 * @return Errors or NT_STATUS_OK.
373 */
374
ntlmssp_server_preauth(struct gensec_security * gensec_security,struct gensec_ntlmssp_context * gensec_ntlmssp,struct ntlmssp_server_auth_state * state,const DATA_BLOB request)375 static NTSTATUS ntlmssp_server_preauth(struct gensec_security *gensec_security,
376 struct gensec_ntlmssp_context *gensec_ntlmssp,
377 struct ntlmssp_server_auth_state *state,
378 const DATA_BLOB request)
379 {
380 struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
381 struct auth4_context *auth_context = gensec_security->auth_context;
382 struct auth_usersupplied_info *user_info = NULL;
383 uint32_t ntlmssp_command, auth_flags;
384 NTSTATUS nt_status;
385 const unsigned int version_len = 8;
386 DATA_BLOB version_blob = data_blob_null;
387 const unsigned int mic_len = NTLMSSP_MIC_SIZE;
388 DATA_BLOB mic_blob = data_blob_null;
389 const char *parse_string;
390 bool ok;
391 struct timeval endtime;
392 bool expired = false;
393
394 #if 0
395 file_save("ntlmssp_auth.dat", request.data, request.length);
396 #endif
397
398 if (ntlmssp_state->unicode) {
399 parse_string = "CdBBUUUBdbb";
400 } else {
401 parse_string = "CdBBAAABdbb";
402 }
403
404 /* zero these out */
405 data_blob_free(&ntlmssp_state->session_key);
406 data_blob_free(&ntlmssp_state->lm_resp);
407 data_blob_free(&ntlmssp_state->nt_resp);
408
409 ntlmssp_state->user = NULL;
410 ntlmssp_state->domain = NULL;
411 ntlmssp_state->client.netbios_name = NULL;
412
413 /* now the NTLMSSP encoded auth hashes */
414 ok = msrpc_parse(ntlmssp_state, &request, parse_string,
415 "NTLMSSP",
416 &ntlmssp_command,
417 &ntlmssp_state->lm_resp,
418 &ntlmssp_state->nt_resp,
419 &ntlmssp_state->domain,
420 &ntlmssp_state->user,
421 &ntlmssp_state->client.netbios_name,
422 &state->encrypted_session_key,
423 &auth_flags,
424 &version_blob, version_len,
425 &mic_blob, mic_len);
426 if (!ok) {
427 DEBUG(10, ("ntlmssp_server_auth: failed to parse NTLMSSP (nonfatal):\n"));
428 dump_data(10, request.data, request.length);
429
430 data_blob_free(&version_blob);
431 data_blob_free(&mic_blob);
432
433 if (ntlmssp_state->unicode) {
434 parse_string = "CdBBUUUBd";
435 } else {
436 parse_string = "CdBBAAABd";
437 }
438
439 ok = msrpc_parse(ntlmssp_state, &request, parse_string,
440 "NTLMSSP",
441 &ntlmssp_command,
442 &ntlmssp_state->lm_resp,
443 &ntlmssp_state->nt_resp,
444 &ntlmssp_state->domain,
445 &ntlmssp_state->user,
446 &ntlmssp_state->client.netbios_name,
447 &state->encrypted_session_key,
448 &auth_flags);
449 }
450
451 if (!ok) {
452 DEBUG(10, ("ntlmssp_server_auth: failed to parse NTLMSSP (nonfatal):\n"));
453 dump_data(10, request.data, request.length);
454
455 /* zero this out */
456 data_blob_free(&state->encrypted_session_key);
457 auth_flags = 0;
458
459 /* Try again with a shorter string (Win9X truncates this packet) */
460 if (ntlmssp_state->unicode) {
461 parse_string = "CdBBUUU";
462 } else {
463 parse_string = "CdBBAAA";
464 }
465
466 /* now the NTLMSSP encoded auth hashes */
467 if (!msrpc_parse(ntlmssp_state, &request, parse_string,
468 "NTLMSSP",
469 &ntlmssp_command,
470 &ntlmssp_state->lm_resp,
471 &ntlmssp_state->nt_resp,
472 &ntlmssp_state->domain,
473 &ntlmssp_state->user,
474 &ntlmssp_state->client.netbios_name)) {
475 DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP (tried both formats):\n"));
476 dump_data(2, request.data, request.length);
477
478 return NT_STATUS_INVALID_PARAMETER;
479 }
480 }
481
482 talloc_steal(state, state->encrypted_session_key.data);
483
484 if (auth_flags != 0) {
485 nt_status = ntlmssp_handle_neg_flags(ntlmssp_state,
486 auth_flags,
487 "authenticate");
488 if (!NT_STATUS_IS_OK(nt_status)){
489 return nt_status;
490 }
491 }
492
493 if (DEBUGLEVEL >= 10) {
494 struct AUTHENTICATE_MESSAGE *authenticate = talloc(
495 ntlmssp_state, struct AUTHENTICATE_MESSAGE);
496 if (authenticate != NULL) {
497 NTSTATUS status;
498 authenticate->NegotiateFlags = auth_flags;
499 status = ntlmssp_pull_AUTHENTICATE_MESSAGE(
500 &request, authenticate, authenticate);
501 if (NT_STATUS_IS_OK(status)) {
502 NDR_PRINT_DEBUG(AUTHENTICATE_MESSAGE,
503 authenticate);
504 }
505 TALLOC_FREE(authenticate);
506 }
507 }
508
509 DEBUG(3,("Got user=[%s] domain=[%s] workstation=[%s] len1=%lu len2=%lu\n",
510 ntlmssp_state->user, ntlmssp_state->domain,
511 ntlmssp_state->client.netbios_name,
512 (unsigned long)ntlmssp_state->lm_resp.length,
513 (unsigned long)ntlmssp_state->nt_resp.length));
514
515 #if 0
516 file_save("nthash1.dat", &ntlmssp_state->nt_resp.data, &ntlmssp_state->nt_resp.length);
517 file_save("lmhash1.dat", &ntlmssp_state->lm_resp.data, &ntlmssp_state->lm_resp.length);
518 #endif
519
520 if (ntlmssp_state->nt_resp.length > 24) {
521 struct NTLMv2_RESPONSE v2_resp;
522 enum ndr_err_code err;
523 uint32_t i = 0;
524 uint32_t count = 0;
525 const struct AV_PAIR *flags = NULL;
526 const struct AV_PAIR *eol = NULL;
527 uint32_t av_flags = 0;
528
529 err = ndr_pull_struct_blob(&ntlmssp_state->nt_resp,
530 ntlmssp_state,
531 &v2_resp,
532 (ndr_pull_flags_fn_t)ndr_pull_NTLMv2_RESPONSE);
533 if (!NDR_ERR_CODE_IS_SUCCESS(err)) {
534 nt_status = ndr_map_error2ntstatus(err);
535 DEBUG(1,("%s: failed to parse NTLMv2_RESPONSE of length %zu for "
536 "user=[%s] domain=[%s] workstation=[%s] - %s %s\n",
537 __func__, ntlmssp_state->nt_resp.length,
538 ntlmssp_state->user, ntlmssp_state->domain,
539 ntlmssp_state->client.netbios_name,
540 ndr_errstr(err), nt_errstr(nt_status)));
541 return nt_status;
542 }
543
544 if (DEBUGLVL(10)) {
545 NDR_PRINT_DEBUG(NTLMv2_RESPONSE, &v2_resp);
546 }
547
548 eol = ndr_ntlmssp_find_av(&v2_resp.Challenge.AvPairs,
549 MsvAvEOL);
550 if (eol == NULL) {
551 DEBUG(1,("%s: missing MsvAvEOL for "
552 "user=[%s] domain=[%s] workstation=[%s]\n",
553 __func__, ntlmssp_state->user, ntlmssp_state->domain,
554 ntlmssp_state->client.netbios_name));
555 return NT_STATUS_INVALID_PARAMETER;
556 }
557
558 flags = ndr_ntlmssp_find_av(&v2_resp.Challenge.AvPairs,
559 MsvAvFlags);
560 if (flags != NULL) {
561 av_flags = flags->Value.AvFlags;
562 }
563
564 if (av_flags & NTLMSSP_AVFLAG_MIC_IN_AUTHENTICATE_MESSAGE) {
565 if (mic_blob.length != NTLMSSP_MIC_SIZE) {
566 DEBUG(1,("%s: mic_blob.length[%u] for "
567 "user=[%s] domain=[%s] workstation=[%s]\n",
568 __func__,
569 (unsigned)mic_blob.length,
570 ntlmssp_state->user,
571 ntlmssp_state->domain,
572 ntlmssp_state->client.netbios_name));
573 return NT_STATUS_INVALID_PARAMETER;
574 }
575
576 if (request.length <
577 (NTLMSSP_MIC_OFFSET + NTLMSSP_MIC_SIZE))
578 {
579 DEBUG(1,("%s: missing MIC "
580 "request.length[%u] for "
581 "user=[%s] domain=[%s] workstation=[%s]\n",
582 __func__,
583 (unsigned)request.length,
584 ntlmssp_state->user,
585 ntlmssp_state->domain,
586 ntlmssp_state->client.netbios_name));
587 return NT_STATUS_INVALID_PARAMETER;
588 }
589
590 ntlmssp_state->new_spnego = true;
591 }
592
593 count = ntlmssp_state->server.av_pair_list.count;
594 if (v2_resp.Challenge.AvPairs.count < count) {
595 return NT_STATUS_INVALID_PARAMETER;
596 }
597
598 for (i = 0; i < count; i++) {
599 const struct AV_PAIR *sp =
600 &ntlmssp_state->server.av_pair_list.pair[i];
601 const struct AV_PAIR *cp = NULL;
602
603 if (sp->AvId == MsvAvEOL) {
604 continue;
605 }
606
607 cp = ndr_ntlmssp_find_av(&v2_resp.Challenge.AvPairs,
608 sp->AvId);
609 if (cp == NULL) {
610 DEBUG(1,("%s: AvId 0x%x missing for"
611 "user=[%s] domain=[%s] "
612 "workstation=[%s]\n",
613 __func__,
614 (unsigned)sp->AvId,
615 ntlmssp_state->user,
616 ntlmssp_state->domain,
617 ntlmssp_state->client.netbios_name));
618 return NT_STATUS_INVALID_PARAMETER;
619 }
620
621 switch (cp->AvId) {
622 #define CASE_STRING(v) case Msv ## v: do { \
623 int cmp; \
624 if (sp->Value.v == NULL) { \
625 return NT_STATUS_INTERNAL_ERROR; \
626 } \
627 if (cp->Value.v == NULL) { \
628 DEBUG(1,("%s: invalid %s " \
629 "got[%s] expect[%s] for " \
630 "user=[%s] domain=[%s] workstation=[%s]\n", \
631 __func__, #v, \
632 cp->Value.v, \
633 sp->Value.v, \
634 ntlmssp_state->user, \
635 ntlmssp_state->domain, \
636 ntlmssp_state->client.netbios_name)); \
637 return NT_STATUS_INVALID_PARAMETER; \
638 } \
639 cmp = strcmp(cp->Value.v, sp->Value.v); \
640 if (cmp != 0) { \
641 DEBUG(1,("%s: invalid %s " \
642 "got[%s] expect[%s] for " \
643 "user=[%s] domain=[%s] workstation=[%s]\n", \
644 __func__, #v, \
645 cp->Value.v, \
646 sp->Value.v, \
647 ntlmssp_state->user, \
648 ntlmssp_state->domain, \
649 ntlmssp_state->client.netbios_name)); \
650 return NT_STATUS_INVALID_PARAMETER; \
651 } \
652 } while(0); break
653 CASE_STRING(AvNbComputerName);
654 CASE_STRING(AvNbDomainName);
655 CASE_STRING(AvDnsComputerName);
656 CASE_STRING(AvDnsDomainName);
657 CASE_STRING(AvDnsTreeName);
658 case MsvAvTimestamp:
659 if (cp->Value.AvTimestamp != sp->Value.AvTimestamp) {
660 struct timeval ct;
661 struct timeval st;
662 struct timeval_buf tmp1;
663 struct timeval_buf tmp2;
664
665 nttime_to_timeval(&ct,
666 cp->Value.AvTimestamp);
667 nttime_to_timeval(&st,
668 sp->Value.AvTimestamp);
669
670 DEBUG(1,("%s: invalid AvTimestamp "
671 "got[%s] expect[%s] for "
672 "user=[%s] domain=[%s] "
673 "workstation=[%s]\n",
674 __func__,
675 timeval_str_buf(&ct, false,
676 true, &tmp1),
677 timeval_str_buf(&st, false,
678 true, &tmp2),
679 ntlmssp_state->user,
680 ntlmssp_state->domain,
681 ntlmssp_state->client.netbios_name));
682 return NT_STATUS_INVALID_PARAMETER;
683 }
684 break;
685 default:
686 /*
687 * This can't happen as we control
688 * ntlmssp_state->server.av_pair_list
689 */
690 return NT_STATUS_INTERNAL_ERROR;
691 }
692 }
693 }
694
695 nttime_to_timeval(&endtime, ntlmssp_state->server.challenge_endtime);
696 expired = timeval_expired(&endtime);
697 if (expired) {
698 struct timeval_buf tmp;
699 DEBUG(1,("%s: challenge invalid (expired %s) for "
700 "user=[%s] domain=[%s] workstation=[%s]\n",
701 __func__,
702 timeval_str_buf(&endtime, false, true, &tmp),
703 ntlmssp_state->user, ntlmssp_state->domain,
704 ntlmssp_state->client.netbios_name));
705 return NT_STATUS_INVALID_PARAMETER;
706 }
707
708 /* NTLM2 uses a 'challenge' that is made of up both the server challenge, and a
709 client challenge
710
711 However, the NTLM2 flag may still be set for the real NTLMv2 logins, be careful.
712 */
713 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
714 if (ntlmssp_state->nt_resp.length == 24 && ntlmssp_state->lm_resp.length == 24) {
715 state->doing_ntlm2 = true;
716
717 memcpy(state->session_nonce, ntlmssp_state->internal_chal.data, 8);
718 memcpy(&state->session_nonce[8], ntlmssp_state->lm_resp.data, 8);
719
720 SMB_ASSERT(ntlmssp_state->internal_chal.data && ntlmssp_state->internal_chal.length == 8);
721
722 /* LM response is no longer useful */
723 data_blob_free(&ntlmssp_state->lm_resp);
724
725 /* We changed the effective challenge - set it */
726 if (auth_context->set_ntlm_challenge) {
727 uint8_t session_nonce_hash[16];
728 int rc;
729
730 rc = gnutls_hash_fast(GNUTLS_DIG_MD5,
731 state->session_nonce,
732 16,
733 session_nonce_hash);
734 if (rc < 0) {
735 return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
736 }
737
738
739 nt_status = auth_context->set_ntlm_challenge(auth_context,
740 session_nonce_hash,
741 "NTLMSSP callback (NTLM2)");
742 ZERO_ARRAY(session_nonce_hash);
743 if (!NT_STATUS_IS_OK(nt_status)) {
744 DEBUG(1, ("gensec_ntlmssp_server_negotiate: failed to get challenge: %s\n",
745 nt_errstr(nt_status)));
746 return nt_status;
747 }
748 } else {
749 DEBUG(1, ("gensec_ntlmssp_server_negotiate: backend doesn't have facility for challenge to be set\n"));
750
751 return NT_STATUS_NOT_IMPLEMENTED;
752 }
753
754 /* LM Key is incompatible. */
755 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
756 }
757 }
758
759 user_info = talloc_zero(state, struct auth_usersupplied_info);
760 if (!user_info) {
761 return NT_STATUS_NO_MEMORY;
762 }
763
764 user_info->logon_parameters = MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT | MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
765 user_info->flags = 0;
766 user_info->mapped_state = false;
767 user_info->client.account_name = ntlmssp_state->user;
768 user_info->client.domain_name = ntlmssp_state->domain;
769 user_info->workstation_name = ntlmssp_state->client.netbios_name;
770 user_info->remote_host = gensec_get_remote_address(gensec_security);
771 user_info->local_host = gensec_get_local_address(gensec_security);
772 user_info->service_description
773 = gensec_get_target_service_description(gensec_security);
774
775 /*
776 * This will just be the string "NTLMSSP" from
777 * gensec_ntlmssp_final_auth_type, but ensures it stays in sync
778 * with the same use in the authorization logging triggered by
779 * gensec_session_info() later
780 */
781 user_info->auth_description = gensec_final_auth_type(gensec_security);
782
783 user_info->password_state = AUTH_PASSWORD_RESPONSE;
784 user_info->password.response.lanman = ntlmssp_state->lm_resp;
785 user_info->password.response.nt = ntlmssp_state->nt_resp;
786
787 state->user_info = user_info;
788 return NT_STATUS_OK;
789 }
790
ntlmssp_server_auth_done(struct tevent_req * subreq)791 static void ntlmssp_server_auth_done(struct tevent_req *subreq)
792 {
793 struct tevent_req *req =
794 tevent_req_callback_data(subreq,
795 struct tevent_req);
796 struct ntlmssp_server_auth_state *state =
797 tevent_req_data(req,
798 struct ntlmssp_server_auth_state);
799 struct gensec_security *gensec_security = state->gensec_security;
800 struct gensec_ntlmssp_context *gensec_ntlmssp = state->gensec_ntlmssp;
801 struct auth4_context *auth_context = gensec_security->auth_context;
802 uint8_t authoritative = 0;
803 NTSTATUS status;
804
805 status = auth_context->check_ntlm_password_recv(subreq,
806 gensec_ntlmssp,
807 &authoritative,
808 &gensec_ntlmssp->server_returned_info,
809 &state->user_session_key,
810 &state->lm_session_key);
811 TALLOC_FREE(subreq);
812 if (!NT_STATUS_IS_OK(status)) {
813 DBG_INFO("Checking NTLMSSP password for %s\\%s failed: %s\n",
814 state->user_info->client.domain_name,
815 state->user_info->client.account_name,
816 nt_errstr(status));
817 }
818 if (tevent_req_nterror(req, status)) {
819 return;
820 }
821 talloc_steal(state, state->user_session_key.data);
822 talloc_steal(state, state->lm_session_key.data);
823
824 status = ntlmssp_server_postauth(state->gensec_security,
825 state->gensec_ntlmssp,
826 state, state->in);
827 if (tevent_req_nterror(req, status)) {
828 return;
829 }
830
831 tevent_req_done(req);
832 }
833
834 /**
835 * Next state function for the Authenticate packet
836 * (after authentication - figures out the session keys etc)
837 *
838 * @param ntlmssp_state NTLMSSP State
839 * @return Errors or NT_STATUS_OK.
840 */
841
ntlmssp_server_postauth(struct gensec_security * gensec_security,struct gensec_ntlmssp_context * gensec_ntlmssp,struct ntlmssp_server_auth_state * state,DATA_BLOB request)842 static NTSTATUS ntlmssp_server_postauth(struct gensec_security *gensec_security,
843 struct gensec_ntlmssp_context *gensec_ntlmssp,
844 struct ntlmssp_server_auth_state *state,
845 DATA_BLOB request)
846 {
847 struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
848 struct auth4_context *auth_context = gensec_security->auth_context;
849 DATA_BLOB user_session_key = state->user_session_key;
850 DATA_BLOB lm_session_key = state->lm_session_key;
851 NTSTATUS nt_status = NT_STATUS_OK;
852 DATA_BLOB session_key = data_blob(NULL, 0);
853 struct auth_session_info *session_info = NULL;
854
855 TALLOC_FREE(state->user_info);
856
857 if (lpcfg_map_to_guest(gensec_security->settings->lp_ctx) != NEVER_MAP_TO_GUEST
858 && auth_context->generate_session_info != NULL)
859 {
860 NTSTATUS tmp_status;
861
862 /*
863 * We need to check if the auth is anonymous or mapped to guest
864 */
865 tmp_status = auth_context->generate_session_info(auth_context, state,
866 gensec_ntlmssp->server_returned_info,
867 gensec_ntlmssp->ntlmssp_state->user,
868 AUTH_SESSION_INFO_SIMPLE_PRIVILEGES,
869 &session_info);
870 if (!NT_STATUS_IS_OK(tmp_status)) {
871 /*
872 * We don't care about failures,
873 * the worst result is that we try MIC checking
874 * for a map to guest authentication.
875 */
876 TALLOC_FREE(session_info);
877 }
878 }
879
880 if (session_info != NULL) {
881 if (security_session_user_level(session_info, NULL) < SECURITY_USER) {
882 /*
883 * Anonymous and GUEST are not secure anyway.
884 * avoid new_spnego and MIC checking.
885 */
886 ntlmssp_state->new_spnego = false;
887 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SIGN;
888 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SEAL;
889 }
890 TALLOC_FREE(session_info);
891 }
892
893 dump_data_pw("NT session key:\n", user_session_key.data, user_session_key.length);
894 dump_data_pw("LM first-8:\n", lm_session_key.data, lm_session_key.length);
895
896 /* Handle the different session key derivation for NTLM2 */
897 if (state->doing_ntlm2) {
898 if (user_session_key.data && user_session_key.length == 16) {
899 int rc;
900
901 session_key = data_blob_talloc(ntlmssp_state,
902 NULL, 16);
903
904 rc = gnutls_hmac_fast(GNUTLS_MAC_MD5,
905 user_session_key.data,
906 user_session_key.length,
907 state->session_nonce,
908 sizeof(state->session_nonce),
909 session_key.data);
910 if (rc < 0) {
911 return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
912 }
913
914 DEBUG(10,("ntlmssp_server_auth: Created NTLM2 session key.\n"));
915 dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
916
917 } else {
918 DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM2 session key.\n"));
919 session_key = data_blob_null;
920 }
921 } else if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
922 /* Ensure we can never get here on NTLMv2 */
923 && (ntlmssp_state->nt_resp.length == 0 || ntlmssp_state->nt_resp.length == 24)) {
924
925 if (lm_session_key.data && lm_session_key.length >= 8) {
926 if (ntlmssp_state->lm_resp.data && ntlmssp_state->lm_resp.length == 24) {
927 session_key = data_blob_talloc(ntlmssp_state,
928 NULL, 16);
929 if (session_key.data == NULL) {
930 return NT_STATUS_NO_MEMORY;
931 }
932 nt_status = SMBsesskeygen_lm_sess_key(lm_session_key.data,
933 ntlmssp_state->lm_resp.data,
934 session_key.data);
935 if (!NT_STATUS_IS_OK(nt_status)) {
936 return nt_status;
937 }
938 DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
939 } else {
940 static const uint8_t zeros[24] = {0, };
941 session_key = data_blob_talloc(
942 ntlmssp_state, NULL, 16);
943 if (session_key.data == NULL) {
944 return NT_STATUS_NO_MEMORY;
945 }
946 nt_status = SMBsesskeygen_lm_sess_key(zeros, zeros,
947 session_key.data);
948 if (!NT_STATUS_IS_OK(nt_status)) {
949 return nt_status;
950 }
951 DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
952 }
953 dump_data_pw("LM session key:\n", session_key.data,
954 session_key.length);
955 } else {
956 /* LM Key not selected */
957 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
958
959 DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM session key.\n"));
960 session_key = data_blob_null;
961 }
962
963 } else if (user_session_key.data) {
964 session_key = user_session_key;
965 DEBUG(10,("ntlmssp_server_auth: Using unmodified nt session key.\n"));
966 dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
967
968 /* LM Key not selected */
969 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
970
971 } else if (lm_session_key.data) {
972 /* Very weird to have LM key, but no user session key, but anyway.. */
973 session_key = lm_session_key;
974 DEBUG(10,("ntlmssp_server_auth: Using unmodified lm session key.\n"));
975 dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
976
977 /* LM Key not selected */
978 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
979
980 } else {
981 DEBUG(10,("ntlmssp_server_auth: Failed to create unmodified session key.\n"));
982 session_key = data_blob_null;
983
984 /* LM Key not selected */
985 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
986 }
987
988 /* With KEY_EXCH, the client supplies the proposed session key,
989 but encrypts it with the long-term key */
990 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
991 if (!state->encrypted_session_key.data
992 || state->encrypted_session_key.length != 16) {
993 DEBUG(1, ("Client-supplied KEY_EXCH session key was of invalid length (%u)!\n",
994 (unsigned)state->encrypted_session_key.length));
995 return NT_STATUS_INVALID_PARAMETER;
996 } else if (!session_key.data || session_key.length != 16) {
997 DEBUG(5, ("server session key is invalid (len == %u), cannot do KEY_EXCH!\n",
998 (unsigned int)session_key.length));
999 ntlmssp_state->session_key = session_key;
1000 talloc_steal(ntlmssp_state, session_key.data);
1001 } else {
1002 gnutls_cipher_hd_t cipher_hnd;
1003 gnutls_datum_t enc_session_key = {
1004 .data = session_key.data,
1005 .size = session_key.length,
1006 };
1007 int rc;
1008
1009 dump_data_pw("KEY_EXCH session key (enc):\n",
1010 state->encrypted_session_key.data,
1011 state->encrypted_session_key.length);
1012
1013 rc = gnutls_cipher_init(&cipher_hnd,
1014 GNUTLS_CIPHER_ARCFOUR_128,
1015 &enc_session_key,
1016 NULL);
1017 if (rc < 0) {
1018 return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
1019 }
1020 rc = gnutls_cipher_encrypt(cipher_hnd,
1021 state->encrypted_session_key.data,
1022 state->encrypted_session_key.length);
1023 gnutls_cipher_deinit(cipher_hnd);
1024 if (rc < 0) {
1025 return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
1026 }
1027
1028 ntlmssp_state->session_key = data_blob_talloc(ntlmssp_state,
1029 state->encrypted_session_key.data,
1030 state->encrypted_session_key.length);
1031 dump_data_pw("KEY_EXCH session key:\n",
1032 state->encrypted_session_key.data,
1033 state->encrypted_session_key.length);
1034 }
1035 } else {
1036 ntlmssp_state->session_key = session_key;
1037 talloc_steal(ntlmssp_state, session_key.data);
1038 }
1039
1040 if (ntlmssp_state->new_spnego) {
1041 gnutls_hmac_hd_t hmac_hnd = NULL;
1042 uint8_t mic_buffer[NTLMSSP_MIC_SIZE] = { 0, };
1043 int cmp;
1044 int rc;
1045
1046 rc = gnutls_hmac_init(&hmac_hnd,
1047 GNUTLS_MAC_MD5,
1048 ntlmssp_state->session_key.data,
1049 MIN(ntlmssp_state->session_key.length, 64));
1050 if (rc < 0) {
1051 return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
1052 }
1053 rc = gnutls_hmac(hmac_hnd,
1054 ntlmssp_state->negotiate_blob.data,
1055 ntlmssp_state->negotiate_blob.length);
1056 if (rc < 0) {
1057 gnutls_hmac_deinit(hmac_hnd, NULL);
1058 return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
1059 }
1060 rc = gnutls_hmac(hmac_hnd,
1061 ntlmssp_state->challenge_blob.data,
1062 ntlmssp_state->challenge_blob.length);
1063 if (rc < 0) {
1064 gnutls_hmac_deinit(hmac_hnd, NULL);
1065 return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
1066 }
1067
1068 /* checked were we set ntlmssp_state->new_spnego */
1069 SMB_ASSERT(request.length >
1070 (NTLMSSP_MIC_OFFSET + NTLMSSP_MIC_SIZE));
1071
1072 rc = gnutls_hmac(hmac_hnd, request.data, NTLMSSP_MIC_OFFSET);
1073 if (rc < 0) {
1074 gnutls_hmac_deinit(hmac_hnd, NULL);
1075 return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
1076 }
1077 rc = gnutls_hmac(hmac_hnd, mic_buffer, NTLMSSP_MIC_SIZE);
1078 if (rc < 0) {
1079 gnutls_hmac_deinit(hmac_hnd, NULL);
1080 return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
1081 }
1082 rc = gnutls_hmac(hmac_hnd,
1083 request.data + (NTLMSSP_MIC_OFFSET + NTLMSSP_MIC_SIZE),
1084 request.length - (NTLMSSP_MIC_OFFSET + NTLMSSP_MIC_SIZE));
1085 if (rc < 0) {
1086 gnutls_hmac_deinit(hmac_hnd, NULL);
1087 return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
1088 }
1089 gnutls_hmac_deinit(hmac_hnd, mic_buffer);
1090
1091 cmp = memcmp(request.data + NTLMSSP_MIC_OFFSET,
1092 mic_buffer, NTLMSSP_MIC_SIZE);
1093 if (cmp != 0) {
1094 DEBUG(1,("%s: invalid NTLMSSP_MIC for "
1095 "user=[%s] domain=[%s] workstation=[%s]\n",
1096 __func__,
1097 ntlmssp_state->user,
1098 ntlmssp_state->domain,
1099 ntlmssp_state->client.netbios_name));
1100 dump_data(11, request.data + NTLMSSP_MIC_OFFSET,
1101 NTLMSSP_MIC_SIZE);
1102 dump_data(11, mic_buffer,
1103 NTLMSSP_MIC_SIZE);
1104 }
1105
1106 ZERO_ARRAY(mic_buffer);
1107
1108 if (cmp != 0) {
1109 return NT_STATUS_INVALID_PARAMETER;
1110 }
1111 }
1112
1113 data_blob_free(&ntlmssp_state->negotiate_blob);
1114 data_blob_free(&ntlmssp_state->challenge_blob);
1115
1116 if (gensec_ntlmssp_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
1117 if (gensec_security->want_features & GENSEC_FEATURE_LDAP_STYLE) {
1118 /*
1119 * We need to handle NTLMSSP_NEGOTIATE_SIGN as
1120 * NTLMSSP_NEGOTIATE_SEAL if GENSEC_FEATURE_LDAP_STYLE
1121 * is requested.
1122 */
1123 ntlmssp_state->force_wrap_seal = true;
1124 }
1125 nt_status = ntlmssp_sign_init(ntlmssp_state);
1126 }
1127
1128 data_blob_clear_free(&ntlmssp_state->internal_chal);
1129 data_blob_clear_free(&ntlmssp_state->chal);
1130 data_blob_clear_free(&ntlmssp_state->lm_resp);
1131 data_blob_clear_free(&ntlmssp_state->nt_resp);
1132
1133 ntlmssp_state->expected_state = NTLMSSP_DONE;
1134
1135 return nt_status;
1136 }
1137
ntlmssp_server_auth_recv(struct tevent_req * req,TALLOC_CTX * out_mem_ctx,DATA_BLOB * out)1138 NTSTATUS ntlmssp_server_auth_recv(struct tevent_req *req,
1139 TALLOC_CTX *out_mem_ctx,
1140 DATA_BLOB *out)
1141 {
1142 NTSTATUS status;
1143
1144 *out = data_blob_null;
1145
1146 if (tevent_req_is_nterror(req, &status)) {
1147 tevent_req_received(req);
1148 return status;
1149 }
1150
1151 tevent_req_received(req);
1152 return NT_STATUS_OK;
1153 }
1154