Coverage Report

Created: 2026-02-14 07:07

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/samba/auth/ntlmssp/ntlmssp_server.c
Line
Count
Source
1
/*
2
   Unix SMB/Netbios implementation.
3
   Version 3.0
4
   handle NTLMSSP, server side
5
6
   Copyright (C) Andrew Tridgell      2001
7
   Copyright (C) Andrew Bartlett 2001-2010
8
9
   This program is free software; you can redistribute it and/or modify
10
   it under the terms of the GNU General Public License as published by
11
   the Free Software Foundation; either version 3 of the License, or
12
   (at your option) any later version.
13
14
   This program is distributed in the hope that it will be useful,
15
   but WITHOUT ANY WARRANTY; without even the implied warranty of
16
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
   GNU General Public License for more details.
18
19
   You should have received a copy of the GNU General Public License
20
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
21
*/
22
23
#include "includes.h"
24
#include <tevent.h>
25
#include "lib/util/tevent_ntstatus.h"
26
#include "lib/util/time_basic.h"
27
#include "auth/ntlmssp/ntlmssp.h"
28
#include "auth/ntlmssp/ntlmssp_private.h"
29
#include "../librpc/gen_ndr/ndr_ntlmssp.h"
30
#include "auth/ntlmssp/ntlmssp_ndr.h"
31
#include "../libcli/auth/libcli_auth.h"
32
#include "auth/gensec/gensec.h"
33
#include "auth/gensec/gensec_internal.h"
34
#include "auth/common_auth.h"
35
#include "param/param.h"
36
#include "param/loadparm.h"
37
#include "libcli/security/session.h"
38
39
#include "lib/crypto/gnutls_helpers.h"
40
#include <gnutls/gnutls.h>
41
#include <gnutls/crypto.h>
42
43
#undef DBGC_CLASS
44
0
#define DBGC_CLASS DBGC_AUTH
45
46
/**
47
 * Determine correct target name flags for reply, given server role
48
 * and negotiated flags
49
 *
50
 * @param ntlmssp_state NTLMSSP State
51
 * @param neg_flags The flags from the packet
52
 * @param chal_flags The flags to be set in the reply packet
53
 * @return The 'target name' string.
54
 */
55
56
const char *ntlmssp_target_name(struct ntlmssp_state *ntlmssp_state,
57
        uint32_t neg_flags, uint32_t *chal_flags)
58
0
{
59
0
  if (neg_flags & NTLMSSP_REQUEST_TARGET) {
60
0
    *chal_flags |= NTLMSSP_NEGOTIATE_TARGET_INFO;
61
0
    *chal_flags |= NTLMSSP_REQUEST_TARGET;
62
0
    if (ntlmssp_state->server.is_standalone) {
63
0
      *chal_flags |= NTLMSSP_TARGET_TYPE_SERVER;
64
0
      return ntlmssp_state->server.netbios_name;
65
0
    } else {
66
0
      *chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN;
67
0
      return ntlmssp_state->server.netbios_domain;
68
0
    };
69
0
  } else {
70
0
    return "";
71
0
  }
72
0
}
73
74
/**
75
 * Next state function for the NTLMSSP Negotiate packet
76
 *
77
 * @param gensec_security GENSEC state
78
 * @param out_mem_ctx Memory context for *out
79
 * @param in The request, as a DATA_BLOB.  reply.data must be NULL
80
 * @param out The reply, as an allocated DATA_BLOB, caller to free.
81
 * @return Errors or MORE_PROCESSING_REQUIRED if (normal) a reply is required.
82
 */
83
84
NTSTATUS gensec_ntlmssp_server_negotiate(struct gensec_security *gensec_security,
85
           TALLOC_CTX *out_mem_ctx,
86
           const DATA_BLOB request, DATA_BLOB *reply)
87
0
{
88
0
  struct gensec_ntlmssp_context *gensec_ntlmssp =
89
0
    talloc_get_type_abort(gensec_security->private_data,
90
0
              struct gensec_ntlmssp_context);
91
0
  struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
92
0
  struct auth4_context *auth_context = gensec_security->auth_context;
93
0
  DATA_BLOB struct_blob;
94
0
  uint32_t neg_flags = 0;
95
0
  uint32_t ntlmssp_command, chal_flags;
96
0
  uint8_t cryptkey[8];
97
0
  const char *target_name;
98
0
  NTSTATUS status;
99
0
  struct timeval tv_now = timeval_current();
100
  /*
101
   * See [MS-NLMP]
102
   *
103
   * Windows NT 4.0, windows_2000: use 30 minutes,
104
   * Windows XP, Windows Server 2003, Windows Vista,
105
   * Windows Server 2008, Windows 7, and Windows Server 2008 R2
106
   * use 36 hours.
107
   *
108
   * Newer systems doesn't check this, likely because the
109
   * connectionless NTLMSSP is no longer supported.
110
   *
111
   * As we expect the AUTHENTICATION_MESSAGE to arrive
112
   * directly after the NEGOTIATE_MESSAGE (typically less than
113
   * as 1 second later). We use a hard timeout of 30 Minutes.
114
   *
115
   * We don't look at AUTHENTICATE_MESSAGE.NtChallengeResponse.TimeStamp
116
   * instead we just remember our own time.
117
   */
118
0
  uint32_t max_lifetime = 30 * 60;
119
0
  struct timeval tv_end = timeval_add(&tv_now, max_lifetime, 0);
120
121
  /* parse the NTLMSSP packet */
122
#if 0
123
  file_save("ntlmssp_negotiate.dat", request.data, request.length);
124
#endif
125
126
0
  if (request.length) {
127
0
    if ((request.length < 16) || !msrpc_parse(ntlmssp_state, &request, "Cdd",
128
0
                "NTLMSSP",
129
0
                &ntlmssp_command,
130
0
                &neg_flags)) {
131
0
      DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP Negotiate of length %u\n",
132
0
        (unsigned int)request.length));
133
0
      dump_data(2, request.data, request.length);
134
0
      return NT_STATUS_INVALID_PARAMETER;
135
0
    }
136
0
    debug_ntlmssp_flags(neg_flags);
137
138
0
    if (DEBUGLEVEL >= 10) {
139
0
      struct NEGOTIATE_MESSAGE *negotiate = talloc(
140
0
        ntlmssp_state, struct NEGOTIATE_MESSAGE);
141
0
      if (negotiate != NULL) {
142
0
        status = ntlmssp_pull_NEGOTIATE_MESSAGE(
143
0
          &request, negotiate, negotiate);
144
0
        if (NT_STATUS_IS_OK(status)) {
145
0
          NDR_PRINT_DEBUG(NEGOTIATE_MESSAGE,
146
0
              negotiate);
147
0
        }
148
0
        TALLOC_FREE(negotiate);
149
0
      }
150
0
    }
151
0
  }
152
153
0
  status = ntlmssp_handle_neg_flags(ntlmssp_state, neg_flags, "negotiate");
