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

Generated by: LCOV version 1.14