Describe implication of upstream ICU-22610
[Samba.git] / source3 / smbd / smb1_signing.c
blobaa3027d531823baedab831159d2c6ed83a8032db
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
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.
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.
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/>.
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"
28 /***********************************************************
29 Called to validate an incoming packet from the client.
30 ************************************************************/
32 bool smb1_srv_check_sign_mac(struct smbXsrv_connection *conn,
33 const char *inbuf, uint32_t *seqnum,
34 bool trusted_channel)
36 const uint8_t *inhdr;
37 size_t len;
39 /* Check if it's a non-session message. */
40 if(CVAL(inbuf,0)) {
41 return true;
44 len = smb_len(inbuf);
45 inhdr = (const uint8_t *)inbuf + NBT_HDR_SIZE;
47 if (trusted_channel) {
48 NTSTATUS status;
50 if (len < (HDR_SS_FIELD + 8)) {
51 DBG_WARNING("Can't check signature "
52 "on short packet! smb_len = %u\n",
53 (unsigned)len);
54 return false;
57 status = NT_STATUS(IVAL(inhdr, HDR_SS_FIELD + 4));
58 if (!NT_STATUS_IS_OK(status)) {
59 DBG_WARNING("trusted channel passed %s\n",
60 nt_errstr(status));
61 return false;
64 *seqnum = IVAL(inhdr, HDR_SS_FIELD);
65 return true;
68 *seqnum = smb1_signing_next_seqnum(conn->smb1.signing_state, false);
69 return smb1_signing_check_pdu(conn->smb1.signing_state,
70 inhdr, len,
71 *seqnum);
74 /***********************************************************
75 Called to sign an outgoing packet to the client.
76 ************************************************************/
78 NTSTATUS smb1_srv_calculate_sign_mac(struct smbXsrv_connection *conn,
79 char *outbuf, uint32_t seqnum)
81 uint8_t *outhdr;
82 size_t len;
84 /* Check if it's a non-session message. */
85 if(CVAL(outbuf,0)) {
86 return NT_STATUS_OK;;
89 len = smb_len(outbuf);
90 outhdr = (uint8_t *)outbuf + NBT_HDR_SIZE;
92 return smb1_signing_sign_pdu(conn->smb1.signing_state,
93 outhdr,
94 len,
95 seqnum);
99 /***********************************************************
100 Called to indicate a oneway request
101 ************************************************************/
102 void smb1_srv_cancel_sign_response(struct smbXsrv_connection *conn)
104 smb1_signing_cancel_reply(conn->smb1.signing_state, true);
107 struct smbd_shm_signing {
108 size_t shm_size;
109 uint8_t *shm_pointer;
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;
118 static int smbd_shm_signing_destructor(struct smbd_shm_signing *s)
120 anonymous_shared_free(s->shm_pointer);
121 return 0;
124 static void *smbd_shm_signing_alloc(TALLOC_CTX *mem_ctx, size_t len)
126 struct smbd_shm_signing *s = talloc_get_type_abort(mem_ctx,
127 struct smbd_shm_signing);
129 if (s->ptr1 == NULL) {
130 s->len1 = len;
131 if (len % 8) {
132 s->len1 += (8 - (len % 8));
134 if (s->len1 > s->shm_size) {
135 s->len1 = 0;
136 errno = ENOMEM;
137 return NULL;
139 s->ptr1 = s->shm_pointer;
140 return s->ptr1;
143 if (s->ptr2 == NULL) {
144 s->len2 = len;
145 if (s->len2 > (s->shm_size - s->len1)) {
146 s->len2 = 0;
147 errno = ENOMEM;
148 return NULL;
150 s->ptr2 = s->shm_pointer + s->len1;
151 return s->ptr2;
154 errno = ENOMEM;
155 return NULL;
158 static void smbd_shm_signing_free(TALLOC_CTX *mem_ctx, void *ptr)
160 struct smbd_shm_signing *s = talloc_get_type_abort(mem_ctx,
161 struct smbd_shm_signing);
163 if (s->ptr2 == ptr) {
164 s->ptr2 = NULL;
165 s->len2 = 0;
169 /***********************************************************
170 Called by server negprot when signing has been negotiated.
171 ************************************************************/
173 bool smb1_srv_init_signing(struct loadparm_context *lp_ctx,
174 struct smbXsrv_connection *conn)
176 bool allowed = true;
177 bool desired;
178 bool mandatory = false;
181 * if the client and server allow signing,
182 * we desire to use it.
184 * This matches Windows behavior and is needed
185 * because not every client that requires signing
186 * sends FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED.
188 * Note that we'll always allow signing if the client
189 * does send FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED.
192 desired = lpcfg_server_signing_allowed(lp_ctx, &mandatory);
194 if (lp_async_smb_echo_handler()) {
195 struct smbd_shm_signing *s;
197 /* setup the signing state in shared memory */
198 s = talloc_zero(conn, struct smbd_shm_signing);
199 if (s == NULL) {
200 return false;
202 s->shm_size = 4096;
203 s->shm_pointer =
204 (uint8_t *)anonymous_shared_allocate(s->shm_size);
205 if (s->shm_pointer == NULL) {
206 talloc_free(s);
207 return false;
209 talloc_set_destructor(s, smbd_shm_signing_destructor);
210 conn->smb1.signing_state = smb1_signing_init_ex(s,
211 allowed, desired, mandatory,
212 smbd_shm_signing_alloc,
213 smbd_shm_signing_free);
214 if (!conn->smb1.signing_state) {
215 return false;
217 return true;
220 conn->smb1.signing_state = smb1_signing_init(conn,
221 allowed, desired, mandatory);
222 if (!conn->smb1.signing_state) {
223 return false;
226 return true;
229 void smb1_srv_set_signing_negotiated(struct smbXsrv_connection *conn,
230 bool allowed, bool mandatory)
232 smb1_signing_set_negotiated(conn->smb1.signing_state,
233 allowed, mandatory);
236 /***********************************************************
237 Returns whether signing is active. We can't use sendfile or raw
238 reads/writes if it is.
239 ************************************************************/
241 bool smb1_srv_is_signing_active(struct smbXsrv_connection *conn)
243 return smb1_signing_is_active(conn->smb1.signing_state);
247 /***********************************************************
248 Returns whether signing is negotiated. We can't use it unless it was
249 in the negprot.
250 ************************************************************/
252 bool smb1_srv_is_signing_negotiated(struct smbXsrv_connection *conn)
254 return smb1_signing_is_negotiated(conn->smb1.signing_state);
257 /***********************************************************
258 Turn on signing from this packet onwards.
259 ************************************************************/
261 void smb1_srv_set_signing(struct smbXsrv_connection *conn,
262 const DATA_BLOB user_session_key,
263 const DATA_BLOB response)
265 bool negotiated;
266 bool mandatory;
268 if (!user_session_key.length)
269 return;
271 negotiated = smb1_signing_is_negotiated(conn->smb1.signing_state);
272 mandatory = smb1_signing_is_mandatory(conn->smb1.signing_state);
274 if (!negotiated && !mandatory) {
275 DBG_INFO("signing negotiated = %u, "
276 "mandatory_signing = %u. Not allowing smb signing.\n",
277 negotiated, mandatory);
278 return;
281 if (!smb1_signing_activate(conn->smb1.signing_state,
282 user_session_key, response)) {
283 return;
286 DBG_NOTICE("turning on SMB signing: "
287 "signing negotiated = %u, mandatory_signing = %u.\n",
288 negotiated, mandatory);