154
0
  if (!NT_STATUS_IS_OK(status)){
155
0
    return status;
156
0
  }
157
158
  /* Ask our caller what challenge they would like in the packet */
159
0
  if (auth_context->get_ntlm_challenge) {
160
0
    status = auth_context->get_ntlm_challenge(auth_context, cryptkey);
161
0
    if (!NT_STATUS_IS_OK(status)) {
162
0
      DEBUG(1, ("gensec_ntlmssp_server_negotiate: failed to get challenge: %s\n",
163
0
          nt_errstr(status)));
164
0
      return status;
165
0
    }
166
0
  } else {
167
0
    DEBUG(1, ("gensec_ntlmssp_server_negotiate: backend doesn't give a challenge\n"));
168
0
    return NT_STATUS_NOT_IMPLEMENTED;
169
0
  }
170
171
  /* The flags we send back are not just the negotiated flags,
172
   * they are also 'what is in this packet'.  Therefore, we
173
   * operate on 'chal_flags' from here on
174
   */
175
176
0
  chal_flags = ntlmssp_state->neg_flags;
177
0
  ntlmssp_state->server.challenge_endtime = timeval_to_nttime(&tv_end);
178
179
  /* get the right name to fill in as 'target' */
180
0
  target_name = ntlmssp_target_name(ntlmssp_state,
181
0
            neg_flags, &chal_flags);
182
0
  if (target_name == NULL)
183
0
    return NT_STATUS_INVALID_PARAMETER;
184
185
0
  ntlmssp_state->chal = data_blob_talloc(ntlmssp_state, cryptkey, 8);
186
0
  ntlmssp_state->internal_chal = data_blob_talloc(ntlmssp_state,
187
0
              cryptkey, 8);
188
189
  /* This creates the 'blob' of names that appears at the end of the packet */
190
0
  if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) {
191
0
    enum ndr_err_code err;
192
0
    struct AV_PAIR *pairs = NULL;
193
0
    uint32_t count = 5;
194
195
0
    pairs = talloc_zero_array(ntlmssp_state, struct AV_PAIR, count + 1);
196
0
    if (pairs == NULL) {
197
0
      return NT_STATUS_NO_MEMORY;
198
0
    }
199
200
0
    pairs[0].AvId     = MsvAvNbDomainName;
201
0
    pairs[0].Value.AvNbDomainName = target_name;
202
203
0
    pairs[1].AvId     = MsvAvNbComputerName;
204
0
    pairs[1].Value.AvNbComputerName = ntlmssp_state->server.netbios_name;
205
206
0
    pairs[2].AvId     = MsvAvDnsDomainName;
207
0
    pairs[2].Value.AvDnsDomainName  = ntlmssp_state->server.dns_domain;
208
209
0
    pairs[3].AvId     = MsvAvDnsComputerName;
210
0
    pairs[3].Value.AvDnsComputerName= ntlmssp_state->server.dns_name;
211
212
0
    if (!ntlmssp_state->force_old_spnego) {
213
0
      pairs[4].AvId     = MsvAvTimestamp;
214
0
      pairs[4].Value.AvTimestamp  =
215
0
            timeval_to_nttime(&tv_now);
216
0
      count += 1;
217
218
0
      pairs[5].AvId     = MsvAvEOL;
219
0
    } else {
220
0
      pairs[4].AvId     = MsvAvEOL;
221
0
    }
222
223
0
    ntlmssp_state->server.av_pair_list.count = count;
224
0
    ntlmssp_state->server.av_pair_list.pair = pairs;
225
226
0
    err = ndr_push_struct_blob(&struct_blob,
227
0
          ntlmssp_state,
228
0
          &ntlmssp_state->server.av_pair_list,
229
0
          (ndr_push_flags_fn_t)ndr_push_AV_PAIR_LIST);
230
0
    if (!NDR_ERR_CODE_IS_SUCCESS(err)) {
231
0
      return NT_STATUS_NO_MEMORY;
232
0
    }
233
0
  } else {
234
0
    struct_blob = data_blob_null;
235
0
  }
236
237
0
  {
238
    /* Marshal the packet in the right format, be it unicode or ASCII */
239
0
    const char *gen_string;
240
0
    const DATA_BLOB version_blob = ntlmssp_version_blob();
241
242
0
    if (ntlmssp_state->unicode) {
243
0
      gen_string = "CdUdbddBb";
244
0
    } else {
245
0
      gen_string = "CdAdbddBb";
246
0
    }
247
248
0
    status = msrpc_gen(out_mem_ctx, reply, gen_string,
249
0
      "NTLMSSP",
250
0
      NTLMSSP_CHALLENGE,
251
0
      target_name,
252
0
      chal_flags,
253
0
      cryptkey, 8,
254
0
      0, 0,
255
0
      struct_blob.data, struct_blob.length,
256
0
      version_blob.data, version_blob.length);
257
258
0
    if (!NT_STATUS_IS_OK(status)) {
259
0
      data_blob_free(&struct_blob);
260
0
      return status;
261
0
    }
262
263
0
    if (DEBUGLEVEL >= 10) {
264
0
      struct CHALLENGE_MESSAGE *challenge = talloc(
265
0
        ntlmssp_state, struct CHALLENGE_MESSAGE);
266
0
      if (challenge != NULL) {
267
0
        challenge->NegotiateFlags = chal_flags;
268
0
        status = ntlmssp_pull_CHALLENGE_MESSAGE(
269
0
          reply, challenge, challenge);
270
0
        if (NT_STATUS_IS_OK(status)) {
271
0
          NDR_PRINT_DEBUG(CHALLENGE_MESSAGE,
272
0
              challenge);
273
0
        }
274
0
        TALLOC_FREE(challenge);
275
0
      }
276
0
    }
277
0
  }
278
279
0
  data_blob_free(&struct_blob);
280
281
0
  ntlmssp_state->negotiate_blob = data_blob_dup_talloc(ntlmssp_state,
282
0
                   request);
283
0
  if (ntlmssp_state->negotiate_blob.length != request.length) {
284
0
    return NT_STATUS_NO_MEMORY;
285
0
  }
286
287
0
  ntlmssp_state->challenge_blob = data_blob_dup_talloc(ntlmssp_state,
288
0
                   *reply);
289
0
  if (ntlmssp_state->challenge_blob.length != reply->length) {
290
0
    return NT_STATUS_NO_MEMORY;
291
0
  }
292
293
0
  ntlmssp_state->expected_state = NTLMSSP_AUTH;
294
295
0
  return NT_STATUS_MORE_PROCESSING_REQUIRED;
