summaryrefslogtreecommitdiff
path: root/source4/smb_server/smb/signing.c
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2005-11-18 13:30:18 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:46:27 -0500
commit6d34ab056f70d85c3207696fac4fbb9e7f437b14 (patch)
treedf735be145469b92302f3dda8112129d3f4f5e18 /source4/smb_server/smb/signing.c
parentda4afcb1186fd833c08d851b94a1dcfb9e1c203b (diff)
downloadsamba-6d34ab056f70d85c3207696fac4fbb9e7f437b14.tar.gz
samba-6d34ab056f70d85c3207696fac4fbb9e7f437b14.tar.bz2
samba-6d34ab056f70d85c3207696fac4fbb9e7f437b14.zip
r11786: move all SMB protocol specific stuff to smb_server/smb/
metze (This used to be commit 5fea278cb65076cea71bb6c921e51c4feffc37d7)
Diffstat (limited to 'source4/smb_server/smb/signing.c')
-rw-r--r--source4/smb_server/smb/signing.c182
1 files changed, 182 insertions, 0 deletions
diff --git a/source4/smb_server/smb/signing.c b/source4/smb_server/smb/signing.c
new file mode 100644
index 0000000000..b461056397
--- /dev/null
+++ b/source4/smb_server/smb/signing.c
@@ -0,0 +1,182 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Copyright (C) Andrew Tridgell 2004
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "smb_server/smb_server.h"
+
+
+/*
+ sign an outgoing packet
+*/
+void req_sign_packet(struct smbsrv_request *req)
+{
+#if 0
+ /* enable this when packet signing is preventing you working out why valgrind
+ says that data is uninitialised */
+ file_save("pkt.dat", req->out.buffer, req->out.size);
+#endif
+
+ switch (req->smb_conn->signing.signing_state) {
+ case SMB_SIGNING_ENGINE_OFF:
+ break;
+
+ case SMB_SIGNING_ENGINE_BSRSPYL:
+ /* mark the packet as signed - BEFORE we sign it...*/
+ mark_packet_signed(&req->out);
+
+ /* I wonder what BSRSPYL stands for - but this is what MS
+ actually sends! */
+ memcpy((req->out.hdr + HDR_SS_FIELD), "BSRSPYL ", 8);
+ break;
+
+ case SMB_SIGNING_ENGINE_ON:
+
+ sign_outgoing_message(&req->out,
+ &req->smb_conn->signing.mac_key,
+ req->seq_num+1);
+ break;
+ }
+ return;
+}
+
+
+
+/*
+ setup the signing key for a connection. Called after authentication succeeds
+ in a session setup
+*/
+BOOL srv_setup_signing(struct smbsrv_connection *smb_conn,
+ DATA_BLOB *session_key,
+ DATA_BLOB *response)
+{
+ if (!set_smb_signing_common(&smb_conn->signing)) {
+ return False;
+ }
+ return smbcli_simple_set_signing(smb_conn,
+ &smb_conn->signing, session_key, response);
+}
+
+void srv_signing_restart(struct smbsrv_connection *smb_conn,
+ DATA_BLOB *session_key,
+ DATA_BLOB *response)
+{
+ if (!smb_conn->signing.seen_valid) {
+ DEBUG(5, ("Client did not send a valid signature on "
+ "SPNEGO session setup - ignored, expect good next time\n"));
+ /* force things back on (most clients do not sign this packet)... */
+ srv_setup_signing(smb_conn, session_key, response);
+ smb_conn->signing.next_seq_num = 2;
+ if (smb_conn->signing.mandatory_signing) {
+ DEBUG(5, ("Configured for mandatory signing, 'good packet seen' forced on\n"));
+ /* if this is mandatory, then
+ * pretend we have seen a
+ * valid packet, so we don't
+ * turn it off */
+ smb_conn->signing.seen_valid = True;
+ }
+ }
+}
+
+BOOL srv_init_signing(struct smbsrv_connection *smb_conn)
+{
+ smb_conn->signing.mac_key = data_blob(NULL, 0);
+ if (!smbcli_set_signing_off(&smb_conn->signing)) {
+ return False;
+ }
+
+ switch (lp_server_signing()) {
+ case SMB_SIGNING_OFF:
+ smb_conn->signing.allow_smb_signing = False;
+ break;
+ case SMB_SIGNING_SUPPORTED:
+ smb_conn->signing.allow_smb_signing = True;
+ break;
+ case SMB_SIGNING_REQUIRED:
+ smb_conn->signing.allow_smb_signing = True;
+ smb_conn->signing.mandatory_signing = True;
+ break;
+ case SMB_SIGNING_AUTO:
+ if (lp_domain_logons()) {
+ smb_conn->signing.allow_smb_signing = True;
+ } else {
+ smb_conn->signing.allow_smb_signing = False;
+ }
+ break;
+ }
+ return True;
+}
+
+/*
+ allocate a sequence number to a request
+*/
+static void req_signing_alloc_seq_num(struct smbsrv_request *req)
+{
+ req->seq_num = req->smb_conn->signing.next_seq_num;
+
+ if (req->smb_conn->signing.signing_state != SMB_SIGNING_ENGINE_OFF) {
+ req->smb_conn->signing.next_seq_num += 2;
+ }
+}
+
+/*
+ called for requests that do not produce a reply of their own
+*/
+void req_signing_no_reply(struct smbsrv_request *req)
+{
+ if (req->smb_conn->signing.signing_state != SMB_SIGNING_ENGINE_OFF) {
+ req->smb_conn->signing.next_seq_num--;
+ }
+}
+
+/***********************************************************
+ SMB signing - Simple implementation - check a MAC sent by client
+************************************************************/
+/**
+ * Check a packet supplied by the server.
+ * @return False if we had an established signing connection
+ * which had a back checksum, True otherwise
+ */
+BOOL req_signing_check_incoming(struct smbsrv_request *req)
+{
+ BOOL good;
+
+ req_signing_alloc_seq_num(req);
+
+ switch (req->smb_conn->signing.signing_state)
+ {
+ case SMB_SIGNING_ENGINE_OFF:
+ return True;
+ case SMB_SIGNING_ENGINE_BSRSPYL:
+ case SMB_SIGNING_ENGINE_ON:
+ {
+ if (req->in.size < (HDR_SS_FIELD + 8)) {
+ return False;
+ } else {
+ good = check_signed_incoming_message(&req->in,
+ &req->smb_conn->signing.mac_key,
+ req->seq_num);
+
+ return signing_good(&req->smb_conn->signing,
+ req->seq_num+1, good);
+ }
+ }
+ }
+ return False;
+}