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/globals.h"
24 #include "smb_signing.h"
26 /***********************************************************
27 Called to validate an incoming packet from the client.
28 ************************************************************/
30 bool srv_check_sign_mac(struct smbd_server_connection
*conn
,
31 const char *inbuf
, uint32_t *seqnum
,
34 /* Check if it's a non-session message. */
39 if (trusted_channel
) {
42 if (smb_len(inbuf
) < (smb_ss_field
+ 8 - 4)) {
43 DEBUG(1,("smb_signing_check_pdu: Can't check signature "
44 "on short packet! smb_len = %u\n",
49 status
= NT_STATUS(IVAL(inbuf
, smb_ss_field
+ 4));
50 if (!NT_STATUS_IS_OK(status
)) {
51 DEBUG(1,("smb_signing_check_pdu: trusted channel passed %s\n",
56 *seqnum
= IVAL(inbuf
, smb_ss_field
);
60 *seqnum
= smb_signing_next_seqnum(conn
->smb1
.signing_state
, false);
61 return smb_signing_check_pdu(conn
->smb1
.signing_state
,
62 (const uint8_t *)inbuf
,
66 /***********************************************************
67 Called to sign an outgoing packet to the client.
68 ************************************************************/
70 void srv_calculate_sign_mac(struct smbd_server_connection
*conn
,
71 char *outbuf
, uint32_t seqnum
)
73 /* Check if it's a non-session message. */
78 smb_signing_sign_pdu(conn
->smb1
.signing_state
, (uint8_t *)outbuf
, seqnum
);
82 /***********************************************************
83 Called to indicate a oneway request
84 ************************************************************/
85 void srv_cancel_sign_response(struct smbd_server_connection
*conn
)
87 smb_signing_cancel_reply(conn
->smb1
.signing_state
, true);
90 struct smbd_shm_signing
{
94 /* we know the signing engine will only allocate 2 chunks */
101 static void *smbd_shm_signing_alloc(TALLOC_CTX
*mem_ctx
, size_t len
)
103 struct smbd_shm_signing
*s
= talloc_get_type_abort(mem_ctx
,
104 struct smbd_shm_signing
);
106 if (s
->ptr1
== NULL
) {
109 s
->len1
+= (8 - (len
% 8));
111 if (s
->len1
> s
->shm_size
) {
116 s
->ptr1
= s
->shm_pointer
;
120 if (s
->ptr2
== NULL
) {
122 if (s
->len2
> (s
->shm_size
- s
->len1
)) {
127 s
->ptr2
= s
->shm_pointer
+ s
->len1
;
135 static void smbd_shm_signing_free(TALLOC_CTX
*mem_ctx
, void *ptr
)
137 struct smbd_shm_signing
*s
= talloc_get_type_abort(mem_ctx
,
138 struct smbd_shm_signing
);
140 if (s
->ptr2
== ptr
) {
146 /***********************************************************
147 Called by server negprot when signing has been negotiated.
148 ************************************************************/
150 bool srv_init_signing(struct smbd_server_connection
*conn
)
153 bool mandatory
= false;
155 switch (lp_server_signing()) {
168 if (lp_async_smb_echo_handler()) {
169 struct smbd_shm_signing
*s
;
171 /* setup the signing state in shared memory */
172 s
= talloc_zero(smbd_event_context(), struct smbd_shm_signing
);
178 (uint8_t *)allocate_anonymous_shared(s
->shm_size
);
179 if (s
->shm_pointer
== NULL
) {
183 conn
->smb1
.signing_state
= smb_signing_init_ex(s
,
185 smbd_shm_signing_alloc
,
186 smbd_shm_signing_free
);
187 if (!conn
->smb1
.signing_state
) {
193 conn
->smb1
.signing_state
= smb_signing_init(smbd_event_context(),
195 if (!conn
->smb1
.signing_state
) {
202 void srv_set_signing_negotiated(struct smbd_server_connection
*conn
)
204 smb_signing_set_negotiated(conn
->smb1
.signing_state
);
207 /***********************************************************
208 Returns whether signing is active. We can't use sendfile or raw
209 reads/writes if it is.
210 ************************************************************/
212 bool srv_is_signing_active(struct smbd_server_connection
*conn
)
214 return smb_signing_is_active(conn
->smb1
.signing_state
);
218 /***********************************************************
219 Returns whether signing is negotiated. We can't use it unless it was
221 ************************************************************/
223 bool srv_is_signing_negotiated(struct smbd_server_connection
*conn
)
225 return smb_signing_is_negotiated(conn
->smb1
.signing_state
);
228 /***********************************************************
229 Turn on signing from this packet onwards.
230 ************************************************************/
232 void srv_set_signing(struct smbd_server_connection
*conn
,
233 const DATA_BLOB user_session_key
,
234 const DATA_BLOB response
)
239 if (!user_session_key
.length
)
242 negotiated
= smb_signing_is_negotiated(conn
->smb1
.signing_state
);
243 mandatory
= smb_signing_is_mandatory(conn
->smb1
.signing_state
);
245 if (!negotiated
&& !mandatory
) {
246 DEBUG(5,("srv_set_signing: signing negotiated = %u, "
247 "mandatory_signing = %u. Not allowing smb signing.\n",
248 negotiated
, mandatory
));
252 if (!smb_signing_activate(conn
->smb1
.signing_state
,
253 user_session_key
, response
)) {
257 DEBUG(3,("srv_set_signing: turning on SMB signing: "
258 "signing negotiated = %u, mandatory_signing = %u.\n",
259 negotiated
, mandatory
));