296
0
}
297
298
struct ntlmssp_server_auth_state {
299
  struct gensec_security *gensec_security;
300
  struct gensec_ntlmssp_context *gensec_ntlmssp;
301
  DATA_BLOB in;
302
  struct auth_usersupplied_info *user_info;
303
  DATA_BLOB user_session_key;
304
  DATA_BLOB lm_session_key;
305
  /* internal variables used by KEY_EXCH (client-supplied user session key */
306
  DATA_BLOB encrypted_session_key;
307
  bool doing_ntlm2;
308
  /* internal variables used by NTLM2 */
309
  uint8_t session_nonce[16];
310
};
311
312
static NTSTATUS ntlmssp_server_preauth(struct gensec_security *gensec_security,
313
               struct gensec_ntlmssp_context *gensec_ntlmssp,
314
               struct ntlmssp_server_auth_state *state,
315
               const DATA_BLOB request);
316
static void ntlmssp_server_auth_done(struct tevent_req *subreq);
317
static NTSTATUS ntlmssp_server_postauth(struct gensec_security *gensec_security,
318
          struct gensec_ntlmssp_context *gensec_ntlmssp,
319
          struct ntlmssp_server_auth_state *state,
320
          DATA_BLOB request);
321
322
struct tevent_req *ntlmssp_server_auth_send(TALLOC_CTX *mem_ctx,
323
              struct tevent_context *ev,
324
              struct gensec_security *gensec_security,
325
              const DATA_BLOB in)
326
0
{
327
0
  struct gensec_ntlmssp_context *gensec_ntlmssp =
328
0
    talloc_get_type_abort(gensec_security->private_data,
329
0
              struct gensec_ntlmssp_context);
330
0
  struct auth4_context *auth_context = gensec_security->auth_context;
331
0
  struct tevent_req *req = NULL;
332
0
  struct tevent_req *subreq = NULL;
333
0
  struct ntlmssp_server_auth_state *state = NULL;
334
0
  NTSTATUS status;
335
336
0
  req = tevent_req_create(mem_ctx, &state,
337
0
        struct ntlmssp_server_auth_state);
338
0
  if (req == NULL) {
339
0
    return NULL;
340
0
  }
341
0
  state->gensec_security = gensec_security;
342
0
  state->gensec_ntlmssp = gensec_ntlmssp;
343
0
  state->in = in;
344
345
0
  status = ntlmssp_server_preauth(gensec_security,
346
0
          gensec_ntlmssp,
347
0
          state, in);
348
0
  if (tevent_req_nterror(req, status)) {
349
0
    return tevent_req_post(req, ev);
350
0
  }
351
352
0
  subreq = auth_context->check_ntlm_password_send(
353
0
    state, ev, auth_context, state->user_info);
354
0
  if (tevent_req_nomem(subreq, req)) {
355
0
    return tevent_req_post(req, ev);
356
0
  }
357
0
  tevent_req_set_callback(subreq,  ntlmssp_server_auth_done, req);
358
0
  return req;
359
0
}
360
361
/**
362
 * Next state function for the Authenticate packet
363
 *
364
 * @param ntlmssp_state NTLMSSP State
365
 * @param request The request, as a DATA_BLOB
366
 * @return Errors or NT_STATUS_OK.
367
 */
368
369
static NTSTATUS ntlmssp_server_preauth(struct gensec_security *gensec_security,
370
               struct gensec_ntlmssp_context *gensec_ntlmssp,
371
               struct ntlmssp_server_auth_state *state,
372
               const DATA_BLOB request)
