Merge branch 'master' of ssh://git.samba.org/data/git/samba into displaysec
[samba.git] / source3 / smbd / signing.c
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
7
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.
12
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.
17
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/>.
20 */
21
22 #include "includes.h"
23 #include "smbd/globals.h"
24
25
26 /***********************************************************
27  Called to validate an incoming packet from the client.
28 ************************************************************/
29
30 bool srv_check_sign_mac(struct smbd_server_connection *conn,
31                         const char *inbuf, uint32_t *seqnum)
32 {
33         /* Check if it's a non-session message. */
34         if(CVAL(inbuf,0)) {
35                 return true;
36         }
37
38         *seqnum = smb_signing_next_seqnum(conn->signing_state, false);
39         return smb_signing_check_pdu(conn->signing_state,
40                                      (const uint8_t *)inbuf,
41                                      *seqnum);
42 }
43
44 /***********************************************************
45  Called to sign an outgoing packet to the client.
46 ************************************************************/
47
48 void srv_calculate_sign_mac(struct smbd_server_connection *conn,
49                             char *outbuf, uint32_t seqnum)
50 {
51         /* Check if it's a non-session message. */
52         if(CVAL(outbuf,0)) {
53                 return;
54         }
55
56         smb_signing_sign_pdu(conn->signing_state, (uint8_t *)outbuf, seqnum);
57 }
58
59
60 /***********************************************************
61  Called to indicate a oneway request
62 ************************************************************/
63 void srv_cancel_sign_response(struct smbd_server_connection *conn)
64 {
65         smb_signing_cancel_reply(conn->signing_state, true);
66 }
67
68 /***********************************************************
69  Called by server negprot when signing has been negotiated.
70 ************************************************************/
71
72 bool srv_init_signing(struct smbd_server_connection *conn)
73 {
74         bool allowed = true;
75         bool mandatory = false;
76
77         switch (lp_server_signing()) {
78         case Required:
79                 mandatory = true;
80                 break;
81         case Auto:
82                 break;
83         case True:
84                 break;
85         case False:
86                 allowed = false;
87                 break;
88         }
89
90         conn->signing_state = smb_signing_init(smbd_event_context(),
91                                                allowed, mandatory);
92         if (!conn->signing_state) {
93                 return false;
94         }
95
96         return true;
97 }
98
99 void srv_set_signing_negotiated(struct smbd_server_connection *conn)
100 {
101         smb_signing_set_negotiated(conn->signing_state);
102 }
103
104 /***********************************************************
105  Returns whether signing is active. We can't use sendfile or raw
106  reads/writes if it is.
107 ************************************************************/
108
109 bool srv_is_signing_active(struct smbd_server_connection *conn)
110 {
111         return smb_signing_is_active(conn->signing_state);
112 }
113
114
115 /***********************************************************
116  Returns whether signing is negotiated. We can't use it unless it was
117  in the negprot.
118 ************************************************************/
119
120 bool srv_is_signing_negotiated(struct smbd_server_connection *conn)
121 {
122         return smb_signing_is_negotiated(conn->signing_state);
123 }
124
125 /***********************************************************
126  Turn on signing from this packet onwards.
127 ************************************************************/
128
129 void srv_set_signing(struct smbd_server_connection *conn,
130                      const DATA_BLOB user_session_key,
131                      const DATA_BLOB response)
132 {
133         bool negotiated;
134         bool mandatory;
135
136         if (!user_session_key.length)
137                 return;
138
139         negotiated = smb_signing_is_negotiated(conn->signing_state);
140         mandatory = smb_signing_is_mandatory(conn->signing_state);
141
142         if (!negotiated && !mandatory) {
143                 DEBUG(5,("srv_set_signing: signing negotiated = %u, "
144                          "mandatory_signing = %u. Not allowing smb signing.\n",
145                          negotiated, mandatory));
146                 return;
147         }
148
149         if (!smb_signing_activate(conn->signing_state,
150                                   user_session_key, response)) {
151                 return;
152         }
153
154         DEBUG(3,("srv_set_signing: turning on SMB signing: "
155                  "signing negotiated = %u, mandatory_signing = %u.\n",
156                  negotiated, mandatory));
157 }
158