LCOV - code coverage report
Current view: top level - source4/smb_server/smb - signing.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 40 47 85.1 %
Date: 2021-09-23 10:06:22 Functions: 6 6 100.0 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             :    
       4             :    Copyright (C) Andrew Tridgell              2004
       5             :    
       6             :    This program is free software; you can redistribute it and/or modify
       7             :    it under the terms of the GNU General Public License as published by
       8             :    the Free Software Foundation; either version 3 of the License, or
       9             :    (at your option) any later version.
      10             :    
      11             :    This program is distributed in the hope that it will be useful,
      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :    GNU General Public License for more details.
      15             :    
      16             :    You should have received a copy of the GNU General Public License
      17             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      18             : */
      19             : 
      20             : #include "includes.h"
      21             : #include "smb_server/smb_server.h"
      22             : #include "libcli/raw/libcliraw.h"
      23             : #include "libcli/raw/raw_proto.h"
      24             : #include "param/param.h"
      25             : 
      26             : 
      27             : /*
      28             :   sign an outgoing packet
      29             : */
      30      415982 : void smbsrv_sign_packet(struct smbsrv_request *req)
      31             : {
      32             : #if 0
      33             :         /* enable this when packet signing is preventing you working out why valgrind 
      34             :            says that data is uninitialised */
      35             :         file_save("pkt.dat", req->out.buffer, req->out.size);
      36             : #endif
      37             : 
      38      415982 :         switch (req->smb_conn->signing.signing_state) {
      39         645 :         case SMB_SIGNING_ENGINE_OFF:
      40         645 :                 break;
      41             : 
      42           0 :         case SMB_SIGNING_ENGINE_BSRSPYL:
      43             :                 /* mark the packet as signed - BEFORE we sign it...*/
      44           0 :                 mark_packet_signed(&req->out);
      45             :                 
      46             :                 /* I wonder what BSRSPYL stands for - but this is what MS 
      47             :                    actually sends! */
      48           0 :                 memcpy((req->out.hdr + HDR_SS_FIELD), "BSRSPYL ", 8);
      49           0 :                 break;
      50             : 
      51      415337 :         case SMB_SIGNING_ENGINE_ON:
      52             :                         
      53      830622 :                 sign_outgoing_message(&req->out, 
      54      415337 :                                       &req->smb_conn->signing.mac_key, 
      55      415337 :                                       req->seq_num+1);
      56      415337 :                 break;
      57             :         }
      58      415982 :         return;
      59             : }
      60             : 
      61             : 
      62             : 
      63             : /*
      64             :   setup the signing key for a connection. Called after authentication succeeds
      65             :   in a session setup
      66             : */
      67         998 : bool smbsrv_setup_signing(struct smbsrv_connection *smb_conn,
      68             :                           DATA_BLOB *session_key,
      69             :                           DATA_BLOB *response)
      70             : {
      71         998 :         if (!set_smb_signing_common(&smb_conn->signing)) {
      72          32 :                 return false;
      73             :         }
      74         966 :         return smbcli_simple_set_signing(smb_conn,
      75             :                                          &smb_conn->signing, session_key, response);
      76             : }
      77             : 
      78        2326 : bool smbsrv_init_signing(struct smbsrv_connection *smb_conn)
      79             : {
      80        2326 :         smb_conn->signing.mac_key = data_blob(NULL, 0);
      81        2326 :         if (!smbcli_set_signing_off(&smb_conn->signing)) {
      82           0 :                 return false;
      83             :         }
      84             : 
      85             :         smb_conn->signing.allow_smb_signing
      86        2326 :                 = lpcfg_server_signing_allowed(smb_conn->lp_ctx,
      87             :                                                &smb_conn->signing.mandatory_signing);
      88        2326 :         return true;
      89             : }
      90             : 
      91             : /*
      92             :   allocate a sequence number to a request
      93             : */
      94      418956 : static void req_signing_alloc_seq_num(struct smbsrv_request *req)
      95             : {
      96      418956 :         req->seq_num = req->smb_conn->signing.next_seq_num;
      97             : 
      98      418956 :         if (req->smb_conn->signing.signing_state != SMB_SIGNING_ENGINE_OFF) {
      99      415140 :                 req->smb_conn->signing.next_seq_num += 2;
     100             :         }
     101      418956 : }
     102             : 
     103             : /*
     104             :   called for requests that do not produce a reply of their own
     105             : */
     106         569 : void smbsrv_signing_no_reply(struct smbsrv_request *req)
     107             : {
     108         569 :         if (req->smb_conn->signing.signing_state != SMB_SIGNING_ENGINE_OFF) {
     109         569 :                 req->smb_conn->signing.next_seq_num--;
     110             :         }
     111         569 : }
     112             : 
     113             : /***********************************************************
     114             :  SMB signing - Simple implementation - check a MAC sent by client
     115             : ************************************************************/
     116             : /**
     117             :  * Check a packet supplied by the server.
     118             :  * @return false if we had an established signing connection
     119             :  *         which had a back checksum, true otherwise
     120             :  */
     121      418956 : bool smbsrv_signing_check_incoming(struct smbsrv_request *req)
     122             : {
     123             :         bool good;
     124             : 
     125      418956 :         req_signing_alloc_seq_num(req);
     126             : 
     127      418956 :         switch (req->smb_conn->signing.signing_state) 
     128             :         {
     129        3816 :         case SMB_SIGNING_ENGINE_OFF:
     130        3816 :                 return true;
     131      415140 :         case SMB_SIGNING_ENGINE_BSRSPYL:
     132             :         case SMB_SIGNING_ENGINE_ON:
     133             :         {                       
     134      415140 :                 if (req->in.size < (HDR_SS_FIELD + 8)) {
     135           0 :                         return false;
     136             :                 } else {
     137      830228 :                         good = check_signed_incoming_message(&req->in, 
     138      415140 :                                                              &req->smb_conn->signing.mac_key, 
     139      415140 :                                                              req->seq_num);
     140             :                         
     141      830228 :                         return signing_good(&req->smb_conn->signing, 
     142      415140 :                                             req->seq_num+1, good);
     143             :                 }
     144             :         }
     145             :         }
     146           0 :         return false;
     147             : }

Generated by: LCOV version 1.13