373
0
{
374
0
  struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
375
0
  struct auth4_context *auth_context = gensec_security->auth_context;
376
0
  struct auth_usersupplied_info *user_info = NULL;
377
0
  uint32_t ntlmssp_command, auth_flags;
378
0
  NTSTATUS nt_status;
379
0
  const unsigned int version_len = 8;
380
0
  DATA_BLOB version_blob = data_blob_null;
381
0
  const unsigned int mic_len = NTLMSSP_MIC_SIZE;
382
0
  DATA_BLOB mic_blob = data_blob_null;
383
0
  const uint8_t zero_channel_bindings[16] = { 0, };
384
0
  const uint8_t *client_channel_bindings = zero_channel_bindings;
385
0
  uint8_t server_channel_bindings[16] = { 0, };
386
0
  const char *parse_string;
387
0
  bool ok;
388
0
  struct timeval endtime;
389
0
  bool expired = false;
390
391
#if 0
392
  file_save("ntlmssp_auth.dat", request.data, request.length);
393
#endif
394
395
0
  if (ntlmssp_state->unicode) {
396
0
    parse_string = "CdBBUUUBdbb";
397
0
  } else {
398
0
    parse_string = "CdBBAAABdbb";
399
0
  }
400
401
  /* zero these out */
402
0
  data_blob_free(&ntlmssp_state->session_key);
403
0
  data_blob_free(&ntlmssp_state->lm_resp);
404
0
  data_blob_free(&ntlmssp_state->nt_resp);
405
406
0
  ntlmssp_state->user = NULL;
407
0
  ntlmssp_state->domain = NULL;
408
0
  ntlmssp_state->client.netbios_name = NULL;
409
410
  /* now the NTLMSSP encoded auth hashes */
411
0
  ok = msrpc_parse(ntlmssp_state, &request, parse_string,
412
0
       "NTLMSSP",
413
0
       &ntlmssp_command,
414
0
       &ntlmssp_state->lm_resp,
415
0
       &ntlmssp_state->nt_resp,
416
0
       &ntlmssp_state->domain,
417
0
       &ntlmssp_state->user,
418
0
       &ntlmssp_state->client.netbios_name,
419
0
       &state->encrypted_session_key,
420
0
       &auth_flags,
421
0
       &version_blob, version_len,
422
0
       &mic_blob, mic_len);
423
0
  if (!ok) {
424
0
    DEBUG(10, ("ntlmssp_server_auth: failed to parse NTLMSSP (nonfatal):\n"));
425
0
    dump_data(10, request.data, request.length);
426
427
0
    data_blob_free(&version_blob);
428
0
    data_blob_free(&mic_blob);
429
430
0
    if (ntlmssp_state->unicode) {
431
0
      parse_string = "CdBBUUUBd";
432
0
    } else {
433
0
      parse_string = "CdBBAAABd";
434
0
    }
435
436
0
    ok = msrpc_parse(ntlmssp_state, &request, parse_string,
437
0
         "NTLMSSP",
438
0
         &ntlmssp_command,
439
0
         &ntlmssp_state->lm_resp,
440
0
         &ntlmssp_state->nt_resp,
441
0
         &ntlmssp_state->domain,
442
0
         &ntlmssp_state->user,
443
0
         &ntlmssp_state->client.netbios_name,
444
0
         &state->encrypted_session_key,
445
0
         &auth_flags);
446
0
  }
447
448
0
  if (!ok) {
449
0
    DEBUG(10, ("ntlmssp_server_auth: failed to parse NTLMSSP (nonfatal):\n"));
450
0
    dump_data(10, request.data, request.length);
451
452
    /* zero this out */
453
0
    data_blob_free(&state->encrypted_session_key);
454
0
    auth_flags = 0;
455
456
    /* Try again with a shorter string (Win9X truncates this packet) */
457
0
    if (ntlmssp_state->unicode) {
458
0
      parse_string = "CdBBUUU";
459
0
    } else {
460
0
      parse_string = "CdBBAAA";
461
0
    }
462
463
    /* now the NTLMSSP encoded auth hashes */
464
0
    if (!msrpc_parse(ntlmssp_state, &request, parse_string,
465
0
         "NTLMSSP",
466
0
         &ntlmssp_command,
467
0
         &ntlmssp_state->lm_resp,
468
0
         &ntlmssp_state->nt_resp,
469
0
         &ntlmssp_state->domain,
470
0
         &ntlmssp_state->user,
471
0
         &ntlmssp_state->client.netbios_name)) {
472
0
      DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP (tried both formats):\n"));
473
0
      dump_data(2, request.data, request.length);
474
475
0
      return NT_STATUS_INVALID_PARAMETER;
476
0
    }
477
0
  }
478
479
0
  talloc_steal(state, state->encrypted_session_key.data);
480
481
0
  if (auth_flags != 0) {
482
0
    nt_status = ntlmssp_handle_neg_flags(ntlmssp_state,
483
0
                 auth_flags,
484
0
                 "authenticate");
485
0
    if (!NT_STATUS_IS_OK(nt_status)){
486
0
      return nt_status;
487
0
    }
488
0
  }
489
490
0
  if (DEBUGLEVEL >= 10) {
491
0
    struct AUTHENTICATE_MESSAGE *authenticate = talloc(
492
0
      ntlmssp_state, struct AUTHENTICATE_MESSAGE);
493
0
    if (authenticate != NULL) {
494
0
      NTSTATUS status;
495
0
      authenticate->NegotiateFlags = auth_flags;
496
0
      status = ntlmssp_pull_AUTHENTICATE_MESSAGE(
497
0
        &request, authenticate, authenticate);
498
0
      if (NT_STATUS_IS_OK(status)) {
499
0
        NDR_PRINT_DEBUG(AUTHENTICATE_MESSAGE,
500
0
            authenticate);
501
0
      }
502
0
      TALLOC_FREE(authenticate);
503
0
    }
504
0
  }
505
506
0
  DEBUG(3,("Got user=[%s] domain=[%s] workstation=[%s] len1=%lu len2=%lu\n",
507
0
     ntlmssp_state->user, ntlmssp_state->domain,
508
0
     ntlmssp_state->client.netbios_name,
509
0
     (unsigned long)ntlmssp_state->lm_resp.length,
510
0
     (unsigned long)ntlmssp_state->nt_resp.length));
511
512
#if 0
513
  file_save("nthash1.dat",  &ntlmssp_state->nt_resp.data,  &ntlmssp_state->nt_resp.length);
514
  file_save("lmhash1.dat",  &ntlmssp_state->lm_resp.data,  &ntlmssp_state->lm_resp.length);
515
#endif
516
517
0
  if (ntlmssp_state->nt_resp.length > 24) {
518
0
    struct NTLMv2_RESPONSE v2_resp;
519
0
    enum ndr_err_code err;
520
0
    uint32_t i = 0;
521
0
    uint32_t count = 0;
522
0
    const struct AV_PAIR *flags = NULL;
523
0
    const struct AV_PAIR *cb = NULL;
524
0
    const struct AV_PAIR *eol = NULL;
525
0
    uint32_t av_flags = 0;
526
527
0
    err = ndr_pull_struct_blob(&ntlmssp_state->nt_resp,
528
0
          ntlmssp_state,
529
0
          &v2_resp,
530
0
          (ndr_pull_flags_fn_t)ndr_pull_NTLMv2_RESPONSE);
531
0
    if (!NDR_ERR_CODE_IS_SUCCESS(err)) {
532
0
      nt_status = ndr_map_error2ntstatus(err);
533
0
      if (NT_STATUS_EQUAL(nt_status, NT_STATUS_BUFFER_TOO_SMALL)) {
534
        /*
535
         * Note that invalid blobs should result in
536
         * INVALID_PARAMETER, as demonstrated by
537
         * smb2.session.ntlmssp_bug14932
538
         */
539
0
        nt_status = NT_STATUS_INVALID_PARAMETER;
540
0
      }
541
0
      DEBUG(1,("%s: failed to parse NTLMv2_RESPONSE of length %zu for "
542
0
         "user=[%s] domain=[%s] workstation=[%s] - %s %s\n",
543
0
         __func__, ntlmssp_state->nt_resp.length,
544
0
         ntlmssp_state->user, ntlmssp_state->domain,
545
0
         ntlmssp_state->client.netbios_name,
546
0
         ndr_errstr(err), nt_errstr(nt_status)));
547
0
      return nt_status;
548
0
    }
549
550
0
    if (DEBUGLVL(10)) {
551
0
      NDR_PRINT_DEBUG(NTLMv2_RESPONSE, &v2_resp);
552
0
    }
553
554
0
    eol = ndr_ntlmssp_find_av(&v2_resp.Challenge.AvPairs,
555
0
            MsvAvEOL);
556
0
    if (eol == NULL) {
557
0
      DEBUG(1,("%s: missing MsvAvEOL for "
558
0
         "user=[%s] domain=[%s] workstation=[%s]\n",
559
0
         __func__, ntlmssp_state->user, ntlmssp_state->domain,
560
0
         ntlmssp_state->client.netbios_name));
561
0
      return NT_STATUS_INVALID_PARAMETER;
562
0
    }
563
564
0
    flags = ndr_ntlmssp_find_av(&v2_resp.Challenge.AvPairs,
565
0
              MsvAvFlags);
566
0
    if (flags != NULL) {
567
0
      av_flags = flags->Value.AvFlags;
568
0
    }
569
570
0
    if (av_flags & NTLMSSP_AVFLAG_MIC_IN_AUTHENTICATE_MESSAGE) {
571
0
      if (mic_blob.length != NTLMSSP_MIC_SIZE) {
572
0
        DEBUG(1,("%s: mic_blob.length[%u] for "
573
0
           "user=[%s] domain=[%s] workstation=[%s]\n",
574
0
           __func__,
575
0
           (unsigned)mic_blob.length,
576
0
           ntlmssp_state->user,
577
0
           ntlmssp_state->domain,
578
0
           ntlmssp_state->client.netbios_name));
579
0
        return NT_STATUS_INVALID_PARAMETER;
580
0
      }
581
582
0
      if (request.length <
583
0
          (NTLMSSP_MIC_OFFSET + NTLMSSP_MIC_SIZE))
584
0
      {
585
0
        DEBUG(1,("%s: missing MIC "
586
0
           "request.length[%u] for "
587
0
           "user=[%s] domain=[%s] workstation=[%s]\n",
588
0
           __func__,
589
0
           (unsigned)request.length,
590
0
           ntlmssp_state->user,
591
0
           ntlmssp_state->domain,
592
0
           ntlmssp_state->client.netbios_name));
593
0
        return NT_STATUS_INVALID_PARAMETER;
594
0
      }
595
596
0
      ntlmssp_state->new_spnego = true;
597
0
    }
598
599
0
    cb = ndr_ntlmssp_find_av(&v2_resp.Challenge.AvPairs,
600
0
           MsvChannelBindings);
601
0
    if (cb != NULL) {
602
0
      client_channel_bindings = cb->Value.ChannelBindings;
603
0
    }
604
605
0
    count = ntlmssp_state->server.av_pair_list.count;
606
0
    if (v2_resp.Challenge.AvPairs.count < count) {
607
0
      return NT_STATUS_INVALID_PARAMETER;
608
0
    }
609
610
0
    for (i = 0; i < count; i++) {
611
0
      const struct AV_PAIR *sp =
612
0
        &ntlmssp_state->server.av_pair_list.pair[i];
613
0
      const struct AV_PAIR *cp = NULL;
614
615
0
      if (sp->AvId == MsvAvEOL) {
616
0
        continue;
617
0
      }
618
619
0
      cp = ndr_ntlmssp_find_av(&v2_resp.Challenge.AvPairs,
620
0
             sp->AvId);
621
0
      if (cp == NULL) {
622
0
        DEBUG(1,("%s: AvId 0x%x missing for"
623
0
           "user=[%s] domain=[%s] "
624
0
           "workstation=[%s]\n",
625
0
           __func__,
626
0
           (unsigned)sp->AvId,
627
0
           ntlmssp_state->user,
628
0
           ntlmssp_state->domain,
629
0
           ntlmssp_state->client.netbios_name));
630
0
        return NT_STATUS_INVALID_PARAMETER;
631
0
      }
632
633
0
      switch (cp->AvId) {
634
0
#define CASE_STRING(v) case Msv ## v: do { \
635
0
  int cmp; \
636
0
  if (sp->Value.v == NULL) { \
637
0
    return NT_STATUS_INTERNAL_ERROR; \
638
0
  } \
639
0
  if (cp->Value.v == NULL) { \
640
0
    DEBUG(1,("%s: invalid %s " \
641
0
       "got[%s] expect[%s] for " \
642
0
       "user=[%s] domain=[%s] workstation=[%s]\n", \
643
0
       __func__, #v, \
644
0
       cp->Value.v, \
645
0
       sp->Value.v, \
646
0
       ntlmssp_state->user, \
647
0
       ntlmssp_state->domain, \
648
0
       ntlmssp_state->client.netbios_name)); \
649
0
    return NT_STATUS_INVALID_PARAMETER; \
650
0
  } \
651
0
  cmp = strcmp(cp->Value.v, sp->Value.v); \
652
0
  if (cmp != 0) { \
653
0
    DEBUG(1,("%s: invalid %s " \
654
0
       "got[%s] expect[%s] for " \
655
0
       "user=[%s] domain=[%s] workstation=[%s]\n", \
656
0
       __func__, #v, \
657
0
       cp->Value.v, \
658
0
       sp->Value.v, \
659
0
       ntlmssp_state->user, \
660
0
       ntlmssp_state->domain, \
661
0
       ntlmssp_state->client.netbios_name)); \
662
0
    return NT_STATUS_INVALID_PARAMETER; \
663
0
  } \
664
0
} while(0); break
665
0
      CASE_STRING(AvNbComputerName);
666
0
      CASE_STRING(AvNbDomainName);
667
0
      CASE_STRING(AvDnsComputerName);
668
0
      CASE_STRING(AvDnsDomainName);
669
0
      CASE_STRING(AvDnsTreeName);
670
0
      case MsvAvTimestamp:
671
0
        if (cp->Value.AvTimestamp != sp->Value.AvTimestamp) {
672
0
          struct timeval ct;
673
0
          struct timeval st;
674
0
          struct timeval_buf tmp1;
675
0
          struct timeval_buf tmp2;
676
677
0
          nttime_to_timeval(&ct,
678
0
                cp->Value.AvTimestamp);
679
0
          nttime_to_timeval(&st,
680
0
                sp->Value.AvTimestamp);
681
682
0
          DEBUG(1,("%s: invalid AvTimestamp "
683
0
             "got[%s] expect[%s] for "
684
0
             "user=[%s] domain=[%s] "
685
0
             "workstation=[%s]\n",
686
0
             __func__,
687
0
             timeval_str_buf(&ct, false,
688
0
                 true, &tmp1),
689
0
             timeval_str_buf(&st, false,
690
0
                 true, &tmp2),
691
0
             ntlmssp_state->user,
692
0
             ntlmssp_state->domain,
693
0
             ntlmssp_state->client.netbios_name));
694
0
          return NT_STATUS_INVALID_PARAMETER;
695
0
        }
696
0
        break;
697
0
      default:
698
        /*
699
         * This can't happen as we control
700
         * ntlmssp_state->server.av_pair_list
701
         */
702
0
        return NT_STATUS_INTERNAL_ERROR;
703
0
      }
704
0
    }
705
0
  }
