LCOV - code coverage report
Current view: top level - source3/smbd - smb2_negprot.c (source / functions) Hit Total Coverage
Test: coverage report for master 6248eab5 Lines: 330 380 86.8 %
Date: 2021-08-25 13:27:56 Functions: 6 6 100.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    Core SMB2 server
       4             : 
       5             :    Copyright (C) Stefan Metzmacher 2009
       6             : 
       7             :    This program is free software; you can redistribute it and/or modify
       8             :    it under the terms of the GNU General Public License as published by
       9             :    the Free Software Foundation; either version 3 of the License, or
      10             :    (at your option) any later version.
      11             : 
      12             :    This program is distributed in the hope that it will be useful,
      13             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :    GNU General Public License for more details.
      16             : 
      17             :    You should have received a copy of the GNU General Public License
      18             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      19             : */
      20             : 
      21             : #include "includes.h"
      22             : #include "smbd/smbd.h"
      23             : #include "smbd/globals.h"
      24             : #include "../libcli/smb/smb_common.h"
      25             : #include "../libcli/smb/smb2_negotiate_context.h"
      26             : #include "../lib/tsocket/tsocket.h"
      27             : #include "../librpc/ndr/libndr.h"
      28             : #include "../libcli/smb/smb_signing.h"
      29             : 
      30             : #undef DBGC_CLASS
      31             : #define DBGC_CLASS DBGC_SMB2
      32             : 
      33             : extern fstring remote_proto;
      34             : 
      35             : /*
      36             :  * this is the entry point if SMB2 is selected via
      37             :  * the SMB negprot and the given dialect.
      38             :  */
      39       14801 : static NTSTATUS reply_smb20xx(struct smb_request *req, uint16_t dialect)
      40             : {
      41             :         uint8_t *smb2_inpdu;
      42             :         uint8_t *smb2_hdr;
      43             :         uint8_t *smb2_body;
      44             :         uint8_t *smb2_dyn;
      45       14801 :         size_t len = SMB2_HDR_BODY + 0x24 + 2;
      46             : 
      47       14801 :         smb2_inpdu = talloc_zero_array(talloc_tos(), uint8_t, len);
      48       14801 :         if (smb2_inpdu == NULL) {
      49           0 :                 DEBUG(0, ("Could not push spnego blob\n"));
      50           0 :                 reply_nterror(req, NT_STATUS_NO_MEMORY);
      51           0 :                 return NT_STATUS_NO_MEMORY;
      52             :         }
      53       14801 :         smb2_hdr = smb2_inpdu;
      54       14801 :         smb2_body = smb2_hdr + SMB2_HDR_BODY;
      55       14801 :         smb2_dyn = smb2_body + 0x24;
      56             : 
      57       14801 :         SIVAL(smb2_hdr, SMB2_HDR_PROTOCOL_ID,   SMB2_MAGIC);
      58       14801 :         SIVAL(smb2_hdr, SMB2_HDR_LENGTH,        SMB2_HDR_BODY);
      59             : 
      60       14801 :         SSVAL(smb2_body, 0x00, 0x0024); /* struct size */
      61       14801 :         SSVAL(smb2_body, 0x02, 0x0001); /* dialect count */
      62             : 
      63       14801 :         SSVAL(smb2_dyn,  0x00, dialect);
      64             : 
      65       14801 :         req->outbuf = NULL;
      66             : 
      67       14801 :         return smbd_smb2_process_negprot(req->xconn, 0, smb2_inpdu, len);
      68             : }
      69             : 
      70             : /*
      71             :  * this is the entry point if SMB2 is selected via
      72             :  * the SMB negprot and the "SMB 2.002" dialect.
      73             :  */
      74          36 : NTSTATUS reply_smb2002(struct smb_request *req, uint16_t choice)
      75             : {
      76          36 :         return reply_smb20xx(req, SMB2_DIALECT_REVISION_202);
      77             : }
      78             : 
      79             : /*
      80             :  * this is the entry point if SMB2 is selected via
      81             :  * the SMB negprot and the "SMB 2.???" dialect.
      82             :  */
      83       14765 : NTSTATUS reply_smb20ff(struct smb_request *req, uint16_t choice)
      84             : {
      85       14765 :         struct smbXsrv_connection *xconn = req->xconn;
      86       14765 :         xconn->smb2.allow_2ff = true;
      87       14765 :         return reply_smb20xx(req, SMB2_DIALECT_REVISION_2FF);
      88             : }
      89             : 
      90       40466 : enum protocol_types smbd_smb2_protocol_dialect_match(const uint8_t *indyn,
      91             :                                 const int dialect_count,
      92             :                                 uint16_t *dialect)
      93             : {
      94             :         struct {
      95             :                 enum protocol_types proto;
      96             :                 uint16_t dialect;
      97       40466 :         } pd[] = {
      98             :                 { PROTOCOL_SMB3_11, SMB3_DIALECT_REVISION_311 },
      99             :                 { PROTOCOL_SMB3_02, SMB3_DIALECT_REVISION_302 },
     100             :                 { PROTOCOL_SMB3_00, SMB3_DIALECT_REVISION_300 },
     101             :                 { PROTOCOL_SMB2_10, SMB2_DIALECT_REVISION_210 },
     102             :                 { PROTOCOL_SMB2_02, SMB2_DIALECT_REVISION_202 },
     103             :         };
     104             :         size_t i;
     105             : 
     106      130419 :         for (i = 0; i < ARRAY_SIZE(pd); i ++) {
     107      115654 :                 int c = 0;
     108             : 
     109      115654 :                 if (lp_server_max_protocol() < pd[i].proto) {
     110       19466 :                         continue;
     111             :                 }
     112       96188 :                 if (lp_server_min_protocol() > pd[i].proto) {
     113          11 :                         continue;
     114             :                 }
     115             : 
     116      248227 :                 for (c = 0; c < dialect_count; c++) {
     117      180091 :                         *dialect = SVAL(indyn, c*2);
     118      180091 :                         if (*dialect == pd[i].dialect) {
     119       25311 :                                 return pd[i].proto;
     120             :                         }
     121             :                 }
     122             :         }
     123             : 
     124       14375 :         return PROTOCOL_NONE;
     125             : }
     126             : 
     127             : struct smbd_smb2_request_process_negprot_state {
     128             :         struct smbd_smb2_request *req;
     129             :         DATA_BLOB outbody;
     130             :         DATA_BLOB outdyn;
     131             : };
     132             : 
     133             : static void smbd_smb2_request_process_negprot_mc_done(struct tevent_req *subreq);
     134             : 
     135       37747 : NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
     136             : {
     137       37747 :         struct smbd_smb2_request_process_negprot_state *state = NULL;
     138       37747 :         struct smbXsrv_connection *xconn = req->xconn;
     139       37747 :         struct tevent_req *subreq = NULL;
     140             :         NTSTATUS status;
     141             :         const uint8_t *inbody;
     142       37747 :         const uint8_t *indyn = NULL;
     143             :         DATA_BLOB outbody;
     144             :         DATA_BLOB outdyn;
     145             :         DATA_BLOB negprot_spnego_blob;
     146             :         uint16_t security_offset;
     147             :         DATA_BLOB security_buffer;
     148       37747 :         size_t expected_dyn_size = 0;
     149             :         size_t c;
     150             :         uint16_t security_mode;
     151             :         uint16_t dialect_count;
     152             :         uint16_t in_security_mode;
     153             :         uint32_t in_capabilities;
     154             :         DATA_BLOB in_guid_blob;
     155             :         struct GUID in_guid;
     156       37747 :         struct smb2_negotiate_contexts in_c = { .num_contexts = 0, };
     157       37747 :         struct smb2_negotiate_context *in_preauth = NULL;
     158       37747 :         struct smb2_negotiate_context *in_cipher = NULL;
     159       37747 :         struct smb2_negotiate_context *in_sign_algo = NULL;
     160       37747 :         struct smb2_negotiate_contexts out_c = { .num_contexts = 0, };
     161       37747 :         const struct smb311_capabilities default_smb3_capabilities =
     162             :                 smb311_capabilities_parse("server",
     163       37747 :                         lp_server_smb3_signing_algorithms(),
     164       37747 :                         lp_server_smb3_encryption_algorithms());
     165       37747 :         DATA_BLOB out_negotiate_context_blob = data_blob_null;
     166       37747 :         uint32_t out_negotiate_context_offset = 0;
     167       37747 :         uint16_t out_negotiate_context_count = 0;
     168       37747 :         uint16_t dialect = 0;
     169             :         uint32_t capabilities;
     170             :         DATA_BLOB out_guid_blob;
     171             :         struct GUID out_guid;
     172       37747 :         enum protocol_types protocol = PROTOCOL_NONE;
     173             :         uint32_t max_limit;
     174       37747 :         uint32_t max_trans = lp_smb2_max_trans();
     175       37747 :         uint32_t max_read = lp_smb2_max_read();
     176       37747 :         uint32_t max_write = lp_smb2_max_write();
     177       37747 :         NTTIME now = timeval_to_nttime(&req->request_time);
     178       37747 :         bool signing_required = true;
     179             :         bool ok;
     180             : 
     181       37747 :         status = smbd_smb2_request_verify_sizes(req, 0x24);
     182       37747 :         if (!NT_STATUS_IS_OK(status)) {
     183           0 :                 return smbd_smb2_request_error(req, status);
     184             :         }
     185       37747 :         inbody = SMBD_SMB2_IN_BODY_PTR(req);
     186             : 
     187       37747 :         dialect_count = SVAL(inbody, 0x02);
     188             : 
     189       37747 :         in_security_mode = SVAL(inbody, 0x04);
     190       37747 :         in_capabilities = IVAL(inbody, 0x08);
     191       37747 :         in_guid_blob = data_blob_const(inbody + 0x0C, 16);
     192             : 
     193       37747 :         if (dialect_count == 0) {
     194           0 :                 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
     195             :         }
     196             : 
     197       37747 :         status = GUID_from_ndr_blob(&in_guid_blob, &in_guid);
     198       37747 :         if (!NT_STATUS_IS_OK(status)) {
     199           0 :                 return smbd_smb2_request_error(req, status);
     200             :         }
     201             : 
     202       37747 :         expected_dyn_size = dialect_count * 2;
     203       37747 :         if (SMBD_SMB2_IN_DYN_LEN(req) < expected_dyn_size) {
     204           0 :                 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
     205             :         }
     206       37747 :         indyn = SMBD_SMB2_IN_DYN_PTR(req);
     207             : 
     208       37747 :         protocol = smbd_smb2_protocol_dialect_match(indyn,
     209             :                                         dialect_count,
     210             :                                         &dialect);
     211             : 
     212       37747 :         for (c=0; protocol == PROTOCOL_NONE && c < dialect_count; c++) {
     213       14765 :                 if (lp_server_max_protocol() < PROTOCOL_SMB2_10) {
     214           0 :                         break;
     215             :                 }
     216             : 
     217       14765 :                 dialect = SVAL(indyn, c*2);
     218       14765 :                 if (dialect == SMB2_DIALECT_REVISION_2FF) {
     219       14765 :                         if (xconn->smb2.allow_2ff) {
     220       14765 :                                 xconn->smb2.allow_2ff = false;
     221       14765 :                                 protocol = PROTOCOL_SMB2_10;
     222       14375 :                                 break;
     223             :                         }
     224             :                 }
     225             :         }
     226             : 
     227       37357 :         if (protocol == PROTOCOL_NONE) {
     228           0 :                 return smbd_smb2_request_error(req, NT_STATUS_NOT_SUPPORTED);
     229             :         }
     230             : 
     231       37747 :         if (protocol >= PROTOCOL_SMB3_11) {
     232       20271 :                 uint32_t in_negotiate_context_offset = 0;
     233       20271 :                 uint16_t in_negotiate_context_count = 0;
     234       20271 :                 DATA_BLOB in_negotiate_context_blob = data_blob_null;
     235             :                 size_t ofs;
     236             : 
     237       20271 :                 in_negotiate_context_offset = IVAL(inbody, 0x1C);
     238       20271 :                 in_negotiate_context_count = SVAL(inbody, 0x20);
     239             : 
     240       20271 :                 ofs = SMB2_HDR_BODY;
     241       20271 :                 ofs += SMBD_SMB2_IN_BODY_LEN(req);
     242       20271 :                 ofs += expected_dyn_size;
     243       20271 :                 if ((ofs % 8) != 0) {
     244       20271 :                         ofs += 8 - (ofs % 8);
     245             :                 }
     246             : 
     247       20271 :                 if (in_negotiate_context_offset != ofs) {
     248           0 :                         return smbd_smb2_request_error(req,
     249             :                                         NT_STATUS_INVALID_PARAMETER);
     250             :                 }
     251             : 
     252       20271 :                 ofs -= SMB2_HDR_BODY;
     253       20271 :                 ofs -= SMBD_SMB2_IN_BODY_LEN(req);
     254             : 
     255       20271 :                 if (SMBD_SMB2_IN_DYN_LEN(req) < ofs) {
     256           0 :                         return smbd_smb2_request_error(req,
     257             :                                         NT_STATUS_INVALID_PARAMETER);
     258             :                 }
     259             : 
     260       20271 :                 in_negotiate_context_blob = data_blob_const(indyn,
     261       19881 :                                                 SMBD_SMB2_IN_DYN_LEN(req));
     262             : 
     263       20271 :                 in_negotiate_context_blob.data += ofs;
     264       20271 :                 in_negotiate_context_blob.length -= ofs;
     265             : 
     266       20271 :                 status = smb2_negotiate_context_parse(req,
     267             :                                                       in_negotiate_context_blob,
     268             :                                                       in_negotiate_context_count,
     269             :                                                       &in_c);
     270       20271 :                 if (!NT_STATUS_IS_OK(status)) {
     271           0 :                         return smbd_smb2_request_error(req, status);
     272             :                 }
     273             :         }
     274             : 
     275       37747 :         if ((dialect != SMB2_DIALECT_REVISION_2FF) &&
     276       22900 :             (protocol >= PROTOCOL_SMB2_10) &&
     277       22900 :             !GUID_all_zero(&in_guid))
     278             :         {
     279       22896 :                 ok = remote_arch_cache_update(&in_guid);
     280       22896 :                 if (!ok) {
     281           0 :                         return smbd_smb2_request_error(
     282             :                                 req, NT_STATUS_UNSUCCESSFUL);
     283             :                 }
     284             :         }
     285             : 
     286       37747 :         switch (get_remote_arch()) {
     287       30352 :         case RA_VISTA:
     288             :         case RA_SAMBA:
     289             :         case RA_CIFSFS:
     290             :         case RA_OSX:
     291       30352 :                 break;
     292        6615 :         default:
     293        6615 :                 set_remote_arch(RA_VISTA);
     294        6615 :                 break;
     295             :         }
     296             : 
     297       37747 :         fstr_sprintf(remote_proto, "SMB%X_%02X",
     298             :                      (dialect >> 8) & 0xFF, dialect & 0xFF);
     299             : 
     300       37747 :         reload_services(req->sconn, conn_snum_used, true);
     301       37747 :         DEBUG(3,("Selected protocol %s\n", remote_proto));
     302             : 
     303       37747 :         in_preauth = smb2_negotiate_context_find(&in_c,
     304             :                                         SMB2_PREAUTH_INTEGRITY_CAPABILITIES);
     305       37747 :         if (protocol >= PROTOCOL_SMB3_11 && in_preauth == NULL) {
     306           0 :                 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
     307             :         }
     308       37747 :         in_cipher = smb2_negotiate_context_find(&in_c,
     309             :                                         SMB2_ENCRYPTION_CAPABILITIES);
     310       37747 :         in_sign_algo = smb2_negotiate_context_find(&in_c,
     311             :                                         SMB2_SIGNING_CAPABILITIES);
     312             : 
     313             :         /* negprot_spnego() returns a the server guid in the first 16 bytes */
     314       37747 :         negprot_spnego_blob = negprot_spnego(req, xconn);
     315       37747 :         if (negprot_spnego_blob.data == NULL) {
     316           0 :                 return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
     317             :         }
     318             : 
     319       37747 :         if (negprot_spnego_blob.length < 16) {
     320           0 :                 return smbd_smb2_request_error(req, NT_STATUS_INTERNAL_ERROR);
     321             :         }
     322             : 
     323       37747 :         security_mode = SMB2_NEGOTIATE_SIGNING_ENABLED;
     324             :         /*
     325             :          * We use xconn->smb1.signing_state as that's already present
     326             :          * and used lpcfg_server_signing_allowed() to get the correct
     327             :          * defaults, e.g. signing_required for an ad_dc.
     328             :          */
     329       37747 :         signing_required = smb_signing_is_mandatory(xconn->smb1.signing_state);
     330       37747 :         if (signing_required) {
     331       12759 :                 security_mode |= SMB2_NEGOTIATE_SIGNING_REQUIRED;
     332             :         }
     333             : 
     334       37747 :         capabilities = 0;
     335       37747 :         if (lp_host_msdfs()) {
     336       37747 :                 capabilities |= SMB2_CAP_DFS;
     337             :         }
     338             : 
     339       75412 :         if (protocol >= PROTOCOL_SMB2_10 &&
     340       66591 :             lp_smb2_leases() &&
     341       57852 :             lp_oplocks(GLOBAL_SECTION_SNUM) &&
     342       28926 :             !lp_kernel_oplocks(GLOBAL_SECTION_SNUM))
     343             :         {
     344       28926 :                 capabilities |= SMB2_CAP_LEASING;
     345             :         }
     346             : 
     347       58104 :         if ((protocol >= PROTOCOL_SMB3_00) &&
     348       40496 :             (lp_server_smb_encrypt(-1) != SMB_ENCRYPTION_OFF) &&
     349       20139 :             (in_capabilities & SMB2_CAP_ENCRYPTION)) {
     350       20139 :                 capabilities |= SMB2_CAP_ENCRYPTION;
     351             :         }
     352             : 
     353             :         /*
     354             :          * 0x10000 (65536) is the maximum allowed message size
     355             :          * for SMB 2.0
     356             :          */
     357       37747 :         max_limit = 0x10000;
     358             : 
     359       37747 :         if (protocol >= PROTOCOL_SMB2_10) {
     360       37665 :                 int p = 0;
     361             : 
     362       37665 :                 if (tsocket_address_is_inet(req->sconn->local_address, "ip")) {
     363       37665 :                         p = tsocket_address_inet_port(req->sconn->local_address);
     364             :                 }
     365             : 
     366             :                 /* largeMTU is not supported over NBT (tcp port 139) */
     367       37665 :                 if (p != NBT_SMB_PORT) {
     368       35987 :                         capabilities |= SMB2_CAP_LARGE_MTU;
     369       35987 :                         xconn->smb2.credits.multicredit = true;
     370             : 
     371             :                         /*
     372             :                          * We allow up to almost 16MB.
     373             :                          *
     374             :                          * The maximum PDU size is 0xFFFFFF (16776960)
     375             :                          * and we need some space for the header.
     376             :                          */
     377       35987 :                         max_limit = 0xFFFF00;
     378             :                 }
     379             :         }
     380             : 
     381             :         /*
     382             :          * the defaults are 8MB, but we'll limit this to max_limit based on
     383             :          * the dialect (64kb for SMB 2.0, 8MB for SMB >= 2.1 with LargeMTU)
     384             :          *
     385             :          * user configured values exceeding the limits will be overwritten,
     386             :          * only smaller values will be accepted
     387             :          */
     388             : 
     389       37747 :         max_trans = MIN(max_limit, lp_smb2_max_trans());
     390       37747 :         max_read = MIN(max_limit, lp_smb2_max_read());
     391       37747 :         max_write = MIN(max_limit, lp_smb2_max_write());
     392             : 
     393       37747 :         if (in_preauth != NULL) {
     394       20271 :                 size_t needed = 4;
     395             :                 uint16_t hash_count;
     396             :                 uint16_t salt_length;
     397       20271 :                 uint16_t selected_preauth = 0;
     398             :                 const uint8_t *p;
     399             :                 uint8_t buf[38];
     400             :                 size_t i;
     401             : 
     402       20271 :                 if (in_preauth->data.length < needed) {
     403           0 :                         return smbd_smb2_request_error(req,
     404             :                                         NT_STATUS_INVALID_PARAMETER);
     405             :                 }
     406             : 
     407       20271 :                 hash_count = SVAL(in_preauth->data.data, 0);
     408       20271 :                 salt_length = SVAL(in_preauth->data.data, 2);
     409             : 
     410       20271 :                 if (hash_count == 0) {
     411           0 :                         return smbd_smb2_request_error(req,
     412             :                                         NT_STATUS_INVALID_PARAMETER);
     413             :                 }
     414             : 
     415       20271 :                 p = in_preauth->data.data + needed;
     416       20271 :                 needed += hash_count * 2;
     417       20271 :                 needed += salt_length;
     418             : 
     419       20271 :                 if (in_preauth->data.length < needed) {
     420           0 :                         return smbd_smb2_request_error(req,
     421             :                                         NT_STATUS_INVALID_PARAMETER);
     422             :                 }
     423             : 
     424       19881 :                 for (i=0; i < hash_count; i++) {
     425             :                         uint16_t v;
     426             : 
     427       20271 :                         v = SVAL(p, 0);
     428       20271 :                         p += 2;
     429             : 
     430       20271 :                         if (v == SMB2_PREAUTH_INTEGRITY_SHA512) {
     431       19881 :                                 selected_preauth = v;
     432       19881 :                                 break;
     433             :                         }
     434             :                 }
     435             : 
     436       20271 :                 if (selected_preauth == 0) {
     437           0 :                         return smbd_smb2_request_error(req,
     438             :                                 NT_STATUS_SMB_NO_PREAUTH_INTEGRITY_HASH_OVERLAP);
     439             :                 }
     440             : 
     441       20271 :                 SSVAL(buf, 0,  1); /* HashAlgorithmCount */
     442       20271 :                 SSVAL(buf, 2, 32); /* SaltLength */
     443       20271 :                 SSVAL(buf, 4, selected_preauth);
     444       20271 :                 generate_random_buffer(buf + 6, 32);
     445             : 
     446       20271 :                 status = smb2_negotiate_context_add(
     447             :                         req,
     448             :                         &out_c,
     449             :                         SMB2_PREAUTH_INTEGRITY_CAPABILITIES,
     450             :                         buf,
     451             :                         sizeof(buf));
     452       20271 :                 if (!NT_STATUS_IS_OK(status)) {
     453           0 :                         return smbd_smb2_request_error(req, status);
     454             :                 }
     455             : 
     456       20271 :                 req->preauth = &req->xconn->smb2.preauth;
     457             :         }
     458             : 
     459       37747 :         if (protocol >= PROTOCOL_SMB3_00) {
     460       20357 :                 xconn->smb2.server.sign_algo = SMB2_SIGNING_AES128_CMAC;
     461             :         } else {
     462       17390 :                 xconn->smb2.server.sign_algo = SMB2_SIGNING_HMAC_SHA256;
     463             :         }
     464             : 
     465       37747 :         if ((capabilities & SMB2_CAP_ENCRYPTION) && (in_cipher != NULL)) {
     466       20065 :                 const struct smb3_encryption_capabilities *srv_ciphers =
     467             :                         &default_smb3_capabilities.encryption;
     468       20065 :                 uint16_t srv_preferred_idx = UINT16_MAX;
     469       20065 :                 size_t needed = 2;
     470             :                 uint16_t cipher_count;
     471             :                 const uint8_t *p;
     472             :                 uint8_t buf[4];
     473             :                 size_t i;
     474             : 
     475       20065 :                 capabilities &= ~SMB2_CAP_ENCRYPTION;
     476             : 
     477       20065 :                 if (in_cipher->data.length < needed) {
     478           0 :                         return smbd_smb2_request_error(req,
     479             :                                         NT_STATUS_INVALID_PARAMETER);
     480             :                 }
     481             : 
     482       20065 :                 cipher_count = SVAL(in_cipher->data.data, 0);
     483       20065 :                 if (cipher_count == 0) {
     484           0 :                         return smbd_smb2_request_error(req,
     485             :                                         NT_STATUS_INVALID_PARAMETER);
     486             :                 }
     487             : 
     488       20065 :                 p = in_cipher->data.data + needed;
     489       20065 :                 needed += cipher_count * 2;
     490             : 
     491       20065 :                 if (in_cipher->data.length < needed) {
     492           0 :                         return smbd_smb2_request_error(req,
     493             :                                         NT_STATUS_INVALID_PARAMETER);
     494             :                 }
     495             : 
     496       99065 :                 for (i=0; i < cipher_count; i++) {
     497             :                         uint16_t si;
     498             :                         uint16_t v;
     499             : 
     500       79390 :                         v = SVAL(p, 0);
     501       79390 :                         p += 2;
     502             : 
     503      396460 :                         for (si = 0; si < srv_ciphers->num_algos; si++) {
     504      198230 :                                 if (srv_ciphers->algos[si] != v) {
     505      118840 :                                         continue;
     506             :                                 }
     507             : 
     508             :                                 /*
     509             :                                  * The server ciphers are listed
     510             :                                  * with the lowest idx being preferred.
     511             :                                  */
     512       79390 :                                 if (si < srv_preferred_idx) {
     513       20065 :                                         srv_preferred_idx = si;
     514             :                                 }
     515       77830 :                                 break;
     516             :                         }
     517             :                 }
     518             : 
     519       20065 :                 if (srv_preferred_idx != UINT16_MAX) {
     520       20065 :                         xconn->smb2.server.cipher =
     521       20065 :                                 srv_ciphers->algos[srv_preferred_idx];
     522             :                 }
     523             : 
     524       20065 :                 SSVAL(buf, 0, 1); /* ChiperCount */
     525       20065 :                 SSVAL(buf, 2, xconn->smb2.server.cipher);
     526             : 
     527       20065 :                 status = smb2_negotiate_context_add(
     528             :                         req,
     529             :                         &out_c,
     530             :                         SMB2_ENCRYPTION_CAPABILITIES,
     531             :                         buf,
     532             :                         sizeof(buf));
     533       20065 :                 if (!NT_STATUS_IS_OK(status)) {
     534           0 :                         return smbd_smb2_request_error(req, status);
     535             :                 }
     536             :         }
     537             : 
     538       37747 :         if (capabilities & SMB2_CAP_ENCRYPTION) {
     539          74 :                 xconn->smb2.server.cipher = SMB2_ENCRYPTION_AES128_CCM;
     540             :         }
     541             : 
     542       37747 :         if (in_sign_algo != NULL) {
     543       20271 :                 const struct smb3_signing_capabilities *srv_sign_algos =
     544             :                         &default_smb3_capabilities.signing;
     545       20271 :                 uint16_t srv_preferred_idx = UINT16_MAX;
     546       20271 :                 size_t needed = 2;
     547             :                 uint16_t sign_algo_count;
     548             :                 const uint8_t *p;
     549             :                 size_t i;
     550             : 
     551       20271 :                 if (in_sign_algo->data.length < needed) {
     552           0 :                         return smbd_smb2_request_error(req,
     553             :                                         NT_STATUS_INVALID_PARAMETER);
     554             :                 }
     555             : 
     556       20271 :                 sign_algo_count = SVAL(in_sign_algo->data.data, 0);
     557       20271 :                 if (sign_algo_count == 0) {
     558           0 :                         return smbd_smb2_request_error(req,
     559             :                                         NT_STATUS_INVALID_PARAMETER);
     560             :                 }
     561             : 
     562       20271 :                 p = in_sign_algo->data.data + needed;
     563       20271 :                 needed += sign_algo_count * 2;
     564             : 
     565       20271 :                 if (in_sign_algo->data.length < needed) {
     566           0 :                         return smbd_smb2_request_error(req,
     567             :                                         NT_STATUS_INVALID_PARAMETER);
     568             :                 }
     569             : 
     570       79326 :                 for (i=0; i < sign_algo_count; i++) {
     571             :                         uint16_t si;
     572             :                         uint16_t v;
     573             : 
     574       59445 :                         v = SVAL(p, 0);
     575       59445 :                         p += 2;
     576             : 
     577      237500 :                         for (si = 0; si < srv_sign_algos->num_algos; si++) {
     578      118750 :                                 if (srv_sign_algos->algos[si] != v) {
     579       59305 :                                         continue;
     580             :                                 }
     581             : 
     582             :                                 /*
     583             :                                  * The server sign_algos are listed
     584             :                                  * with the lowest idx being preferred.
     585             :                                  */
     586       59445 :                                 if (si < srv_preferred_idx) {
     587       20271 :                                         srv_preferred_idx = si;
     588             :                                 }
     589       58275 :                                 break;
     590             :                         }
     591             :                 }
     592             : 
     593             :                 /*
     594             :                  * If we found a match announce it
     595             :                  * otherwise we'll keep the default
     596             :                  * of SMB2_SIGNING_AES128_CMAC
     597             :                  */
     598       20271 :                 if (srv_preferred_idx != UINT16_MAX) {
     599             :                         uint8_t buf[4];
     600             : 
     601       20271 :                         xconn->smb2.server.sign_algo =
     602       20271 :                                 srv_sign_algos->algos[srv_preferred_idx];
     603             : 
     604       20271 :                         SSVAL(buf, 0, 1); /* SigningAlgorithmCount */
     605       20271 :                         SSVAL(buf, 2, xconn->smb2.server.sign_algo);
     606             : 
     607       20271 :                         status = smb2_negotiate_context_add(
     608             :                                 req,
     609             :                                 &out_c,
     610             :                                 SMB2_SIGNING_CAPABILITIES,
     611             :                                 buf,
     612             :                                 sizeof(buf));
     613       20271 :                         if (!NT_STATUS_IS_OK(status)) {
     614           0 :                                 return smbd_smb2_request_error(req, status);
     615             :                         }
     616             :                 }
     617             :         }
     618             : 
     619      113241 :         status = smb311_capabilities_check(&default_smb3_capabilities,
     620             :                                            "smb2srv_negprot",
     621             :                                            DBGLVL_NOTICE,
     622       37747 :                                            NT_STATUS_INVALID_PARAMETER,
     623             :                                            "server",
     624             :                                            protocol,
     625       37747 :                                            xconn->smb2.server.sign_algo,
     626       37747 :                                            xconn->smb2.server.cipher);
     627       37747 :         if (!NT_STATUS_IS_OK(status)) {
     628           0 :                 return smbd_smb2_request_error(req, status);
     629             :         }
     630             : 
     631       58104 :         if (protocol >= PROTOCOL_SMB3_00 &&
     632       20357 :             xconn->client->server_multi_channel_enabled)
     633             :         {
     634       20357 :                 if (in_capabilities & SMB2_CAP_MULTI_CHANNEL) {
     635       20357 :                         capabilities |= SMB2_CAP_MULTI_CHANNEL;
     636             :                 }
     637             :         }
     638             : 
     639       37747 :         security_offset = SMB2_HDR_BODY + 0x40;
     640             : 
     641             : #if 1
     642             :         /* Try SPNEGO auth... */
     643       37747 :         security_buffer = data_blob_const(negprot_spnego_blob.data + 16,
     644       36967 :                                           negprot_spnego_blob.length - 16);
     645             : #else
     646             :         /* for now we want raw NTLMSSP */
     647             :         security_buffer = data_blob_const(NULL, 0);
     648             : #endif
     649             : 
     650       37747 :         if (out_c.num_contexts != 0) {
     651       20271 :                 status = smb2_negotiate_context_push(req,
     652             :                                                 &out_negotiate_context_blob,
     653             :                                                 out_c);
     654       20271 :                 if (!NT_STATUS_IS_OK(status)) {
     655           0 :                         return smbd_smb2_request_error(req, status);
     656             :                 }
     657             :         }
     658             : 
     659       37747 :         if (out_negotiate_context_blob.length != 0) {
     660             :                 static const uint8_t zeros[8];
     661       20271 :                 size_t pad = 0;
     662             :                 size_t ofs;
     663             : 
     664       20271 :                 outdyn = data_blob_dup_talloc(req, security_buffer);
     665       20271 :                 if (outdyn.length != security_buffer.length) {
     666           0 :                         return smbd_smb2_request_error(req,
     667             :                                                 NT_STATUS_NO_MEMORY);
     668             :                 }
     669             : 
     670       20271 :                 ofs = security_offset + security_buffer.length;
     671       20271 :                 if ((ofs % 8) != 0) {
     672       13346 :                         pad = 8 - (ofs % 8);
     673             :                 }
     674       20271 :                 ofs += pad;
     675             : 
     676       20271 :                 ok = data_blob_append(req, &outdyn, zeros, pad);
     677       20271 :                 if (!ok) {
     678           0 :                         return smbd_smb2_request_error(req,
     679             :                                                 NT_STATUS_NO_MEMORY);
     680             :                 }
     681             : 
     682       40542 :                 ok = data_blob_append(req, &outdyn,
     683       20271 :                                       out_negotiate_context_blob.data,
     684             :                                       out_negotiate_context_blob.length);
     685       20271 :                 if (!ok) {
     686           0 :                         return smbd_smb2_request_error(req,
     687             :                                                 NT_STATUS_NO_MEMORY);
     688             :                 }
     689             : 
     690       20271 :                 out_negotiate_context_offset = ofs;
     691       20271 :                 out_negotiate_context_count = out_c.num_contexts;
     692             :         } else {
     693       17476 :                 outdyn = security_buffer;
     694             :         }
     695             : 
     696       37747 :         out_guid_blob = data_blob_const(negprot_spnego_blob.data, 16);
     697       37747 :         status = GUID_from_ndr_blob(&out_guid_blob, &out_guid);
     698       37747 :         if (!NT_STATUS_IS_OK(status)) {
     699           0 :                 return smbd_smb2_request_error(req, status);
     700             :         }
     701             : 
     702       37747 :         outbody = smbd_smb2_generate_outbody(req, 0x40);
     703       37747 :         if (outbody.data == NULL) {
     704           0 :                 return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
     705             :         }
     706             : 
     707       37747 :         SSVAL(outbody.data, 0x00, 0x40 + 1);    /* struct size */
     708       37747 :         SSVAL(outbody.data, 0x02,
     709             :               security_mode);                   /* security mode */
     710       37747 :         SSVAL(outbody.data, 0x04, dialect);     /* dialect revision */
     711       37747 :         SSVAL(outbody.data, 0x06,
     712             :               out_negotiate_context_count);     /* reserved/NegotiateContextCount */
     713       38527 :         memcpy(outbody.data + 0x08,
     714       37747 :                out_guid_blob.data, 16); /* server guid */
     715       37747 :         SIVAL(outbody.data, 0x18,
     716             :               capabilities);                    /* capabilities */
     717       37747 :         SIVAL(outbody.data, 0x1C, max_trans);   /* max transact size */
     718       37747 :         SIVAL(outbody.data, 0x20, max_read);    /* max read size */
     719       37747 :         SIVAL(outbody.data, 0x24, max_write);   /* max write size */
     720       37747 :         SBVAL(outbody.data, 0x28, now);         /* system time */
     721       37747 :         SBVAL(outbody.data, 0x30, 0);           /* server start time */
     722       37747 :         SSVAL(outbody.data, 0x38,
     723             :               security_offset);                 /* security buffer offset */
     724       37747 :         SSVAL(outbody.data, 0x3A,
     725             :               security_buffer.length);          /* security buffer length */
     726       37747 :         SIVAL(outbody.data, 0x3C,
     727             :               out_negotiate_context_offset);    /* reserved/NegotiateContextOffset */
     728             : 
     729       37747 :         req->sconn->using_smb2 = true;
     730             : 
     731       37747 :         if (dialect == SMB2_DIALECT_REVISION_2FF) {
     732       14765 :                 return smbd_smb2_request_done(req, outbody, &outdyn);
     733             :         }
     734             : 
     735       22982 :         status = smbXsrv_connection_init_tables(xconn, protocol);
     736       22982 :         if (!NT_STATUS_IS_OK(status)) {
     737           0 :                 return smbd_smb2_request_error(req, status);
     738             :         }
     739             : 
     740       22982 :         xconn->smb2.client.capabilities = in_capabilities;
     741       22982 :         xconn->smb2.client.security_mode = in_security_mode;
     742       22982 :         xconn->smb2.client.guid = in_guid;
     743       22982 :         xconn->smb2.client.num_dialects = dialect_count;
     744       22982 :         xconn->smb2.client.dialects = talloc_array(xconn,
     745             :                                                    uint16_t,
     746             :                                                    dialect_count);
     747       22982 :         if (xconn->smb2.client.dialects == NULL) {
     748           0 :                 return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
     749             :         }
     750      133198 :         for (c=0; c < dialect_count; c++) {
     751      110606 :                 xconn->smb2.client.dialects[c] = SVAL(indyn, c*2);
     752             :         }
     753             : 
     754       22982 :         xconn->smb2.server.capabilities = capabilities;
     755       22982 :         xconn->smb2.server.security_mode = security_mode;
     756       22982 :         xconn->smb2.server.guid = out_guid;
     757       22982 :         xconn->smb2.server.dialect = dialect;
     758       22982 :         xconn->smb2.server.max_trans = max_trans;
     759       22982 :         xconn->smb2.server.max_read  = max_read;
     760       22982 :         xconn->smb2.server.max_write = max_write;
     761             : 
     762       22982 :         if (xconn->protocol < PROTOCOL_SMB2_10) {
     763             :                 /*
     764             :                  * SMB2_02 doesn't support client guids
     765             :                  */
     766          82 :                 return smbd_smb2_request_done(req, outbody, &outdyn);
     767             :         }
     768             : 
     769       22900 :         if (!xconn->client->server_multi_channel_enabled) {
     770             :                 /*
     771             :                  * Only deal with the client guid database
     772             :                  * if multi-channel is enabled.
     773             :                  *
     774             :                  * But we still need to setup
     775             :                  * xconn->client->global->client_guid to
     776             :                  * the correct value.
     777             :                  */
     778           0 :                 xconn->client->global->client_guid =
     779             :                         xconn->smb2.client.guid;
     780           0 :                 return smbd_smb2_request_done(req, outbody, &outdyn);
     781             :         }
     782             : 
     783       22900 :         if (xconn->smb2.client.guid_verified) {
     784             :                 /*
     785             :                  * The connection was passed from another
     786             :                  * smbd process.
     787             :                  */
     788         930 :                 return smbd_smb2_request_done(req, outbody, &outdyn);
     789             :         }
     790             : 
     791       21970 :         state = talloc_zero(req, struct smbd_smb2_request_process_negprot_state);
     792       21970 :         if (state == NULL) {
     793           0 :                 return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
     794             :         }
     795       21970 :         *state = (struct smbd_smb2_request_process_negprot_state) {
     796             :                 .req = req,
     797             :                 .outbody = outbody,
     798             :                 .outdyn = outdyn,
     799             :         };
     800             : 
     801       21970 :         subreq = smb2srv_client_mc_negprot_send(state,
     802       21970 :                                                 req->xconn->client->raw_ev_ctx,
     803             :                                                 req);
     804       21970 :         if (subreq == NULL) {
     805           0 :                 return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
     806             :         }
     807       21970 :         tevent_req_set_callback(subreq,
     808             :                                 smbd_smb2_request_process_negprot_mc_done,
     809             :                                 state);
     810       21970 :         return NT_STATUS_OK;
     811             : }
     812             : 
     813       21970 : static void smbd_smb2_request_process_negprot_mc_done(struct tevent_req *subreq)
     814             : {
     815       21970 :         struct smbd_smb2_request_process_negprot_state *state =
     816       21970 :                 tevent_req_callback_data(subreq,
     817             :                 struct smbd_smb2_request_process_negprot_state);
     818       21970 :         struct smbd_smb2_request *req = state->req;
     819       21970 :         struct smbXsrv_connection *xconn = req->xconn;
     820             :         NTSTATUS status;
     821             : 
     822       21970 :         status = smb2srv_client_mc_negprot_recv(subreq);
     823       21970 :         TALLOC_FREE(subreq);
     824       21970 :         if (NT_STATUS_EQUAL(status, NT_STATUS_MESSAGE_RETRIEVED)) {
     825             :                 /*
     826             :                  * The connection was passed to another process
     827             :                  */
     828         992 :                 smbd_server_connection_terminate(xconn,
     829             :                                                  "passed connection");
     830             :                 /*
     831             :                  * smbd_server_connection_terminate() should not return!
     832             :                  */
     833           0 :                 smb_panic(__location__);
     834             :                 return;
     835             :         }
     836       20978 :         if (!NT_STATUS_IS_OK(status)) {
     837           0 :                 status = smbd_smb2_request_error(req, status);
     838           0 :                 if (NT_STATUS_IS_OK(status)) {
     839           0 :                         return;
     840             :                 }
     841             : 
     842             :                 /*
     843             :                  * The connection was passed to another process
     844             :                  */
     845           0 :                 smbd_server_connection_terminate(xconn, nt_errstr(status));
     846             :                 /*
     847             :                  * smbd_server_connection_terminate() should not return!
     848             :                  */
     849           0 :                 smb_panic(__location__);
     850             :                 return;
     851             :         }
     852             : 
     853             :         /*
     854             :          * We're the first connection...
     855             :          */
     856       20978 :         status = smbd_smb2_request_done(req, state->outbody, &state->outdyn);
     857       20978 :         if (NT_STATUS_IS_OK(status)) {
     858       20588 :                 return;
     859             :         }
     860             : 
     861             :         /*
     862             :          * The connection was passed to another process
     863             :          */
     864           0 :         smbd_server_connection_terminate(xconn, nt_errstr(status));
     865             :         /*
     866             :          * smbd_server_connection_terminate() should not return!
     867             :          */
     868           0 :         smb_panic(__location__);
     869             :         return;
     870             : }

Generated by: LCOV version 1.13