Line data Source code
1 : /*
2 : Unix SMB/Netbios implementation.
3 : Version 3.0
4 : handle NLTMSSP, client server side parsing
5 :
6 : Copyright (C) Andrew Tridgell 2001
7 : Copyright (C) Andrew Bartlett <abartlet@samba.org> 2001-2005
8 : Copyright (C) Stefan Metzmacher 2005
9 :
10 : This program is free software; you can redistribute it and/or modify
11 : it under the terms of the GNU General Public License as published by
12 : the Free Software Foundation; either version 3 of the License, or
13 : (at your option) any later version.
14 :
15 : This program is distributed in the hope that it will be useful,
16 : but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 : GNU General Public License for more details.
19 :
20 : You should have received a copy of the GNU General Public License
21 : along with this program. If not, see <http://www.gnu.org/licenses/>.
22 : */
23 :
24 : struct auth_session_info;
25 :
26 : #include "includes.h"
27 : #include "auth/ntlmssp/ntlmssp.h"
28 : #include "../libcli/auth/libcli_auth.h"
29 : #include "auth/credentials/credentials.h"
30 : #include "auth/gensec/gensec.h"
31 : #include "auth/gensec/gensec_internal.h"
32 : #include "param/param.h"
33 : #include "auth/ntlmssp/ntlmssp_private.h"
34 : #include "../librpc/gen_ndr/ndr_ntlmssp.h"
35 : #include "../auth/ntlmssp/ntlmssp_ndr.h"
36 : #include "../nsswitch/libwbclient/wbclient.h"
37 :
38 : #include "lib/crypto/gnutls_helpers.h"
39 : #include <gnutls/gnutls.h>
40 : #include <gnutls/crypto.h>
41 :
42 : #undef DBGC_CLASS
43 : #define DBGC_CLASS DBGC_AUTH
44 :
45 : /*********************************************************************
46 : Client side NTLMSSP
47 : *********************************************************************/
48 :
49 : /**
50 : * Next state function for the Initial packet
51 : *
52 : * @param ntlmssp_state NTLMSSP State
53 : * @param out_mem_ctx The DATA_BLOB *out will be allocated on this context
54 : * @param in A NULL data blob (input ignored)
55 : * @param out The initial negotiate request to the server, as an talloc()ed DATA_BLOB, on out_mem_ctx
56 : * @return Errors or NT_STATUS_OK.
57 : */
58 :
59 38666 : NTSTATUS ntlmssp_client_initial(struct gensec_security *gensec_security,
60 : TALLOC_CTX *out_mem_ctx,
61 : DATA_BLOB in, DATA_BLOB *out)
62 : {
63 296 : struct gensec_ntlmssp_context *gensec_ntlmssp =
64 38666 : talloc_get_type_abort(gensec_security->private_data,
65 : struct gensec_ntlmssp_context);
66 38666 : struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
67 296 : NTSTATUS status;
68 38666 : const DATA_BLOB version_blob = ntlmssp_version_blob();
69 :
70 : /* generate the ntlmssp negotiate packet */
71 38962 : status = msrpc_gen(out_mem_ctx,
72 : out, "CddAAb",
73 : "NTLMSSP",
74 : NTLMSSP_NEGOTIATE,
75 : ntlmssp_state->neg_flags,
76 : "", /* domain */
77 : "", /* workstation */
78 38666 : version_blob.data, version_blob.length);
79 38666 : if (!NT_STATUS_IS_OK(status)) {
80 0 : DEBUG(0, ("ntlmssp_client_initial: failed to generate "
81 : "ntlmssp negotiate packet\n"));
82 0 : return status;
83 : }
84 :
85 38666 : if (DEBUGLEVEL >= 10) {
86 2 : struct NEGOTIATE_MESSAGE *negotiate = talloc(
87 : ntlmssp_state, struct NEGOTIATE_MESSAGE);
88 2 : if (negotiate != NULL) {
89 2 : status = ntlmssp_pull_NEGOTIATE_MESSAGE(
90 : out, negotiate, negotiate);
91 2 : if (NT_STATUS_IS_OK(status)) {
92 2 : NDR_PRINT_DEBUG(NEGOTIATE_MESSAGE,
93 : negotiate);
94 : }
95 2 : TALLOC_FREE(negotiate);
96 : }
97 : }
98 :
99 38666 : ntlmssp_state->negotiate_blob = data_blob_dup_talloc(ntlmssp_state,
100 : *out);
101 38666 : if (ntlmssp_state->negotiate_blob.length != out->length) {
102 0 : return NT_STATUS_NO_MEMORY;
103 : }
104 :
105 38666 : ntlmssp_state->expected_state = NTLMSSP_CHALLENGE;
106 :
107 38666 : return NT_STATUS_MORE_PROCESSING_REQUIRED;
108 : }
109 :
110 50 : NTSTATUS gensec_ntlmssp_resume_ccache(struct gensec_security *gensec_security,
111 : TALLOC_CTX *out_mem_ctx,
112 : DATA_BLOB in, DATA_BLOB *out)
113 : {
114 0 : struct gensec_ntlmssp_context *gensec_ntlmssp =
115 50 : talloc_get_type_abort(gensec_security->private_data,
116 : struct gensec_ntlmssp_context);
117 50 : struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
118 50 : uint32_t neg_flags = 0;
119 0 : uint32_t ntlmssp_command;
120 0 : NTSTATUS status;
121 0 : bool ok;
122 :
123 50 : *out = data_blob_null;
124 :
125 50 : if (in.length == 0) {
126 : /*
127 : * This is compat code for older callers
128 : * which were missing the "initial_blob"/"negotiate_blob".
129 : *
130 : * That means we can't calculate the NTLMSSP_MIC
131 : * field correctly and need to force the
132 : * old_spnego behaviour.
133 : */
134 0 : DEBUG(10, ("%s: in.length==%u force_old_spnego!\n",
135 : __func__, (unsigned int)in.length));
136 0 : ntlmssp_state->force_old_spnego = true;
137 0 : ntlmssp_state->neg_flags |= ntlmssp_state->required_flags;
138 0 : ntlmssp_state->required_flags = 0;
139 0 : ntlmssp_state->expected_state = NTLMSSP_CHALLENGE;
140 0 : return NT_STATUS_MORE_PROCESSING_REQUIRED;
141 : }
142 :
143 : /* parse the NTLMSSP packet */
144 :
145 50 : if (in.length > UINT16_MAX) {
146 0 : DEBUG(1, ("%s: reject large request of length %u\n",
147 : __func__, (unsigned int)in.length));
148 0 : return NT_STATUS_INVALID_PARAMETER;
149 : }
150 :
151 50 : ok = msrpc_parse(ntlmssp_state, &in, "Cdd",
152 : "NTLMSSP",
153 : &ntlmssp_command,
154 : &neg_flags);
155 50 : if (!ok) {
156 0 : DEBUG(1, ("%s: failed to parse NTLMSSP Negotiate of length %u\n",
157 : __func__, (unsigned int)in.length));
158 0 : dump_data(2, in.data, in.length);
159 0 : return NT_STATUS_INVALID_PARAMETER;
160 : }
161 :
162 50 : if (ntlmssp_command != NTLMSSP_NEGOTIATE) {
163 0 : DEBUG(1, ("%s: no NTLMSSP Negotiate message (length %u)\n",
164 : __func__, (unsigned int)in.length));
165 0 : dump_data(2, in.data, in.length);
166 0 : return NT_STATUS_INVALID_PARAMETER;
167 : }
168 :
169 50 : ntlmssp_state->neg_flags = neg_flags;
170 50 : DEBUG(3, ("Imported Negotiate flags:\n"));
171 50 : debug_ntlmssp_flags(neg_flags);
172 :
173 50 : if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_UNICODE) {
174 50 : ntlmssp_state->unicode = true;
175 : } else {
176 0 : ntlmssp_state->unicode = false;
177 : }
178 :
179 50 : if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN) {
180 44 : gensec_security->want_features |= GENSEC_FEATURE_SIGN;
181 : }
182 :
183 50 : if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL) {
184 12 : gensec_security->want_features |= GENSEC_FEATURE_SEAL;
185 : }
186 :
187 50 : ntlmssp_state->conf_flags = ntlmssp_state->neg_flags;
188 50 : ntlmssp_state->required_flags = 0;
189 :
190 50 : if (DEBUGLEVEL >= 10) {
191 0 : struct NEGOTIATE_MESSAGE *negotiate = talloc(
192 : ntlmssp_state, struct NEGOTIATE_MESSAGE);
193 0 : if (negotiate != NULL) {
194 0 : status = ntlmssp_pull_NEGOTIATE_MESSAGE(
195 : &in, negotiate, negotiate);
196 0 : if (NT_STATUS_IS_OK(status)) {
197 0 : NDR_PRINT_DEBUG(NEGOTIATE_MESSAGE,
198 : negotiate);
199 : }
200 0 : TALLOC_FREE(negotiate);
201 : }
202 : }
203 :
204 50 : ntlmssp_state->negotiate_blob = data_blob_dup_talloc(ntlmssp_state,
205 : in);
206 50 : if (ntlmssp_state->negotiate_blob.length != in.length) {
207 0 : return NT_STATUS_NO_MEMORY;
208 : }
209 :
210 50 : ntlmssp_state->expected_state = NTLMSSP_CHALLENGE;
211 :
212 50 : return NT_STATUS_MORE_PROCESSING_REQUIRED;
213 : }
214 :
215 : /**
216 : * Next state function for the Challenge Packet. Generate an auth packet.
217 : *
218 : * @param gensec_security GENSEC state
219 : * @param out_mem_ctx Memory context for *out
220 : * @param in The server challnege, as a DATA_BLOB. reply.data must be NULL
221 : * @param out The next request (auth packet) to the server, as an allocated DATA_BLOB, on the out_mem_ctx context
222 : * @return Errors or NT_STATUS_OK.
223 : */
224 :
225 37754 : NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security,
226 : TALLOC_CTX *out_mem_ctx,
227 : const DATA_BLOB in, DATA_BLOB *out)
228 : {
229 148 : struct gensec_ntlmssp_context *gensec_ntlmssp =
230 37754 : talloc_get_type_abort(gensec_security->private_data,
231 : struct gensec_ntlmssp_context);
232 37754 : struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
233 37754 : uint32_t chal_flags, ntlmssp_command, unkn1 = 0, unkn2 = 0;
234 148 : DATA_BLOB server_domain_blob;
235 148 : DATA_BLOB challenge_blob;
236 37754 : DATA_BLOB target_info = data_blob(NULL, 0);
237 148 : char *server_domain;
238 148 : const char *chal_parse_string;
239 37754 : const char *chal_parse_string_short = NULL;
240 148 : const char *auth_gen_string;
241 37754 : DATA_BLOB lm_response = data_blob(NULL, 0);
242 37754 : DATA_BLOB nt_response = data_blob(NULL, 0);
243 37754 : DATA_BLOB session_key = data_blob(NULL, 0);
244 37754 : DATA_BLOB lm_session_key = data_blob(NULL, 0);
245 37754 : DATA_BLOB encrypted_session_key = data_blob(NULL, 0);
246 148 : NTSTATUS nt_status;
247 37754 : int flags = 0;
248 37754 : const char *user = NULL, *domain = NULL, *workstation = NULL;
249 37754 : bool is_anonymous = false;
250 37754 : const DATA_BLOB version_blob = ntlmssp_version_blob();
251 37754 : const NTTIME *server_timestamp = NULL;
252 37754 : uint8_t mic_buffer[NTLMSSP_MIC_SIZE] = { 0, };
253 37754 : DATA_BLOB mic_blob = data_blob_const(mic_buffer, sizeof(mic_buffer));
254 37754 : gnutls_hmac_hd_t hmac_hnd = NULL;
255 148 : int rc;
256 :
257 37754 : TALLOC_CTX *mem_ctx = talloc_new(out_mem_ctx);
258 37754 : if (!mem_ctx) {
259 0 : return NT_STATUS_NO_MEMORY;
260 : }
261 :
262 37754 : if (!msrpc_parse(mem_ctx,
263 : &in, "CdBd",
264 : "NTLMSSP",
265 : &ntlmssp_command,
266 : &server_domain_blob,
267 : &chal_flags)) {
268 0 : DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n"));
269 0 : dump_data(2, in.data, in.length);
270 0 : talloc_free(mem_ctx);
271 :
272 0 : return NT_STATUS_INVALID_PARAMETER;
273 : }
274 :
275 37754 : data_blob_free(&server_domain_blob);
276 :
277 37754 : DEBUG(3, ("Got challenge flags:\n"));
278 37754 : debug_ntlmssp_flags(chal_flags);
279 :
280 37754 : nt_status = ntlmssp_handle_neg_flags(ntlmssp_state,
281 : chal_flags, "challenge");
282 37754 : if (!NT_STATUS_IS_OK(nt_status)) {
283 0 : return nt_status;
284 : }
285 :
286 37754 : if (ntlmssp_state->unicode) {
287 37754 : if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) {
288 37606 : chal_parse_string = "CdUdbddB";
289 : } else {
290 0 : chal_parse_string = "CdUdbdd";
291 0 : chal_parse_string_short = "CdUdb";
292 : }
293 37606 : auth_gen_string = "CdBBUUUBdbb";
294 : } else {
295 0 : if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) {
296 0 : chal_parse_string = "CdAdbddB";
297 : } else {
298 0 : chal_parse_string = "CdAdbdd";
299 0 : chal_parse_string_short = "CdAdb";
300 : }
301 :
302 0 : auth_gen_string = "CdBBAAABdbb";
303 : }
304 :
305 37754 : if (!msrpc_parse(mem_ctx,
306 : &in, chal_parse_string,
307 : "NTLMSSP",
308 : &ntlmssp_command,
309 : &server_domain,
310 : &chal_flags,
311 : &challenge_blob, 8,
312 : &unkn1, &unkn2,
313 : &target_info)) {
314 :
315 0 : bool ok = false;
316 :
317 0 : DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#2)\n"));
318 :
319 0 : if (chal_parse_string_short != NULL) {
320 : /*
321 : * In the case where NTLMSSP_NEGOTIATE_TARGET_INFO
322 : * is not used, some NTLMSSP servers don't return
323 : * the unused unkn1 and unkn2 fields.
324 : * See bug:
325 : * https://bugzilla.samba.org/show_bug.cgi?id=10016
326 : * for packet traces.
327 : * Try and parse again without them.
328 : */
329 0 : ok = msrpc_parse(mem_ctx,
330 : &in, chal_parse_string_short,
331 : "NTLMSSP",
332 : &ntlmssp_command,
333 : &server_domain,
334 : &chal_flags,
335 : &challenge_blob, 8);
336 0 : if (!ok) {
337 0 : DEBUG(1, ("Failed to short parse "
338 : "the NTLMSSP Challenge: (#2)\n"));
339 : }
340 : }
341 :
342 0 : if (!ok) {
343 0 : dump_data(2, in.data, in.length);
344 0 : talloc_free(mem_ctx);
345 0 : return NT_STATUS_INVALID_PARAMETER;
346 : }
347 : }
348 :
349 37754 : if (DEBUGLEVEL >= 10) {
350 0 : struct CHALLENGE_MESSAGE *challenge =
351 2 : talloc(ntlmssp_state, struct CHALLENGE_MESSAGE);
352 2 : if (challenge != NULL) {
353 0 : NTSTATUS status;
354 2 : challenge->NegotiateFlags = chal_flags;
355 2 : status = ntlmssp_pull_CHALLENGE_MESSAGE(
356 : &in, challenge, challenge);
357 2 : if (NT_STATUS_IS_OK(status)) {
358 2 : NDR_PRINT_DEBUG(CHALLENGE_MESSAGE,
359 : challenge);
360 : }
361 2 : TALLOC_FREE(challenge);
362 : }
363 : }
364 :
365 37754 : if (chal_flags & NTLMSSP_TARGET_TYPE_SERVER) {
366 11340 : ntlmssp_state->server.is_standalone = true;
367 : } else {
368 26414 : ntlmssp_state->server.is_standalone = false;
369 : }
370 : /* TODO: parse struct_blob and fill in the rest */
371 37754 : ntlmssp_state->server.netbios_name = "";
372 37754 : ntlmssp_state->server.netbios_domain = talloc_move(ntlmssp_state, &server_domain);
373 37754 : ntlmssp_state->server.dns_name = "";
374 37754 : ntlmssp_state->server.dns_domain = "";
375 :
376 37754 : if (challenge_blob.length != 8) {
377 0 : talloc_free(mem_ctx);
378 0 : return NT_STATUS_INVALID_PARAMETER;
379 : }
380 :
381 37754 : is_anonymous = cli_credentials_is_anonymous(gensec_security->credentials);
382 37754 : cli_credentials_get_ntlm_username_domain(gensec_security->credentials, mem_ctx,
383 : &user, &domain);
384 :
385 37754 : workstation = cli_credentials_get_workstation(gensec_security->credentials);
386 :
387 37754 : if (user == NULL) {
388 0 : DEBUG(10, ("User is NULL, returning INVALID_PARAMETER\n"));
389 0 : return NT_STATUS_INVALID_PARAMETER;
390 : }
391 :
392 37754 : if (domain == NULL) {
393 98 : DEBUG(10, ("Domain is NULL, returning INVALID_PARAMETER\n"));
394 98 : return NT_STATUS_INVALID_PARAMETER;
395 : }
396 :
397 37656 : if (workstation == NULL) {
398 0 : DEBUG(10, ("Workstation is NULL, returning INVALID_PARAMETER\n"));
399 0 : return NT_STATUS_INVALID_PARAMETER;
400 : }
401 :
402 37656 : if (is_anonymous) {
403 1052 : ntlmssp_state->neg_flags |= NTLMSSP_ANONYMOUS;
404 : /*
405 : * don't use the ccache for anonymous auth
406 : */
407 1052 : ntlmssp_state->use_ccache = false;
408 : }
409 37656 : if (ntlmssp_state->use_ccache) {
410 104 : struct samr_Password *nt_hash = NULL;
411 :
412 : /*
413 : * If we have a password given we don't
414 : * use the ccache
415 : */
416 104 : nt_hash = cli_credentials_get_nt_hash(gensec_security->credentials,
417 : mem_ctx);
418 104 : if (nt_hash != NULL) {
419 50 : ZERO_STRUCTP(nt_hash);
420 50 : TALLOC_FREE(nt_hash);
421 50 : ntlmssp_state->use_ccache = false;
422 : }
423 : }
424 :
425 37656 : if (ntlmssp_state->use_ccache) {
426 0 : struct wbcCredentialCacheParams params;
427 54 : struct wbcCredentialCacheInfo *info = NULL;
428 54 : struct wbcAuthErrorInfo *error = NULL;
429 0 : struct wbcNamedBlob auth_blobs[2];
430 54 : const struct wbcBlob *wbc_auth_blob = NULL;
431 54 : const struct wbcBlob *wbc_session_key = NULL;
432 0 : wbcErr wbc_status;
433 0 : size_t i;
434 54 : bool new_spnego = false;
435 :
436 54 : params.account_name = user;
437 54 : params.domain_name = domain;
438 54 : params.level = WBC_CREDENTIAL_CACHE_LEVEL_NTLMSSP;
439 :
440 54 : auth_blobs[0].name = "challenge_blob";
441 54 : auth_blobs[0].flags = 0;
442 54 : auth_blobs[0].blob.data = in.data;
443 54 : auth_blobs[0].blob.length = in.length;
444 54 : auth_blobs[1].name = "negotiate_blob";
445 54 : auth_blobs[1].flags = 0;
446 54 : auth_blobs[1].blob.data = ntlmssp_state->negotiate_blob.data;
447 54 : auth_blobs[1].blob.length = ntlmssp_state->negotiate_blob.length;
448 54 : params.num_blobs = ARRAY_SIZE(auth_blobs);
449 54 : params.blobs = auth_blobs;
450 :
451 54 : wbc_status = wbcCredentialCache(¶ms, &info, &error);
452 54 : wbcFreeMemory(error);
453 54 : if (!WBC_ERROR_IS_OK(wbc_status)) {
454 0 : return NT_STATUS_WRONG_CREDENTIAL_HANDLE;
455 : }
456 :
457 206 : for (i=0; i<info->num_blobs; i++) {
458 152 : if (strequal(info->blobs[i].name, "auth_blob")) {
459 54 : wbc_auth_blob = &info->blobs[i].blob;
460 : }
461 152 : if (strequal(info->blobs[i].name, "session_key")) {
462 54 : wbc_session_key = &info->blobs[i].blob;
463 : }
464 152 : if (strequal(info->blobs[i].name, "new_spnego")) {
465 44 : new_spnego = true;
466 : }
467 : }
468 54 : if ((wbc_auth_blob == NULL) || (wbc_session_key == NULL)) {
469 0 : wbcFreeMemory(info);
470 0 : return NT_STATUS_WRONG_CREDENTIAL_HANDLE;
471 : }
472 :
473 54 : session_key = data_blob_talloc(mem_ctx,
474 : wbc_session_key->data,
475 : wbc_session_key->length);
476 54 : if (session_key.length != wbc_session_key->length) {
477 0 : wbcFreeMemory(info);
478 0 : return NT_STATUS_NO_MEMORY;
479 : }
480 54 : *out = data_blob_talloc(mem_ctx,
481 : wbc_auth_blob->data,
482 : wbc_auth_blob->length);
483 54 : if (out->length != wbc_auth_blob->length) {
484 0 : wbcFreeMemory(info);
485 0 : return NT_STATUS_NO_MEMORY;
486 : }
487 54 : ntlmssp_state->new_spnego = new_spnego;
488 :
489 54 : wbcFreeMemory(info);
490 54 : goto done;
491 : }
492 :
493 37602 : if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
494 36994 : flags |= CLI_CRED_NTLM2;
495 : }
496 37602 : if (ntlmssp_state->use_ntlmv2) {
497 36717 : flags |= CLI_CRED_NTLMv2_AUTH;
498 : }
499 37602 : if (ntlmssp_state->use_nt_response) {
500 37602 : flags |= CLI_CRED_NTLM_AUTH;
501 : }
502 37602 : if (ntlmssp_state->allow_lm_response) {
503 885 : flags |= CLI_CRED_LANMAN_AUTH;
504 : }
505 :
506 37602 : if (target_info.length != 0 && !is_anonymous) {
507 36550 : struct AV_PAIR *pairs = NULL;
508 36550 : uint32_t count = 0;
509 138 : enum ndr_err_code err;
510 36550 : struct AV_PAIR *timestamp = NULL;
511 36550 : struct AV_PAIR *eol = NULL;
512 36550 : uint32_t i = 0;
513 36550 : const char *service = NULL;
514 36550 : const char *hostname = NULL;
515 :
516 36688 : err = ndr_pull_struct_blob(&target_info,
517 : ntlmssp_state,
518 36550 : &ntlmssp_state->server.av_pair_list,
519 : (ndr_pull_flags_fn_t)ndr_pull_AV_PAIR_LIST);
520 36550 : if (!NDR_ERR_CODE_IS_SUCCESS(err)) {
521 0 : return ndr_map_error2ntstatus(err);
522 : }
523 :
524 36550 : count = ntlmssp_state->server.av_pair_list.count;
525 : /*
526 : * We need room for Flags, SingleHost,
527 : * ChannelBindings and Target
528 : */
529 36550 : pairs = talloc_zero_array(ntlmssp_state, struct AV_PAIR,
530 : count + 4);
531 36550 : if (pairs == NULL) {
532 0 : return NT_STATUS_NO_MEMORY;
533 : }
534 :
535 254382 : for (i = 0; i < count; i++) {
536 217832 : pairs[i] = ntlmssp_state->server.av_pair_list.pair[i];
537 : }
538 :
539 36550 : ntlmssp_state->client.av_pair_list.count = count;
540 36550 : ntlmssp_state->client.av_pair_list.pair = pairs;
541 :
542 36550 : eol = ndr_ntlmssp_find_av(&ntlmssp_state->client.av_pair_list,
543 : MsvAvEOL);
544 36550 : if (eol == NULL) {
545 0 : return NT_STATUS_INVALID_PARAMETER;
546 : }
547 :
548 36550 : timestamp = ndr_ntlmssp_find_av(&ntlmssp_state->client.av_pair_list,
549 : MsvAvTimestamp);
550 36550 : if (timestamp != NULL) {
551 35082 : uint32_t sign_features =
552 : GENSEC_FEATURE_SESSION_KEY |
553 : GENSEC_FEATURE_SIGN |
554 : GENSEC_FEATURE_SEAL;
555 :
556 35082 : server_timestamp = ×tamp->Value.AvTimestamp;
557 :
558 35082 : if (ntlmssp_state->force_old_spnego) {
559 0 : sign_features = 0;
560 : }
561 :
562 35082 : if (gensec_security->want_features & sign_features) {
563 34815 : struct AV_PAIR *av_flags = NULL;
564 :
565 34815 : av_flags = ndr_ntlmssp_find_av(&ntlmssp_state->client.av_pair_list,
566 : MsvAvFlags);
567 34815 : if (av_flags == NULL) {
568 34815 : av_flags = eol;
569 34815 : eol++;
570 34815 : count++;
571 34815 : *eol = *av_flags;
572 34815 : av_flags->AvId = MsvAvFlags;
573 34815 : av_flags->Value.AvFlags = 0;
574 : }
575 :
576 34815 : av_flags->Value.AvFlags |= NTLMSSP_AVFLAG_MIC_IN_AUTHENTICATE_MESSAGE;
577 34815 : ntlmssp_state->new_spnego = true;
578 : }
579 : }
580 :
581 : {
582 36550 : struct AV_PAIR *SingleHost = NULL;
583 :
584 36550 : SingleHost = eol;
585 36550 : eol++;
586 36550 : count++;
587 36550 : *eol = *SingleHost;
588 :
589 : /*
590 : * This is not really used, but we want to
591 : * add some more random bytes and match
592 : * Windows.
593 : */
594 36550 : SingleHost->AvId = MsvAvSingleHost;
595 36550 : SingleHost->Value.AvSingleHost.token_info.Flags = 0;
596 36550 : SingleHost->Value.AvSingleHost.token_info.TokenIL = 0;
597 36550 : generate_random_buffer(SingleHost->Value.AvSingleHost.token_info.MachineId,
598 : sizeof(SingleHost->Value.AvSingleHost.token_info.MachineId));
599 36550 : SingleHost->Value.AvSingleHost.remaining = data_blob_null;
600 : }
601 :
602 : {
603 36550 : struct AV_PAIR *ChannelBindings = NULL;
604 :
605 36550 : ChannelBindings = eol;
606 36550 : eol++;
607 36550 : count++;
608 36550 : *eol = *ChannelBindings;
609 :
610 : /*
611 : * gensec doesn't support channel bindings yet,
612 : * but we want to match Windows on the wire
613 : */
614 36550 : ChannelBindings->AvId = MsvChannelBindings;
615 36550 : memset(ChannelBindings->Value.ChannelBindings, 0,
616 : sizeof(ChannelBindings->Value.ChannelBindings));
617 : }
618 :
619 36550 : service = gensec_get_target_service(gensec_security);
620 36550 : hostname = gensec_get_target_hostname(gensec_security);
621 36550 : if (service != NULL && hostname != NULL) {
622 36119 : struct AV_PAIR *target = NULL;
623 :
624 36119 : target = eol;
625 36119 : eol++;
626 36119 : count++;
627 36119 : *eol = *target;
628 :
629 36119 : target->AvId = MsvAvTargetName;
630 36119 : target->Value.AvTargetName = talloc_asprintf(pairs, "%s/%s",
631 : service,
632 : hostname);
633 36119 : if (target->Value.AvTargetName == NULL) {
634 0 : return NT_STATUS_NO_MEMORY;
635 : }
636 : }
637 :
638 36550 : ntlmssp_state->client.av_pair_list.count = count;
639 36550 : ntlmssp_state->client.av_pair_list.pair = pairs;
640 :
641 36550 : err = ndr_push_struct_blob(&target_info,
642 : ntlmssp_state,
643 36412 : &ntlmssp_state->client.av_pair_list,
644 : (ndr_push_flags_fn_t)ndr_push_AV_PAIR_LIST);
645 36550 : if (!NDR_ERR_CODE_IS_SUCCESS(err)) {
646 0 : return NT_STATUS_NO_MEMORY;
647 : }
648 : }
649 :
650 37602 : nt_status = cli_credentials_get_ntlm_response(gensec_security->credentials, mem_ctx,
651 : &flags, challenge_blob,
652 : server_timestamp, target_info,
653 : &lm_response, &nt_response,
654 : &lm_session_key, &session_key);
655 37602 : if (!NT_STATUS_IS_OK(nt_status)) {
656 0 : return nt_status;
657 : }
658 :
659 37602 : if (!(flags & CLI_CRED_LANMAN_AUTH)) {
660 : /* LM Key is still possible, just silly, so we do not
661 : * allow it. Fortunately all LM crypto is off by
662 : * default and we require command line options to end
663 : * up here */
664 36886 : ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
665 : }
666 :
667 37602 : if (!(flags & CLI_CRED_NTLM2)) {
668 : /* NTLM2 is incompatible... */
669 1686 : ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
670 : }
671 :
672 37602 : if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
673 0 : && ntlmssp_state->allow_lm_key && lm_session_key.length == 16) {
674 0 : DATA_BLOB new_session_key = data_blob_talloc(mem_ctx, NULL, 16);
675 0 : if (lm_response.length == 24) {
676 0 : nt_status = SMBsesskeygen_lm_sess_key(lm_session_key.data,
677 0 : lm_response.data,
678 : new_session_key.data);
679 0 : if (!NT_STATUS_IS_OK(nt_status)) {
680 0 : return nt_status;
681 : }
682 : } else {
683 0 : static const uint8_t zeros[24];
684 0 : nt_status = SMBsesskeygen_lm_sess_key(lm_session_key.data,
685 : zeros,
686 : new_session_key.data);
687 0 : if (!NT_STATUS_IS_OK(nt_status)) {
688 0 : return nt_status;
689 : }
690 : }
691 0 : session_key = new_session_key;
692 0 : dump_data_pw("LM session key\n", session_key.data, session_key.length);
693 : }
694 :
695 :
696 : /* Key exchange encryptes a new client-generated session key with
697 : the password-derived key */
698 37602 : if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
699 : /* Make up a new session key */
700 148 : uint8_t client_session_key[16];
701 148 : gnutls_cipher_hd_t cipher_hnd;
702 37602 : gnutls_datum_t enc_session_key = {
703 37602 : .data = session_key.data,
704 37602 : .size = session_key.length,
705 : };
706 :
707 37602 : generate_random_buffer(client_session_key, sizeof(client_session_key));
708 :
709 : /* Encrypt the new session key with the old one */
710 37602 : encrypted_session_key = data_blob_talloc(ntlmssp_state,
711 : client_session_key, sizeof(client_session_key));
712 37602 : dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, encrypted_session_key.length);
713 :
714 37602 : rc = gnutls_cipher_init(&cipher_hnd,
715 : GNUTLS_CIPHER_ARCFOUR_128,
716 : &enc_session_key,
717 : NULL);
718 37602 : if (rc < 0) {
719 0 : nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
720 0 : ZERO_ARRAY(client_session_key);
721 0 : goto done;
722 : }
723 37602 : rc = gnutls_cipher_encrypt(cipher_hnd,
724 37454 : encrypted_session_key.data,
725 : encrypted_session_key.length);
726 37602 : gnutls_cipher_deinit(cipher_hnd);
727 37602 : if (rc < 0) {
728 0 : nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
729 0 : ZERO_ARRAY(client_session_key);
730 0 : goto done;
731 : }
732 :
733 37602 : dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length);
734 :
735 : /* Mark the new session key as the 'real' session key */
736 37602 : session_key = data_blob_talloc(mem_ctx, client_session_key, sizeof(client_session_key));
737 37602 : ZERO_ARRAY(client_session_key);
738 : }
739 :
740 : /* this generates the actual auth packet */
741 37750 : nt_status = msrpc_gen(mem_ctx,
742 : out, auth_gen_string,
743 : "NTLMSSP",
744 : NTLMSSP_AUTH,
745 : lm_response.data, lm_response.length,
746 : nt_response.data, nt_response.length,
747 : domain,
748 : user,
749 : workstation,
750 : encrypted_session_key.data, encrypted_session_key.length,
751 : ntlmssp_state->neg_flags,
752 37602 : version_blob.data, version_blob.length,
753 : mic_blob.data, mic_blob.length);
754 37602 : if (!NT_STATUS_IS_OK(nt_status)) {
755 0 : talloc_free(mem_ctx);
756 0 : return nt_status;
757 : }
758 :
759 37602 : if (DEBUGLEVEL >= 10) {
760 0 : struct AUTHENTICATE_MESSAGE *authenticate =
761 2 : talloc(ntlmssp_state, struct AUTHENTICATE_MESSAGE);
762 2 : if (authenticate != NULL) {
763 0 : NTSTATUS status;
764 2 : authenticate->NegotiateFlags = ntlmssp_state->neg_flags;
765 2 : status = ntlmssp_pull_AUTHENTICATE_MESSAGE(
766 : out, authenticate, authenticate);
767 2 : if (NT_STATUS_IS_OK(status)) {
768 2 : NDR_PRINT_DEBUG(AUTHENTICATE_MESSAGE,
769 : authenticate);
770 : }
771 2 : TALLOC_FREE(authenticate);
772 : }
773 : }
774 :
775 : /*
776 : * We always include the MIC, even without:
777 : * av_flags->Value.AvFlags |= NTLMSSP_AVFLAG_MIC_IN_AUTHENTICATE_MESSAGE;
778 : * ntlmssp_state->new_spnego = true;
779 : *
780 : * This matches a Windows client.
781 : */
782 37750 : rc = gnutls_hmac_init(&hmac_hnd,
783 : GNUTLS_MAC_MD5,
784 37602 : session_key.data,
785 37602 : MIN(session_key.length, 64));
786 37602 : if (rc < 0) {
787 0 : nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
788 0 : goto done;
789 : }
790 :
791 37750 : rc = gnutls_hmac(hmac_hnd,
792 37602 : ntlmssp_state->negotiate_blob.data,
793 : ntlmssp_state->negotiate_blob.length);
794 37602 : if (rc < 0) {
795 0 : gnutls_hmac_deinit(hmac_hnd, NULL);
796 0 : nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
797 0 : goto done;
798 : }
799 37602 : rc = gnutls_hmac(hmac_hnd, in.data, in.length);
800 37602 : if (rc < 0) {
801 0 : gnutls_hmac_deinit(hmac_hnd, NULL);
802 0 : nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
803 0 : goto done;
804 : }
805 37602 : rc = gnutls_hmac(hmac_hnd, out->data, out->length);
806 37602 : if (rc < 0) {
807 0 : gnutls_hmac_deinit(hmac_hnd, NULL);
808 0 : nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
809 0 : goto done;
810 : }
811 :
812 37602 : gnutls_hmac_deinit(hmac_hnd, mic_buffer);
813 :
814 37602 : memcpy(out->data + NTLMSSP_MIC_OFFSET, mic_buffer, NTLMSSP_MIC_SIZE);
815 37602 : ZERO_ARRAY(mic_buffer);
816 :
817 37602 : nt_status = NT_STATUS_OK;
818 37656 : done:
819 37656 : ZERO_ARRAY_LEN(ntlmssp_state->negotiate_blob.data,
820 : ntlmssp_state->negotiate_blob.length);
821 37656 : data_blob_free(&ntlmssp_state->negotiate_blob);
822 :
823 37656 : ntlmssp_state->session_key = session_key;
824 37656 : talloc_steal(ntlmssp_state, session_key.data);
825 :
826 37656 : DEBUG(3, ("NTLMSSP: Set final flags:\n"));
827 37656 : debug_ntlmssp_flags(ntlmssp_state->neg_flags);
828 :
829 37656 : talloc_steal(out_mem_ctx, out->data);
830 :
831 37656 : ntlmssp_state->expected_state = NTLMSSP_DONE;
832 :
833 37656 : if (gensec_ntlmssp_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
834 37310 : nt_status = ntlmssp_sign_init(ntlmssp_state);
835 37310 : if (!NT_STATUS_IS_OK(nt_status)) {
836 0 : DEBUG(1, ("Could not setup NTLMSSP signing/sealing system (error was: %s)\n",
837 : nt_errstr(nt_status)));
838 0 : talloc_free(mem_ctx);
839 0 : return nt_status;
840 : }
841 : }
842 :
843 37656 : talloc_free(mem_ctx);
844 37656 : return nt_status;
845 : }
846 :
847 38823 : NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security)
848 : {
849 298 : struct gensec_ntlmssp_context *gensec_ntlmssp;
850 298 : struct ntlmssp_state *ntlmssp_state;
851 298 : NTSTATUS nt_status;
852 :
853 38823 : nt_status = gensec_ntlmssp_start(gensec_security);
854 38823 : NT_STATUS_NOT_OK_RETURN(nt_status);
855 :
856 298 : gensec_ntlmssp =
857 38823 : talloc_get_type_abort(gensec_security->private_data,
858 : struct gensec_ntlmssp_context);
859 :
860 38823 : ntlmssp_state = talloc_zero(gensec_ntlmssp,
861 : struct ntlmssp_state);
862 38823 : if (!ntlmssp_state) {
863 0 : return NT_STATUS_NO_MEMORY;
864 : }
865 :
866 38823 : gensec_ntlmssp->ntlmssp_state = ntlmssp_state;
867 :
868 38823 : ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
869 :
870 38823 : ntlmssp_state->role = NTLMSSP_CLIENT;
871 :
872 38823 : ntlmssp_state->client.netbios_domain = lpcfg_workgroup(gensec_security->settings->lp_ctx);
873 38823 : ntlmssp_state->client.netbios_name = cli_credentials_get_workstation(gensec_security->credentials);
874 :
875 38823 : ntlmssp_state->unicode = gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "unicode", true);
876 :
877 39121 : ntlmssp_state->use_nt_response = \
878 38823 : gensec_setting_bool(gensec_security->settings,
879 : "ntlmssp_client",
880 : "send_nt_response",
881 : true);
882 :
883 38823 : ntlmssp_state->allow_lm_response = lpcfg_client_lanman_auth(gensec_security->settings->lp_ctx);
884 :
885 77646 : ntlmssp_state->allow_lm_key = (ntlmssp_state->allow_lm_response
886 60123 : && (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "allow_lm_key", false)
887 21598 : || gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "lm_key", false)));
888 :
889 38823 : ntlmssp_state->use_ntlmv2 = lpcfg_client_ntlmv2_auth(gensec_security->settings->lp_ctx);
890 :
891 38823 : ntlmssp_state->force_old_spnego = gensec_setting_bool(gensec_security->settings,
892 : "ntlmssp_client", "force_old_spnego", false);
893 :
894 38823 : ntlmssp_state->expected_state = NTLMSSP_INITIAL;
895 :
896 38823 : ntlmssp_state->neg_flags =
897 : NTLMSSP_NEGOTIATE_NTLM |
898 : NTLMSSP_NEGOTIATE_VERSION |
899 : NTLMSSP_REQUEST_TARGET;
900 :
901 38823 : if (ntlmssp_state->unicode) {
902 38823 : ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
903 : } else {
904 0 : ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
905 : }
906 :
907 38823 : if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "128bit", true)) {
908 38343 : ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_128;
909 : }
910 :
911 38823 : if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "56bit", false)) {
912 288 : ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_56;
913 : }
914 :
915 38823 : if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "lm_key", false)) {
916 608 : ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY;
917 : }
918 :
919 38823 : if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "keyexchange", true)) {
920 38823 : ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_KEY_EXCH;
921 : }
922 :
923 38823 : if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "alwayssign", true)) {
924 38823 : ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
925 : }
926 :
927 38823 : if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "ntlm2", true)) {
928 38215 : ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
929 : } else {
930 : /* apparently we can't do ntlmv2 if we don't do ntlm2 */
931 608 : ntlmssp_state->use_ntlmv2 = false;
932 : }
933 :
934 38823 : if (ntlmssp_state->use_ntlmv2) {
935 37938 : ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_NTLM2;
936 37938 : ntlmssp_state->allow_lm_response = false;
937 37938 : ntlmssp_state->allow_lm_key = false;
938 : }
939 :
940 38823 : if (ntlmssp_state->allow_lm_key) {
941 304 : ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY;
942 : }
943 :
944 38823 : if (gensec_security->want_features & GENSEC_FEATURE_SESSION_KEY) {
945 : /*
946 : * We need to set this to allow a later SetPassword
947 : * via the SAMR pipe to succeed. Strange.... We could
948 : * also add NTLMSSP_NEGOTIATE_SEAL here. JRA.
949 : *
950 : * Without this, Windows will not create the master key
951 : * that it thinks is only used for NTLMSSP signing and
952 : * sealing. (It is actually pulled out and used directly)
953 : *
954 : * We don't require this here as some servers (e.g. NetAPP)
955 : * doesn't support this.
956 : */
957 26740 : ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
958 : }
959 38823 : if (gensec_security->want_features & GENSEC_FEATURE_SIGN) {
960 12650 : ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN;
961 :
962 12650 : if (gensec_security->want_features & GENSEC_FEATURE_LDAP_STYLE) {
963 : /*
964 : * We need to handle NTLMSSP_NEGOTIATE_SIGN as
965 : * NTLMSSP_NEGOTIATE_SEAL if GENSEC_FEATURE_LDAP_STYLE
966 : * is requested.
967 : */
968 8997 : ntlmssp_state->force_wrap_seal = true;
969 : }
970 : }
971 38823 : if (ntlmssp_state->force_wrap_seal) {
972 0 : bool ret;
973 :
974 : /*
975 : * We want also work against old Samba servers
976 : * which didn't had GENSEC_FEATURE_LDAP_STYLE
977 : * we negotiate SEAL too. We may remove this
978 : * in a few years. As all servers should have
979 : * GENSEC_FEATURE_LDAP_STYLE by then.
980 : */
981 8997 : ret = gensec_setting_bool(gensec_security->settings,
982 : "ntlmssp_client",
983 : "ldap_style_send_seal",
984 : true);
985 8997 : if (ret) {
986 8992 : ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SEAL;
987 : }
988 : }
989 38823 : if (gensec_security->want_features & GENSEC_FEATURE_SEAL) {
990 10716 : ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN;
991 10716 : ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SEAL;
992 : }
993 38823 : if (gensec_security->want_features & GENSEC_FEATURE_NTLM_CCACHE) {
994 104 : ntlmssp_state->use_ccache = true;
995 : }
996 :
997 38823 : ntlmssp_state->neg_flags |= ntlmssp_state->required_flags;
998 38823 : ntlmssp_state->conf_flags = ntlmssp_state->neg_flags;
999 :
1000 38823 : return NT_STATUS_OK;
1001 : }
1002 :
1003 50 : NTSTATUS gensec_ntlmssp_resume_ccache_start(struct gensec_security *gensec_security)
1004 : {
1005 50 : struct gensec_ntlmssp_context *gensec_ntlmssp = NULL;
1006 0 : NTSTATUS status;
1007 :
1008 50 : status = gensec_ntlmssp_client_start(gensec_security);
1009 50 : if (!NT_STATUS_IS_OK(status)) {
1010 0 : return status;
1011 : }
1012 :
1013 50 : gensec_ntlmssp = talloc_get_type_abort(gensec_security->private_data,
1014 : struct gensec_ntlmssp_context);
1015 50 : gensec_ntlmssp->ntlmssp_state->use_ccache = false;
1016 50 : gensec_ntlmssp->ntlmssp_state->resume_ccache = true;
1017 50 : gensec_ntlmssp->ntlmssp_state->expected_state = NTLMSSP_NEGOTIATE;
1018 :
1019 50 : return NT_STATUS_OK;
1020 : }
|