706
707
0
  if (gensec_security->channel_bindings != NULL) {
708
0
    nt_status = ntlmssp_hash_channel_bindings(gensec_security,
709
0
                server_channel_bindings);
710
0
    if (!NT_STATUS_IS_OK(nt_status)) {
711
0
      return nt_status;
712
0
    }
713
714
0
    ok = mem_equal_const_time(client_channel_bindings,
715
0
            server_channel_bindings,
716
0
            16);
717
0
    if (!ok && gensec_security->want_features & GENSEC_FEATURE_CB_OPTIONAL) {
718
      /*
719
       * Unlike kerberos, explicit 16 zeros in
720
       * MsvChannelBindings are not enough to
721
       * pass the optional check.
722
       *
723
       * So we only let it through without explicit
724
       * MsvChannelBindings.
725
       */
726
0
      ok = (client_channel_bindings == zero_channel_bindings);
727
0
    }
728
0
    if (!ok) {
729
0
      DBG_WARNING("Invalid channel bindings for "
730
0
            "user=[%s] domain=[%s] workstation=[%s]\n",
731
0
            ntlmssp_state->user,
732
0
            ntlmssp_state->domain,
733
0
            ntlmssp_state->client.netbios_name);
734
0
      dump_data(DBGLVL_WARNING,
735
0
          client_channel_bindings,
736
0
          16);
737
0
      dump_data(DBGLVL_WARNING,
738
0
          server_channel_bindings,
739
0
          16);
740
0
      return NT_STATUS_BAD_BINDINGS;
741
0
    }
742
0
  }
743
744
0
  nttime_to_timeval(&endtime, ntlmssp_state->server.challenge_endtime);
745
0
  expired = timeval_expired(&endtime);
