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 420575 : 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 420575 : switch (req->smb_conn->signing.signing_state) {
39 589 : case SMB_SIGNING_ENGINE_OFF:
40 589 : 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 419986 : case SMB_SIGNING_ENGINE_ON:
52 :
53 839926 : sign_outgoing_message(&req->out,
54 419986 : &req->smb_conn->signing.mac_key,
55 419986 : req->seq_num+1);
56 419986 : break;
57 : }
58 420575 : 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 986 : bool smbsrv_setup_signing(struct smbsrv_connection *smb_conn,
68 : DATA_BLOB *session_key,
69 : DATA_BLOB *response)
70 : {
71 986 : if (!set_smb_signing_common(&smb_conn->signing)) {
72 32 : return false;
73 : }
74 954 : return smbcli_simple_set_signing(smb_conn,
75 : &smb_conn->signing, session_key, response);
76 : }
77 :
78 2253 : bool smbsrv_init_signing(struct smbsrv_connection *smb_conn)
79 : {
80 2253 : smb_conn->signing.mac_key = data_blob(NULL, 0);
81 2253 : if (!smbcli_set_signing_off(&smb_conn->signing)) {
82 0 : return false;
83 : }
84 :
85 : smb_conn->signing.allow_smb_signing
86 2253 : = lpcfg_server_signing_allowed(smb_conn->lp_ctx,
87 : &smb_conn->signing.mandatory_signing);
88 2253 : return true;
89 : }
90 :
91 : /*
92 : allocate a sequence number to a request
93 : */
94 423428 : static void req_signing_alloc_seq_num(struct smbsrv_request *req)
95 : {
96 423428 : req->seq_num = req->smb_conn->signing.next_seq_num;
97 :
98 423428 : if (req->smb_conn->signing.signing_state != SMB_SIGNING_ENGINE_OFF) {
99 419741 : req->smb_conn->signing.next_seq_num += 2;
100 : }
101 423428 : }
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 423428 : bool smbsrv_signing_check_incoming(struct smbsrv_request *req)
122 : {
123 : bool good;
124 :
125 423428 : req_signing_alloc_seq_num(req);
126 :
127 423428 : switch (req->smb_conn->signing.signing_state)
128 : {
129 3687 : case SMB_SIGNING_ENGINE_OFF:
130 3687 : return true;
131 419741 : case SMB_SIGNING_ENGINE_BSRSPYL:
132 : case SMB_SIGNING_ENGINE_ON:
133 : {
134 419741 : if (req->in.size < (HDR_SS_FIELD + 8)) {
135 0 : return false;
136 : } else {
137 839436 : good = check_signed_incoming_message(&req->in,
138 419741 : &req->smb_conn->signing.mac_key,
139 419741 : req->seq_num);
140 :
141 839436 : return signing_good(&req->smb_conn->signing,
142 419741 : req->seq_num+1, good);
143 : }
144 : }
145 : }
146 0 : return false;
147 : }
|