2 Unix SMB/CIFS implementation.
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/>.
23 #include "smbd/smbd.h"
24 #include "smbd/globals.h"
25 #include "../libcli/smb/smb_signing.h"
27 /***********************************************************
28 Called to validate an incoming packet from the client.
29 ************************************************************/
31 bool srv_check_sign_mac(struct smbd_server_connection *conn,
32 const char *inbuf, uint32_t *seqnum,
38 /* Check if it's a non-session message. */
44 inhdr = (const uint8_t *)inbuf + NBT_HDR_SIZE;
46 if (trusted_channel) {
49 if (len < (HDR_SS_FIELD + 8)) {
50 DEBUG(1,("smb_signing_check_pdu: Can't check signature "
51 "on short packet! smb_len = %u\n",
56 status = NT_STATUS(IVAL(inhdr, HDR_SS_FIELD + 4));
57 if (!NT_STATUS_IS_OK(status)) {
58 DEBUG(1,("smb_signing_check_pdu: trusted channel passed %s\n",
63 *seqnum = IVAL(inhdr, HDR_SS_FIELD);
67 *seqnum = smb_signing_next_seqnum(conn->smb1.signing_state, false);
68 return smb_signing_check_pdu(conn->smb1.signing_state,
73 /***********************************************************
74 Called to sign an outgoing packet to the client.
75 ************************************************************/
77 void srv_calculate_sign_mac(struct smbd_server_connection *conn,
78 char *outbuf, uint32_t seqnum)
83 /* Check if it's a non-session message. */
88 len = smb_len(outbuf);
89 outhdr = (uint8_t *)outbuf + NBT_HDR_SIZE;
91 smb_signing_sign_pdu(conn->smb1.signing_state, outhdr, len, seqnum);
95 /***********************************************************
96 Called to indicate a oneway request
97 ************************************************************/
98 void srv_cancel_sign_response(struct smbd_server_connection *conn)
100 smb_signing_cancel_reply(conn->smb1.signing_state, true);
103 struct smbd_shm_signing {
105 uint8_t *shm_pointer;
107 /* we know the signing engine will only allocate 2 chunks */
114 static int smbd_shm_signing_destructor(struct smbd_shm_signing *s)
116 anonymous_shared_free(s->shm_pointer);
120 static void *smbd_shm_signing_alloc(TALLOC_CTX *mem_ctx, size_t len)
122 struct smbd_shm_signing *s = talloc_get_type_abort(mem_ctx,
123 struct smbd_shm_signing);
125 if (s->ptr1 == NULL) {
128 s->len1 += (8 - (len % 8));
130 if (s->len1 > s->shm_size) {
135 s->ptr1 = s->shm_pointer;
139 if (s->ptr2 == NULL) {
141 if (s->len2 > (s->shm_size - s->len1)) {
146 s->ptr2 = s->shm_pointer + s->len1;
154 static void smbd_shm_signing_free(TALLOC_CTX *mem_ctx, void *ptr)
156 struct smbd_shm_signing *s = talloc_get_type_abort(mem_ctx,
157 struct smbd_shm_signing);
159 if (s->ptr2 == ptr) {
165 /***********************************************************
166 Called by server negprot when signing has been negotiated.
167 ************************************************************/
169 bool srv_init_signing(struct smbd_server_connection *conn)
173 bool mandatory = false;
175 switch (lp_server_signing()) {
176 case SMB_SIGNING_REQUIRED:
179 case SMB_SIGNING_IF_REQUIRED:
181 case SMB_SIGNING_DEFAULT:
182 case SMB_SIGNING_OFF:
188 * if the client and server allow signing,
189 * we desire to use it.
191 * This matches Windows behavior and is needed
192 * because not every client that requires signing
193 * sends FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED.
197 if (lp_async_smb_echo_handler()) {
198 struct smbd_shm_signing *s;
200 /* setup the signing state in shared memory */
201 s = talloc_zero(conn, struct smbd_shm_signing);
207 (uint8_t *)anonymous_shared_allocate(s->shm_size);
208 if (s->shm_pointer == NULL) {
212 talloc_set_destructor(s, smbd_shm_signing_destructor);
213 conn->smb1.signing_state = smb_signing_init_ex(s,
214 allowed, desired, mandatory,
215 smbd_shm_signing_alloc,
216 smbd_shm_signing_free);
217 if (!conn->smb1.signing_state) {
223 conn->smb1.signing_state = smb_signing_init(conn,
224 allowed, desired, mandatory);
225 if (!conn->smb1.signing_state) {
232 void srv_set_signing_negotiated(struct smbd_server_connection *conn,
233 bool allowed, bool mandatory)
235 smb_signing_set_negotiated(conn->smb1.signing_state,
239 /***********************************************************
240 Returns whether signing is active. We can't use sendfile or raw
241 reads/writes if it is.
242 ************************************************************/
244 bool srv_is_signing_active(struct smbd_server_connection *conn)
246 return smb_signing_is_active(conn->smb1.signing_state);
250 /***********************************************************
251 Returns whether signing is negotiated. We can't use it unless it was
253 ************************************************************/
255 bool srv_is_signing_negotiated(struct smbd_server_connection *conn)
257 return smb_signing_is_negotiated(conn->smb1.signing_state);
260 /***********************************************************
261 Turn on signing from this packet onwards.
262 ************************************************************/
264 void srv_set_signing(struct smbd_server_connection *conn,
265 const DATA_BLOB user_session_key,
266 const DATA_BLOB response)
271 if (!user_session_key.length)
274 negotiated = smb_signing_is_negotiated(conn->smb1.signing_state);
275 mandatory = smb_signing_is_mandatory(conn->smb1.signing_state);
277 if (!negotiated && !mandatory) {
278 DEBUG(5,("srv_set_signing: signing negotiated = %u, "
279 "mandatory_signing = %u. Not allowing smb signing.\n",
280 negotiated, mandatory));
284 if (!smb_signing_activate(conn->smb1.signing_state,
285 user_session_key, response)) {
289 DEBUG(3,("srv_set_signing: turning on SMB signing: "
290 "signing negotiated = %u, mandatory_signing = %u.\n",
291 negotiated, mandatory));