746
0
  if (expired) {
747
0
    struct timeval_buf tmp;
748
0
    DEBUG(1,("%s: challenge invalid (expired %s) for "
749
0
       "user=[%s] domain=[%s] workstation=[%s]\n",
750
0
       __func__,
751
0
       timeval_str_buf(&endtime, false, true, &tmp),
752
0
       ntlmssp_state->user, ntlmssp_state->domain,
753
0
       ntlmssp_state->client.netbios_name));
754
0
    return NT_STATUS_INVALID_PARAMETER;
755
0
  }
756
757
  /* NTLM2 uses a 'challenge' that is made of up both the server challenge, and a
758
     client challenge
759
760
     However, the NTLM2 flag may still be set for the real NTLMv2 logins, be careful.
761
  */
762
0
  if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
763
0
    if (ntlmssp_state->nt_resp.length == 24 && ntlmssp_state->lm_resp.length == 24) {
764
0
      state->doing_ntlm2 = true;
765
766
0
      memcpy(state->session_nonce, ntlmssp_state->internal_chal.data, 8);
767
0
      memcpy(&state->session_nonce[8], ntlmssp_state->lm_resp.data, 8);
768
769
0
      SMB_ASSERT(ntlmssp_state->internal_chal.data && ntlmssp_state->internal_chal.length == 8);
770
771
      /* LM response is no longer useful */
772
0
      data_blob_free(&ntlmssp_state->lm_resp);
773
774
      /* We changed the effective challenge - set it */
775
0
      if (auth_context->set_ntlm_challenge) {
776
0
        uint8_t session_nonce_hash[16];
777
0
        int rc;
778
779
0
        rc = gnutls_hash_fast(GNUTLS_DIG_MD5,
780
0
                  state->session_nonce,
781
0
                  16,
782
0
                  session_nonce_hash);
783
0
        if (rc < 0) {
784
0
          return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
785
0
        }
786
787
788
0
        nt_status = auth_context->set_ntlm_challenge(auth_context,
789
0
                       session_nonce_hash,
790
0
                       "NTLMSSP callback (NTLM2)");
791
0
        ZERO_ARRAY(session_nonce_hash);
792
0
        if (!NT_STATUS_IS_OK(nt_status)) {
793
0
          DEBUG(1, ("gensec_ntlmssp_server_negotiate: failed to get challenge: %s\n",
794
0
              nt_errstr(nt_status)));
795
0
          return nt_status;
796
0
        }
797
0
      } else {
798
0
        DEBUG(1, ("gensec_ntlmssp_server_negotiate: backend doesn't have facility for challenge to be set\n"));
799
800
0
        return NT_STATUS_NOT_IMPLEMENTED;
801
0
      }
802
803
      /* LM Key is incompatible. */
804
0
      ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
805
0
    }
806
0
  }
807
808
0
  user_info = talloc_zero(state, struct auth_usersupplied_info);
809
0
  if (!user_info) {
810
0
    return NT_STATUS_NO_MEMORY;
811
0
  }
812
813
0
  user_info->logon_parameters = MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT | MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
814
0
  user_info->flags = 0;
815
0
  user_info->client.account_name = ntlmssp_state->user;
816
0
  user_info->client.domain_name = ntlmssp_state->domain;
817
0
  user_info->workstation_name = ntlmssp_state->client.netbios_name;
818
0
  user_info->remote_host = gensec_get_remote_address(gensec_security);
819
0
  user_info->local_host = gensec_get_local_address(gensec_security);
820
0
  user_info->service_description
821
0
    = gensec_get_target_service_description(gensec_security);
822
823
  /*
824
   * This will just be the string "NTLMSSP" from
825
   * gensec_ntlmssp_final_auth_type, but ensures it stays in sync
826
   * with the same use in the authorization logging triggered by
827
   * gensec_session_info() later
828
   */
829
0
  user_info->auth_description = gensec_final_auth_type(gensec_security);
830
831
0
  user_info->password_state = AUTH_PASSWORD_RESPONSE;
832
0
  user_info->password.response.lanman = ntlmssp_state->lm_resp;
833
0
  user_info->password.response.nt = ntlmssp_state->nt_resp;
834
835
0
  state->user_info = user_info;
836
0
  return NT_STATUS_OK;
837
0
}
838
839
static void ntlmssp_server_auth_done(struct tevent_req *subreq)
840
0
{
841
0
  struct tevent_req *req =
842
0
    tevent_req_callback_data(subreq,
843
0
    struct tevent_req);
844
0
  struct ntlmssp_server_auth_state *state =
845
0
    tevent_req_data(req,
846
0
    struct ntlmssp_server_auth_state);
847
0
  struct gensec_security *gensec_security = state->gensec_security;
848
0
  struct gensec_ntlmssp_context *gensec_ntlmssp = state->gensec_ntlmssp;
849
0
  struct auth4_context *auth_context = gensec_security->auth_context;
850
0
  uint8_t authoritative = 1;
851
0
  NTSTATUS status;
852
853
0
  status = auth_context->check_ntlm_password_recv(subreq,
854
0
            gensec_ntlmssp,
855
0
            &authoritative,
856
0
            &gensec_ntlmssp->server_returned_info,
857
0
            &state->user_session_key,
858
0
            &state->lm_session_key);
859
0
  TALLOC_FREE(subreq);
860
0
  if (!NT_STATUS_IS_OK(status)) {
861
0
    DBG_INFO("Checking NTLMSSP password for %s\\%s failed: %s\n",
862
0
       state->user_info->client.domain_name,
863
0
       state->user_info->client.account_name,
864
0
       nt_errstr(status));
865
0
  }
866
0
  if (tevent_req_nterror(req, status)) {
867
0
    return;
868
0
  }
869
0
  talloc_steal(state, state->user_session_key.data);
870
0
  talloc_steal(state, state->lm_session_key.data);
871
872
0
  status = ntlmssp_server_postauth(state->gensec_security,
873
0
           state->gensec_ntlmssp,
874
0
           state, state->in);
875
0
  if (tevent_req_nterror(req, status)) {
876
0
    return;
877
0
  }
878
879
0
  tevent_req_done(req);
880
0
}
881
882
/**
883
 * Next state function for the Authenticate packet
884
 * (after authentication - figures out the session keys etc)
885
 *
886
 * @param ntlmssp_state NTLMSSP State
887
 * @return Errors or NT_STATUS_OK.
888
 */
889
890
static NTSTATUS ntlmssp_server_postauth(struct gensec_security *gensec_security,
891
          struct gensec_ntlmssp_context *gensec_ntlmssp,
892
          struct ntlmssp_server_auth_state *state,
893
          DATA_BLOB request)
