r21883: Try and fix the build by removing the prototypes for
[samba.git] / source / libsmb / smb_seal.c
1 /* 
2    Unix SMB/CIFS implementation.
3    SMB Transport encryption (sealing) code.
4    Copyright (C) Jeremy Allison 2007.
5    
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10    
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15    
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include "includes.h"
22
23 /******************************************************************************
24  Generic code for client and server.
25  Is encryption turned on ?
26 ******************************************************************************/
27
28 BOOL common_encryption_on(struct smb_trans_enc_state *es)
29 {
30         return ((es != NULL) && es->enc_on);
31 }
32
33 /******************************************************************************
34  Generic code for client and server.
35  NTLM decrypt an incoming buffer.
36 ******************************************************************************/
37
38 NTSTATUS common_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf)
39 {
40         NTSTATUS status;
41         size_t orig_len = smb_len(buf);
42         size_t new_len = orig_len - NTLMSSP_SIG_SIZE;
43         DATA_BLOB sig;
44
45         if (orig_len < 8 + NTLMSSP_SIG_SIZE) {
46                 return NT_STATUS_BUFFER_TOO_SMALL;
47         }
48
49         /* Save off the signature. */
50         sig = data_blob(buf+orig_len-NTLMSSP_SIG_SIZE, NTLMSSP_SIG_SIZE);
51
52         status = ntlmssp_unseal_packet(ntlmssp_state,
53                 (unsigned char *)buf + 8, /* 4 byte len + 0xFF 'S' 'M' 'B' */
54                 new_len - 8,
55                 (unsigned char *)buf,
56                 new_len,
57                 &sig);
58
59         if (!NT_STATUS_IS_OK(status)) {
60                 data_blob_free(&sig);
61                 return status;
62         }
63         /* Reset the length. */
64         smb_setlen(buf, new_len);
65         return NT_STATUS_OK;
66 }
67
68 /******************************************************************************
69  Generic code for client and server.
70  NTLM encrypt an outgoing buffer. Return the encrypted pointer in ppbuf_out.
71 ******************************************************************************/
72
73 NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, char **ppbuf_out)
74 {
75         NTSTATUS status;
76         char *buf_out;
77         size_t orig_len = smb_len(buf);
78         size_t new_len = orig_len + NTLMSSP_SIG_SIZE;
79         DATA_BLOB sig;
80
81         *ppbuf_out = NULL;
82
83         if (orig_len < 8) {
84                 return NT_STATUS_BUFFER_TOO_SMALL;
85         }
86
87         /* 
88          * We know smb_len can't return a value > 128k, so no int overflow
89          * check needed.
90          */
91
92         /* Copy the original buffer. */
93
94         buf_out = SMB_XMALLOC_ARRAY(char, new_len);
95         memcpy(buf_out, buf, orig_len);
96         /* Last 16 bytes undefined here... */
97
98         smb_setlen(buf_out, new_len);
99
100         sig = data_blob(NULL, NTLMSSP_SIG_SIZE);
101
102         status = ntlmssp_seal_packet(ntlmssp_state,
103                 (unsigned char *)buf_out + 8, /* 4 byte len + 0xFF 'S' 'M' 'B' */
104                 orig_len - 8,
105                 (unsigned char *)buf_out,
106                 orig_len,
107                 &sig);
108
109         if (!NT_STATUS_IS_OK(status)) {
110                 data_blob_free(&sig);
111                 SAFE_FREE(buf_out);
112                 return status;
113         }
114
115         memcpy(buf_out+orig_len, sig.data, NTLMSSP_SIG_SIZE);
116         *ppbuf_out = buf_out;
117         return NT_STATUS_OK;
118 }
119
120 /******************************************************************************
121  Generic code for client and server.
122  gss-api decrypt an incoming buffer.
123 ******************************************************************************/
124
125 #if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5)
126  NTSTATUS common_gss_decrypt_buffer(gss_ctx_id_t context_handle, char *buf)
127 {
128         return NT_STATUS_NOT_SUPPORTED;
129 }
130 #endif
131
132 /******************************************************************************
133  Generic code for client and server.
134  gss-api encrypt an outgoing buffer. Return the alloced encrypted pointer in buf_out.
135 ******************************************************************************/
136
137 #if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5)
138  NTSTATUS common_gss_encrypt_buffer(gss_ctx_id_t context_handle, char *buf, char **buf_out)
139 {
140         return NT_STATUS_NOT_SUPPORTED;
141 }
142 #endif
143
144 /******************************************************************************
145  Generic code for client and server.
146  Encrypt an outgoing buffer. Return the alloced encrypted pointer in buf_out.
147 ******************************************************************************/
148
149 NTSTATUS common_encrypt_buffer(struct smb_trans_enc_state *es, char *buffer, char **buf_out)
150 {
151         if (!common_encryption_on(es)) {
152                 /* Not encrypting. */
153                 *buf_out = buffer;
154                 return NT_STATUS_OK;
155         }
156
157         if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) {
158                 return common_ntlm_encrypt_buffer(es->ntlmssp_state, buffer, buf_out);
159         } else {
160 #if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5)
161                 return common_gss_encrypt_buffer(es->context_handle, buffer, buf_out);
162 #else
163                 return NT_STATUS_NOT_SUPPORTED;
164 #endif
165         }
166 }
167
168 /******************************************************************************
169  Generic code for client and server.
170  Decrypt an incoming SMB buffer. Replaces the data within it.
171  New data must be less than or equal to the current length.
172 ******************************************************************************/
173
174 NTSTATUS common_decrypt_buffer(struct smb_trans_enc_state *es, char *buf)
175 {
176         if (!common_encryption_on(es)) {
177                 /* Not decrypting. */
178                 return NT_STATUS_OK;
179         }
180         if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) {
181                 return common_ntlm_decrypt_buffer(es->ntlmssp_state, buf);
182         } else {
183 #if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5)
184                 return common_gss_decrypt_buffer(es->context_handle, buf);
185 #else
186                 return NT_STATUS_NOT_SUPPORTED;
187 #endif
188         }
189 }
190
191 /******************************************************************************
192  Shutdown an encryption state.
193 ******************************************************************************/
194
195 void common_free_encryption_state(struct smb_trans_enc_state **pp_es)
196 {
197         struct smb_trans_enc_state *es = *pp_es;
198
199         if (es == NULL) {
200                 return;
201         }
202
203         if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) {
204                 if (es->ntlmssp_state) {
205                         ntlmssp_end(&es->ntlmssp_state);
206                 }
207         }
208 #if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5)
209         if (es->smb_enc_type == SMB_TRANS_ENC_GSS) {
210                 /* Free the gss context handle. */
211         }
212 #endif
213         SAFE_FREE(es);
214         *pp_es = NULL;
215 }
216
217 /******************************************************************************
218  Free an encryption-allocated buffer.
219 ******************************************************************************/
220
221 void common_free_enc_buffer(struct smb_trans_enc_state *es, char *buf)
222 {
223         if (!common_encryption_on(es)) {
224                 return;
225         }
226
227         if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) {
228                 SAFE_FREE(buf);
229                 return;
230         }
231
232 #if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5)
233         /* gss-api free buffer.... */
234 #endif
235 }
236
237 /******************************************************************************
238  Client side encryption.
239 ******************************************************************************/
240
241 /******************************************************************************
242  Is client encryption on ?
243 ******************************************************************************/
244
245 BOOL cli_encryption_on(struct cli_state *cli)
246 {
247         return common_encryption_on(cli->trans_enc_state);
248 }
249
250 /******************************************************************************
251  Shutdown a client encryption state.
252 ******************************************************************************/
253
254 void cli_free_encryption_context(struct cli_state *cli)
255 {
256         return common_free_encryption_state(&cli->trans_enc_state);
257 }
258
259 /******************************************************************************
260  Free an encryption-allocated buffer.
261 ******************************************************************************/
262
263 void cli_free_enc_buffer(struct cli_state *cli, char *buf)
264 {
265         return common_free_enc_buffer(cli->trans_enc_state, buf);
266 }
267
268 /******************************************************************************
269  Decrypt an incoming buffer.
270 ******************************************************************************/
271
272 NTSTATUS cli_decrypt_message(struct cli_state *cli)
273 {
274         return common_decrypt_buffer(cli->trans_enc_state, cli->inbuf);
275 }
276
277 /******************************************************************************
278  Encrypt an outgoing buffer. Return the encrypted pointer in buf_out.
279 ******************************************************************************/
280
281 NTSTATUS cli_encrypt_message(struct cli_state *cli, char **buf_out)
282 {
283         return common_encrypt_buffer(cli->trans_enc_state, cli->outbuf, buf_out);
284 }