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 420435 : 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 420435 : switch (req->smb_conn->signing.signing_state) { 39 594 : case SMB_SIGNING_ENGINE_OFF: 40 594 : 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 419841 : case SMB_SIGNING_ENGINE_ON: 52 : 53 419841 : sign_outgoing_message(&req->out, 54 419841 : &req->smb_conn->signing.mac_key, 55 419841 : req->seq_num+1); 56 419841 : break; 57 : } 58 420435 : 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 962 : bool smbsrv_setup_signing(struct smbsrv_connection *smb_conn, 68 : DATA_BLOB *session_key, 69 : DATA_BLOB *response) 70 : { 71 962 : if (!set_smb_signing_common(&smb_conn->signing)) { 72 32 : return false; 73 : } 74 930 : return smbcli_simple_set_signing(smb_conn, 75 : &smb_conn->signing, session_key, response); 76 : } 77 : 78 2165 : bool smbsrv_init_signing(struct smbsrv_connection *smb_conn) 79 : { 80 2165 : smb_conn->signing.mac_key = data_blob(NULL, 0); 81 2165 : if (!smbcli_set_signing_off(&smb_conn->signing)) { 82 0 : return false; 83 : } 84 : 85 0 : smb_conn->signing.allow_smb_signing 86 2165 : = lpcfg_server_signing_allowed(smb_conn->lp_ctx, 87 : &smb_conn->signing.mandatory_signing); 88 2165 : return true; 89 : } 90 : 91 : /* 92 : allocate a sequence number to a request 93 : */ 94 423203 : static void req_signing_alloc_seq_num(struct smbsrv_request *req) 95 : { 96 423203 : req->seq_num = req->smb_conn->signing.next_seq_num; 97 : 98 423203 : if (req->smb_conn->signing.signing_state != SMB_SIGNING_ENGINE_OFF) { 99 419618 : req->smb_conn->signing.next_seq_num += 2; 100 : } 101 423203 : } 102 : 103 : /* 104 : called for requests that do not produce a reply of their own 105 : */ 106 529 : void smbsrv_signing_no_reply(struct smbsrv_request *req) 107 : { 108 529 : if (req->smb_conn->signing.signing_state != SMB_SIGNING_ENGINE_OFF) { 109 529 : req->smb_conn->signing.next_seq_num--; 110 : } 111 529 : } 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 423203 : bool smbsrv_signing_check_incoming(struct smbsrv_request *req) 122 : { 123 0 : bool good; 124 : 125 423203 : req_signing_alloc_seq_num(req); 126 : 127 423203 : switch (req->smb_conn->signing.signing_state) 128 : { 129 3585 : case SMB_SIGNING_ENGINE_OFF: 130 3585 : return true; 131 419618 : case SMB_SIGNING_ENGINE_BSRSPYL: 132 : case SMB_SIGNING_ENGINE_ON: 133 : { 134 419618 : if (req->in.size < (HDR_SS_FIELD + 8)) { 135 0 : return false; 136 : } else { 137 419618 : good = check_signed_incoming_message(&req->in, 138 419618 : &req->smb_conn->signing.mac_key, 139 419618 : req->seq_num); 140 : 141 419618 : return signing_good(&req->smb_conn->signing, 142 419618 : req->seq_num+1, good); 143 : } 144 : } 145 : } 146 0 : return false; 147 : }