LCOV - code coverage report
Current view: top level - auth/ntlmssp - ntlmssp_server.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 350 499 70.1 %
Date: 2024-04-21 15:09:00 Functions: 7 7 100.0 %

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

Generated by: LCOV version 1.14