Line data Source code
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 :
56 37449 : const char *ntlmssp_target_name(struct ntlmssp_state *ntlmssp_state,
57 : uint32_t neg_flags, uint32_t *chal_flags)
58 : {
59 37449 : if (neg_flags & NTLMSSP_REQUEST_TARGET) {
60 37449 : *chal_flags |= NTLMSSP_NEGOTIATE_TARGET_INFO;
61 37449 : *chal_flags |= NTLMSSP_REQUEST_TARGET;
62 37449 : if (ntlmssp_state->server.is_standalone) {
63 11360 : *chal_flags |= NTLMSSP_TARGET_TYPE_SERVER;
64 11360 : return ntlmssp_state->server.netbios_name;
65 : } else {
66 26089 : *chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN;
67 26089 : return ntlmssp_state->server.netbios_domain;
68 : };
69 : } else {
70 0 : 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 :
84 37451 : 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 148 : struct gensec_ntlmssp_context *gensec_ntlmssp =
89 37451 : talloc_get_type_abort(gensec_security->private_data,
90 : struct gensec_ntlmssp_context);
91 37451 : struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
92 37451 : struct auth4_context *auth_context = gensec_security->auth_context;
93 148 : DATA_BLOB struct_blob;
94 37451 : uint32_t neg_flags = 0;
95 148 : uint32_t ntlmssp_command, chal_flags;
96 148 : uint8_t cryptkey[8];
97 148 : const char *target_name;
98 148 : NTSTATUS status;
99 37451 : 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 37451 : uint32_t max_lifetime = 30 * 60;
119 37451 : 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 37451 : if (request.length) {
127 37451 : if (request.length > UINT16_MAX) {
128 0 : DEBUG(1, ("ntlmssp_server_negotiate: reject large request of length %u\n",
129 : (unsigned int)request.length));
130 0 : return NT_STATUS_INVALID_PARAMETER;
131 : }
132 :
133 37451 : if ((request.length < 16) || !msrpc_parse(ntlmssp_state, &request, "Cdd",
134 : "NTLMSSP",
135 : &ntlmssp_command,
136 : &neg_flags)) {
137 0 : DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP Negotiate of length %u\n",
138 : (unsigned int)request.length));
139 0 : dump_data(2, request.data, request.length);
140 0 : return NT_STATUS_INVALID_PARAMETER;
141 : }
142 37451 : debug_ntlmssp_flags(neg_flags);
143 :
144 37451 : if (DEBUGLEVEL >= 10) {
145 0 : struct NEGOTIATE_MESSAGE *negotiate = talloc(
146 : ntlmssp_state, struct NEGOTIATE_MESSAGE);
147 0 : if (negotiate != NULL) {
148 0 : status = ntlmssp_pull_NEGOTIATE_MESSAGE(
149 : &request, negotiate, negotiate);
150 0 : if (NT_STATUS_IS_OK(status)) {
151 0 : NDR_PRINT_DEBUG(NEGOTIATE_MESSAGE,
152 : negotiate);
153 : }
154 0 : TALLOC_FREE(negotiate);
155 : }
156 : }
157 : }
158 :
159 37451 : status = ntlmssp_handle_neg_flags(ntlmssp_state, neg_flags, "negotiate");
160 37451 : if (!NT_STATUS_IS_OK(status)){
161 0 : return status;
162 : }
163 :
164 : /* Ask our caller what challenge they would like in the packet */
165 37451 : if (auth_context->get_ntlm_challenge) {
166 37449 : status = auth_context->get_ntlm_challenge(auth_context, cryptkey);
167 37449 : if (!NT_STATUS_IS_OK(status)) {
168 0 : DEBUG(1, ("gensec_ntlmssp_server_negotiate: failed to get challenge: %s\n",
169 : nt_errstr(status)));
170 0 : return status;
171 : }
172 : } else {
173 2 : DEBUG(1, ("gensec_ntlmssp_server_negotiate: backend doesn't give a challenge\n"));
174 2 : 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'. Therefore, we
179 : * operate on 'chal_flags' from here on
180 : */
181 :
182 37449 : chal_flags = ntlmssp_state->neg_flags;
183 37449 : ntlmssp_state->server.challenge_endtime = timeval_to_nttime(&tv_end);
184 :
185 : /* get the right name to fill in as 'target' */
186 37449 : target_name = ntlmssp_target_name(ntlmssp_state,
187 : neg_flags, &chal_flags);
188 37449 : if (target_name == NULL)
189 0 : return NT_STATUS_INVALID_PARAMETER;
190 :
191 37449 : ntlmssp_state->chal = data_blob_talloc(ntlmssp_state, cryptkey, 8);
192 37449 : 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 37449 : if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) {
197 148 : enum ndr_err_code err;
198 37449 : struct AV_PAIR *pairs = NULL;
199 37449 : uint32_t count = 5;
200 :
201 37449 : pairs = talloc_zero_array(ntlmssp_state, struct AV_PAIR, count + 1);
202 37449 : if (pairs == NULL) {
203 0 : return NT_STATUS_NO_MEMORY;
204 : }
205 :
206 37449 : pairs[0].AvId = MsvAvNbDomainName;
207 37449 : pairs[0].Value.AvNbDomainName = target_name;
208 :
209 37449 : pairs[1].AvId = MsvAvNbComputerName;
210 37449 : pairs[1].Value.AvNbComputerName = ntlmssp_state->server.netbios_name;
211 :
212 37449 : pairs[2].AvId = MsvAvDnsDomainName;
213 37449 : pairs[2].Value.AvDnsDomainName = ntlmssp_state->server.dns_domain;
214 :
215 37449 : pairs[3].AvId = MsvAvDnsComputerName;
216 37449 : pairs[3].Value.AvDnsComputerName= ntlmssp_state->server.dns_name;
217 :
218 37449 : if (!ntlmssp_state->force_old_spnego) {
219 35975 : pairs[4].AvId = MsvAvTimestamp;
220 71950 : pairs[4].Value.AvTimestamp =
221 35975 : timeval_to_nttime(&tv_now);
222 35975 : count += 1;
223 :
224 35975 : pairs[5].AvId = MsvAvEOL;
225 : } else {
226 1474 : pairs[4].AvId = MsvAvEOL;
227 : }
228 :
229 37449 : ntlmssp_state->server.av_pair_list.count = count;
230 37449 : ntlmssp_state->server.av_pair_list.pair = pairs;
231 :
232 37597 : err = ndr_push_struct_blob(&struct_blob,
233 : ntlmssp_state,
234 37449 : &ntlmssp_state->server.av_pair_list,
235 : (ndr_push_flags_fn_t)ndr_push_AV_PAIR_LIST);
236 37449 : if (!NDR_ERR_CODE_IS_SUCCESS(err)) {
237 0 : return NT_STATUS_NO_MEMORY;
238 : }
239 : } else {
240 0 : struct_blob = data_blob_null;
241 : }
242 :
243 : {
244 : /* Marshal the packet in the right format, be it unicode or ASCII */
245 148 : const char *gen_string;
246 37449 : const DATA_BLOB version_blob = ntlmssp_version_blob();
247 :
248 37449 : if (ntlmssp_state->unicode) {
249 37301 : gen_string = "CdUdbddBb";
250 : } else {
251 0 : gen_string = "CdAdbddBb";
252 : }
253 :
254 37597 : 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 37449 : version_blob.data, version_blob.length);
263 :
264 37449 : if (!NT_STATUS_IS_OK(status)) {
265 0 : data_blob_free(&struct_blob);
266 0 : return status;
267 : }
268 :
269 37449 : if (DEBUGLEVEL >= 10) {
270 0 : struct CHALLENGE_MESSAGE *challenge = talloc(
271 : ntlmssp_state, struct CHALLENGE_MESSAGE);
272 0 : if (challenge != NULL) {
273 0 : challenge->NegotiateFlags = chal_flags;
274 0 : status = ntlmssp_pull_CHALLENGE_MESSAGE(
275 : reply, challenge, challenge);
276 0 : if (NT_STATUS_IS_OK(status)) {
277 0 : NDR_PRINT_DEBUG(CHALLENGE_MESSAGE,
278 : challenge);
279 : }
280 0 : TALLOC_FREE(challenge);
281 : }
282 : }
283 : }
284 :
285 37449 : data_blob_free(&struct_blob);
286 :
287 37449 : ntlmssp_state->negotiate_blob = data_blob_dup_talloc(ntlmssp_state,
288 : request);
289 37449 : if (ntlmssp_state->negotiate_blob.length != request.length) {
290 0 : return NT_STATUS_NO_MEMORY;
291 : }
292 :
293 37449 : ntlmssp_state->challenge_blob = data_blob_dup_talloc(ntlmssp_state,
294 : *reply);
295 37449 : if (ntlmssp_state->challenge_blob.length != reply->length) {
296 0 : return NT_STATUS_NO_MEMORY;
297 : }
298 :
299 37449 : ntlmssp_state->expected_state = NTLMSSP_AUTH;
300 :
301 37449 : 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 :
328 37324 : 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 148 : struct gensec_ntlmssp_context *gensec_ntlmssp =
334 37324 : talloc_get_type_abort(gensec_security->private_data,
335 : struct gensec_ntlmssp_context);
336 37324 : struct auth4_context *auth_context = gensec_security->auth_context;
337 37324 : struct tevent_req *req = NULL;
338 37324 : struct tevent_req *subreq = NULL;
339 37324 : struct ntlmssp_server_auth_state *state = NULL;
340 148 : NTSTATUS status;
341 :
342 37324 : req = tevent_req_create(mem_ctx, &state,
343 : struct ntlmssp_server_auth_state);
344 37324 : if (req == NULL) {
345 0 : return NULL;
346 : }
347 37324 : state->gensec_security = gensec_security;
348 37324 : state->gensec_ntlmssp = gensec_ntlmssp;
349 37324 : state->in = in;
350 :
351 37324 : status = ntlmssp_server_preauth(gensec_security,
352 : gensec_ntlmssp,
353 : state, in);
354 37324 : if (tevent_req_nterror(req, status)) {
355 12 : return tevent_req_post(req, ev);
356 : }
357 :
358 37458 : subreq = auth_context->check_ntlm_password_send(
359 37312 : state, ev, auth_context, state->user_info);
360 37312 : if (tevent_req_nomem(subreq, req)) {
361 0 : return tevent_req_post(req, ev);
362 : }
363 37312 : tevent_req_set_callback(subreq, ntlmssp_server_auth_done, req);
364 37312 : 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 :
375 37324 : 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 37324 : struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
381 37324 : struct auth4_context *auth_context = gensec_security->auth_context;
382 37324 : struct auth_usersupplied_info *user_info = NULL;
383 148 : uint32_t ntlmssp_command, auth_flags;
384 148 : NTSTATUS nt_status;
385 37324 : const unsigned int version_len = 8;
386 37324 : DATA_BLOB version_blob = data_blob_null;
387 37324 : const unsigned int mic_len = NTLMSSP_MIC_SIZE;
388 37324 : DATA_BLOB mic_blob = data_blob_null;
389 148 : const char *parse_string;
390 148 : bool ok;
391 148 : struct timeval endtime;
392 37324 : bool expired = false;
393 :
394 : #if 0
395 : file_save("ntlmssp_auth.dat", request.data, request.length);
396 : #endif
397 :
398 37324 : if (ntlmssp_state->unicode) {
399 37176 : parse_string = "CdBBUUUBdbb";
400 : } else {
401 0 : parse_string = "CdBBAAABdbb";
402 : }
403 :
404 : /* zero these out */
405 37324 : data_blob_free(&ntlmssp_state->session_key);
406 37324 : data_blob_free(&ntlmssp_state->lm_resp);
407 37324 : data_blob_free(&ntlmssp_state->nt_resp);
408 :
409 37324 : ntlmssp_state->user = NULL;
410 37324 : ntlmssp_state->domain = NULL;
411 37324 : ntlmssp_state->client.netbios_name = NULL;
412 :
413 : /* now the NTLMSSP encoded auth hashes */
414 37324 : 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 37324 : if (!ok) {
427 0 : DEBUG(10, ("ntlmssp_server_auth: failed to parse NTLMSSP (nonfatal):\n"));
428 0 : dump_data(10, request.data, request.length);
429 :
430 0 : data_blob_free(&version_blob);
431 0 : data_blob_free(&mic_blob);
432 :
433 0 : if (ntlmssp_state->unicode) {
434 0 : parse_string = "CdBBUUUBd";
435 : } else {
436 0 : parse_string = "CdBBAAABd";
437 : }
438 :
439 0 : 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 37324 : if (!ok) {
452 0 : DEBUG(10, ("ntlmssp_server_auth: failed to parse NTLMSSP (nonfatal):\n"));
453 0 : dump_data(10, request.data, request.length);
454 :
455 : /* zero this out */
456 0 : data_blob_free(&state->encrypted_session_key);
457 0 : auth_flags = 0;
458 :
459 : /* Try again with a shorter string (Win9X truncates this packet) */
460 0 : if (ntlmssp_state->unicode) {
461 0 : parse_string = "CdBBUUU";
462 : } else {
463 0 : parse_string = "CdBBAAA";
464 : }
465 :
466 : /* now the NTLMSSP encoded auth hashes */
467 0 : 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 0 : DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP (tried both formats):\n"));
476 0 : dump_data(2, request.data, request.length);
477 :
478 0 : return NT_STATUS_INVALID_PARAMETER;
479 : }
480 : }
481 :
482 37324 : talloc_steal(state, state->encrypted_session_key.data);
483 :
484 37324 : if (auth_flags != 0) {
485 37324 : nt_status = ntlmssp_handle_neg_flags(ntlmssp_state,
486 : auth_flags,
487 : "authenticate");
488 37324 : if (!NT_STATUS_IS_OK(nt_status)){
489 0 : return nt_status;
490 : }
491 : }
492 :
493 37324 : if (DEBUGLEVEL >= 10) {
494 0 : struct AUTHENTICATE_MESSAGE *authenticate = talloc(
495 : ntlmssp_state, struct AUTHENTICATE_MESSAGE);
496 0 : if (authenticate != NULL) {
497 0 : NTSTATUS status;
498 0 : authenticate->NegotiateFlags = auth_flags;
499 0 : status = ntlmssp_pull_AUTHENTICATE_MESSAGE(
500 : &request, authenticate, authenticate);
501 0 : if (NT_STATUS_IS_OK(status)) {
502 0 : NDR_PRINT_DEBUG(AUTHENTICATE_MESSAGE,
503 : authenticate);
504 : }
505 0 : TALLOC_FREE(authenticate);
506 : }
507 : }
508 :
509 37324 : 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 37324 : if (ntlmssp_state->nt_resp.length > 24) {
521 138 : struct NTLMv2_RESPONSE v2_resp;
522 138 : enum ndr_err_code err;
523 35536 : uint32_t i = 0;
524 35536 : uint32_t count = 0;
525 35536 : const struct AV_PAIR *flags = NULL;
526 35536 : const struct AV_PAIR *eol = NULL;
527 35536 : uint32_t av_flags = 0;
528 :
529 35536 : 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 35536 : if (!NDR_ERR_CODE_IS_SUCCESS(err)) {
534 12 : nt_status = ndr_map_error2ntstatus(err);
535 12 : if (NT_STATUS_EQUAL(nt_status, NT_STATUS_BUFFER_TOO_SMALL)) {
536 : /*
537 : * Note that invalid blobs should result in
538 : * INVALID_PARAMETER, as demonstrated by
539 : * smb2.session.ntlmssp_bug14932
540 : */
541 12 : nt_status = NT_STATUS_INVALID_PARAMETER;
542 : }
543 12 : DEBUG(1,("%s: failed to parse NTLMv2_RESPONSE of length %zu for "
544 : "user=[%s] domain=[%s] workstation=[%s] - %s %s\n",
545 : __func__, ntlmssp_state->nt_resp.length,
546 : ntlmssp_state->user, ntlmssp_state->domain,
547 : ntlmssp_state->client.netbios_name,
548 : ndr_errstr(err), nt_errstr(nt_status)));
549 12 : return nt_status;
550 : }
551 :
552 35524 : if (DEBUGLVL(10)) {
553 0 : NDR_PRINT_DEBUG(NTLMv2_RESPONSE, &v2_resp);
554 : }
555 :
556 35524 : eol = ndr_ntlmssp_find_av(&v2_resp.Challenge.AvPairs,
557 : MsvAvEOL);
558 35524 : if (eol == NULL) {
559 0 : DEBUG(1,("%s: missing MsvAvEOL for "
560 : "user=[%s] domain=[%s] workstation=[%s]\n",
561 : __func__, ntlmssp_state->user, ntlmssp_state->domain,
562 : ntlmssp_state->client.netbios_name));
563 0 : return NT_STATUS_INVALID_PARAMETER;
564 : }
565 :
566 35524 : flags = ndr_ntlmssp_find_av(&v2_resp.Challenge.AvPairs,
567 : MsvAvFlags);
568 35524 : if (flags != NULL) {
569 33807 : av_flags = flags->Value.AvFlags;
570 : }
571 :
572 35524 : if (av_flags & NTLMSSP_AVFLAG_MIC_IN_AUTHENTICATE_MESSAGE) {
573 33807 : if (mic_blob.length != NTLMSSP_MIC_SIZE) {
574 0 : DEBUG(1,("%s: mic_blob.length[%u] for "
575 : "user=[%s] domain=[%s] workstation=[%s]\n",
576 : __func__,
577 : (unsigned)mic_blob.length,
578 : ntlmssp_state->user,
579 : ntlmssp_state->domain,
580 : ntlmssp_state->client.netbios_name));
581 0 : return NT_STATUS_INVALID_PARAMETER;
582 : }
583 :
584 33807 : if (request.length <
585 : (NTLMSSP_MIC_OFFSET + NTLMSSP_MIC_SIZE))
586 : {
587 0 : DEBUG(1,("%s: missing MIC "
588 : "request.length[%u] for "
589 : "user=[%s] domain=[%s] workstation=[%s]\n",
590 : __func__,
591 : (unsigned)request.length,
592 : ntlmssp_state->user,
593 : ntlmssp_state->domain,
594 : ntlmssp_state->client.netbios_name));
595 0 : return NT_STATUS_INVALID_PARAMETER;
596 : }
597 :
598 33807 : ntlmssp_state->new_spnego = true;
599 : }
600 :
601 35524 : count = ntlmssp_state->server.av_pair_list.count;
602 35524 : if (v2_resp.Challenge.AvPairs.count < count) {
603 0 : return NT_STATUS_INVALID_PARAMETER;
604 : }
605 :
606 247198 : for (i = 0; i < count; i++) {
607 211674 : const struct AV_PAIR *sp =
608 211674 : &ntlmssp_state->server.av_pair_list.pair[i];
609 211674 : const struct AV_PAIR *cp = NULL;
610 :
611 211674 : if (sp->AvId == MsvAvEOL) {
612 35524 : continue;
613 : }
614 :
615 176150 : cp = ndr_ntlmssp_find_av(&v2_resp.Challenge.AvPairs,
616 175470 : sp->AvId);
617 176150 : if (cp == NULL) {
618 0 : DEBUG(1,("%s: AvId 0x%x missing for"
619 : "user=[%s] domain=[%s] "
620 : "workstation=[%s]\n",
621 : __func__,
622 : (unsigned)sp->AvId,
623 : ntlmssp_state->user,
624 : ntlmssp_state->domain,
625 : ntlmssp_state->client.netbios_name));
626 0 : return NT_STATUS_INVALID_PARAMETER;
627 : }
628 :
629 176150 : switch (cp->AvId) {
630 : #define CASE_STRING(v) case Msv ## v: do { \
631 : int cmp; \
632 : if (sp->Value.v == NULL) { \
633 : return NT_STATUS_INTERNAL_ERROR; \
634 : } \
635 : if (cp->Value.v == NULL) { \
636 : DEBUG(1,("%s: invalid %s " \
637 : "got[%s] expect[%s] for " \
638 : "user=[%s] domain=[%s] workstation=[%s]\n", \
639 : __func__, #v, \
640 : cp->Value.v, \
641 : sp->Value.v, \
642 : ntlmssp_state->user, \
643 : ntlmssp_state->domain, \
644 : ntlmssp_state->client.netbios_name)); \
645 : return NT_STATUS_INVALID_PARAMETER; \
646 : } \
647 : cmp = strcmp(cp->Value.v, sp->Value.v); \
648 : if (cmp != 0) { \
649 : DEBUG(1,("%s: invalid %s " \
650 : "got[%s] expect[%s] for " \
651 : "user=[%s] domain=[%s] workstation=[%s]\n", \
652 : __func__, #v, \
653 : cp->Value.v, \
654 : sp->Value.v, \
655 : ntlmssp_state->user, \
656 : ntlmssp_state->domain, \
657 : ntlmssp_state->client.netbios_name)); \
658 : return NT_STATUS_INVALID_PARAMETER; \
659 : } \
660 : } while(0); break
661 175606 : CASE_STRING(AvNbComputerName);
662 35524 : CASE_STRING(AvNbDomainName);
663 35524 : CASE_STRING(AvDnsComputerName);
664 35524 : CASE_STRING(AvDnsDomainName);
665 0 : CASE_STRING(AvDnsTreeName);
666 34054 : case MsvAvTimestamp:
667 34054 : if (cp->Value.AvTimestamp != sp->Value.AvTimestamp) {
668 0 : struct timeval ct;
669 0 : struct timeval st;
670 0 : struct timeval_buf tmp1;
671 0 : struct timeval_buf tmp2;
672 :
673 0 : nttime_to_timeval(&ct,
674 0 : cp->Value.AvTimestamp);
675 0 : nttime_to_timeval(&st,
676 0 : sp->Value.AvTimestamp);
677 :
678 0 : DEBUG(1,("%s: invalid AvTimestamp "
679 : "got[%s] expect[%s] for "
680 : "user=[%s] domain=[%s] "
681 : "workstation=[%s]\n",
682 : __func__,
683 : timeval_str_buf(&ct, false,
684 : true, &tmp1),
685 : timeval_str_buf(&st, false,
686 : true, &tmp2),
687 : ntlmssp_state->user,
688 : ntlmssp_state->domain,
689 : ntlmssp_state->client.netbios_name));
690 0 : return NT_STATUS_INVALID_PARAMETER;
691 : }
692 33918 : break;
693 0 : default:
694 : /*
695 : * This can't happen as we control
696 : * ntlmssp_state->server.av_pair_list
697 : */
698 0 : return NT_STATUS_INTERNAL_ERROR;
699 : }
700 : }
701 : }
702 :
703 37312 : nttime_to_timeval(&endtime, ntlmssp_state->server.challenge_endtime);
704 37312 : expired = timeval_expired(&endtime);
705 37312 : if (expired) {
706 0 : struct timeval_buf tmp;
707 0 : DEBUG(1,("%s: challenge invalid (expired %s) for "
708 : "user=[%s] domain=[%s] workstation=[%s]\n",
709 : __func__,
710 : timeval_str_buf(&endtime, false, true, &tmp),
711 : ntlmssp_state->user, ntlmssp_state->domain,
712 : ntlmssp_state->client.netbios_name));
713 0 : return NT_STATUS_INVALID_PARAMETER;
714 : }
715 :
716 : /* NTLM2 uses a 'challenge' that is made of up both the server challenge, and a
717 : client challenge
718 :
719 : However, the NTLM2 flag may still be set for the real NTLMv2 logins, be careful.
720 : */
721 37312 : if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
722 35693 : if (ntlmssp_state->nt_resp.length == 24 && ntlmssp_state->lm_resp.length == 24) {
723 169 : state->doing_ntlm2 = true;
724 :
725 169 : memcpy(state->session_nonce, ntlmssp_state->internal_chal.data, 8);
726 169 : memcpy(&state->session_nonce[8], ntlmssp_state->lm_resp.data, 8);
727 :
728 169 : SMB_ASSERT(ntlmssp_state->internal_chal.data && ntlmssp_state->internal_chal.length == 8);
729 :
730 : /* LM response is no longer useful */
731 169 : data_blob_free(&ntlmssp_state->lm_resp);
732 :
733 : /* We changed the effective challenge - set it */
734 169 : if (auth_context->set_ntlm_challenge) {
735 0 : uint8_t session_nonce_hash[16];
736 0 : int rc;
737 :
738 169 : rc = gnutls_hash_fast(GNUTLS_DIG_MD5,
739 169 : state->session_nonce,
740 : 16,
741 : session_nonce_hash);
742 169 : if (rc < 0) {
743 0 : return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
744 : }
745 :
746 :
747 169 : nt_status = auth_context->set_ntlm_challenge(auth_context,
748 : session_nonce_hash,
749 : "NTLMSSP callback (NTLM2)");
750 169 : ZERO_ARRAY(session_nonce_hash);
751 169 : if (!NT_STATUS_IS_OK(nt_status)) {
752 0 : DEBUG(1, ("gensec_ntlmssp_server_negotiate: failed to get challenge: %s\n",
753 : nt_errstr(nt_status)));
754 0 : return nt_status;
755 : }
756 : } else {
757 0 : DEBUG(1, ("gensec_ntlmssp_server_negotiate: backend doesn't have facility for challenge to be set\n"));
758 :
759 0 : return NT_STATUS_NOT_IMPLEMENTED;
760 : }
761 :
762 : /* LM Key is incompatible. */
763 169 : ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
764 : }
765 : }
766 :
767 37312 : user_info = talloc_zero(state, struct auth_usersupplied_info);
768 37312 : if (!user_info) {
769 0 : return NT_STATUS_NO_MEMORY;
770 : }
771 :
772 37312 : user_info->logon_parameters = MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT | MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
773 37312 : user_info->flags = 0;
774 37312 : user_info->client.account_name = ntlmssp_state->user;
775 37312 : user_info->client.domain_name = ntlmssp_state->domain;
776 37312 : user_info->workstation_name = ntlmssp_state->client.netbios_name;
777 37312 : user_info->remote_host = gensec_get_remote_address(gensec_security);
778 37312 : user_info->local_host = gensec_get_local_address(gensec_security);
779 146 : user_info->service_description
780 37312 : = gensec_get_target_service_description(gensec_security);
781 :
782 : /*
783 : * This will just be the string "NTLMSSP" from
784 : * gensec_ntlmssp_final_auth_type, but ensures it stays in sync
785 : * with the same use in the authorization logging triggered by
786 : * gensec_session_info() later
787 : */
788 37312 : user_info->auth_description = gensec_final_auth_type(gensec_security);
789 :
790 37312 : user_info->password_state = AUTH_PASSWORD_RESPONSE;
791 37312 : user_info->password.response.lanman = ntlmssp_state->lm_resp;
792 37312 : user_info->password.response.nt = ntlmssp_state->nt_resp;
793 :
794 37312 : state->user_info = user_info;
795 37312 : return NT_STATUS_OK;
796 : }
797 :
798 37312 : static void ntlmssp_server_auth_done(struct tevent_req *subreq)
799 : {
800 146 : struct tevent_req *req =
801 37312 : tevent_req_callback_data(subreq,
802 : struct tevent_req);
803 146 : struct ntlmssp_server_auth_state *state =
804 37312 : tevent_req_data(req,
805 : struct ntlmssp_server_auth_state);
806 37312 : struct gensec_security *gensec_security = state->gensec_security;
807 37312 : struct gensec_ntlmssp_context *gensec_ntlmssp = state->gensec_ntlmssp;
808 37312 : struct auth4_context *auth_context = gensec_security->auth_context;
809 37312 : uint8_t authoritative = 1;
810 146 : NTSTATUS status;
811 :
812 37312 : status = auth_context->check_ntlm_password_recv(subreq,
813 : gensec_ntlmssp,
814 : &authoritative,
815 : &gensec_ntlmssp->server_returned_info,
816 : &state->user_session_key,
817 : &state->lm_session_key);
818 37312 : TALLOC_FREE(subreq);
819 37312 : if (!NT_STATUS_IS_OK(status)) {
820 3783 : DBG_INFO("Checking NTLMSSP password for %s\\%s failed: %s\n",
821 : state->user_info->client.domain_name,
822 : state->user_info->client.account_name,
823 : nt_errstr(status));
824 : }
825 37312 : if (tevent_req_nterror(req, status)) {
826 3783 : return;
827 : }
828 33529 : talloc_steal(state, state->user_session_key.data);
829 33529 : talloc_steal(state, state->lm_session_key.data);
830 :
831 33529 : status = ntlmssp_server_postauth(state->gensec_security,
832 : state->gensec_ntlmssp,
833 : state, state->in);
834 33529 : if (tevent_req_nterror(req, status)) {
835 0 : return;
836 : }
837 :
838 33529 : tevent_req_done(req);
839 : }
840 :
841 : /**
842 : * Next state function for the Authenticate packet
843 : * (after authentication - figures out the session keys etc)
844 : *
845 : * @param ntlmssp_state NTLMSSP State
846 : * @return Errors or NT_STATUS_OK.
847 : */
848 :
849 33529 : static NTSTATUS ntlmssp_server_postauth(struct gensec_security *gensec_security,
850 : struct gensec_ntlmssp_context *gensec_ntlmssp,
851 : struct ntlmssp_server_auth_state *state,
852 : DATA_BLOB request)
853 : {
854 33529 : struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
855 33529 : struct auth4_context *auth_context = gensec_security->auth_context;
856 33529 : DATA_BLOB user_session_key = state->user_session_key;
857 33529 : DATA_BLOB lm_session_key = state->lm_session_key;
858 33529 : NTSTATUS nt_status = NT_STATUS_OK;
859 33529 : DATA_BLOB session_key = data_blob(NULL, 0);
860 33529 : struct auth_session_info *session_info = NULL;
861 :
862 33529 : TALLOC_FREE(state->user_info);
863 :
864 33529 : if (lpcfg_map_to_guest(gensec_security->settings->lp_ctx) != NEVER_MAP_TO_GUEST
865 78 : && auth_context->generate_session_info != NULL)
866 : {
867 0 : NTSTATUS tmp_status;
868 :
869 : /*
870 : * We need to check if the auth is anonymous or mapped to guest
871 : */
872 78 : tmp_status = auth_context->generate_session_info(auth_context, state,
873 : gensec_ntlmssp->server_returned_info,
874 78 : gensec_ntlmssp->ntlmssp_state->user,
875 : AUTH_SESSION_INFO_SIMPLE_PRIVILEGES,
876 : &session_info);
877 78 : if (!NT_STATUS_IS_OK(tmp_status)) {
878 : /*
879 : * We don't care about failures,
880 : * the worst result is that we try MIC checking
881 : * for a map to guest authentication.
882 : */
883 0 : TALLOC_FREE(session_info);
884 : }
885 : }
886 :
887 33529 : if (session_info != NULL) {
888 78 : if (security_session_user_level(session_info, NULL) < SECURITY_USER) {
889 : /*
890 : * Anonymous and GUEST are not secure anyway.
891 : * avoid new_spnego and MIC checking.
892 : */
893 54 : ntlmssp_state->new_spnego = false;
894 54 : ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SIGN;
895 54 : ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SEAL;
896 : }
897 78 : TALLOC_FREE(session_info);
898 : }
899 :
900 33529 : dump_data_pw("NT session key:\n", user_session_key.data, user_session_key.length);
901 33529 : dump_data_pw("LM first-8:\n", lm_session_key.data, lm_session_key.length);
902 :
903 : /* Handle the different session key derivation for NTLM2 */
904 33529 : if (state->doing_ntlm2) {
905 219 : if (user_session_key.data && user_session_key.length == 16) {
906 0 : int rc;
907 :
908 106 : session_key = data_blob_talloc(ntlmssp_state,
909 : NULL, 16);
910 :
911 106 : rc = gnutls_hmac_fast(GNUTLS_MAC_MD5,
912 106 : user_session_key.data,
913 : user_session_key.length,
914 106 : state->session_nonce,
915 : sizeof(state->session_nonce),
916 106 : session_key.data);
917 106 : if (rc < 0) {
918 0 : return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
919 : }
920 :
921 106 : DEBUG(10,("ntlmssp_server_auth: Created NTLM2 session key.\n"));
922 106 : dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
923 :
924 : } else {
925 7 : DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM2 session key.\n"));
926 7 : session_key = data_blob_null;
927 : }
928 33416 : } else if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
929 : /* Ensure we can never get here on NTLMv2 */
930 0 : && (ntlmssp_state->nt_resp.length == 0 || ntlmssp_state->nt_resp.length == 24)) {
931 :
932 0 : if (lm_session_key.data && lm_session_key.length >= 8) {
933 0 : if (ntlmssp_state->lm_resp.data && ntlmssp_state->lm_resp.length == 24) {
934 0 : session_key = data_blob_talloc(ntlmssp_state,
935 : NULL, 16);
936 0 : if (session_key.data == NULL) {
937 0 : return NT_STATUS_NO_MEMORY;
938 : }
939 0 : nt_status = SMBsesskeygen_lm_sess_key(lm_session_key.data,
940 0 : ntlmssp_state->lm_resp.data,
941 : session_key.data);
942 0 : if (!NT_STATUS_IS_OK(nt_status)) {
943 0 : return nt_status;
944 : }
945 0 : DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
946 : } else {
947 0 : static const uint8_t zeros[24] = {0, };
948 0 : session_key = data_blob_talloc(
949 : ntlmssp_state, NULL, 16);
950 0 : if (session_key.data == NULL) {
951 0 : return NT_STATUS_NO_MEMORY;
952 : }
953 0 : nt_status = SMBsesskeygen_lm_sess_key(zeros, zeros,
954 : session_key.data);
955 0 : if (!NT_STATUS_IS_OK(nt_status)) {
956 0 : return nt_status;
957 : }
958 0 : DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
959 : }
960 0 : dump_data_pw("LM session key:\n", session_key.data,
961 : session_key.length);
962 : } else {
963 : /* LM Key not selected */
964 0 : ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
965 :
966 0 : DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM session key.\n"));
967 0 : session_key = data_blob_null;
968 : }
969 :
970 33416 : } else if (user_session_key.data) {
971 33395 : session_key = user_session_key;
972 33395 : DEBUG(10,("ntlmssp_server_auth: Using unmodified nt session key.\n"));
973 33395 : dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
974 :
975 : /* LM Key not selected */
976 33395 : ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
977 :
978 21 : } else if (lm_session_key.data) {
979 : /* Very weird to have LM key, but no user session key, but anyway.. */
980 0 : session_key = lm_session_key;
981 0 : DEBUG(10,("ntlmssp_server_auth: Using unmodified lm session key.\n"));
982 0 : dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
983 :
984 : /* LM Key not selected */
985 0 : ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
986 :
987 : } else {
988 21 : DEBUG(10,("ntlmssp_server_auth: Failed to create unmodified session key.\n"));
989 21 : session_key = data_blob_null;
990 :
991 : /* LM Key not selected */
992 21 : ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
993 : }
994 :
995 : /* With KEY_EXCH, the client supplies the proposed session key,
996 : but encrypts it with the long-term key */
997 33529 : if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
998 33529 : if (!state->encrypted_session_key.data
999 33529 : || state->encrypted_session_key.length != 16) {
1000 0 : DEBUG(1, ("Client-supplied KEY_EXCH session key was of invalid length (%u)!\n",
1001 : (unsigned)state->encrypted_session_key.length));
1002 0 : return NT_STATUS_INVALID_PARAMETER;
1003 33529 : } else if (!session_key.data || session_key.length != 16) {
1004 28 : DEBUG(5, ("server session key is invalid (len == %u), cannot do KEY_EXCH!\n",
1005 : (unsigned int)session_key.length));
1006 28 : ntlmssp_state->session_key = session_key;
1007 28 : talloc_steal(ntlmssp_state, session_key.data);
1008 : } else {
1009 139 : gnutls_cipher_hd_t cipher_hnd;
1010 33501 : gnutls_datum_t enc_session_key = {
1011 33362 : .data = session_key.data,
1012 33362 : .size = session_key.length,
1013 : };
1014 139 : int rc;
1015 :
1016 33501 : dump_data_pw("KEY_EXCH session key (enc):\n",
1017 33362 : state->encrypted_session_key.data,
1018 : state->encrypted_session_key.length);
1019 :
1020 33501 : rc = gnutls_cipher_init(&cipher_hnd,
1021 : GNUTLS_CIPHER_ARCFOUR_128,
1022 : &enc_session_key,
1023 : NULL);
1024 33501 : if (rc < 0) {
1025 0 : return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
1026 : }
1027 33640 : rc = gnutls_cipher_encrypt(cipher_hnd,
1028 33501 : state->encrypted_session_key.data,
1029 : state->encrypted_session_key.length);
1030 33501 : gnutls_cipher_deinit(cipher_hnd);
1031 33501 : if (rc < 0) {
1032 0 : return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
1033 : }
1034 :
1035 33501 : ntlmssp_state->session_key = data_blob_talloc(ntlmssp_state,
1036 : state->encrypted_session_key.data,
1037 : state->encrypted_session_key.length);
1038 33501 : dump_data_pw("KEY_EXCH session key:\n",
1039 33501 : state->encrypted_session_key.data,
1040 : state->encrypted_session_key.length);
1041 : }
1042 : } else {
1043 0 : ntlmssp_state->session_key = session_key;
1044 0 : talloc_steal(ntlmssp_state, session_key.data);
1045 : }
1046 :
1047 33529 : if (ntlmssp_state->new_spnego) {
1048 30153 : gnutls_hmac_hd_t hmac_hnd = NULL;
1049 30153 : uint8_t mic_buffer[NTLMSSP_MIC_SIZE] = { 0, };
1050 129 : bool cmp;
1051 129 : int rc;
1052 :
1053 30282 : rc = gnutls_hmac_init(&hmac_hnd,
1054 : GNUTLS_MAC_MD5,
1055 30153 : ntlmssp_state->session_key.data,
1056 30153 : MIN(ntlmssp_state->session_key.length, 64));
1057 30153 : if (rc < 0) {
1058 0 : return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
1059 : }
1060 30282 : rc = gnutls_hmac(hmac_hnd,
1061 30153 : ntlmssp_state->negotiate_blob.data,
1062 : ntlmssp_state->negotiate_blob.length);
1063 30153 : if (rc < 0) {
1064 0 : gnutls_hmac_deinit(hmac_hnd, NULL);
1065 0 : return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
1066 : }
1067 30282 : rc = gnutls_hmac(hmac_hnd,
1068 30153 : ntlmssp_state->challenge_blob.data,
1069 : ntlmssp_state->challenge_blob.length);
1070 30153 : if (rc < 0) {
1071 0 : gnutls_hmac_deinit(hmac_hnd, NULL);
1072 0 : return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
1073 : }
1074 :
1075 : /* checked were we set ntlmssp_state->new_spnego */
1076 30153 : SMB_ASSERT(request.length >
1077 : (NTLMSSP_MIC_OFFSET + NTLMSSP_MIC_SIZE));
1078 :
1079 30153 : rc = gnutls_hmac(hmac_hnd, request.data, NTLMSSP_MIC_OFFSET);
1080 30153 : if (rc < 0) {
1081 0 : gnutls_hmac_deinit(hmac_hnd, NULL);
1082 0 : return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
1083 : }
1084 30153 : rc = gnutls_hmac(hmac_hnd, mic_buffer, NTLMSSP_MIC_SIZE);
1085 30153 : if (rc < 0) {
1086 0 : gnutls_hmac_deinit(hmac_hnd, NULL);
1087 0 : return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
1088 : }
1089 30282 : rc = gnutls_hmac(hmac_hnd,
1090 30153 : request.data + (NTLMSSP_MIC_OFFSET + NTLMSSP_MIC_SIZE),
1091 30024 : request.length - (NTLMSSP_MIC_OFFSET + NTLMSSP_MIC_SIZE));
1092 30153 : if (rc < 0) {
1093 0 : gnutls_hmac_deinit(hmac_hnd, NULL);
1094 0 : return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
1095 : }
1096 30153 : gnutls_hmac_deinit(hmac_hnd, mic_buffer);
1097 :
1098 30153 : cmp = mem_equal_const_time(request.data + NTLMSSP_MIC_OFFSET,
1099 : mic_buffer, NTLMSSP_MIC_SIZE);
1100 30153 : if (!cmp) {
1101 0 : DEBUG(1,("%s: invalid NTLMSSP_MIC for "
1102 : "user=[%s] domain=[%s] workstation=[%s]\n",
1103 : __func__,
1104 : ntlmssp_state->user,
1105 : ntlmssp_state->domain,
1106 : ntlmssp_state->client.netbios_name));
1107 0 : dump_data(11, request.data + NTLMSSP_MIC_OFFSET,
1108 : NTLMSSP_MIC_SIZE);
1109 0 : dump_data(11, mic_buffer,
1110 : NTLMSSP_MIC_SIZE);
1111 : }
1112 :
1113 30153 : ZERO_ARRAY(mic_buffer);
1114 :
1115 30153 : if (!cmp) {
1116 0 : return NT_STATUS_INVALID_PARAMETER;
1117 : }
1118 : }
1119 :
1120 33529 : data_blob_free(&ntlmssp_state->negotiate_blob);
1121 33529 : data_blob_free(&ntlmssp_state->challenge_blob);
1122 :
1123 33529 : if (gensec_ntlmssp_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
1124 33232 : if (gensec_security->want_features & GENSEC_FEATURE_LDAP_STYLE) {
1125 : /*
1126 : * We need to handle NTLMSSP_NEGOTIATE_SIGN as
1127 : * NTLMSSP_NEGOTIATE_SEAL if GENSEC_FEATURE_LDAP_STYLE
1128 : * is requested.
1129 : */
1130 8763 : ntlmssp_state->force_wrap_seal = true;
1131 : }
1132 33232 : nt_status = ntlmssp_sign_init(ntlmssp_state);
1133 : }
1134 :
1135 33529 : data_blob_clear_free(&ntlmssp_state->internal_chal);
1136 33529 : data_blob_clear_free(&ntlmssp_state->chal);
1137 33529 : data_blob_clear_free(&ntlmssp_state->lm_resp);
1138 33529 : data_blob_clear_free(&ntlmssp_state->nt_resp);
1139 :
1140 33529 : ntlmssp_state->expected_state = NTLMSSP_DONE;
1141 :
1142 33529 : return nt_status;
1143 : }
1144 :
1145 37324 : NTSTATUS ntlmssp_server_auth_recv(struct tevent_req *req,
1146 : TALLOC_CTX *out_mem_ctx,
1147 : DATA_BLOB *out)
1148 : {
1149 148 : NTSTATUS status;
1150 :
1151 37324 : *out = data_blob_null;
1152 :
1153 37324 : if (tevent_req_is_nterror(req, &status)) {
1154 3795 : tevent_req_received(req);
1155 3795 : return status;
1156 : }
1157 :
1158 33529 : tevent_req_received(req);
1159 33529 : return NT_STATUS_OK;
1160 : }
|