r6113: Move GENSEC and the kerberos code out of libcli/auth, and into
[samba.git] / source / auth / gensec / ntlmssp.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
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 2 of the License, or
12    (at your option) any later version.
13    
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18    
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24 #include "includes.h"
25 #include "auth/auth.h"
26 #include "lib/crypto/crypto.h"
27 #include "pstring.h"
28
29 static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state, 
30                                        TALLOC_CTX *out_mem_ctx, 
31                                        DATA_BLOB in, DATA_BLOB *out);
32 static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,
33                                          TALLOC_CTX *out_mem_ctx, 
34                                          const DATA_BLOB in, DATA_BLOB *out);
35 static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, 
36                                          TALLOC_CTX *out_mem_ctx, 
37                                          const DATA_BLOB in, DATA_BLOB *out);
38 static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
39                                     TALLOC_CTX *out_mem_ctx, 
40                                     const DATA_BLOB in, DATA_BLOB *out);
41
42 /**
43  * Callbacks for NTLMSSP - for both client and server operating modes
44  * 
45  */
46
47 static const struct ntlmssp_callbacks {
48         enum ntlmssp_role role;
49         enum ntlmssp_message_type ntlmssp_command;
50         NTSTATUS (*fn)(struct ntlmssp_state *ntlmssp_state, 
51                        TALLOC_CTX *out_mem_ctx, 
52                        DATA_BLOB in, DATA_BLOB *out);
53 } ntlmssp_callbacks[] = {
54         {NTLMSSP_CLIENT, NTLMSSP_INITIAL, ntlmssp_client_initial},
55         {NTLMSSP_SERVER, NTLMSSP_NEGOTIATE, ntlmssp_server_negotiate},
56         {NTLMSSP_CLIENT, NTLMSSP_CHALLENGE, ntlmssp_client_challenge},
57         {NTLMSSP_SERVER, NTLMSSP_AUTH, ntlmssp_server_auth},
58         {NTLMSSP_CLIENT, NTLMSSP_UNKNOWN, NULL},
59         {NTLMSSP_SERVER, NTLMSSP_UNKNOWN, NULL}
60 };
61
62
63 /**
64  * Print out the NTLMSSP flags for debugging 
65  * @param neg_flags The flags from the packet
66  */
67
68 void debug_ntlmssp_flags(uint32_t neg_flags)
69 {
70         DEBUG(3,("Got NTLMSSP neg_flags=0x%08x\n", neg_flags));
71         
72         if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) 
73                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_UNICODE\n"));
74         if (neg_flags & NTLMSSP_NEGOTIATE_OEM) 
75                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_OEM\n"));
76         if (neg_flags & NTLMSSP_REQUEST_TARGET) 
77                 DEBUGADD(4, ("  NTLMSSP_REQUEST_TARGET\n"));
78         if (neg_flags & NTLMSSP_NEGOTIATE_SIGN) 
79                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_SIGN\n"));
80         if (neg_flags & NTLMSSP_NEGOTIATE_SEAL) 
81                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_SEAL\n"));
82         if (neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) 
83                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_LM_KEY\n"));
84         if (neg_flags & NTLMSSP_NEGOTIATE_NETWARE) 
85                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_NETWARE\n"));
86         if (neg_flags & NTLMSSP_NEGOTIATE_NTLM) 
87                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_NTLM\n"));
88         if (neg_flags & NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED) 
89                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED\n"));
90         if (neg_flags & NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED) 
91                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED\n"));
92         if (neg_flags & NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL) 
93                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL\n"));
94         if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN) 
95                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_ALWAYS_SIGN\n"));
96         if (neg_flags & NTLMSSP_NEGOTIATE_NTLM2) 
97                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_NTLM2\n"));
98         if (neg_flags & NTLMSSP_CHAL_TARGET_INFO) 
99                 DEBUGADD(4, ("  NTLMSSP_CHAL_TARGET_INFO\n"));
100         if (neg_flags & NTLMSSP_NEGOTIATE_128) 
101                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_128\n"));
102         if (neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) 
103                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_KEY_EXCH\n"));
104 }
105
106 /**
107  * Default challenge generation code.
108  *
109  */
110    
111 static const uint8_t *get_challenge(const struct ntlmssp_state *ntlmssp_state)
112 {
113         uint8_t *chal = talloc_size(ntlmssp_state, 8);
114         generate_random_buffer(chal, 8);
115
116         return chal;
117 }
118
119 /**
120  * Default 'we can set the challenge to anything we like' implementation
121  *
122  */
123    
124 static BOOL may_set_challenge(const struct ntlmssp_state *ntlmssp_state)
125 {
126         return True;
127 }
128
129 /**
130  * Default 'we can set the challenge to anything we like' implementation
131  *
132  * Does not actually do anything, as the value is always in the structure anyway.
133  *
134  */
135    
136 static NTSTATUS set_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *challenge)
137 {
138         SMB_ASSERT(challenge->length == 8);
139         return NT_STATUS_OK;
140 }
141
142 /** 
143  * Set a username on an NTLMSSP context - ensures it is talloc()ed 
144  *
145  */
146
147 NTSTATUS ntlmssp_set_username(struct ntlmssp_state *ntlmssp_state, const char *user) 
148 {
149         if (!user) {
150                 /* it should be at least "" */
151                 DEBUG(1, ("NTLMSSP failed to set username - cannot accept NULL username\n"));
152                 return NT_STATUS_INVALID_PARAMETER;
153         }
154         ntlmssp_state->user = talloc_strdup(ntlmssp_state, user);
155         if (!ntlmssp_state->user) {
156                 return NT_STATUS_NO_MEMORY;
157         }
158         return NT_STATUS_OK;
159 }
160
161 /** 
162  * Set a password on an NTLMSSP context - ensures it is talloc()ed 
163  *
164  */
165 NTSTATUS ntlmssp_set_password(struct ntlmssp_state *ntlmssp_state, const char *password) 
166 {
167         if (!password) {
168                 ntlmssp_state->password = NULL;
169         } else {
170                 ntlmssp_state->password = talloc_strdup(ntlmssp_state, password);
171                 if (!ntlmssp_state->password) {
172                         return NT_STATUS_NO_MEMORY;
173                 }
174         }
175         return NT_STATUS_OK;
176 }
177
178 /** 
179  * Set a domain on an NTLMSSP context - ensures it is talloc()ed 
180  *
181  */
182 NTSTATUS ntlmssp_set_domain(struct ntlmssp_state *ntlmssp_state, const char *domain) 
183 {
184         ntlmssp_state->domain = talloc_strdup(ntlmssp_state, domain);
185         if (!ntlmssp_state->domain) {
186                 return NT_STATUS_NO_MEMORY;
187         }
188         return NT_STATUS_OK;
189 }
190
191 /** 
192  * Set a workstation on an NTLMSSP context - ensures it is talloc()ed 
193  *
194  */
195 NTSTATUS ntlmssp_set_workstation(struct ntlmssp_state *ntlmssp_state, const char *workstation) 
196 {
197         ntlmssp_state->workstation = talloc_strdup(ntlmssp_state, workstation);
198         if (!ntlmssp_state->workstation) {
199                 return NT_STATUS_NO_MEMORY;
200         }
201         return NT_STATUS_OK;
202 }
203
204 /**
205  *  Store a DATA_BLOB containing an NTLMSSP response, for use later.
206  *  This copies the data blob
207  */
208
209 NTSTATUS ntlmssp_store_response(struct ntlmssp_state *ntlmssp_state,
210                                 DATA_BLOB response) 
211 {
212         ntlmssp_state->stored_response = data_blob_talloc(ntlmssp_state, 
213                                                           response.data, response.length);
214         return NT_STATUS_OK;
215 }
216
217 /**
218  * Next state function for the NTLMSSP state machine
219  * 
220  * @param ntlmssp_state NTLMSSP State
221  * @param out_mem_ctx The TALLOC_CTX for *out to be allocated on
222  * @param in The request, as a DATA_BLOB
223  * @param out The reply, as an talloc()ed DATA_BLOB, on *out_mem_ctx
224  * @return Error, MORE_PROCESSING_REQUIRED if a reply is sent, 
225  *                or NT_STATUS_OK if the user is authenticated. 
226  */
227
228 NTSTATUS ntlmssp_update(struct ntlmssp_state *ntlmssp_state, 
229                         TALLOC_CTX *out_mem_ctx, 
230                         const DATA_BLOB in, DATA_BLOB *out) 
231 {
232         DATA_BLOB input;
233         uint32_t ntlmssp_command;
234         int i;
235
236         *out = data_blob(NULL, 0);
237
238         if (ntlmssp_state->expected_state == NTLMSSP_DONE) {
239                 return NT_STATUS_OK;
240         }
241
242         if (!out_mem_ctx) {
243                 /* if the caller doesn't want to manage/own the memory, 
244                    we can put it on our context */
245                 out_mem_ctx = ntlmssp_state;
246         }
247
248         if (!in.length && ntlmssp_state->stored_response.length) {
249                 input = ntlmssp_state->stored_response;
250                 
251                 /* we only want to read the stored response once - overwrite it */
252                 ntlmssp_state->stored_response = data_blob(NULL, 0);
253         } else {
254                 input = in;
255         }
256
257         if (!input.length) {
258                 switch (ntlmssp_state->role) {
259                 case NTLMSSP_CLIENT:
260                         ntlmssp_command = NTLMSSP_INITIAL;
261                         break;
262                 case NTLMSSP_SERVER:
263                         /* 'datagram' mode - no neg packet */
264                         ntlmssp_command = NTLMSSP_NEGOTIATE;
265                         break;
266                 }
267         } else {
268                 if (!msrpc_parse(ntlmssp_state, 
269                                  &input, "Cd",
270                                  "NTLMSSP",
271                                  &ntlmssp_command)) {
272                         DEBUG(1, ("Failed to parse NTLMSSP packet, could not extract NTLMSSP command\n"));
273                         dump_data(2, input.data, input.length);
274                         return NT_STATUS_INVALID_PARAMETER;
275                 }
276         }
277
278         if (ntlmssp_command != ntlmssp_state->expected_state) {
279                 DEBUG(1, ("got NTLMSSP command %u, expected %u\n", ntlmssp_command, ntlmssp_state->expected_state));
280                 return NT_STATUS_INVALID_PARAMETER;
281         }
282
283         for (i=0; ntlmssp_callbacks[i].fn; i++) {
284                 if (ntlmssp_callbacks[i].role == ntlmssp_state->role 
285                     && ntlmssp_callbacks[i].ntlmssp_command == ntlmssp_command 
286                     && ntlmssp_callbacks[i].fn) {
287                         return ntlmssp_callbacks[i].fn(ntlmssp_state, out_mem_ctx, input, out);
288                 }
289         }
290
291         DEBUG(1, ("failed to find NTLMSSP callback for NTLMSSP mode %u, command %u\n", 
292                   ntlmssp_state->role, ntlmssp_command)); 
293
294         return NT_STATUS_INVALID_PARAMETER;
295 }
296
297 /**
298  * Return the NTLMSSP master session key
299  * 
300  * @param ntlmssp_state NTLMSSP State
301  */
302
303 NTSTATUS ntlmssp_session_key(struct ntlmssp_state *ntlmssp_state,
304                              DATA_BLOB *session_key)
305 {
306         if (!ntlmssp_state->session_key.data) {
307                 return NT_STATUS_NO_USER_SESSION_KEY;
308         }
309         *session_key = ntlmssp_state->session_key;
310
311         return NT_STATUS_OK;
312 }
313
314 /**
315  * End an NTLMSSP state machine
316  * 
317  * @param ntlmssp_state NTLMSSP State, free()ed by this function
318  */
319
320 void ntlmssp_end(struct ntlmssp_state **ntlmssp_state)
321 {
322         (*ntlmssp_state)->ref_count--;
323
324         if ((*ntlmssp_state)->ref_count == 0) {
325                 talloc_free(*ntlmssp_state);
326         }
327
328         *ntlmssp_state = NULL;
329         return;
330 }
331
332 /**
333  * Determine correct target name flags for reply, given server role 
334  * and negotiated flags
335  * 
336  * @param ntlmssp_state NTLMSSP State
337  * @param neg_flags The flags from the packet
338  * @param chal_flags The flags to be set in the reply packet
339  * @return The 'target name' string.
340  */
341
342 static const char *ntlmssp_target_name(struct ntlmssp_state *ntlmssp_state,
343                                        uint32_t neg_flags, uint32_t *chal_flags) 
344 {
345         if (neg_flags & NTLMSSP_REQUEST_TARGET) {
346                 *chal_flags |= NTLMSSP_CHAL_TARGET_INFO;
347                 *chal_flags |= NTLMSSP_REQUEST_TARGET;
348                 if (ntlmssp_state->server_role == ROLE_STANDALONE) {
349                         *chal_flags |= NTLMSSP_TARGET_TYPE_SERVER;
350                         return ntlmssp_state->server_name;
351                 } else {
352                         *chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN;
353                         return ntlmssp_state->get_domain();
354                 };
355         } else {
356                 return "";
357         }
358 }
359
360 static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state,
361                                       uint32_t neg_flags, BOOL allow_lm) {
362         if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) {
363                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
364                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_OEM;
365                 ntlmssp_state->unicode = True;
366         } else {
367                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_UNICODE;
368                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
369                 ntlmssp_state->unicode = False;
370         }
371
372         if ((neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) && allow_lm && !ntlmssp_state->use_ntlmv2) {
373                 /* other end forcing us to use LM */
374                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY;
375                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
376         } else {
377                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
378         }
379
380         if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN) {
381                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
382         }
383
384         if (!(neg_flags & NTLMSSP_NEGOTIATE_SIGN)) {
385                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SIGN;
386         }
387
388         if (!(neg_flags & NTLMSSP_NEGOTIATE_SEAL)) {
389                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SEAL;
390         }
391
392         if (!(neg_flags & NTLMSSP_NEGOTIATE_NTLM2)) {
393                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
394         }
395
396         if (!(neg_flags & NTLMSSP_NEGOTIATE_128)) {
397                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_128;
398                 if (neg_flags & NTLMSSP_NEGOTIATE_56) {
399                         ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_56;
400                 }
401         }
402
403         if (!(neg_flags & NTLMSSP_NEGOTIATE_56)) {
404                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_56;
405         }
406
407         if (!(neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) {
408                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_KEY_EXCH;
409         }
410
411         if ((neg_flags & NTLMSSP_REQUEST_TARGET)) {
412                 ntlmssp_state->neg_flags |= NTLMSSP_REQUEST_TARGET;
413         }
414         
415 }
416
417 /**
418    Weaken NTLMSSP keys to cope with down-level clients and servers.
419
420    We probably should have some parameters to control this, but as
421    it only occours for LM_KEY connections, and this is controlled
422    by the client lanman auth/lanman auth parameters, it isn't too bad.
423 */
424
425 static void ntlmssp_weaken_keys(struct ntlmssp_state *ntlmssp_state) {
426         /* Key weakening not performed on the master key for NTLM2
427            and does not occour for NTLM1.  Therefore we only need
428            to do this for the LM_KEY.  
429         */
430
431         if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) {
432                 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_128) {
433                         
434                 } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_56) {
435                         ntlmssp_state->session_key.data[7] = 0xa0;
436                 } else { /* forty bits */
437                         ntlmssp_state->session_key.data[5] = 0xe5;
438                         ntlmssp_state->session_key.data[6] = 0x38;
439                         ntlmssp_state->session_key.data[7] = 0xb0;
440                 }
441                 ntlmssp_state->session_key.length = 8;
442         }
443 }
444
445 /**
446  * Next state function for the Negotiate packet
447  * 
448  * @param ntlmssp_state NTLMSSP State
449  * @param out_mem_ctx The TALLOC_CTX for *out to be allocated on
450  * @param in The request, as a DATA_BLOB
451  * @param out The reply, as an talloc()ed DATA_BLOB, on *out_mem_ctx
452  * @return Errors or MORE_PROCESSING_REQUIRED if a reply is sent. 
453  */
454
455 static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,
456                                          TALLOC_CTX *out_mem_ctx, 
457                                          const DATA_BLOB in, DATA_BLOB *out) 
458 {
459         DATA_BLOB struct_blob;
460         fstring dnsname, dnsdomname;
461         uint32_t neg_flags = 0;
462         uint32_t ntlmssp_command, chal_flags;
463         char *cliname=NULL, *domname=NULL;
464         const uint8_t *cryptkey;
465         const char *target_name;
466
467         /* parse the NTLMSSP packet */
468 #if 0
469         file_save("ntlmssp_negotiate.dat", request.data, request.length);
470 #endif
471
472         if (in.length) {
473                 if (!msrpc_parse(ntlmssp_state, 
474                                  &in, "CddAA",
475                                  "NTLMSSP",
476                                  &ntlmssp_command,
477                                  &neg_flags,
478                                  &cliname,
479                                  &domname)) {
480                         DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP:\n"));
481                         dump_data(2, in.data, in.length);
482                         return NT_STATUS_INVALID_PARAMETER;
483                 }
484                 
485                 debug_ntlmssp_flags(neg_flags);
486         }
487         
488         ntlmssp_handle_neg_flags(ntlmssp_state, neg_flags, ntlmssp_state->allow_lm_key);
489
490         /* Ask our caller what challenge they would like in the packet */
491         cryptkey = ntlmssp_state->get_challenge(ntlmssp_state);
492
493         /* Check if we may set the challenge */
494         if (!ntlmssp_state->may_set_challenge(ntlmssp_state)) {
495                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
496         }
497
498         /* The flags we send back are not just the negotiated flags,
499          * they are also 'what is in this packet'.  Therfore, we
500          * operate on 'chal_flags' from here on 
501          */
502
503         chal_flags = ntlmssp_state->neg_flags;
504
505         /* get the right name to fill in as 'target' */
506         target_name = ntlmssp_target_name(ntlmssp_state, 
507                                           neg_flags, &chal_flags); 
508         if (target_name == NULL) 
509                 return NT_STATUS_INVALID_PARAMETER;
510
511         ntlmssp_state->chal = data_blob_talloc(ntlmssp_state, cryptkey, 8);
512         ntlmssp_state->internal_chal = data_blob_talloc(ntlmssp_state, cryptkey, 8);
513
514         /* This should be a 'netbios domain -> DNS domain' mapping */
515         dnsdomname[0] = '\0';
516         get_mydomname(dnsdomname);
517         strlower_m(dnsdomname);
518         
519         dnsname[0] = '\0';
520         get_myfullname(dnsname);
521         
522         /* This creates the 'blob' of names that appears at the end of the packet */
523         if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) 
524         {
525                 const char *target_name_dns = "";
526                 if (chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN) {
527                         target_name_dns = dnsdomname;
528                 } else if (chal_flags |= NTLMSSP_TARGET_TYPE_SERVER) {
529                         target_name_dns = dnsname;
530                 }
531
532                 msrpc_gen(out_mem_ctx, 
533                           &struct_blob, "aaaaa",
534                           NTLMSSP_NAME_TYPE_DOMAIN, target_name,
535                           NTLMSSP_NAME_TYPE_SERVER, ntlmssp_state->server_name,
536                           NTLMSSP_NAME_TYPE_DOMAIN_DNS, dnsdomname,
537                           NTLMSSP_NAME_TYPE_SERVER_DNS, dnsname,
538                           0, "");
539         } else {
540                 struct_blob = data_blob(NULL, 0);
541         }
542
543         {
544                 /* Marshel the packet in the right format, be it unicode or ASCII */
545                 const char *gen_string;
546                 if (ntlmssp_state->unicode) {
547                         gen_string = "CdUdbddB";
548                 } else {
549                         gen_string = "CdAdbddB";
550                 }
551                 
552                 msrpc_gen(out_mem_ctx, 
553                           out, gen_string,
554                           "NTLMSSP", 
555                           NTLMSSP_CHALLENGE,
556                           target_name,
557                           chal_flags,
558                           cryptkey, 8,
559                           0, 0,
560                           struct_blob.data, struct_blob.length);
561         }
562                 
563         ntlmssp_state->expected_state = NTLMSSP_AUTH;
564
565         return NT_STATUS_MORE_PROCESSING_REQUIRED;
566 }
567
568 /**
569  * Next state function for the Authenticate packet
570  * 
571  * @param ntlmssp_state NTLMSSP State
572  * @param request The request, as a DATA_BLOB
573  * @return Errors or NT_STATUS_OK. 
574  */
575
576 static NTSTATUS ntlmssp_server_preauth(struct ntlmssp_state *ntlmssp_state,
577                                        const DATA_BLOB request) 
578 {
579         uint32_t ntlmssp_command, auth_flags;
580         NTSTATUS nt_status;
581
582         uint8_t session_nonce_hash[16];
583
584         const char *parse_string;
585         char *domain = NULL;
586         char *user = NULL;
587         char *workstation = NULL;
588
589 #if 0
590         file_save("ntlmssp_auth.dat", request.data, request.length);
591 #endif
592
593         if (ntlmssp_state->unicode) {
594                 parse_string = "CdBBUUUBd";
595         } else {
596                 parse_string = "CdBBAAABd";
597         }
598
599         /* zero these out */
600         data_blob_free(&ntlmssp_state->lm_resp);
601         data_blob_free(&ntlmssp_state->nt_resp);
602
603         ntlmssp_state->user = NULL;
604         ntlmssp_state->domain = NULL;
605         ntlmssp_state->workstation = NULL;
606
607         /* now the NTLMSSP encoded auth hashes */
608         if (!msrpc_parse(ntlmssp_state, 
609                          &request, parse_string,
610                          "NTLMSSP", 
611                          &ntlmssp_command, 
612                          &ntlmssp_state->lm_resp,
613                          &ntlmssp_state->nt_resp,
614                          &domain, 
615                          &user, 
616                          &workstation,
617                          &ntlmssp_state->encrypted_session_key,
618                          &auth_flags)) {
619                 DEBUG(10, ("ntlmssp_server_auth: failed to parse NTLMSSP (nonfatal):\n"));
620                 dump_data(10, request.data, request.length);
621
622                 /* zero this out */
623                 data_blob_free(&ntlmssp_state->encrypted_session_key);
624                 auth_flags = 0;
625                 
626                 /* Try again with a shorter string (Win9X truncates this packet) */
627                 if (ntlmssp_state->unicode) {
628                         parse_string = "CdBBUUU";
629                 } else {
630                         parse_string = "CdBBAAA";
631                 }
632
633                 /* now the NTLMSSP encoded auth hashes */
634                 if (!msrpc_parse(ntlmssp_state, 
635                                  &request, parse_string,
636                                  "NTLMSSP", 
637                                  &ntlmssp_command, 
638                                  &ntlmssp_state->lm_resp,
639                                  &ntlmssp_state->nt_resp,
640                                  &domain, 
641                                  &user, 
642                                  &workstation)) {
643                         DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP:\n"));
644                         dump_data(2, request.data, request.length);
645
646                         return NT_STATUS_INVALID_PARAMETER;
647                 }
648         }
649
650         if (auth_flags)
651                 ntlmssp_handle_neg_flags(ntlmssp_state, auth_flags, ntlmssp_state->allow_lm_key);
652
653         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, domain))) {
654                 /* zero this out */
655                 data_blob_free(&ntlmssp_state->encrypted_session_key);
656                 return nt_status;
657         }
658
659         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) {
660                 /* zero this out */
661                 data_blob_free(&ntlmssp_state->encrypted_session_key);
662                 return nt_status;
663         }
664
665         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_workstation(ntlmssp_state, workstation))) {
666                 /* zero this out */
667                 data_blob_free(&ntlmssp_state->encrypted_session_key);
668                 return nt_status;
669         }
670
671         DEBUG(3,("Got user=[%s] domain=[%s] workstation=[%s] len1=%lu len2=%lu\n",
672                  ntlmssp_state->user, ntlmssp_state->domain, ntlmssp_state->workstation, (unsigned long)ntlmssp_state->lm_resp.length, (unsigned long)ntlmssp_state->nt_resp.length));
673
674 #if 0
675         file_save("nthash1.dat",  &ntlmssp_state->nt_resp.data,  &ntlmssp_state->nt_resp.length);
676         file_save("lmhash1.dat",  &ntlmssp_state->lm_resp.data,  &ntlmssp_state->lm_resp.length);
677 #endif
678
679         /* NTLM2 uses a 'challenge' that is made of up both the server challenge, and a 
680            client challenge 
681         
682            However, the NTLM2 flag may still be set for the real NTLMv2 logins, be careful.
683         */
684         if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
685                 if (ntlmssp_state->nt_resp.length == 24 && ntlmssp_state->lm_resp.length == 24) {
686                         struct MD5Context md5_session_nonce_ctx;
687                         SMB_ASSERT(ntlmssp_state->internal_chal.data 
688                                    && ntlmssp_state->internal_chal.length == 8);
689                         
690                         ntlmssp_state->doing_ntlm2 = True;
691
692                         memcpy(ntlmssp_state->session_nonce, ntlmssp_state->internal_chal.data, 8);
693                         memcpy(&ntlmssp_state->session_nonce[8], ntlmssp_state->lm_resp.data, 8);
694                         
695                         MD5Init(&md5_session_nonce_ctx);
696                         MD5Update(&md5_session_nonce_ctx, ntlmssp_state->session_nonce, 16);
697                         MD5Final(session_nonce_hash, &md5_session_nonce_ctx);
698                         
699                         ntlmssp_state->chal = data_blob_talloc(ntlmssp_state, 
700                                                                session_nonce_hash, 8);
701
702                         /* LM response is no longer useful, zero it out */
703                         data_blob_free(&ntlmssp_state->lm_resp);
704
705                         /* We changed the effective challenge - set it */
706                         if (!NT_STATUS_IS_OK(nt_status = 
707                                              ntlmssp_state->set_challenge(ntlmssp_state, 
708                                                                           &ntlmssp_state->chal))) {
709                                 /* zero this out */
710                                 data_blob_free(&ntlmssp_state->encrypted_session_key);
711                                 return nt_status;
712                         }
713
714                         /* LM Key is incompatible... */
715                         ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
716                 }
717         }
718         return NT_STATUS_OK;
719 }
720
721 /**
722  * Next state function for the Authenticate packet 
723  * (after authentication - figures out the session keys etc)
724  * 
725  * @param ntlmssp_state NTLMSSP State
726  * @return Errors or NT_STATUS_OK. 
727  */
728
729 static NTSTATUS ntlmssp_server_postauth(struct ntlmssp_state *ntlmssp_state,
730                                         DATA_BLOB *user_session_key, 
731                                         DATA_BLOB *lm_session_key) 
732 {
733         NTSTATUS nt_status;
734         DATA_BLOB session_key = data_blob(NULL, 0);
735
736         if (user_session_key)
737                 dump_data_pw("USER session key:\n", user_session_key->data, user_session_key->length);
738
739         if (lm_session_key) 
740                 dump_data_pw("LM first-8:\n", lm_session_key->data, lm_session_key->length);
741
742         /* Handle the different session key derivation for NTLM2 */
743         if (ntlmssp_state->doing_ntlm2) {
744                 if (user_session_key && user_session_key->data && user_session_key->length == 16) {
745                         session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
746                         hmac_md5(user_session_key->data, ntlmssp_state->session_nonce, 
747                                  sizeof(ntlmssp_state->session_nonce), session_key.data);
748                         DEBUG(10,("ntlmssp_server_auth: Created NTLM2 session key.\n"));
749                         dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
750                         
751                 } else {
752                         DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM2 session key.\n"));
753                         session_key = data_blob(NULL, 0);
754                 }
755         } else if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) 
756                 /* Ensure we can never get here on NTLMv2 */
757                 && (ntlmssp_state->nt_resp.length == 0 || ntlmssp_state->nt_resp.length == 24)) {
758
759                 if (lm_session_key && lm_session_key->data && lm_session_key->length >= 8) {
760                         if (ntlmssp_state->lm_resp.data && ntlmssp_state->lm_resp.length == 24) {
761                                 session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
762                                 SMBsesskeygen_lm_sess_key(lm_session_key->data, ntlmssp_state->lm_resp.data, 
763                                                           session_key.data);
764                                 DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
765                                 dump_data_pw("LM session key:\n", session_key.data, session_key.length);
766                         } else {
767                                 
768                                 /* When there is no LM response, just use zeros */
769                                 static const uint8_t zeros[24];
770                                 session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
771                                 SMBsesskeygen_lm_sess_key(zeros, zeros, 
772                                                           session_key.data);
773                                 DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
774                                 dump_data_pw("LM session key:\n", session_key.data, session_key.length);
775                         }
776                 } else {
777                         /* LM Key not selected */
778                         ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
779
780                         DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM session key.\n"));
781                         session_key = data_blob(NULL, 0);
782                 }
783
784         } else if (user_session_key && user_session_key->data) {
785                 session_key = *user_session_key;
786                 DEBUG(10,("ntlmssp_server_auth: Using unmodified nt session key.\n"));
787                 dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
788
789                 /* LM Key not selected */
790                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
791
792         } else if (lm_session_key && lm_session_key->data) {
793                 /* Very weird to have LM key, but no user session key, but anyway.. */
794                 session_key = *lm_session_key;
795                 DEBUG(10,("ntlmssp_server_auth: Using unmodified lm session key.\n"));
796                 dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
797
798                 /* LM Key not selected */
799                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
800
801         } else {
802                 DEBUG(10,("ntlmssp_server_auth: Failed to create unmodified session key.\n"));
803                 session_key = data_blob(NULL, 0);
804
805                 /* LM Key not selected */
806                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
807         }
808
809         /* With KEY_EXCH, the client supplies the proposed session key, 
810            but encrypts it with the long-term key */
811         if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
812                 if (!ntlmssp_state->encrypted_session_key.data 
813                     || ntlmssp_state->encrypted_session_key.length != 16) {
814                         data_blob_free(&ntlmssp_state->encrypted_session_key);
815                         DEBUG(1, ("Client-supplied KEY_EXCH session key was of invalid length (%u)!\n", 
816                                   ntlmssp_state->encrypted_session_key.length));
817                         return NT_STATUS_INVALID_PARAMETER;
818                 } else if (!session_key.data || session_key.length != 16) {
819                         DEBUG(5, ("server session key is invalid (len == %u), cannot do KEY_EXCH!\n", 
820                                   session_key.length));
821                         ntlmssp_state->session_key = session_key;
822                 } else {
823                         dump_data_pw("KEY_EXCH session key (enc):\n", 
824                                      ntlmssp_state->encrypted_session_key.data, 
825                                      ntlmssp_state->encrypted_session_key.length);
826                         arcfour_crypt(ntlmssp_state->encrypted_session_key.data, 
827                                       session_key.data, 
828                                       ntlmssp_state->encrypted_session_key.length);
829                         ntlmssp_state->session_key = data_blob_talloc(ntlmssp_state, 
830                                                                       ntlmssp_state->encrypted_session_key.data, 
831                                                                       ntlmssp_state->encrypted_session_key.length);
832                         dump_data_pw("KEY_EXCH session key:\n", ntlmssp_state->encrypted_session_key.data, 
833                                      ntlmssp_state->encrypted_session_key.length);
834                 }
835         } else {
836                 ntlmssp_state->session_key = session_key;
837         }
838
839         /* The server might need us to use a partial-strength session key */
840         ntlmssp_weaken_keys(ntlmssp_state);
841
842         nt_status = ntlmssp_sign_init(ntlmssp_state);
843
844         data_blob_free(&ntlmssp_state->encrypted_session_key);
845         
846         /* allow arbitarily many authentications, but watch that this will cause a 
847            memory leak, until the ntlmssp_state is shutdown 
848         */
849
850         if (ntlmssp_state->server_multiple_authentications) {
851                 ntlmssp_state->expected_state = NTLMSSP_AUTH;
852         } else {
853                 ntlmssp_state->expected_state = NTLMSSP_DONE;
854         }
855
856         return nt_status;
857 }
858
859
860 /**
861  * Next state function for the Authenticate packet
862  * 
863  * @param ntlmssp_state NTLMSSP State
864  * @param in The packet in from the NTLMSSP partner, as a DATA_BLOB
865  * @param out The reply, as an allocated DATA_BLOB, caller to free.
866  * @return Errors, NT_STATUS_MORE_PROCESSING_REQUIRED or NT_STATUS_OK. 
867  */
868
869 static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
870                                     TALLOC_CTX *out_mem_ctx, 
871                                     const DATA_BLOB in, DATA_BLOB *out) 
872 {
873         DATA_BLOB user_session_key = data_blob(NULL, 0);
874         DATA_BLOB lm_session_key = data_blob(NULL, 0);
875         NTSTATUS nt_status;
876
877         /* zero the outbound NTLMSSP packet */
878         *out = data_blob_talloc(out_mem_ctx, NULL, 0);
879
880         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_server_preauth(ntlmssp_state, in))) {
881                 return nt_status;
882         }
883
884         /*
885          * Note we don't check here for NTLMv2 auth settings. If NTLMv2 auth
886          * is required (by "ntlm auth = no" and "lm auth = no" being set in the
887          * smb.conf file) and no NTLMv2 response was sent then the password check
888          * will fail here. JRA.
889          */
890
891         /* Finally, actually ask if the password is OK */
892
893         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->check_password(ntlmssp_state, 
894                                                                        &user_session_key, &lm_session_key))) {
895                 return nt_status;
896         }
897         
898         if (ntlmssp_state->server_use_session_keys) {
899                 return ntlmssp_server_postauth(ntlmssp_state, &user_session_key, &lm_session_key);
900         } else {
901                 ntlmssp_state->session_key = data_blob(NULL, 0);
902                 return NT_STATUS_OK;
903         }
904 }
905
906 /**
907  * Create an NTLMSSP state machine
908  * 
909  * @param ntlmssp_state NTLMSSP State, allocated by this function
910  */
911
912 NTSTATUS ntlmssp_server_start(TALLOC_CTX *mem_ctx, struct ntlmssp_state **ntlmssp_state)
913 {
914         *ntlmssp_state = talloc(mem_ctx, struct ntlmssp_state);
915         if (!*ntlmssp_state) {
916                 DEBUG(0,("ntlmssp_server_start: talloc failed!\n"));
917                 return NT_STATUS_NO_MEMORY;
918         }
919         ZERO_STRUCTP(*ntlmssp_state);
920
921         (*ntlmssp_state)->role = NTLMSSP_SERVER;
922
923         (*ntlmssp_state)->get_challenge = get_challenge;
924         (*ntlmssp_state)->set_challenge = set_challenge;
925         (*ntlmssp_state)->may_set_challenge = may_set_challenge;
926
927         (*ntlmssp_state)->workstation = NULL;
928         (*ntlmssp_state)->server_name = lp_netbios_name();
929
930         (*ntlmssp_state)->get_domain = lp_workgroup;
931         (*ntlmssp_state)->server_role = ROLE_DOMAIN_MEMBER; /* a good default */
932
933         (*ntlmssp_state)->expected_state = NTLMSSP_NEGOTIATE;
934
935         (*ntlmssp_state)->allow_lm_key = (lp_lanman_auth() 
936                                           && lp_parm_bool(-1, "ntlmssp_server", "allow_lm_key", False));
937
938         (*ntlmssp_state)->server_use_session_keys = True;
939         (*ntlmssp_state)->server_multiple_authentications = False;
940         
941         (*ntlmssp_state)->ref_count = 1;
942
943         (*ntlmssp_state)->neg_flags = 
944                 NTLMSSP_NEGOTIATE_NTLM;
945
946         if (lp_parm_bool(-1, "ntlmssp_server", "128bit", True)) {
947                 (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_128;           
948         }
949
950         if (lp_parm_bool(-1, "ntlmssp_server", "keyexchange", True)) {
951                 (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_KEY_EXCH;              
952         }
953
954         if (lp_parm_bool(-1, "ntlmssp_server", "ntlm2", True)) {
955                 (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;         
956         }
957
958         return NT_STATUS_OK;
959 }
960
961 /*********************************************************************
962  Client side NTLMSSP
963 *********************************************************************/
964
965 /**
966  * Next state function for the Initial packet
967  * 
968  * @param ntlmssp_state NTLMSSP State
969  * @param out_mem_ctx The DATA_BLOB *out will be allocated on this context
970  * @param in The request, as a DATA_BLOB.  reply.data must be NULL
971  * @param out The reply, as an talloc()ed DATA_BLOB, on out_mem_ctx
972  * @return Errors or NT_STATUS_OK. 
973  */
974
975 static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state, 
976                                        TALLOC_CTX *out_mem_ctx, 
977                                        DATA_BLOB in, DATA_BLOB *out) 
978 {
979         if (ntlmssp_state->unicode) {
980                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
981         } else {
982                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
983         }
984         
985         if (ntlmssp_state->use_ntlmv2) {
986                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
987         }
988
989         /* generate the ntlmssp negotiate packet */
990         msrpc_gen(out_mem_ctx, 
991                   out, "CddAA",
992                   "NTLMSSP",
993                   NTLMSSP_NEGOTIATE,
994                   ntlmssp_state->neg_flags,
995                   ntlmssp_state->get_domain(), 
996                   ntlmssp_state->workstation);
997
998         ntlmssp_state->expected_state = NTLMSSP_CHALLENGE;
999
1000         return NT_STATUS_MORE_PROCESSING_REQUIRED;
1001 }
1002
1003 /**
1004  * Next state function for the Challenge Packet.  Generate an auth packet.
1005  * 
1006  * @param ntlmssp_state NTLMSSP State
1007  * @param request The request, as a DATA_BLOB.  reply.data must be NULL
1008  * @param request The reply, as an allocated DATA_BLOB, caller to free.
1009  * @return Errors or NT_STATUS_OK. 
1010  */
1011
1012 static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, 
1013                                          TALLOC_CTX *out_mem_ctx,
1014                                          const DATA_BLOB in, DATA_BLOB *out) 
1015 {
1016         uint32_t chal_flags, ntlmssp_command, unkn1, unkn2;
1017         DATA_BLOB server_domain_blob;
1018         DATA_BLOB challenge_blob;
1019         DATA_BLOB struct_blob = data_blob(NULL, 0);
1020         char *server_domain;
1021         const char *chal_parse_string;
1022         const char *auth_gen_string;
1023         uint8_t lm_hash[16];
1024         DATA_BLOB lm_response = data_blob(NULL, 0);
1025         DATA_BLOB nt_response = data_blob(NULL, 0);
1026         DATA_BLOB session_key = data_blob(NULL, 0);
1027         DATA_BLOB lm_session_key = data_blob(NULL, 0);
1028         DATA_BLOB encrypted_session_key = data_blob(NULL, 0);
1029         NTSTATUS nt_status;
1030
1031         if (!msrpc_parse(ntlmssp_state, 
1032                          &in, "CdBd",
1033                          "NTLMSSP",
1034                          &ntlmssp_command, 
1035                          &server_domain_blob,
1036                          &chal_flags)) {
1037                 DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n"));
1038                 dump_data(2, in.data, in.length);
1039
1040                 return NT_STATUS_INVALID_PARAMETER;
1041         }
1042         
1043         data_blob_free(&server_domain_blob);
1044
1045         DEBUG(3, ("Got challenge flags:\n"));
1046         debug_ntlmssp_flags(chal_flags);
1047
1048         ntlmssp_handle_neg_flags(ntlmssp_state, chal_flags, ntlmssp_state->allow_lm_key);
1049
1050         if (ntlmssp_state->unicode) {
1051                 if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) {
1052                         chal_parse_string = "CdUdbddB";
1053                 } else {
1054                         chal_parse_string = "CdUdbdd";
1055                 }
1056                 auth_gen_string = "CdBBUUUBd";
1057         } else {
1058                 if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) {
1059                         chal_parse_string = "CdAdbddB";
1060                 } else {
1061                         chal_parse_string = "CdAdbdd";
1062                 }
1063
1064                 auth_gen_string = "CdBBAAABd";
1065         }
1066
1067         DEBUG(3, ("NTLMSSP: Set final flags:\n"));
1068         debug_ntlmssp_flags(ntlmssp_state->neg_flags);
1069
1070         if (!msrpc_parse(ntlmssp_state, 
1071                          &in, chal_parse_string,
1072                          "NTLMSSP",
1073                          &ntlmssp_command, 
1074                          &server_domain,
1075                          &chal_flags,
1076                          &challenge_blob, 8,
1077                          &unkn1, &unkn2,
1078                          &struct_blob)) {
1079                 DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#2)\n"));
1080                 dump_data(2, in.data, in.length);
1081                 return NT_STATUS_INVALID_PARAMETER;
1082         }
1083
1084         ntlmssp_state->server_domain = server_domain;
1085
1086         if (challenge_blob.length != 8) {
1087                 return NT_STATUS_INVALID_PARAMETER;
1088         }
1089
1090         if (!ntlmssp_state->password) {
1091                 static const uint8_t zeros[16];
1092                 /* do nothing - blobs are zero length */
1093
1094                 /* session key is all zeros */
1095                 session_key = data_blob_talloc(ntlmssp_state, zeros, 16);
1096                 lm_session_key = data_blob_talloc(ntlmssp_state, zeros, 16);
1097
1098                 /* not doing NLTM2 without a password */
1099                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
1100         } else if (ntlmssp_state->use_ntlmv2) {
1101
1102                 if (!struct_blob.length) {
1103                         /* be lazy, match win2k - we can't do NTLMv2 without it */
1104                         DEBUG(1, ("Server did not provide 'target information', required for NTLMv2\n"));
1105                         return NT_STATUS_INVALID_PARAMETER;
1106                 }
1107
1108                 /* TODO: if the remote server is standalone, then we should replace 'domain'
1109                    with the server name as supplied above */
1110                 
1111                 if (!SMBNTLMv2encrypt(ntlmssp_state->user, 
1112                                       ntlmssp_state->domain, 
1113                                       ntlmssp_state->password, &challenge_blob, 
1114                                       &struct_blob, 
1115                                       &lm_response, &nt_response, 
1116                                       NULL, &session_key)) {
1117                         data_blob_free(&challenge_blob);
1118                         data_blob_free(&struct_blob);
1119                         return NT_STATUS_NO_MEMORY;
1120                 }
1121
1122                 /* LM Key is incompatible... */
1123                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
1124
1125         } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
1126                 struct MD5Context md5_session_nonce_ctx;
1127                 uint8_t nt_hash[16];
1128                 uint8_t session_nonce[16];
1129                 uint8_t session_nonce_hash[16];
1130                 uint8_t user_session_key[16];
1131                 E_md4hash(ntlmssp_state->password, nt_hash);
1132                 
1133                 lm_response = data_blob_talloc(ntlmssp_state, NULL, 24);
1134                 generate_random_buffer(lm_response.data, 8);
1135                 memset(lm_response.data+8, 0, 16);
1136
1137                 memcpy(session_nonce, challenge_blob.data, 8);
1138                 memcpy(&session_nonce[8], lm_response.data, 8);
1139         
1140                 MD5Init(&md5_session_nonce_ctx);
1141                 MD5Update(&md5_session_nonce_ctx, challenge_blob.data, 8);
1142                 MD5Update(&md5_session_nonce_ctx, lm_response.data, 8);
1143                 MD5Final(session_nonce_hash, &md5_session_nonce_ctx);
1144
1145                 DEBUG(5, ("NTLMSSP challenge set by NTLM2\n"));
1146                 DEBUG(5, ("challenge is: \n"));
1147                 dump_data(5, session_nonce_hash, 8);
1148                 
1149                 nt_response = data_blob_talloc(ntlmssp_state, NULL, 24);
1150                 SMBNTencrypt(ntlmssp_state->password,
1151                              session_nonce_hash,
1152                              nt_response.data);
1153
1154                 session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
1155
1156                 SMBsesskeygen_ntv1(nt_hash, user_session_key);
1157                 hmac_md5(user_session_key, session_nonce, sizeof(session_nonce), session_key.data);
1158                 dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
1159
1160                 /* LM Key is incompatible... */
1161                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
1162         } else {
1163                 uint8_t nt_hash[16];
1164
1165                 if (ntlmssp_state->use_nt_response) {
1166                         nt_response = data_blob_talloc(ntlmssp_state, NULL, 24);
1167                         SMBNTencrypt(ntlmssp_state->password,challenge_blob.data,
1168                                      nt_response.data);
1169                         E_md4hash(ntlmssp_state->password, nt_hash);
1170                         session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
1171                         SMBsesskeygen_ntv1(nt_hash, session_key.data);
1172                         dump_data_pw("NT session key:\n", session_key.data, session_key.length);
1173                 }
1174
1175                 /* lanman auth is insecure, it may be disabled */
1176                 if (lp_client_lanman_auth()) {
1177                         lm_response = data_blob_talloc(ntlmssp_state, NULL, 24);
1178                         if (!SMBencrypt(ntlmssp_state->password,challenge_blob.data,
1179                                         lm_response.data)) {
1180                                 /* If the LM password was too long (and therefore the LM hash being
1181                                    of the first 14 chars only), don't send it */
1182                                 data_blob_free(&lm_response);
1183
1184                                 /* LM Key is incompatible with 'long' passwords */
1185                                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
1186                         } else {
1187                                 E_deshash(ntlmssp_state->password, lm_hash);
1188                                 lm_session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
1189                                 memcpy(lm_session_key.data, lm_hash, 8);
1190                                 memset(&lm_session_key.data[8], '\0', 8);
1191
1192                                 if (!ntlmssp_state->use_nt_response) {
1193                                         session_key = lm_session_key;
1194                                 }
1195                         }
1196                 } else {
1197                         /* LM Key is incompatible... */
1198                         ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
1199                 }
1200         }
1201         
1202         if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) 
1203             && lp_client_lanman_auth() && lm_session_key.length == 16) {
1204                 DATA_BLOB new_session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
1205                 if (lm_response.length == 24) {
1206                         SMBsesskeygen_lm_sess_key(lm_session_key.data, lm_response.data, 
1207                                                   new_session_key.data);
1208                 } else {
1209                         static const uint8_t zeros[24];
1210                         SMBsesskeygen_lm_sess_key(lm_session_key.data, zeros,
1211                                                   new_session_key.data);
1212                 }
1213                 new_session_key.length = 16;
1214                 session_key = new_session_key;
1215                 dump_data_pw("LM session key\n", session_key.data, session_key.length);
1216         }
1217
1218
1219         /* Key exchange encryptes a new client-generated session key with
1220            the password-derived key */
1221         if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
1222                 /* Make up a new session key */
1223                 uint8_t client_session_key[16];
1224                 generate_random_buffer(client_session_key, sizeof(client_session_key));
1225
1226                 /* Encrypt the new session key with the old one */
1227                 encrypted_session_key = data_blob_talloc(ntlmssp_state, 
1228                                                          client_session_key, sizeof(client_session_key));
1229                 dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, encrypted_session_key.length);
1230                 arcfour_crypt(encrypted_session_key.data, session_key.data, encrypted_session_key.length);
1231                 dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length);
1232
1233                 /* Mark the new session key as the 'real' session key */
1234                 session_key = data_blob_talloc(ntlmssp_state, client_session_key, sizeof(client_session_key));
1235         }
1236
1237         /* this generates the actual auth packet */
1238         if (!msrpc_gen(out_mem_ctx, 
1239                        out, auth_gen_string, 
1240                        "NTLMSSP", 
1241                        NTLMSSP_AUTH, 
1242                        lm_response.data, lm_response.length,
1243                        nt_response.data, nt_response.length,
1244                        ntlmssp_state->domain, 
1245                        ntlmssp_state->user, 
1246                        ntlmssp_state->workstation, 
1247                        encrypted_session_key.data, encrypted_session_key.length,
1248                        ntlmssp_state->neg_flags)) {
1249                 
1250                 return NT_STATUS_NO_MEMORY;
1251         }
1252
1253         ntlmssp_state->session_key = session_key;
1254
1255         /* The client might be using 56 or 40 bit weakened keys */
1256         ntlmssp_weaken_keys(ntlmssp_state);
1257
1258         ntlmssp_state->chal = challenge_blob;
1259         ntlmssp_state->lm_resp = lm_response;
1260         ntlmssp_state->nt_resp = nt_response;
1261
1262         ntlmssp_state->expected_state = NTLMSSP_DONE;
1263
1264         nt_status = ntlmssp_sign_init(ntlmssp_state);
1265         if (!NT_STATUS_IS_OK(nt_status)) {
1266                 DEBUG(1, ("Could not setup NTLMSSP signing/sealing system (error was: %s)\n", 
1267                           nt_errstr(nt_status)));
1268                 return nt_status;
1269         }
1270
1271         return nt_status;
1272 }
1273
1274 NTSTATUS ntlmssp_client_start(TALLOC_CTX *mem_ctx, struct ntlmssp_state **ntlmssp_state)
1275 {
1276         *ntlmssp_state = talloc(mem_ctx, struct ntlmssp_state);
1277         if (!*ntlmssp_state) {
1278                 DEBUG(0,("ntlmssp_client_start: talloc failed!\n"));
1279                 return NT_STATUS_NO_MEMORY;
1280         }
1281         ZERO_STRUCTP(*ntlmssp_state);
1282
1283         (*ntlmssp_state)->role = NTLMSSP_CLIENT;
1284
1285         (*ntlmssp_state)->workstation = lp_netbios_name();
1286         (*ntlmssp_state)->get_domain = lp_workgroup;
1287
1288         (*ntlmssp_state)->unicode = lp_parm_bool(-1, "ntlmssp_client", "unicode", True);
1289
1290         (*ntlmssp_state)->use_nt_response = lp_parm_bool(-1, "ntlmssp_client", "send_nt_reponse", True);
1291
1292         (*ntlmssp_state)->allow_lm_key = (lp_lanman_auth() 
1293                                           && lp_parm_bool(-1, "ntlmssp_client", "allow_lm_key", False));
1294
1295         (*ntlmssp_state)->use_ntlmv2 = lp_client_ntlmv2_auth();
1296
1297         (*ntlmssp_state)->expected_state = NTLMSSP_INITIAL;
1298
1299         (*ntlmssp_state)->ref_count = 1;
1300
1301         (*ntlmssp_state)->neg_flags = 
1302                 NTLMSSP_NEGOTIATE_NTLM |
1303                 NTLMSSP_REQUEST_TARGET;
1304
1305         if (lp_parm_bool(-1, "ntlmssp_client", "128bit", True)) {
1306                 (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_128;           
1307         }
1308
1309         if (lp_parm_bool(-1, "ntlmssp_client", "keyexchange", True)) {
1310                 (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_KEY_EXCH;              
1311         }
1312
1313         if (lp_parm_bool(-1, "ntlmssp_client", "ntlm2", True)) {
1314                 (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;         
1315         } else {
1316                 /* apparently we can't do ntlmv2 if we don't do ntlm2 */
1317                 (*ntlmssp_state)->use_ntlmv2 = False;
1318         }
1319
1320         return NT_STATUS_OK;
1321 }
1322