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"
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
,
39 /* Check if it's a non-session message. */
45 inhdr
= (const uint8_t *)inbuf
+ NBT_HDR_SIZE
;
47 if (trusted_channel
) {
50 if (len
< (HDR_SS_FIELD
+ 8)) {
51 DBG_WARNING("Can't check signature "
52 "on short packet! smb_len = %u\n",
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",
64 *seqnum
= IVAL(inhdr
, HDR_SS_FIELD
);
68 *seqnum
= smb1_signing_next_seqnum(conn
->smb1
.signing_state
, false);
69 return smb1_signing_check_pdu(conn
->smb1
.signing_state
,
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
)
84 /* Check if it's a non-session message. */
89 len
= smb_len(outbuf
);
90 outhdr
= (uint8_t *)outbuf
+ NBT_HDR_SIZE
;
92 return smb1_signing_sign_pdu(conn
->smb1
.signing_state
,
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
{
109 uint8_t *shm_pointer
;
111 /* we know the signing engine will only allocate 2 chunks */
118 static int smbd_shm_signing_destructor(struct smbd_shm_signing
*s
)
120 anonymous_shared_free(s
->shm_pointer
);
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
) {
132 s
->len1
+= (8 - (len
% 8));
134 if (s
->len1
> s
->shm_size
) {
139 s
->ptr1
= s
->shm_pointer
;
143 if (s
->ptr2
== NULL
) {
145 if (s
->len2
> (s
->shm_size
- s
->len1
)) {
150 s
->ptr2
= s
->shm_pointer
+ s
->len1
;
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
) {
169 /***********************************************************
170 Called by server negprot when signing has been negotiated.
171 ************************************************************/
173 bool smb1_srv_init_signing(struct smbXsrv_connection
*conn
)
177 bool mandatory
= false;
179 struct loadparm_context
*lp_ctx
= loadparm_init_s3(conn
, loadparm_s3_helpers());
180 if (lp_ctx
== NULL
) {
181 DEBUG(10, ("loadparm_init_s3 failed\n"));
186 * if the client and server allow signing,
187 * we desire to use it.
189 * This matches Windows behavior and is needed
190 * because not every client that requires signing
191 * sends FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED.
193 * Note that we'll always allow signing if the client
194 * does send FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED.
197 desired
= lpcfg_server_signing_allowed(lp_ctx
, &mandatory
);
198 talloc_unlink(conn
, lp_ctx
);
200 if (lp_async_smb_echo_handler()) {
201 struct smbd_shm_signing
*s
;
203 /* setup the signing state in shared memory */
204 s
= talloc_zero(conn
, struct smbd_shm_signing
);
210 (uint8_t *)anonymous_shared_allocate(s
->shm_size
);
211 if (s
->shm_pointer
== NULL
) {
215 talloc_set_destructor(s
, smbd_shm_signing_destructor
);
216 conn
->smb1
.signing_state
= smb1_signing_init_ex(s
,
217 allowed
, desired
, mandatory
,
218 smbd_shm_signing_alloc
,
219 smbd_shm_signing_free
);
220 if (!conn
->smb1
.signing_state
) {
226 conn
->smb1
.signing_state
= smb1_signing_init(conn
,
227 allowed
, desired
, mandatory
);
228 if (!conn
->smb1
.signing_state
) {
235 void smb1_srv_set_signing_negotiated(struct smbXsrv_connection
*conn
,
236 bool allowed
, bool mandatory
)
238 smb1_signing_set_negotiated(conn
->smb1
.signing_state
,
242 /***********************************************************
243 Returns whether signing is active. We can't use sendfile or raw
244 reads/writes if it is.
245 ************************************************************/
247 bool smb1_srv_is_signing_active(struct smbXsrv_connection
*conn
)
249 return smb1_signing_is_active(conn
->smb1
.signing_state
);
253 /***********************************************************
254 Returns whether signing is negotiated. We can't use it unless it was
256 ************************************************************/
258 bool smb1_srv_is_signing_negotiated(struct smbXsrv_connection
*conn
)
260 return smb1_signing_is_negotiated(conn
->smb1
.signing_state
);
263 /***********************************************************
264 Turn on signing from this packet onwards.
265 ************************************************************/
267 void smb1_srv_set_signing(struct smbXsrv_connection
*conn
,
268 const DATA_BLOB user_session_key
,
269 const DATA_BLOB response
)
274 if (!user_session_key
.length
)
277 negotiated
= smb1_signing_is_negotiated(conn
->smb1
.signing_state
);
278 mandatory
= smb1_signing_is_mandatory(conn
->smb1
.signing_state
);
280 if (!negotiated
&& !mandatory
) {
281 DBG_INFO("signing negotiated = %u, "
282 "mandatory_signing = %u. Not allowing smb signing.\n",
283 negotiated
, mandatory
);
287 if (!smb1_signing_activate(conn
->smb1
.signing_state
,
288 user_session_key
, response
)) {
292 DBG_NOTICE("turning on SMB signing: "
293 "signing negotiated = %u, mandatory_signing = %u.\n",
294 negotiated
, mandatory
);