894
0
{
895
0
  struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
896
0
  struct auth4_context *auth_context = gensec_security->auth_context;
897
0
  DATA_BLOB user_session_key = state->user_session_key;
898
0
  DATA_BLOB lm_session_key = state->lm_session_key;
899
0
  NTSTATUS nt_status = NT_STATUS_OK;
900
0
  DATA_BLOB session_key = {};
901
0
  struct auth_session_info *session_info = NULL;
902
903
0
  TALLOC_FREE(state->user_info);
904
905
0
  if (lpcfg_map_to_guest(gensec_security->settings->lp_ctx) != NEVER_MAP_TO_GUEST
906
0
      && auth_context->generate_session_info != NULL)
907
0
  {
908
0
    NTSTATUS tmp_status;
909
910
    /*
911
     * We need to check if the auth is anonymous or mapped to guest
912
     */
913
0
    tmp_status = auth_context->generate_session_info(auth_context, state,
914
0
                 gensec_ntlmssp->server_returned_info,
915
0
                 gensec_ntlmssp->ntlmssp_state->user,
916
0
                 AUTH_SESSION_INFO_SIMPLE_PRIVILEGES,
917
0
                 &session_info);
918
0
    if (!NT_STATUS_IS_OK(tmp_status)) {
919
      /*
920
       * We don't care about failures,
921
       * the worst result is that we try MIC checking
922
       * for a map to guest authentication.
923
       */
924
0
      TALLOC_FREE(session_info);
925
0
    }
926
0
  }
927
928
0
  if (session_info != NULL) {
929
0
    if (security_session_user_level(session_info, NULL) < SECURITY_USER) {
930
      /*
931
       * Anonymous and GUEST are not secure anyway.
932
       * avoid new_spnego and MIC checking.
933
       */
934
0
      ntlmssp_state->new_spnego = false;
935
0
      ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SIGN;
936
0
      ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SEAL;
937
0
    }
938
0
    TALLOC_FREE(session_info);
939
0
  }
940
941
0
  dump_data_pw("NT session key:\n", user_session_key.data, user_session_key.length);
942
0
  dump_data_pw("LM first-8:\n", lm_session_key.data, lm_session_key.length);
943
944
  /* Handle the different session key derivation for NTLM2 */
945
0
  if (state->doing_ntlm2) {
946
0
    if (user_session_key.data && user_session_key.length == 16) {
947
0
      int rc;
948
949
0
      session_key = data_blob_talloc(ntlmssp_state,
950
0
                   NULL, 16);
951
952
0
      rc = gnutls_hmac_fast(GNUTLS_MAC_MD5,
953
0
                user_session_key.data,
954
0
                user_session_key.length,
955
0
                state->session_nonce,
956
0
                sizeof(state->session_nonce),
957
0
                session_key.data);
958
0
      if (rc < 0) {
959
0
        return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
960
0
      }
961
962
0
      DEBUG(10,("ntlmssp_server_auth: Created NTLM2 session key.\n"));
963
0
      dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
964
965
0
    } else {
966
0
      DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM2 session key.\n"));
967
0
      session_key = data_blob_null;
968
0
    }
969
0
  } else if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
970
    /* Ensure we can never get here on NTLMv2 */
971
0
    && (ntlmssp_state->nt_resp.length == 0 || ntlmssp_state->nt_resp.length == 24)) {
972
973
0
    if (lm_session_key.data && lm_session_key.length >= 8) {
974
0
      if (ntlmssp_state->lm_resp.data && ntlmssp_state->lm_resp.length == 24) {
975
0
        session_key = data_blob_talloc(ntlmssp_state,
976
0
                     NULL, 16);
977
0
        if (session_key.data == NULL) {
978
0
          return NT_STATUS_NO_MEMORY;
979
0
        }
980
0
        nt_status = SMBsesskeygen_lm_sess_key(lm_session_key.data,
981
0
                      ntlmssp_state->lm_resp.data,
982
0
                      session_key.data);
983
0
        if (!NT_STATUS_IS_OK(nt_status)) {
984
0
          return nt_status;
985
0
        }
986
0
        DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
987
0
      } else {
988
0
        static const uint8_t zeros[24] = {0, };
989
0
        session_key = data_blob_talloc(
990
0
          ntlmssp_state, NULL, 16);
991
0
        if (session_key.data == NULL) {
992
0
          return NT_STATUS_NO_MEMORY;
993
0
        }
994
0
        nt_status = SMBsesskeygen_lm_sess_key(zeros, zeros,
995
0
                      session_key.data);
996
0
        if (!NT_STATUS_IS_OK(nt_status)) {
997
0
          return nt_status;
998
0
        }
999
0
        DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
1000
0
      }
1001
0
      dump_data_pw("LM session key:\n", session_key.data,
1002
0
             session_key.length);
1003
0
    } else {
1004
      /* LM Key not selected */
1005
0
      ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
1006
1007
0
      DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM session key.\n"));
1008
0
      session_key = data_blob_null;
1009
0
    }
1010
1011
0
  } else if (user_session_key.data) {
1012
0
    session_key = user_session_key;
1013
0
    DEBUG(10,("ntlmssp_server_auth: Using unmodified nt session key.\n"));
1014
0
    dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
1015
1016
    /* LM Key not selected */
1017
0
    ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
1018
1019
0
  } else if (lm_session_key.data) {
1020
    /* Very weird to have LM key, but no user session key, but anyway.. */
1021
0
    session_key = lm_session_key;
1022
0
    DEBUG(10,("ntlmssp_server_auth: Using unmodified lm session key.\n"));
1023
0
    dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
1024
1025
    /* LM Key not selected */
1026
0
    ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
1027
1028
0
  } else {
1029
0
    DEBUG(10,("ntlmssp_server_auth: Failed to create unmodified session key.\n"));
1030
0
    session_key = data_blob_null;
1031
1032
    /* LM Key not selected */
1033
0
    ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
1034
0
  }
1035
1036
  /* With KEY_EXCH, the client supplies the proposed session key,
1037
     but encrypts it with the long-term key */
1038
0
  if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
1039
0
    if (!state->encrypted_session_key.data
1040
0
        || state->encrypted_session_key.length != 16) {
1041
0
      DEBUG(1, ("Client-supplied KEY_EXCH session key was of invalid length (%u)!\n",
1042
0
          (unsigned)state->encrypted_session_key.length));
1043
0
      return NT_STATUS_INVALID_PARAMETER;
1044
0
    } else if (!session_key.data || session_key.length != 16) {
1045
0
      DEBUG(5, ("server session key is invalid (len == %u), cannot do KEY_EXCH!\n",
1046
0
          (unsigned int)session_key.length));
1047
0
      ntlmssp_state->session_key = session_key;
1048
0
      talloc_steal(ntlmssp_state, session_key.data);
1049
0
    } else {
1050
0
      gnutls_cipher_hd_t cipher_hnd;
1051
0
      gnutls_datum_t enc_session_key = {
1052
0
        .data = session_key.data,
1053
0
        .size = session_key.length,
1054
0
      };
1055
0
      int rc;
1056
1057
0
      dump_data_pw("KEY_EXCH session key (enc):\n",
1058
0
             state->encrypted_session_key.data,
1059
0
             state->encrypted_session_key.length);
1060
1061
0
      rc = gnutls_cipher_init(&cipher_hnd,
1062
0
            GNUTLS_CIPHER_ARCFOUR_128,
1063
0
            &enc_session_key,
1064
0
            NULL);
1065
0
      if (rc < 0) {
1066
0
        return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
1067
0
      }
1068
0
      rc = gnutls_cipher_encrypt(cipher_hnd,
1069
0
               state->encrypted_session_key.data,
1070
0
               state->encrypted_session_key.length);
1071
0
      gnutls_cipher_deinit(cipher_hnd);
1072
0
      if (rc < 0) {
1073
0
        return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
1074
0
      }
1075
1076
0
      ntlmssp_state->session_key = data_blob_talloc(ntlmssp_state,
1077
0
                      state->encrypted_session_key.data,
1078
0
                      state->encrypted_session_key.length);
1079
0
      dump_data_pw("KEY_EXCH session key:\n",
1080
0
             state->encrypted_session_key.data,
1081
0
             state->encrypted_session_key.length);
1082
0
    }
