LCOV - code coverage report
Current view: top level - source3/smbd - signing.c (source / functions) Hit Total Coverage
Test: coverage report for master 6248eab5 Lines: 42 103 40.8 %
Date: 2021-08-25 13:27:56 Functions: 8 11 72.7 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    SMB Signing Code
       4             :    Copyright (C) Jeremy Allison 2003.
       5             :    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2002-2003
       6             :    Copyright (C) Stefan Metzmacher 2009
       7             : 
       8             :    This program is free software; you can redistribute it and/or modify
       9             :    it under the terms of the GNU General Public License as published by
      10             :    the Free Software Foundation; either version 3 of the License, or
      11             :    (at your option) any later version.
      12             : 
      13             :    This program is distributed in the hope that it will be useful,
      14             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :    GNU General Public License for more details.
      17             : 
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      20             : */
      21             : 
      22             : #include "includes.h"
      23             : #include "smbd/smbd.h"
      24             : #include "smbd/globals.h"
      25             : #include "../libcli/smb/smb_signing.h"
      26             : #include "lib/param/param.h"
      27             : 
      28             : /***********************************************************
      29             :  Called to validate an incoming packet from the client.
      30             : ************************************************************/
      31             : 
      32      650714 : bool srv_check_sign_mac(struct smbXsrv_connection *conn,
      33             :                         const char *inbuf, uint32_t *seqnum,
      34             :                         bool trusted_channel)
      35             : {
      36             :         const uint8_t *inhdr;
      37             :         size_t len;
      38             : 
      39             :         /* Check if it's a non-session message. */
      40      650714 :         if(CVAL(inbuf,0)) {
      41        1095 :                 return true;
      42             :         }
      43             : 
      44      649619 :         len = smb_len(inbuf);
      45      649619 :         inhdr = (const uint8_t *)inbuf + NBT_HDR_SIZE;
      46             : 
      47      649619 :         if (trusted_channel) {
      48             :                 NTSTATUS status;
      49             : 
      50           0 :                 if (len < (HDR_SS_FIELD + 8)) {
      51           0 :                         DEBUG(1,("smb_signing_check_pdu: Can't check signature "
      52             :                                  "on short packet! smb_len = %u\n",
      53             :                                  (unsigned)len));
      54           0 :                         return false;
      55             :                 }
      56             : 
      57           0 :                 status = NT_STATUS(IVAL(inhdr, HDR_SS_FIELD + 4));
      58           0 :                 if (!NT_STATUS_IS_OK(status)) {
      59           0 :                         DEBUG(1,("smb_signing_check_pdu: trusted channel passed %s\n",
      60             :                                  nt_errstr(status)));
      61           0 :                         return false;
      62             :                 }
      63             : 
      64           0 :                 *seqnum = IVAL(inhdr, HDR_SS_FIELD);
      65           0 :                 return true;
      66             :         }
      67             : 
      68      649619 :         *seqnum = smb_signing_next_seqnum(conn->smb1.signing_state, false);
      69      649619 :         return smb_signing_check_pdu(conn->smb1.signing_state,
      70             :                                      inhdr, len,
      71             :                                      *seqnum);
      72             : }
      73             : 
      74             : /***********************************************************
      75             :  Called to sign an outgoing packet to the client.
      76             : ************************************************************/
      77             : 
      78      625835 : NTSTATUS srv_calculate_sign_mac(struct smbXsrv_connection *conn,
      79             :                                 char *outbuf, uint32_t seqnum)
      80             : {
      81             :         uint8_t *outhdr;
      82             :         size_t len;
      83             : 
      84             :         /* Check if it's a non-session message. */
      85      625835 :         if(CVAL(outbuf,0)) {
      86           0 :                 return NT_STATUS_OK;;
      87             :         }
      88             : 
      89      625835 :         len = smb_len(outbuf);
      90      625835 :         outhdr = (uint8_t *)outbuf + NBT_HDR_SIZE;
      91             : 
      92      625835 :         return smb_signing_sign_pdu(conn->smb1.signing_state,
      93             :                                     outhdr,
      94             :                                     len,
      95             :                                     seqnum);
      96             : }
      97             : 
      98             : 
      99             : /***********************************************************
     100             :  Called to indicate a oneway request
     101             : ************************************************************/
     102        1004 : void srv_cancel_sign_response(struct smbXsrv_connection *conn)
     103             : {
     104        1004 :         smb_signing_cancel_reply(conn->smb1.signing_state, true);
     105        1004 : }
     106             : 
     107             : struct smbd_shm_signing {
     108             :         size_t shm_size;
     109             :         uint8_t *shm_pointer;
     110             : 
     111             :         /* we know the signing engine will only allocate 2 chunks */
     112             :         uint8_t *ptr1;
     113             :         size_t len1;
     114             :         uint8_t *ptr2;
     115             :         size_t len2;
     116             : };
     117             : 
     118           0 : static int smbd_shm_signing_destructor(struct smbd_shm_signing *s)
     119             : {
     120           0 :         anonymous_shared_free(s->shm_pointer);
     121           0 :         return 0;
     122             : }
     123             : 
     124           0 : static void *smbd_shm_signing_alloc(TALLOC_CTX *mem_ctx, size_t len)
     125             : {
     126           0 :         struct smbd_shm_signing *s = talloc_get_type_abort(mem_ctx,
     127             :                                      struct smbd_shm_signing);
     128             : 
     129           0 :         if (s->ptr1 == NULL) {
     130           0 :                 s->len1 = len;
     131           0 :                 if (len % 8) {
     132           0 :                         s->len1 += (8 - (len % 8));
     133             :                 }
     134           0 :                 if (s->len1 > s->shm_size) {
     135           0 :                         s->len1 = 0;
     136           0 :                         errno = ENOMEM;
     137           0 :                         return NULL;
     138             :                 }
     139           0 :                 s->ptr1 = s->shm_pointer;
     140           0 :                 return s->ptr1;
     141             :         }
     142             : 
     143           0 :         if (s->ptr2 == NULL) {
     144           0 :                 s->len2 = len;
     145           0 :                 if (s->len2 > (s->shm_size - s->len1)) {
     146           0 :                         s->len2 = 0;
     147           0 :                         errno = ENOMEM;
     148           0 :                         return NULL;
     149             :                 }
     150           0 :                 s->ptr2 = s->shm_pointer + s->len1;
     151           0 :                 return s->ptr2;
     152             :         }
     153             : 
     154           0 :         errno = ENOMEM;
     155           0 :         return NULL;
     156             : }
     157             : 
     158           0 : static void smbd_shm_signing_free(TALLOC_CTX *mem_ctx, void *ptr)
     159             : {
     160           0 :         struct smbd_shm_signing *s = talloc_get_type_abort(mem_ctx,
     161             :                                      struct smbd_shm_signing);
     162             : 
     163           0 :         if (s->ptr2 == ptr) {
     164           0 :                 s->ptr2 = NULL;
     165           0 :                 s->len2 = 0;
     166             :         }
     167           0 : }
     168             : 
     169             : /***********************************************************
     170             :  Called by server negprot when signing has been negotiated.
     171             : ************************************************************/
     172             : 
     173       28434 : bool srv_init_signing(struct smbXsrv_connection *conn)
     174             : {
     175       28434 :         bool allowed = true;
     176             :         bool desired;
     177       28434 :         bool mandatory = false;
     178             : 
     179       28434 :         struct loadparm_context *lp_ctx = loadparm_init_s3(conn, loadparm_s3_helpers());
     180       28434 :         if (lp_ctx == NULL) {
     181           0 :                 DEBUG(10, ("loadparm_init_s3 failed\n"));
     182           0 :                 return false;
     183             :         }
     184             : 
     185             :         /*
     186             :          * if the client and server allow signing,
     187             :          * we desire to use it.
     188             :          *
     189             :          * This matches Windows behavior and is needed
     190             :          * because not every client that requires signing
     191             :          * sends FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED.
     192             :          *
     193             :          * Note that we'll always allow signing if the client
     194             :          * does send FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED.
     195             :          */
     196             : 
     197       28434 :         desired = lpcfg_server_signing_allowed(lp_ctx, &mandatory);
     198       28434 :         talloc_unlink(conn, lp_ctx);
     199             : 
     200       28434 :         if (lp_async_smb_echo_handler()) {
     201             :                 struct smbd_shm_signing *s;
     202             : 
     203             :                 /* setup the signing state in shared memory */
     204           0 :                 s = talloc_zero(conn, struct smbd_shm_signing);
     205           0 :                 if (s == NULL) {
     206           0 :                         return false;
     207             :                 }
     208           0 :                 s->shm_size = 4096;
     209           0 :                 s->shm_pointer =
     210           0 :                         (uint8_t *)anonymous_shared_allocate(s->shm_size);
     211           0 :                 if (s->shm_pointer == NULL) {
     212           0 :                         talloc_free(s);
     213           0 :                         return false;
     214             :                 }
     215           0 :                 talloc_set_destructor(s, smbd_shm_signing_destructor);
     216           0 :                 conn->smb1.signing_state = smb_signing_init_ex(s,
     217             :                                                         allowed, desired, mandatory,
     218             :                                                         smbd_shm_signing_alloc,
     219             :                                                         smbd_shm_signing_free);
     220           0 :                 if (!conn->smb1.signing_state) {
     221           0 :                         return false;
     222             :                 }
     223           0 :                 return true;
     224             :         }
     225             : 
     226       28434 :         conn->smb1.signing_state = smb_signing_init(conn,
     227             :                                                     allowed, desired, mandatory);
     228       28434 :         if (!conn->smb1.signing_state) {
     229           0 :                 return false;
     230             :         }
     231             : 
     232       28434 :         return true;
     233             : }
     234             : 
     235        9838 : void srv_set_signing_negotiated(struct smbXsrv_connection *conn,
     236             :                                 bool allowed, bool mandatory)
     237             : {
     238        9838 :         smb_signing_set_negotiated(conn->smb1.signing_state,
     239             :                                    allowed, mandatory);
     240        9838 : }
     241             : 
     242             : /***********************************************************
     243             :  Returns whether signing is active. We can't use sendfile or raw
     244             :  reads/writes if it is.
     245             : ************************************************************/
     246             : 
     247      627888 : bool srv_is_signing_active(struct smbXsrv_connection *conn)
     248             : {
     249      627888 :         return smb_signing_is_active(conn->smb1.signing_state);
     250             : }
     251             : 
     252             : 
     253             : /***********************************************************
     254             :  Returns whether signing is negotiated. We can't use it unless it was
     255             :  in the negprot.
     256             : ************************************************************/
     257             : 
     258        4842 : bool srv_is_signing_negotiated(struct smbXsrv_connection *conn)
     259             : {
     260        4842 :         return smb_signing_is_negotiated(conn->smb1.signing_state);
     261             : }
     262             : 
     263             : /***********************************************************
     264             :  Turn on signing from this packet onwards.
     265             : ************************************************************/
     266             : 
     267        1012 : void srv_set_signing(struct smbXsrv_connection *conn,
     268             :                      const DATA_BLOB user_session_key,
     269             :                      const DATA_BLOB response)
     270             : {
     271             :         bool negotiated;
     272             :         bool mandatory;
     273             : 
     274        1012 :         if (!user_session_key.length)
     275           0 :                 return;
     276             : 
     277        1012 :         negotiated = smb_signing_is_negotiated(conn->smb1.signing_state);
     278        1012 :         mandatory = smb_signing_is_mandatory(conn->smb1.signing_state);
     279             : 
     280        1012 :         if (!negotiated && !mandatory) {
     281           0 :                 DEBUG(5,("srv_set_signing: signing negotiated = %u, "
     282             :                          "mandatory_signing = %u. Not allowing smb signing.\n",
     283             :                          negotiated, mandatory));
     284           0 :                 return;
     285             :         }
     286             : 
     287        1012 :         if (!smb_signing_activate(conn->smb1.signing_state,
     288             :                                   user_session_key, response)) {
     289           2 :                 return;
     290             :         }
     291             : 
     292        1010 :         DEBUG(3,("srv_set_signing: turning on SMB signing: "
     293             :                  "signing negotiated = %u, mandatory_signing = %u.\n",
     294             :                  negotiated, mandatory));
     295             : }
     296             : 

Generated by: LCOV version 1.13