root/source4/smb_server/smb/signing.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. smbsrv_sign_packet
  2. smbsrv_setup_signing
  3. smbsrv_init_signing
  4. req_signing_alloc_seq_num
  5. smbsrv_signing_no_reply
  6. smbsrv_signing_check_incoming

   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 void smbsrv_sign_packet(struct smbsrv_request *req)
     /* [<][>][^][v][top][bottom][index][help] */
  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         switch (req->smb_conn->signing.signing_state) {
  39         case SMB_SIGNING_ENGINE_OFF:
  40                 break;
  41 
  42         case SMB_SIGNING_ENGINE_BSRSPYL:
  43                 /* mark the packet as signed - BEFORE we sign it...*/
  44                 mark_packet_signed(&req->out);
  45                 
  46                 /* I wonder what BSRSPYL stands for - but this is what MS 
  47                    actually sends! */
  48                 memcpy((req->out.hdr + HDR_SS_FIELD), "BSRSPYL ", 8);
  49                 break;
  50 
  51         case SMB_SIGNING_ENGINE_ON:
  52                         
  53                 sign_outgoing_message(&req->out, 
  54                                       &req->smb_conn->signing.mac_key, 
  55                                       req->seq_num+1);
  56                 break;
  57         }
  58         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 bool smbsrv_setup_signing(struct smbsrv_connection *smb_conn,
     /* [<][>][^][v][top][bottom][index][help] */
  68                           DATA_BLOB *session_key,
  69                           DATA_BLOB *response)
  70 {
  71         if (!set_smb_signing_common(&smb_conn->signing)) {
  72                 return false;
  73         }
  74         return smbcli_simple_set_signing(smb_conn,
  75                                          &smb_conn->signing, session_key, response);
  76 }
  77 
  78 bool smbsrv_init_signing(struct smbsrv_connection *smb_conn)
     /* [<][>][^][v][top][bottom][index][help] */
  79 {
  80         smb_conn->signing.mac_key = data_blob(NULL, 0);
  81         if (!smbcli_set_signing_off(&smb_conn->signing)) {
  82                 return false;
  83         }
  84         
  85         switch (lp_server_signing(smb_conn->lp_ctx)) {
  86         case SMB_SIGNING_OFF:
  87                 smb_conn->signing.allow_smb_signing = false;
  88                 break;
  89         case SMB_SIGNING_SUPPORTED:
  90                 smb_conn->signing.allow_smb_signing = true;
  91                 break;
  92         case SMB_SIGNING_REQUIRED:
  93                 smb_conn->signing.allow_smb_signing = true;
  94                 smb_conn->signing.mandatory_signing = true;
  95                 break;
  96         case SMB_SIGNING_AUTO:
  97                 /* If we are a domain controller, SMB signing is
  98                  * really important, as it can prevent a number of
  99                  * attacks on communications between us and the
 100                  * clients */
 101 
 102                 if (lp_server_role(smb_conn->lp_ctx) == ROLE_DOMAIN_CONTROLLER) {
 103                         smb_conn->signing.allow_smb_signing = true;
 104                         smb_conn->signing.mandatory_signing = true;
 105                 } else {
 106                         /* However, it really sucks (no sendfile, CPU
 107                          * overhead) performance-wise when used on a
 108                          * file server, so disable it by default (auto
 109                          * is the default) on non-DCs */
 110                         smb_conn->signing.allow_smb_signing = false;
 111                 }
 112                 break;
 113         }
 114         return true;
 115 }
 116 
 117 /*
 118   allocate a sequence number to a request
 119 */
 120 static void req_signing_alloc_seq_num(struct smbsrv_request *req)
     /* [<][>][^][v][top][bottom][index][help] */
 121 {
 122         req->seq_num = req->smb_conn->signing.next_seq_num;
 123 
 124         if (req->smb_conn->signing.signing_state != SMB_SIGNING_ENGINE_OFF) {
 125                 req->smb_conn->signing.next_seq_num += 2;
 126         }
 127 }
 128 
 129 /*
 130   called for requests that do not produce a reply of their own
 131 */
 132 void smbsrv_signing_no_reply(struct smbsrv_request *req)
     /* [<][>][^][v][top][bottom][index][help] */
 133 {
 134         if (req->smb_conn->signing.signing_state != SMB_SIGNING_ENGINE_OFF) {
 135                 req->smb_conn->signing.next_seq_num--;
 136         }
 137 }
 138 
 139 /***********************************************************
 140  SMB signing - Simple implementation - check a MAC sent by client
 141 ************************************************************/
 142 /**
 143  * Check a packet supplied by the server.
 144  * @return false if we had an established signing connection
 145  *         which had a back checksum, true otherwise
 146  */
 147 bool smbsrv_signing_check_incoming(struct smbsrv_request *req)
     /* [<][>][^][v][top][bottom][index][help] */
 148 {
 149         bool good;
 150 
 151         req_signing_alloc_seq_num(req);
 152 
 153         switch (req->smb_conn->signing.signing_state) 
 154         {
 155         case SMB_SIGNING_ENGINE_OFF:
 156                 return true;
 157         case SMB_SIGNING_ENGINE_BSRSPYL:
 158         case SMB_SIGNING_ENGINE_ON:
 159         {                       
 160                 if (req->in.size < (HDR_SS_FIELD + 8)) {
 161                         return false;
 162                 } else {
 163                         good = check_signed_incoming_message(&req->in, 
 164                                                              &req->smb_conn->signing.mac_key, 
 165                                                              req->seq_num);
 166                         
 167                         return signing_good(&req->smb_conn->signing, 
 168                                             req->seq_num+1, good);
 169                 }
 170         }
 171         }
 172         return false;
 173 }

/* [<][>][^][v][top][bottom][index][help] */