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 39391 : NTSTATUS ntlmssp_client_initial(struct gensec_security *gensec_security,
60 : TALLOC_CTX *out_mem_ctx,
61 : DATA_BLOB in, DATA_BLOB *out)
62 : {
63 313 : struct gensec_ntlmssp_context *gensec_ntlmssp =
64 39391 : talloc_get_type_abort(gensec_security->private_data,
65 : struct gensec_ntlmssp_context);
66 39391 : struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
67 313 : NTSTATUS status;
68 39391 : const DATA_BLOB version_blob = ntlmssp_version_blob();
69 :
70 : /* generate the ntlmssp negotiate packet */
71 39704 : status = msrpc_gen(out_mem_ctx,
72 : out, "CddAAb",
73 : "NTLMSSP",
74 : NTLMSSP_NEGOTIATE,
75 : ntlmssp_state->neg_flags,
76 : "", /* domain */
77 : "", /* workstation */
78 39391 : version_blob.data, version_blob.length);
79 39391 : 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 39391 : 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 39391 : ntlmssp_state->negotiate_blob = data_blob_dup_talloc(ntlmssp_state,
100 : *out);
101 39391 : if (ntlmssp_state->negotiate_blob.length != out->length) {
102 0 : return NT_STATUS_NO_MEMORY;
103 : }
104 :
105 39391 : ntlmssp_state->expected_state = NTLMSSP_CHALLENGE;
106 :
107 39391 : 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 38479 : 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 165 : struct gensec_ntlmssp_context *gensec_ntlmssp =
230 38479 : talloc_get_type_abort(gensec_security->private_data,
231 : struct gensec_ntlmssp_context);
232 38479 : struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
233 38479 : uint32_t chal_flags, ntlmssp_command, unkn1 = 0, unkn2 = 0;
234 165 : DATA_BLOB server_domain_blob;
235 165 : DATA_BLOB challenge_blob;
236 38479 : DATA_BLOB target_info = data_blob(NULL, 0);
237 165 : char *server_domain;
238 165 : const char *chal_parse_string;
239 38479 : const char *chal_parse_string_short = NULL;
240 165 : const char *auth_gen_string;
241 38479 : DATA_BLOB lm_response = data_blob(NULL, 0);
242 38479 : DATA_BLOB nt_response = data_blob(NULL, 0);
243 38479 : DATA_BLOB session_key = data_blob(NULL, 0);
244 38479 : DATA_BLOB lm_session_key = data_blob(NULL, 0);
245 38479 : DATA_BLOB encrypted_session_key = data_blob(NULL, 0);
246 165 : NTSTATUS nt_status;
247 38479 : int flags = 0;
248 38479 : const char *user = NULL, *domain = NULL, *workstation = NULL;
249 38479 : bool is_anonymous = false;
250 38479 : const DATA_BLOB version_blob = ntlmssp_version_blob();
251 38479 : const NTTIME *server_timestamp = NULL;
252 38479 : uint8_t mic_buffer[NTLMSSP_MIC_SIZE] = { 0, };
253 38479 : DATA_BLOB mic_blob = data_blob_const(mic_buffer, sizeof(mic_buffer));
254 38479 : gnutls_hmac_hd_t hmac_hnd = NULL;
255 165 : int rc;
256 :
257 38479 : TALLOC_CTX *mem_ctx = talloc_new(out_mem_ctx);
258 38479 : if (!mem_ctx) {
259 0 : return NT_STATUS_NO_MEMORY;
260 : }
261 :
262 38479 : 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 38479 : data_blob_free(&server_domain_blob);
276 :
277 38479 : DEBUG(3, ("Got challenge flags:\n"));
278 38479 : debug_ntlmssp_flags(chal_flags);
279 :
280 38479 : nt_status = ntlmssp_handle_neg_flags(ntlmssp_state,
281 : chal_flags, "challenge");
282 38479 : if (!NT_STATUS_IS_OK(nt_status)) {
283 0 : return nt_status;
284 : }
285 :
286 38479 : if (ntlmssp_state->unicode) {
287 38479 : if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) {
288 38314 : chal_parse_string = "CdUdbddB";
289 : } else {
290 0 : chal_parse_string = "CdUdbdd";
291 0 : chal_parse_string_short = "CdUdb";
292 : }
293 38314 : 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 38479 : 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 38479 : 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 38479 : if (chal_flags & NTLMSSP_TARGET_TYPE_SERVER) {
366 11751 : ntlmssp_state->server.is_standalone = true;
367 : } else {
368 26728 : ntlmssp_state->server.is_standalone = false;
369 : }
370 : /* TODO: parse struct_blob and fill in the rest */
371 38479 : ntlmssp_state->server.netbios_name = "";
372 38479 : ntlmssp_state->server.netbios_domain = talloc_move(ntlmssp_state, &server_domain);
373 38479 : ntlmssp_state->server.dns_name = "";
374 38479 : ntlmssp_state->server.dns_domain = "";
375 :
376 38479 : if (challenge_blob.length != 8) {
377 0 : talloc_free(mem_ctx);
378 0 : return NT_STATUS_INVALID_PARAMETER;
379 : }
380 :
381 38479 : is_anonymous = cli_credentials_is_anonymous(gensec_security->credentials);
382 38479 : cli_credentials_get_ntlm_username_domain(gensec_security->credentials, mem_ctx,
383 : &user, &domain);
384 :
385 38479 : workstation = cli_credentials_get_workstation(gensec_security->credentials);
386 :
387 38479 : if (user == NULL) {
388 0 : DEBUG(10, ("User is NULL, returning INVALID_PARAMETER\n"));
389 0 : return NT_STATUS_INVALID_PARAMETER;
390 : }
391 :
392 38479 : if (domain == NULL) {
393 97 : DEBUG(10, ("Domain is NULL, returning INVALID_PARAMETER\n"));
394 97 : return NT_STATUS_INVALID_PARAMETER;
395 : }
396 :
397 38382 : if (workstation == NULL) {
398 0 : DEBUG(10, ("Workstation is NULL, returning INVALID_PARAMETER\n"));
399 0 : return NT_STATUS_INVALID_PARAMETER;
400 : }
401 :
402 38382 : if (is_anonymous) {
403 1111 : ntlmssp_state->neg_flags |= NTLMSSP_ANONYMOUS;
404 : /*
405 : * don't use the ccache for anonymous auth
406 : */
407 1111 : ntlmssp_state->use_ccache = false;
408 : }
409 38382 : if (ntlmssp_state->use_ccache) {
410 103 : struct samr_Password *nt_hash = NULL;
411 :
412 : /*
413 : * If we have a password given we don't
414 : * use the ccache
415 : */
416 103 : nt_hash = cli_credentials_get_nt_hash(gensec_security->credentials,
417 : mem_ctx);
418 103 : if (nt_hash != NULL) {
419 49 : ZERO_STRUCTP(nt_hash);
420 49 : TALLOC_FREE(nt_hash);
421 49 : ntlmssp_state->use_ccache = false;
422 : }
423 : }
424 :
425 38382 : 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 38328 : if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
494 37720 : flags |= CLI_CRED_NTLM2;
495 : }
496 38328 : if (ntlmssp_state->use_ntlmv2) {
497 37443 : flags |= CLI_CRED_NTLMv2_AUTH;
498 : }
499 38328 : if (ntlmssp_state->use_nt_response) {
500 38328 : flags |= CLI_CRED_NTLM_AUTH;
501 : }
502 38328 : if (ntlmssp_state->allow_lm_response) {
503 885 : flags |= CLI_CRED_LANMAN_AUTH;
504 : }
505 :
506 38328 : if (target_info.length != 0 && !is_anonymous) {
507 37217 : struct AV_PAIR *pairs = NULL;
508 37217 : uint32_t count = 0;
509 145 : enum ndr_err_code err;
510 37217 : struct AV_PAIR *timestamp = NULL;
511 37217 : struct AV_PAIR *eol = NULL;
512 37217 : uint32_t i = 0;
513 37217 : const char *service = NULL;
514 37217 : const char *hostname = NULL;
515 :
516 37362 : err = ndr_pull_struct_blob(&target_info,
517 : ntlmssp_state,
518 37217 : &ntlmssp_state->server.av_pair_list,
519 : (ndr_pull_flags_fn_t)ndr_pull_AV_PAIR_LIST);
520 37217 : if (!NDR_ERR_CODE_IS_SUCCESS(err)) {
521 0 : return ndr_map_error2ntstatus(err);
522 : }
523 :
524 37217 : count = ntlmssp_state->server.av_pair_list.count;
525 : /*
526 : * We need room for Flags, SingleHost,
527 : * ChannelBindings and Target
528 : */
529 37217 : pairs = talloc_zero_array(ntlmssp_state, struct AV_PAIR,
530 : count + 4);
531 37217 : if (pairs == NULL) {
532 0 : return NT_STATUS_NO_MEMORY;
533 : }
534 :
535 259053 : for (i = 0; i < count; i++) {
536 221836 : pairs[i] = ntlmssp_state->server.av_pair_list.pair[i];
537 : }
538 :
539 37217 : ntlmssp_state->client.av_pair_list.count = count;
540 37217 : ntlmssp_state->client.av_pair_list.pair = pairs;
541 :
542 37217 : eol = ndr_ntlmssp_find_av(&ntlmssp_state->client.av_pair_list,
543 : MsvAvEOL);
544 37217 : if (eol == NULL) {
545 0 : return NT_STATUS_INVALID_PARAMETER;
546 : }
547 :
548 37217 : timestamp = ndr_ntlmssp_find_av(&ntlmssp_state->client.av_pair_list,
549 : MsvAvTimestamp);
550 37217 : if (timestamp != NULL) {
551 35751 : uint32_t sign_features =
552 : GENSEC_FEATURE_SESSION_KEY |
553 : GENSEC_FEATURE_SIGN |
554 : GENSEC_FEATURE_SEAL;
555 :
556 35751 : server_timestamp = ×tamp->Value.AvTimestamp;
557 :
558 35751 : if (ntlmssp_state->force_old_spnego) {
559 0 : sign_features = 0;
560 : }
561 :
562 35751 : if (gensec_security->want_features & sign_features) {
563 35420 : struct AV_PAIR *av_flags = NULL;
564 :
565 35420 : av_flags = ndr_ntlmssp_find_av(&ntlmssp_state->client.av_pair_list,
566 : MsvAvFlags);
567 35420 : if (av_flags == NULL) {
568 35420 : av_flags = eol;
569 35420 : eol++;
570 35420 : count++;
571 35420 : *eol = *av_flags;
572 35420 : av_flags->AvId = MsvAvFlags;
573 35420 : av_flags->Value.AvFlags = 0;
574 : }
575 :
576 35420 : av_flags->Value.AvFlags |= NTLMSSP_AVFLAG_MIC_IN_AUTHENTICATE_MESSAGE;
577 35420 : ntlmssp_state->new_spnego = true;
578 : }
579 : }
580 :
581 : {
582 37217 : struct AV_PAIR *SingleHost = NULL;
583 :
584 37217 : SingleHost = eol;
585 37217 : eol++;
586 37217 : count++;
587 37217 : *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 37217 : SingleHost->AvId = MsvAvSingleHost;
595 37217 : SingleHost->Value.AvSingleHost.token_info.Flags = 0;
596 37217 : SingleHost->Value.AvSingleHost.token_info.TokenIL = 0;
597 37217 : generate_random_buffer(SingleHost->Value.AvSingleHost.token_info.MachineId,
598 : sizeof(SingleHost->Value.AvSingleHost.token_info.MachineId));
599 37217 : SingleHost->Value.AvSingleHost.remaining = data_blob_null;
600 : }
601 :
602 37217 : if (!(gensec_security->want_features & GENSEC_FEATURE_CB_OPTIONAL)
603 40 : || gensec_security->channel_bindings != NULL)
604 : {
605 37202 : struct AV_PAIR *ChannelBindings = NULL;
606 :
607 37202 : ChannelBindings = eol;
608 37202 : eol++;
609 37202 : count++;
610 37202 : *eol = *ChannelBindings;
611 :
612 37202 : ChannelBindings->AvId = MsvChannelBindings;
613 37347 : nt_status = ntlmssp_hash_channel_bindings(gensec_security,
614 37202 : ChannelBindings->Value.ChannelBindings);
615 37202 : if (!NT_STATUS_IS_OK(nt_status)) {
616 0 : return nt_status;
617 : }
618 : }
619 :
620 37217 : service = gensec_get_target_service(gensec_security);
621 37217 : hostname = gensec_get_target_hostname(gensec_security);
622 37217 : if (service != NULL && hostname != NULL) {
623 36786 : struct AV_PAIR *target = NULL;
624 :
625 36786 : target = eol;
626 36786 : eol++;
627 36786 : count++;
628 36786 : *eol = *target;
629 :
630 36786 : target->AvId = MsvAvTargetName;
631 36786 : target->Value.AvTargetName = talloc_asprintf(pairs, "%s/%s",
632 : service,
633 : hostname);
634 36786 : if (target->Value.AvTargetName == NULL) {
635 0 : return NT_STATUS_NO_MEMORY;
636 : }
637 : }
638 :
639 37217 : ntlmssp_state->client.av_pair_list.count = count;
640 37217 : ntlmssp_state->client.av_pair_list.pair = pairs;
641 :
642 37217 : err = ndr_push_struct_blob(&target_info,
643 : ntlmssp_state,
644 37072 : &ntlmssp_state->client.av_pair_list,
645 : (ndr_push_flags_fn_t)ndr_push_AV_PAIR_LIST);
646 37217 : if (!NDR_ERR_CODE_IS_SUCCESS(err)) {
647 0 : return NT_STATUS_NO_MEMORY;
648 : }
649 : }
650 :
651 38328 : nt_status = cli_credentials_get_ntlm_response(gensec_security->credentials, mem_ctx,
652 : &flags, challenge_blob,
653 : server_timestamp, target_info,
654 : &lm_response, &nt_response,
655 : &lm_session_key, &session_key);
656 38328 : if (!NT_STATUS_IS_OK(nt_status)) {
657 0 : return nt_status;
658 : }
659 :
660 38328 : if (!(flags & CLI_CRED_LANMAN_AUTH)) {
661 : /* LM Key is still possible, just silly, so we do not
662 : * allow it. Fortunately all LM crypto is off by
663 : * default and we require command line options to end
664 : * up here */
665 37612 : ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
666 : }
667 :
668 38328 : if (!(flags & CLI_CRED_NTLM2)) {
669 : /* NTLM2 is incompatible... */
670 1745 : ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
671 : }
672 :
673 38328 : if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
674 0 : && ntlmssp_state->allow_lm_key && lm_session_key.length == 16) {
675 0 : DATA_BLOB new_session_key = data_blob_talloc(mem_ctx, NULL, 16);
676 0 : if (lm_response.length == 24) {
677 0 : nt_status = SMBsesskeygen_lm_sess_key(lm_session_key.data,
678 0 : lm_response.data,
679 : new_session_key.data);
680 0 : if (!NT_STATUS_IS_OK(nt_status)) {
681 0 : return nt_status;
682 : }
683 : } else {
684 0 : static const uint8_t zeros[24];
685 0 : nt_status = SMBsesskeygen_lm_sess_key(lm_session_key.data,
686 : zeros,
687 : new_session_key.data);
688 0 : if (!NT_STATUS_IS_OK(nt_status)) {
689 0 : return nt_status;
690 : }
691 : }
692 0 : session_key = new_session_key;
693 0 : dump_data_pw("LM session key\n", session_key.data, session_key.length);
694 : }
695 :
696 :
697 : /* Key exchange encryptes a new client-generated session key with
698 : the password-derived key */
699 38328 : if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
700 : /* Make up a new session key */
701 165 : uint8_t client_session_key[16];
702 165 : gnutls_cipher_hd_t cipher_hnd;
703 38328 : gnutls_datum_t enc_session_key = {
704 38328 : .data = session_key.data,
705 38328 : .size = session_key.length,
706 : };
707 :
708 38328 : generate_random_buffer(client_session_key, sizeof(client_session_key));
709 :
710 : /* Encrypt the new session key with the old one */
711 38328 : encrypted_session_key = data_blob_talloc(ntlmssp_state,
712 : client_session_key, sizeof(client_session_key));
713 38328 : dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, encrypted_session_key.length);
714 :
715 38328 : rc = gnutls_cipher_init(&cipher_hnd,
716 : GNUTLS_CIPHER_ARCFOUR_128,
717 : &enc_session_key,
718 : NULL);
719 38328 : if (rc < 0) {
720 0 : nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
721 0 : ZERO_ARRAY(client_session_key);
722 0 : goto done;
723 : }
724 38328 : rc = gnutls_cipher_encrypt(cipher_hnd,
725 38163 : encrypted_session_key.data,
726 : encrypted_session_key.length);
727 38328 : gnutls_cipher_deinit(cipher_hnd);
728 38328 : if (rc < 0) {
729 0 : nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
730 0 : ZERO_ARRAY(client_session_key);
731 0 : goto done;
732 : }
733 :
734 38328 : dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length);
735 :
736 : /* Mark the new session key as the 'real' session key */
737 38328 : session_key = data_blob_talloc(mem_ctx, client_session_key, sizeof(client_session_key));
738 38328 : ZERO_ARRAY(client_session_key);
739 : }
740 :
741 : /* this generates the actual auth packet */
742 38493 : nt_status = msrpc_gen(mem_ctx,
743 : out, auth_gen_string,
744 : "NTLMSSP",
745 : NTLMSSP_AUTH,
746 : lm_response.data, lm_response.length,
747 : nt_response.data, nt_response.length,
748 : domain,
749 : user,
750 : workstation,
751 : encrypted_session_key.data, encrypted_session_key.length,
752 : ntlmssp_state->neg_flags,
753 38328 : version_blob.data, version_blob.length,
754 : mic_blob.data, mic_blob.length);
755 38328 : if (!NT_STATUS_IS_OK(nt_status)) {
756 0 : talloc_free(mem_ctx);
757 0 : return nt_status;
758 : }
759 :
760 38328 : if (DEBUGLEVEL >= 10) {
761 0 : struct AUTHENTICATE_MESSAGE *authenticate =
762 2 : talloc(ntlmssp_state, struct AUTHENTICATE_MESSAGE);
763 2 : if (authenticate != NULL) {
764 0 : NTSTATUS status;
765 2 : authenticate->NegotiateFlags = ntlmssp_state->neg_flags;
766 2 : status = ntlmssp_pull_AUTHENTICATE_MESSAGE(
767 : out, authenticate, authenticate);
768 2 : if (NT_STATUS_IS_OK(status)) {
769 2 : NDR_PRINT_DEBUG(AUTHENTICATE_MESSAGE,
770 : authenticate);
771 : }
772 2 : TALLOC_FREE(authenticate);
773 : }
774 : }
775 :
776 : /*
777 : * We always include the MIC, even without:
778 : * av_flags->Value.AvFlags |= NTLMSSP_AVFLAG_MIC_IN_AUTHENTICATE_MESSAGE;
779 : * ntlmssp_state->new_spnego = true;
780 : *
781 : * This matches a Windows client.
782 : */
783 38493 : rc = gnutls_hmac_init(&hmac_hnd,
784 : GNUTLS_MAC_MD5,
785 38328 : session_key.data,
786 38328 : MIN(session_key.length, 64));
787 38328 : if (rc < 0) {
788 0 : nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
789 0 : goto done;
790 : }
791 :
792 38493 : rc = gnutls_hmac(hmac_hnd,
793 38328 : ntlmssp_state->negotiate_blob.data,
794 : ntlmssp_state->negotiate_blob.length);
795 38328 : if (rc < 0) {
796 0 : gnutls_hmac_deinit(hmac_hnd, NULL);
797 0 : nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
798 0 : goto done;
799 : }
800 38328 : rc = gnutls_hmac(hmac_hnd, in.data, in.length);
801 38328 : if (rc < 0) {
802 0 : gnutls_hmac_deinit(hmac_hnd, NULL);
803 0 : nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
804 0 : goto done;
805 : }
806 38328 : rc = gnutls_hmac(hmac_hnd, out->data, out->length);
807 38328 : if (rc < 0) {
808 0 : gnutls_hmac_deinit(hmac_hnd, NULL);
809 0 : nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
810 0 : goto done;
811 : }
812 :
813 38328 : gnutls_hmac_deinit(hmac_hnd, mic_buffer);
814 :
815 38328 : memcpy(out->data + NTLMSSP_MIC_OFFSET, mic_buffer, NTLMSSP_MIC_SIZE);
816 38328 : ZERO_ARRAY(mic_buffer);
817 :
818 38328 : nt_status = NT_STATUS_OK;
819 38382 : done:
820 38382 : ZERO_ARRAY_LEN(ntlmssp_state->negotiate_blob.data,
821 : ntlmssp_state->negotiate_blob.length);
822 38382 : data_blob_free(&ntlmssp_state->negotiate_blob);
823 :
824 38382 : ntlmssp_state->session_key = session_key;
825 38382 : talloc_steal(ntlmssp_state, session_key.data);
826 :
827 38382 : DEBUG(3, ("NTLMSSP: Set final flags:\n"));
828 38382 : debug_ntlmssp_flags(ntlmssp_state->neg_flags);
829 :
830 38382 : talloc_steal(out_mem_ctx, out->data);
831 :
832 38382 : ntlmssp_state->expected_state = NTLMSSP_DONE;
833 :
834 38382 : if (gensec_ntlmssp_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
835 37972 : nt_status = ntlmssp_sign_init(ntlmssp_state);
836 37972 : if (!NT_STATUS_IS_OK(nt_status)) {
837 0 : DEBUG(1, ("Could not setup NTLMSSP signing/sealing system (error was: %s)\n",
838 : nt_errstr(nt_status)));
839 0 : talloc_free(mem_ctx);
840 0 : return nt_status;
841 : }
842 : }
843 :
844 38382 : talloc_free(mem_ctx);
845 38382 : return nt_status;
846 : }
847 :
848 39548 : NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security)
849 : {
850 315 : struct gensec_ntlmssp_context *gensec_ntlmssp;
851 315 : struct ntlmssp_state *ntlmssp_state;
852 315 : NTSTATUS nt_status;
853 :
854 39548 : nt_status = gensec_ntlmssp_start(gensec_security);
855 39548 : NT_STATUS_NOT_OK_RETURN(nt_status);
856 :
857 315 : gensec_ntlmssp =
858 39548 : talloc_get_type_abort(gensec_security->private_data,
859 : struct gensec_ntlmssp_context);
860 :
861 39548 : ntlmssp_state = talloc_zero(gensec_ntlmssp,
862 : struct ntlmssp_state);
863 39548 : if (!ntlmssp_state) {
864 0 : return NT_STATUS_NO_MEMORY;
865 : }
866 :
867 39548 : gensec_ntlmssp->ntlmssp_state = ntlmssp_state;
868 :
869 39548 : ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
870 :
871 39548 : ntlmssp_state->role = NTLMSSP_CLIENT;
872 :
873 39548 : ntlmssp_state->client.netbios_domain = lpcfg_workgroup(gensec_security->settings->lp_ctx);
874 39548 : ntlmssp_state->client.netbios_name = cli_credentials_get_workstation(gensec_security->credentials);
875 :
876 39548 : ntlmssp_state->unicode = gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "unicode", true);
877 :
878 39863 : ntlmssp_state->use_nt_response = \
879 39548 : gensec_setting_bool(gensec_security->settings,
880 : "ntlmssp_client",
881 : "send_nt_response",
882 : true);
883 :
884 39548 : ntlmssp_state->allow_lm_response = lpcfg_client_lanman_auth(gensec_security->settings->lp_ctx);
885 :
886 79096 : ntlmssp_state->allow_lm_key = (ntlmssp_state->allow_lm_response
887 61132 : && (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "allow_lm_key", false)
888 21899 : || gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "lm_key", false)));
889 :
890 39548 : ntlmssp_state->use_ntlmv2 = lpcfg_client_ntlmv2_auth(gensec_security->settings->lp_ctx);
891 :
892 39548 : ntlmssp_state->force_old_spnego = gensec_setting_bool(gensec_security->settings,
893 : "ntlmssp_client", "force_old_spnego", false);
894 :
895 39548 : ntlmssp_state->expected_state = NTLMSSP_INITIAL;
896 :
897 39548 : ntlmssp_state->neg_flags =
898 : NTLMSSP_NEGOTIATE_NTLM |
899 : NTLMSSP_NEGOTIATE_VERSION |
900 : NTLMSSP_REQUEST_TARGET;
901 :
902 39548 : if (ntlmssp_state->unicode) {
903 39548 : ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
904 : } else {
905 0 : ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
906 : }
907 :
908 39548 : if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "128bit", true)) {
909 39068 : ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_128;
910 : }
911 :
912 39548 : if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "56bit", false)) {
913 288 : ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_56;
914 : }
915 :
916 39548 : if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "lm_key", false)) {
917 608 : ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY;
918 : }
919 :
920 39548 : if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "keyexchange", true)) {
921 39548 : ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_KEY_EXCH;
922 : }
923 :
924 39548 : if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "alwayssign", true)) {
925 39548 : ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
926 : }
927 :
928 39548 : if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "ntlm2", true)) {
929 38940 : ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
930 : } else {
931 : /* apparently we can't do ntlmv2 if we don't do ntlm2 */
932 608 : ntlmssp_state->use_ntlmv2 = false;
933 : }
934 :
935 39548 : if (ntlmssp_state->use_ntlmv2) {
936 38663 : ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_NTLM2;
937 38663 : ntlmssp_state->allow_lm_response = false;
938 38663 : ntlmssp_state->allow_lm_key = false;
939 : }
940 :
941 39548 : if (ntlmssp_state->allow_lm_key) {
942 304 : ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY;
943 : }
944 :
945 39548 : if (gensec_security->want_features & GENSEC_FEATURE_SESSION_KEY) {
946 : /*
947 : * We need to set this to allow a later SetPassword
948 : * via the SAMR pipe to succeed. Strange.... We could
949 : * also add NTLMSSP_NEGOTIATE_SEAL here. JRA.
950 : *
951 : * Without this, Windows will not create the master key
952 : * that it thinks is only used for NTLMSSP signing and
953 : * sealing. (It is actually pulled out and used directly)
954 : *
955 : * We don't require this here as some servers (e.g. NetAPP)
956 : * doesn't support this.
957 : */
958 27341 : ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
959 : }
960 39548 : if (gensec_security->want_features & GENSEC_FEATURE_SIGN) {
961 12680 : ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN;
962 :
963 12680 : if (gensec_security->want_features & GENSEC_FEATURE_LDAP_STYLE) {
964 : /*
965 : * We need to handle NTLMSSP_NEGOTIATE_SIGN as
966 : * NTLMSSP_NEGOTIATE_SEAL if GENSEC_FEATURE_LDAP_STYLE
967 : * is requested.
968 : */
969 9019 : ntlmssp_state->force_wrap_seal = true;
970 : }
971 : }
972 39548 : if (ntlmssp_state->force_wrap_seal) {
973 0 : bool ret;
974 :
975 : /*
976 : * We want also work against old Samba servers
977 : * which didn't had GENSEC_FEATURE_LDAP_STYLE
978 : * we negotiate SEAL too. We may remove this
979 : * in a few years. As all servers should have
980 : * GENSEC_FEATURE_LDAP_STYLE by then.
981 : */
982 9019 : ret = gensec_setting_bool(gensec_security->settings,
983 : "ntlmssp_client",
984 : "ldap_style_send_seal",
985 : true);
986 9019 : if (ret) {
987 9014 : ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SEAL;
988 : }
989 : }
990 39548 : if (gensec_security->want_features & GENSEC_FEATURE_SEAL) {
991 10777 : ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN;
992 10777 : ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SEAL;
993 : }
994 39548 : if (gensec_security->want_features & GENSEC_FEATURE_NTLM_CCACHE) {
995 103 : ntlmssp_state->use_ccache = true;
996 : }
997 :
998 39548 : ntlmssp_state->neg_flags |= ntlmssp_state->required_flags;
999 39548 : ntlmssp_state->conf_flags = ntlmssp_state->neg_flags;
1000 :
1001 39548 : return NT_STATUS_OK;
1002 : }
1003 :
1004 50 : NTSTATUS gensec_ntlmssp_resume_ccache_start(struct gensec_security *gensec_security)
1005 : {
1006 50 : struct gensec_ntlmssp_context *gensec_ntlmssp = NULL;
1007 0 : NTSTATUS status;
1008 :
1009 50 : status = gensec_ntlmssp_client_start(gensec_security);
1010 50 : if (!NT_STATUS_IS_OK(status)) {
1011 0 : return status;
1012 : }
1013 :
1014 50 : gensec_ntlmssp = talloc_get_type_abort(gensec_security->private_data,
1015 : struct gensec_ntlmssp_context);
1016 50 : gensec_ntlmssp->ntlmssp_state->use_ccache = false;
1017 50 : gensec_ntlmssp->ntlmssp_state->resume_ccache = true;
1018 50 : gensec_ntlmssp->ntlmssp_state->expected_state = NTLMSSP_NEGOTIATE;
1019 :
1020 50 : return NT_STATUS_OK;
1021 : }
|