1083
0
  } else {
1084
0
    ntlmssp_state->session_key = session_key;
1085
0
    talloc_steal(ntlmssp_state, session_key.data);
1086
0
  }
1087
1088
0
  if (ntlmssp_state->new_spnego) {
1089
0
    gnutls_hmac_hd_t hmac_hnd = NULL;
1090
0
    uint8_t mic_buffer[NTLMSSP_MIC_SIZE] = { 0, };
1091
0
    bool cmp;
1092
0
    int rc;
1093
1094
0
    rc = gnutls_hmac_init(&hmac_hnd,
1095
0
         GNUTLS_MAC_MD5,
1096
0
         ntlmssp_state->session_key.data,
1097
0
         MIN(ntlmssp_state->session_key.length, 64));
1098
0
    if (rc < 0) {
1099
0
      return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
1100
0
    }
1101
0
    rc = gnutls_hmac(hmac_hnd,
1102
0
         ntlmssp_state->negotiate_blob.data,
1103
0
         ntlmssp_state->negotiate_blob.length);
1104
0
    if (rc < 0) {
1105
0
      gnutls_hmac_deinit(hmac_hnd, NULL);
1106
0
      return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
1107
0
    }
1108
0
    rc = gnutls_hmac(hmac_hnd,
1109
0
          ntlmssp_state->challenge_blob.data,
1110
0
          ntlmssp_state->challenge_blob.length);
1111
0
    if (rc < 0) {
1112
0
      gnutls_hmac_deinit(hmac_hnd, NULL);
1113
0
      return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
1114
0
    }
1115
1116
    /* checked were we set ntlmssp_state->new_spnego */
1117
0
    SMB_ASSERT(request.length >
1118
0
         (NTLMSSP_MIC_OFFSET + NTLMSSP_MIC_SIZE));
1119
1120
0
    rc = gnutls_hmac(hmac_hnd, request.data, NTLMSSP_MIC_OFFSET);
1121
0
    if (rc < 0) {
1122
0
      gnutls_hmac_deinit(hmac_hnd, NULL);
1123
0
      return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
1124
0
    }
1125
0
    rc = gnutls_hmac(hmac_hnd, mic_buffer, NTLMSSP_MIC_SIZE);
1126
0
    if (rc < 0) {
1127
0
      gnutls_hmac_deinit(hmac_hnd, NULL);
1128
0
      return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
1129
0
    }
1130
0
    rc = gnutls_hmac(hmac_hnd,
1131
0
         request.data + (NTLMSSP_MIC_OFFSET + NTLMSSP_MIC_SIZE),
1132
0
         request.length - (NTLMSSP_MIC_OFFSET + NTLMSSP_MIC_SIZE));
1133
0
    if (rc < 0) {
1134
0
      gnutls_hmac_deinit(hmac_hnd, NULL);
1135
0
      return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
1136
0
    }
1137
0
    gnutls_hmac_deinit(hmac_hnd, mic_buffer);
1138
1139
0
    cmp = mem_equal_const_time(request.data + NTLMSSP_MIC_OFFSET,
1140
0
             mic_buffer, NTLMSSP_MIC_SIZE);
1141
0
    if (!cmp) {
1142
0
      DEBUG(1,("%s: invalid NTLMSSP_MIC for "
1143
0
         "user=[%s] domain=[%s] workstation=[%s]\n",
1144
0
         __func__,
1145
0
         ntlmssp_state->user,
1146
0
         ntlmssp_state->domain,
1147
0
         ntlmssp_state->client.netbios_name));
1148
0
      dump_data(11, request.data + NTLMSSP_MIC_OFFSET,
1149
0
          NTLMSSP_MIC_SIZE);
1150
0
      dump_data(11, mic_buffer,
1151
0
          NTLMSSP_MIC_SIZE);
1152
0
    }
1153
1154
0
    ZERO_ARRAY(mic_buffer);
1155
1156
0
    if (!cmp) {
1157
0
      return NT_STATUS_INVALID_PARAMETER;
1158
0
    }
1159
0
  }
1160
1161
0
  data_blob_free(&ntlmssp_state->negotiate_blob);
1162
0
  data_blob_free(&ntlmssp_state->challenge_blob);
1163
1164
0
  if (gensec_ntlmssp_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
1165
0
    if (gensec_security->want_features & GENSEC_FEATURE_LDAP_STYLE) {
1166
      /*
1167
       * We need to handle NTLMSSP_NEGOTIATE_SIGN as
1168
       * NTLMSSP_NEGOTIATE_SEAL if GENSEC_FEATURE_LDAP_STYLE
1169
       * is requested.
1170
       */
1171
0
      ntlmssp_state->force_wrap_seal = true;
1172
0
    }
1173
0
    nt_status = ntlmssp_sign_init(ntlmssp_state);
1174
0
  }
1175
1176
0
  data_blob_clear_free(&ntlmssp_state->internal_chal);
1177
0
  data_blob_clear_free(&ntlmssp_state->chal);
1178
0
  data_blob_clear_free(&ntlmssp_state->lm_resp);
1179
0
  data_blob_clear_free(&ntlmssp_state->nt_resp);
1180
1181
0
  ntlmssp_state->expected_state = NTLMSSP_DONE;
1182
1183
0
  return nt_status;
1184
0
}
1185
1186
NTSTATUS ntlmssp_server_auth_recv(struct tevent_req *req,
1187
          TALLOC_CTX *out_mem_ctx,
1188
          DATA_BLOB *out)
1189
0
{
1190
0
  NTSTATUS status;
1191
1192
0
  *out = data_blob_null;
1193
1194
0
  if (tevent_req_is_nterror(req, &status)) {
1195
0
    tevent_req_received(req);
1196
0
    return status;
1197
0
  }
1198
1199
0
  tevent_req_received(req);
1200
0
  return NT_STATUS_OK;
1201
0
}