auth: Fix code spelling
[gd/samba-autobuild/.git] / auth / ntlmssp / ntlmssp_client.c
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 NTSTATUS ntlmssp_client_initial(struct gensec_security *gensec_security,
60                                 TALLOC_CTX *out_mem_ctx,
61                                 DATA_BLOB in, DATA_BLOB *out)
62 {
63         struct gensec_ntlmssp_context *gensec_ntlmssp =
64                 talloc_get_type_abort(gensec_security->private_data,
65                                       struct gensec_ntlmssp_context);
66         struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
67         NTSTATUS status;
68         const DATA_BLOB version_blob = ntlmssp_version_blob();
69
70         /* generate the ntlmssp negotiate packet */
71         status = msrpc_gen(out_mem_ctx,
72                   out, "CddAAb",
73                   "NTLMSSP",
74                   NTLMSSP_NEGOTIATE,
75                   ntlmssp_state->neg_flags,
76                   "", /* domain */
77                   "", /* workstation */
78                   version_blob.data, version_blob.length);
79         if (!NT_STATUS_IS_OK(status)) {
80                 DEBUG(0, ("ntlmssp_client_initial: failed to generate "
81                           "ntlmssp negotiate packet\n"));
82                 return status;
83         }
84
85         if (DEBUGLEVEL >= 10) {
86                 struct NEGOTIATE_MESSAGE *negotiate = talloc(
87                         ntlmssp_state, struct NEGOTIATE_MESSAGE);
88                 if (negotiate != NULL) {
89                         status = ntlmssp_pull_NEGOTIATE_MESSAGE(
90                                 out, negotiate, negotiate);
91                         if (NT_STATUS_IS_OK(status)) {
92                                 NDR_PRINT_DEBUG(NEGOTIATE_MESSAGE,
93                                                 negotiate);
94                         }
95                         TALLOC_FREE(negotiate);
96                 }
97         }
98
99         ntlmssp_state->negotiate_blob = data_blob_dup_talloc(ntlmssp_state,
100                                                              *out);
101         if (ntlmssp_state->negotiate_blob.length != out->length) {
102                 return NT_STATUS_NO_MEMORY;
103         }
104
105         ntlmssp_state->expected_state = NTLMSSP_CHALLENGE;
106
107         return NT_STATUS_MORE_PROCESSING_REQUIRED;
108 }
109
110 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         struct gensec_ntlmssp_context *gensec_ntlmssp =
115                 talloc_get_type_abort(gensec_security->private_data,
116                                       struct gensec_ntlmssp_context);
117         struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
118         uint32_t neg_flags = 0;
119         uint32_t ntlmssp_command;
120         NTSTATUS status;
121         bool ok;
122
123         *out = data_blob_null;
124
125         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                 DEBUG(10, ("%s: in.length==%u force_old_spnego!\n",
135                            __func__, (unsigned int)in.length));
136                 ntlmssp_state->force_old_spnego = true;
137                 ntlmssp_state->neg_flags |= ntlmssp_state->required_flags;
138                 ntlmssp_state->required_flags = 0;
139                 ntlmssp_state->expected_state = NTLMSSP_CHALLENGE;
140                 return NT_STATUS_MORE_PROCESSING_REQUIRED;
141         }
142
143         /* parse the NTLMSSP packet */
144
145         if (in.length > UINT16_MAX) {
146                 DEBUG(1, ("%s: reject large request of length %u\n",
147                         __func__, (unsigned int)in.length));
148                 return NT_STATUS_INVALID_PARAMETER;
149         }
150
151         ok = msrpc_parse(ntlmssp_state, &in, "Cdd",
152                          "NTLMSSP",
153                          &ntlmssp_command,
154                          &neg_flags);
155         if (!ok) {
156                 DEBUG(1, ("%s: failed to parse NTLMSSP Negotiate of length %u\n",
157                         __func__, (unsigned int)in.length));
158                 dump_data(2, in.data, in.length);
159                 return NT_STATUS_INVALID_PARAMETER;
160         }
161
162         if (ntlmssp_command != NTLMSSP_NEGOTIATE) {
163                 DEBUG(1, ("%s: no NTLMSSP Negotiate message (length %u)\n",
164                         __func__, (unsigned int)in.length));
165                 dump_data(2, in.data, in.length);
166                 return NT_STATUS_INVALID_PARAMETER;
167         }
168
169         ntlmssp_state->neg_flags = neg_flags;
170         DEBUG(3, ("Imported Negotiate flags:\n"));
171         debug_ntlmssp_flags(neg_flags);
172
173         if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_UNICODE) {
174                 ntlmssp_state->unicode = true;
175         } else {
176                 ntlmssp_state->unicode = false;
177         }
178
179         if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN) {
180                 gensec_security->want_features |= GENSEC_FEATURE_SIGN;
181         }
182
183         if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL) {
184                 gensec_security->want_features |= GENSEC_FEATURE_SEAL;
185         }
186
187         ntlmssp_state->conf_flags = ntlmssp_state->neg_flags;
188         ntlmssp_state->required_flags = 0;
189
190         if (DEBUGLEVEL >= 10) {
191                 struct NEGOTIATE_MESSAGE *negotiate = talloc(
192                         ntlmssp_state, struct NEGOTIATE_MESSAGE);
193                 if (negotiate != NULL) {
194                         status = ntlmssp_pull_NEGOTIATE_MESSAGE(
195                                 &in, negotiate, negotiate);
196                         if (NT_STATUS_IS_OK(status)) {
197                                 NDR_PRINT_DEBUG(NEGOTIATE_MESSAGE,
198                                                 negotiate);
199                         }
200                         TALLOC_FREE(negotiate);
201                 }
202         }
203
204         ntlmssp_state->negotiate_blob = data_blob_dup_talloc(ntlmssp_state,
205                                                              in);
206         if (ntlmssp_state->negotiate_blob.length != in.length) {
207                 return NT_STATUS_NO_MEMORY;
208         }
209
210         ntlmssp_state->expected_state = NTLMSSP_CHALLENGE;
211
212         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 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         struct gensec_ntlmssp_context *gensec_ntlmssp =
230                 talloc_get_type_abort(gensec_security->private_data,
231                                       struct gensec_ntlmssp_context);
232         struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
233         uint32_t chal_flags, ntlmssp_command, unkn1 = 0, unkn2 = 0;
234         DATA_BLOB server_domain_blob;
235         DATA_BLOB challenge_blob;
236         DATA_BLOB target_info = data_blob(NULL, 0);
237         char *server_domain;
238         const char *chal_parse_string;
239         const char *chal_parse_string_short = NULL;
240         const char *auth_gen_string;
241         DATA_BLOB lm_response = data_blob(NULL, 0);
242         DATA_BLOB nt_response = data_blob(NULL, 0);
243         DATA_BLOB session_key = data_blob(NULL, 0);
244         DATA_BLOB lm_session_key = data_blob(NULL, 0);
245         DATA_BLOB encrypted_session_key = data_blob(NULL, 0);
246         NTSTATUS nt_status;
247         int flags = 0;
248         const char *user = NULL, *domain = NULL, *workstation = NULL;
249         bool is_anonymous = false;
250         const DATA_BLOB version_blob = ntlmssp_version_blob();
251         const NTTIME *server_timestamp = NULL;
252         uint8_t mic_buffer[NTLMSSP_MIC_SIZE] = { 0, };
253         DATA_BLOB mic_blob = data_blob_const(mic_buffer, sizeof(mic_buffer));
254         gnutls_hmac_hd_t hmac_hnd = NULL;
255         int rc;
256
257         TALLOC_CTX *mem_ctx = talloc_new(out_mem_ctx);
258         if (!mem_ctx) {
259                 return NT_STATUS_NO_MEMORY;
260         }
261
262         if (!msrpc_parse(mem_ctx,
263                          &in, "CdBd",
264                          "NTLMSSP",
265                          &ntlmssp_command,
266                          &server_domain_blob,
267                          &chal_flags)) {
268                 DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n"));
269                 dump_data(2, in.data, in.length);
270                 talloc_free(mem_ctx);
271
272                 return NT_STATUS_INVALID_PARAMETER;
273         }
274
275         data_blob_free(&server_domain_blob);
276
277         DEBUG(3, ("Got challenge flags:\n"));
278         debug_ntlmssp_flags(chal_flags);
279
280         nt_status = ntlmssp_handle_neg_flags(ntlmssp_state,
281                                              chal_flags, "challenge");
282         if (!NT_STATUS_IS_OK(nt_status)) {
283                 return nt_status;
284         }
285
286         if (ntlmssp_state->unicode) {
287                 if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) {
288                         chal_parse_string = "CdUdbddB";
289                 } else {
290                         chal_parse_string = "CdUdbdd";
291                         chal_parse_string_short = "CdUdb";
292                 }
293                 auth_gen_string = "CdBBUUUBdbb";
294         } else {
295                 if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) {
296                         chal_parse_string = "CdAdbddB";
297                 } else {
298                         chal_parse_string = "CdAdbdd";
299                         chal_parse_string_short = "CdAdb";
300                 }
301
302                 auth_gen_string = "CdBBAAABdbb";
303         }
304
305         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                 bool ok = false;
316
317                 DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#2)\n"));
318
319                 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                         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                         if (!ok) {
337                                 DEBUG(1, ("Failed to short parse "
338                                         "the NTLMSSP Challenge: (#2)\n"));
339                         }
340                 }
341
342                 if (!ok) {
343                         dump_data(2, in.data, in.length);
344                         talloc_free(mem_ctx);
345                         return NT_STATUS_INVALID_PARAMETER;
346                 }
347         }
348
349         if (DEBUGLEVEL >= 10) {
350                 struct CHALLENGE_MESSAGE *challenge =
351                         talloc(ntlmssp_state, struct CHALLENGE_MESSAGE);
352                 if (challenge != NULL) {
353                         NTSTATUS status;
354                         challenge->NegotiateFlags = chal_flags;
355                         status = ntlmssp_pull_CHALLENGE_MESSAGE(
356                                         &in, challenge, challenge);
357                         if (NT_STATUS_IS_OK(status)) {
358                                 NDR_PRINT_DEBUG(CHALLENGE_MESSAGE,
359                                                 challenge);
360                         }
361                         TALLOC_FREE(challenge);
362                 }
363         }
364
365         if (chal_flags & NTLMSSP_TARGET_TYPE_SERVER) {
366                 ntlmssp_state->server.is_standalone = true;
367         } else {
368                 ntlmssp_state->server.is_standalone = false;
369         }
370         /* TODO: parse struct_blob and fill in the rest */
371         ntlmssp_state->server.netbios_name = "";
372         ntlmssp_state->server.netbios_domain = talloc_move(ntlmssp_state, &server_domain);
373         ntlmssp_state->server.dns_name = "";
374         ntlmssp_state->server.dns_domain = "";
375
376         if (challenge_blob.length != 8) {
377                 talloc_free(mem_ctx);
378                 return NT_STATUS_INVALID_PARAMETER;
379         }
380
381         is_anonymous = cli_credentials_is_anonymous(gensec_security->credentials);
382         cli_credentials_get_ntlm_username_domain(gensec_security->credentials, mem_ctx,
383                                                  &user, &domain);
384
385         workstation = cli_credentials_get_workstation(gensec_security->credentials);
386
387         if (user == NULL) {
388                 DEBUG(10, ("User is NULL, returning INVALID_PARAMETER\n"));
389                 return NT_STATUS_INVALID_PARAMETER;
390         }
391
392         if (domain == NULL) {
393                 DEBUG(10, ("Domain is NULL, returning INVALID_PARAMETER\n"));
394                 return NT_STATUS_INVALID_PARAMETER;
395         }
396
397         if (workstation == NULL) {
398                 DEBUG(10, ("Workstation is NULL, returning INVALID_PARAMETER\n"));
399                 return NT_STATUS_INVALID_PARAMETER;
400         }
401
402         if (is_anonymous) {
403                 ntlmssp_state->neg_flags |= NTLMSSP_ANONYMOUS;
404                 /*
405                  * don't use the ccache for anonymous auth
406                  */
407                 ntlmssp_state->use_ccache = false;
408         }
409         if (ntlmssp_state->use_ccache) {
410                 struct samr_Password *nt_hash = NULL;
411
412                 /*
413                  * If we have a password given we don't
414                  * use the ccache
415                  */
416                 nt_hash = cli_credentials_get_nt_hash(gensec_security->credentials,
417                                                       mem_ctx);
418                 if (nt_hash != NULL) {
419                         ZERO_STRUCTP(nt_hash);
420                         TALLOC_FREE(nt_hash);
421                         ntlmssp_state->use_ccache = false;
422                 }
423         }
424
425         if (ntlmssp_state->use_ccache) {
426                 struct wbcCredentialCacheParams params;
427                 struct wbcCredentialCacheInfo *info = NULL;
428                 struct wbcAuthErrorInfo *error = NULL;
429                 struct wbcNamedBlob auth_blobs[2];
430                 const struct wbcBlob *wbc_auth_blob = NULL;
431                 const struct wbcBlob *wbc_session_key = NULL;
432                 wbcErr wbc_status;
433                 size_t i;
434                 bool new_spnego = false;
435
436                 params.account_name = user;
437                 params.domain_name = domain;
438                 params.level = WBC_CREDENTIAL_CACHE_LEVEL_NTLMSSP;
439
440                 auth_blobs[0].name = "challenge_blob";
441                 auth_blobs[0].flags = 0;
442                 auth_blobs[0].blob.data = in.data;
443                 auth_blobs[0].blob.length = in.length;
444                 auth_blobs[1].name = "negotiate_blob";
445                 auth_blobs[1].flags = 0;
446                 auth_blobs[1].blob.data = ntlmssp_state->negotiate_blob.data;
447                 auth_blobs[1].blob.length = ntlmssp_state->negotiate_blob.length;
448                 params.num_blobs = ARRAY_SIZE(auth_blobs);
449                 params.blobs = auth_blobs;
450
451                 wbc_status = wbcCredentialCache(&params, &info, &error);
452                 wbcFreeMemory(error);
453                 if (!WBC_ERROR_IS_OK(wbc_status)) {
454                         return NT_STATUS_WRONG_CREDENTIAL_HANDLE;
455                 }
456
457                 for (i=0; i<info->num_blobs; i++) {
458                         if (strequal(info->blobs[i].name, "auth_blob")) {
459                                 wbc_auth_blob = &info->blobs[i].blob;
460                         }
461                         if (strequal(info->blobs[i].name, "session_key")) {
462                                 wbc_session_key = &info->blobs[i].blob;
463                         }
464                         if (strequal(info->blobs[i].name, "new_spnego")) {
465                                 new_spnego = true;
466                         }
467                 }
468                 if ((wbc_auth_blob == NULL) || (wbc_session_key == NULL)) {
469                         wbcFreeMemory(info);
470                         return NT_STATUS_WRONG_CREDENTIAL_HANDLE;
471                 }
472
473                 session_key = data_blob_talloc(mem_ctx,
474                                                wbc_session_key->data,
475                                                wbc_session_key->length);
476                 if (session_key.length != wbc_session_key->length) {
477                         wbcFreeMemory(info);
478                         return NT_STATUS_NO_MEMORY;
479                 }
480                 *out = data_blob_talloc(mem_ctx,
481                                         wbc_auth_blob->data,
482                                         wbc_auth_blob->length);
483                 if (out->length != wbc_auth_blob->length) {
484                         wbcFreeMemory(info);
485                         return NT_STATUS_NO_MEMORY;
486                 }
487                 ntlmssp_state->new_spnego = new_spnego;
488
489                 wbcFreeMemory(info);
490                 goto done;
491         }
492
493         if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
494                 flags |= CLI_CRED_NTLM2;
495         }
496         if (ntlmssp_state->use_ntlmv2) {
497                 flags |= CLI_CRED_NTLMv2_AUTH;
498         }
499         if (ntlmssp_state->use_nt_response) {
500                 flags |= CLI_CRED_NTLM_AUTH;
501         }
502         if (ntlmssp_state->allow_lm_response) {
503                 flags |= CLI_CRED_LANMAN_AUTH;
504         }
505
506         if (target_info.length != 0 && !is_anonymous) {
507                 struct AV_PAIR *pairs = NULL;
508                 uint32_t count = 0;
509                 enum ndr_err_code err;
510                 struct AV_PAIR *timestamp = NULL;
511                 struct AV_PAIR *eol = NULL;
512                 uint32_t i = 0;
513                 const char *service = NULL;
514                 const char *hostname = NULL;
515
516                 err = ndr_pull_struct_blob(&target_info,
517                                         ntlmssp_state,
518                                         &ntlmssp_state->server.av_pair_list,
519                                         (ndr_pull_flags_fn_t)ndr_pull_AV_PAIR_LIST);
520                 if (!NDR_ERR_CODE_IS_SUCCESS(err)) {
521                         return ndr_map_error2ntstatus(err);
522                 }
523
524                 count = ntlmssp_state->server.av_pair_list.count;
525                 /*
526                  * We need room for Flags, SingleHost,
527                  * ChannelBindings and Target
528                  */
529                 pairs = talloc_zero_array(ntlmssp_state, struct AV_PAIR,
530                                           count + 4);
531                 if (pairs == NULL) {
532                         return NT_STATUS_NO_MEMORY;
533                 }
534
535                 for (i = 0; i < count; i++) {
536                         pairs[i] = ntlmssp_state->server.av_pair_list.pair[i];
537                 }
538
539                 ntlmssp_state->client.av_pair_list.count = count;
540                 ntlmssp_state->client.av_pair_list.pair = pairs;
541
542                 eol = ndr_ntlmssp_find_av(&ntlmssp_state->client.av_pair_list,
543                                           MsvAvEOL);
544                 if (eol == NULL) {
545                         return NT_STATUS_INVALID_PARAMETER;
546                 }
547
548                 timestamp = ndr_ntlmssp_find_av(&ntlmssp_state->client.av_pair_list,
549                                                 MsvAvTimestamp);
550                 if (timestamp != NULL) {
551                         uint32_t sign_features =
552                                         GENSEC_FEATURE_SESSION_KEY |
553                                         GENSEC_FEATURE_SIGN |
554                                         GENSEC_FEATURE_SEAL;
555
556                         server_timestamp = &timestamp->Value.AvTimestamp;
557
558                         if (ntlmssp_state->force_old_spnego) {
559                                 sign_features = 0;
560                         }
561
562                         if (gensec_security->want_features & sign_features) {
563                                 struct AV_PAIR *av_flags = NULL;
564
565                                 av_flags = ndr_ntlmssp_find_av(&ntlmssp_state->client.av_pair_list,
566                                                                MsvAvFlags);
567                                 if (av_flags == NULL) {
568                                         av_flags = eol;
569                                         eol++;
570                                         count++;
571                                         *eol = *av_flags;
572                                         av_flags->AvId = MsvAvFlags;
573                                         av_flags->Value.AvFlags = 0;
574                                 }
575
576                                 av_flags->Value.AvFlags |= NTLMSSP_AVFLAG_MIC_IN_AUTHENTICATE_MESSAGE;
577                                 ntlmssp_state->new_spnego = true;
578                         }
579                 }
580
581                 {
582                         struct AV_PAIR *SingleHost = NULL;
583
584                         SingleHost = eol;
585                         eol++;
586                         count++;
587                         *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                         SingleHost->AvId = MsvAvSingleHost;
595                         SingleHost->Value.AvSingleHost.token_info.Flags = 0;
596                         SingleHost->Value.AvSingleHost.token_info.TokenIL = 0;
597                         generate_random_buffer(SingleHost->Value.AvSingleHost.token_info.MachineId,
598                                         sizeof(SingleHost->Value.AvSingleHost.token_info.MachineId));
599                         SingleHost->Value.AvSingleHost.remaining = data_blob_null;
600                 }
601
602                 {
603                         struct AV_PAIR *ChannelBindings = NULL;
604
605                         ChannelBindings = eol;
606                         eol++;
607                         count++;
608                         *eol = *ChannelBindings;
609
610                         /*
611                          * gensec doesn't support channel bindings yet,
612                          * but we want to match Windows on the wire
613                          */
614                         ChannelBindings->AvId = MsvChannelBindings;
615                         memset(ChannelBindings->Value.ChannelBindings, 0,
616                                sizeof(ChannelBindings->Value.ChannelBindings));
617                 }
618
619                 service = gensec_get_target_service(gensec_security);
620                 hostname = gensec_get_target_hostname(gensec_security);
621                 if (service != NULL && hostname != NULL) {
622                         struct AV_PAIR *target = NULL;
623
624                         target = eol;
625                         eol++;
626                         count++;
627                         *eol = *target;
628
629                         target->AvId = MsvAvTargetName;
630                         target->Value.AvTargetName = talloc_asprintf(pairs, "%s/%s",
631                                                                      service,
632                                                                      hostname);
633                         if (target->Value.AvTargetName == NULL) {
634                                 return NT_STATUS_NO_MEMORY;
635                         }
636                 }
637
638                 ntlmssp_state->client.av_pair_list.count = count;
639                 ntlmssp_state->client.av_pair_list.pair = pairs;
640
641                 err = ndr_push_struct_blob(&target_info,
642                                         ntlmssp_state,
643                                         &ntlmssp_state->client.av_pair_list,
644                                         (ndr_push_flags_fn_t)ndr_push_AV_PAIR_LIST);
645                 if (!NDR_ERR_CODE_IS_SUCCESS(err)) {
646                         return NT_STATUS_NO_MEMORY;
647                 }
648         }
649
650         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         if (!NT_STATUS_IS_OK(nt_status)) {
656                 return nt_status;
657         }
658
659         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                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
665         }
666
667         if (!(flags & CLI_CRED_NTLM2)) {
668                 /* NTLM2 is incompatible... */
669                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
670         }
671
672         if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
673             && ntlmssp_state->allow_lm_key && lm_session_key.length == 16) {
674                 DATA_BLOB new_session_key = data_blob_talloc(mem_ctx, NULL, 16);
675                 if (lm_response.length == 24) {
676                         nt_status = SMBsesskeygen_lm_sess_key(lm_session_key.data,
677                                                               lm_response.data,
678                                                               new_session_key.data);
679                         if (!NT_STATUS_IS_OK(nt_status)) {
680                                 return nt_status;
681                         }
682                 } else {
683                         static const uint8_t zeros[24];
684                         nt_status = SMBsesskeygen_lm_sess_key(lm_session_key.data,
685                                                               zeros,
686                                                               new_session_key.data);
687                         if (!NT_STATUS_IS_OK(nt_status)) {
688                                 return nt_status;
689                         }
690                 }
691                 session_key = new_session_key;
692                 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         if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
699                 /* Make up a new session key */
700                 uint8_t client_session_key[16];
701                 gnutls_cipher_hd_t cipher_hnd;
702                 gnutls_datum_t enc_session_key = {
703                         .data = session_key.data,
704                         .size = session_key.length,
705                 };
706
707                 generate_random_buffer(client_session_key, sizeof(client_session_key));
708
709                 /* Encrypt the new session key with the old one */
710                 encrypted_session_key = data_blob_talloc(ntlmssp_state,
711                                                          client_session_key, sizeof(client_session_key));
712                 dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, encrypted_session_key.length);
713
714                 rc = gnutls_cipher_init(&cipher_hnd,
715                                         GNUTLS_CIPHER_ARCFOUR_128,
716                                         &enc_session_key,
717                                         NULL);
718                 if (rc < 0) {
719                         nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
720                         ZERO_ARRAY(client_session_key);
721                         goto done;
722                 }
723                 rc = gnutls_cipher_encrypt(cipher_hnd,
724                                            encrypted_session_key.data,
725                                            encrypted_session_key.length);
726                 gnutls_cipher_deinit(cipher_hnd);
727                 if (rc < 0) {
728                         nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
729                         ZERO_ARRAY(client_session_key);
730                         goto done;
731                 }
732
733                 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                 session_key = data_blob_talloc(mem_ctx, client_session_key, sizeof(client_session_key));
737                 ZERO_ARRAY(client_session_key);
738         }
739
740         /* this generates the actual auth packet */
741         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                        version_blob.data, version_blob.length,
753                        mic_blob.data, mic_blob.length);
754         if (!NT_STATUS_IS_OK(nt_status)) {
755                 talloc_free(mem_ctx);
756                 return nt_status;
757         }
758
759         if (DEBUGLEVEL >= 10) {
760                 struct AUTHENTICATE_MESSAGE *authenticate =
761                         talloc(ntlmssp_state, struct AUTHENTICATE_MESSAGE);
762                 if (authenticate != NULL) {
763                         NTSTATUS status;
764                         authenticate->NegotiateFlags = ntlmssp_state->neg_flags;
765                         status = ntlmssp_pull_AUTHENTICATE_MESSAGE(
766                                 out, authenticate, authenticate);
767                         if (NT_STATUS_IS_OK(status)) {
768                                 NDR_PRINT_DEBUG(AUTHENTICATE_MESSAGE,
769                                                 authenticate);
770                         }
771                         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         rc = gnutls_hmac_init(&hmac_hnd,
783                               GNUTLS_MAC_MD5,
784                          session_key.data,
785                          MIN(session_key.length, 64));
786         if (rc < 0) {
787                 nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
788                 goto done;
789         }
790
791         rc = gnutls_hmac(hmac_hnd,
792                          ntlmssp_state->negotiate_blob.data,
793                          ntlmssp_state->negotiate_blob.length);
794         if (rc < 0) {
795                 gnutls_hmac_deinit(hmac_hnd, NULL);
796                 nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
797                 goto done;
798         }
799         rc = gnutls_hmac(hmac_hnd, in.data, in.length);
800         if (rc < 0) {
801                 gnutls_hmac_deinit(hmac_hnd, NULL);
802                 nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
803                 goto done;
804         }
805         rc = gnutls_hmac(hmac_hnd, out->data, out->length);
806         if (rc < 0) {
807                 gnutls_hmac_deinit(hmac_hnd, NULL);
808                 nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
809                 goto done;
810         }
811
812         gnutls_hmac_deinit(hmac_hnd, mic_buffer);
813
814         memcpy(out->data + NTLMSSP_MIC_OFFSET, mic_buffer, NTLMSSP_MIC_SIZE);
815         ZERO_ARRAY(mic_buffer);
816
817         nt_status = NT_STATUS_OK;
818 done:
819         ZERO_ARRAY_LEN(ntlmssp_state->negotiate_blob.data,
820                        ntlmssp_state->negotiate_blob.length);
821         data_blob_free(&ntlmssp_state->negotiate_blob);
822
823         ntlmssp_state->session_key = session_key;
824         talloc_steal(ntlmssp_state, session_key.data);
825
826         DEBUG(3, ("NTLMSSP: Set final flags:\n"));
827         debug_ntlmssp_flags(ntlmssp_state->neg_flags);
828
829         talloc_steal(out_mem_ctx, out->data);
830
831         ntlmssp_state->expected_state = NTLMSSP_DONE;
832
833         if (gensec_ntlmssp_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
834                 nt_status = ntlmssp_sign_init(ntlmssp_state);
835                 if (!NT_STATUS_IS_OK(nt_status)) {
836                         DEBUG(1, ("Could not setup NTLMSSP signing/sealing system (error was: %s)\n",
837                                   nt_errstr(nt_status)));
838                         talloc_free(mem_ctx);
839                         return nt_status;
840                 }
841         }
842
843         talloc_free(mem_ctx);
844         return nt_status;
845 }
846
847 NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security)
848 {
849         struct gensec_ntlmssp_context *gensec_ntlmssp;
850         struct ntlmssp_state *ntlmssp_state;
851         NTSTATUS nt_status;
852
853         nt_status = gensec_ntlmssp_start(gensec_security);
854         NT_STATUS_NOT_OK_RETURN(nt_status);
855
856         gensec_ntlmssp =
857                 talloc_get_type_abort(gensec_security->private_data,
858                                       struct gensec_ntlmssp_context);
859
860         ntlmssp_state = talloc_zero(gensec_ntlmssp,
861                                     struct ntlmssp_state);
862         if (!ntlmssp_state) {
863                 return NT_STATUS_NO_MEMORY;
864         }
865
866         gensec_ntlmssp->ntlmssp_state = ntlmssp_state;
867
868         ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
869
870         ntlmssp_state->role = NTLMSSP_CLIENT;
871
872         ntlmssp_state->client.netbios_domain = lpcfg_workgroup(gensec_security->settings->lp_ctx);
873         ntlmssp_state->client.netbios_name = cli_credentials_get_workstation(gensec_security->credentials);
874
875         ntlmssp_state->unicode = gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "unicode", true);
876
877         ntlmssp_state->use_nt_response = \
878                 gensec_setting_bool(gensec_security->settings,
879                                     "ntlmssp_client",
880                                     "send_nt_response",
881                                     true);
882
883         ntlmssp_state->allow_lm_response = lpcfg_client_lanman_auth(gensec_security->settings->lp_ctx);
884
885         ntlmssp_state->allow_lm_key = (ntlmssp_state->allow_lm_response
886                                               && (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "allow_lm_key", false)
887                                                   || gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "lm_key", false)));
888
889         ntlmssp_state->use_ntlmv2 = lpcfg_client_ntlmv2_auth(gensec_security->settings->lp_ctx);
890
891         ntlmssp_state->force_old_spnego = gensec_setting_bool(gensec_security->settings,
892                                                 "ntlmssp_client", "force_old_spnego", false);
893
894         ntlmssp_state->expected_state = NTLMSSP_INITIAL;
895
896         ntlmssp_state->neg_flags =
897                 NTLMSSP_NEGOTIATE_NTLM |
898                 NTLMSSP_NEGOTIATE_VERSION |
899                 NTLMSSP_REQUEST_TARGET;
900
901         if (ntlmssp_state->unicode) {
902                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
903         } else {
904                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
905         }
906
907         if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "128bit", true)) {
908                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_128;
909         }
910
911         if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "56bit", false)) {
912                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_56;
913         }
914
915         if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "lm_key", false)) {
916                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY;
917         }
918
919         if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "keyexchange", true)) {
920                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_KEY_EXCH;
921         }
922
923         if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "alwayssign", true)) {
924                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
925         }
926
927         if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "ntlm2", true)) {
928                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
929         } else {
930                 /* apparently we can't do ntlmv2 if we don't do ntlm2 */
931                 ntlmssp_state->use_ntlmv2 = false;
932         }
933
934         if (ntlmssp_state->use_ntlmv2) {
935                 ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_NTLM2;
936                 ntlmssp_state->allow_lm_response = false;
937                 ntlmssp_state->allow_lm_key = false;
938         }
939
940         if (ntlmssp_state->allow_lm_key) {
941                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY;
942         }
943
944         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                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
958         }
959         if (gensec_security->want_features & GENSEC_FEATURE_SIGN) {
960                 ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN;
961
962                 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                         ntlmssp_state->force_wrap_seal = true;
969                 }
970         }
971         if (ntlmssp_state->force_wrap_seal) {
972                 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                 ret = gensec_setting_bool(gensec_security->settings,
982                                           "ntlmssp_client",
983                                           "ldap_style_send_seal",
984                                           true);
985                 if (ret) {
986                         ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SEAL;
987                 }
988         }
989         if (gensec_security->want_features & GENSEC_FEATURE_SEAL) {
990                 ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN;
991                 ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SEAL;
992         }
993         if (gensec_security->want_features & GENSEC_FEATURE_NTLM_CCACHE) {
994                 ntlmssp_state->use_ccache = true;
995         }
996
997         ntlmssp_state->neg_flags |= ntlmssp_state->required_flags;
998         ntlmssp_state->conf_flags = ntlmssp_state->neg_flags;
999
1000         return NT_STATUS_OK;
1001 }
1002
1003 NTSTATUS gensec_ntlmssp_resume_ccache_start(struct gensec_security *gensec_security)
1004 {
1005         struct gensec_ntlmssp_context *gensec_ntlmssp = NULL;
1006         NTSTATUS status;
1007
1008         status = gensec_ntlmssp_client_start(gensec_security);
1009         if (!NT_STATUS_IS_OK(status)) {
1010                 return status;
1011         }
1012
1013         gensec_ntlmssp = talloc_get_type_abort(gensec_security->private_data,
1014                                                struct gensec_ntlmssp_context);
1015         gensec_ntlmssp->ntlmssp_state->use_ccache = false;
1016         gensec_ntlmssp->ntlmssp_state->resume_ccache = true;
1017         gensec_ntlmssp->ntlmssp_state->expected_state = NTLMSSP_NEGOTIATE;
1018
1019         return NT_STATUS_OK;
1020 }