2 Unix SMB/CIFS implementation.
3 SMB Transport encryption (sealing) code.
4 Copyright (C) Jeremy Allison 2007.
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 3 of the License, or
9 (at your option) any later version.
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.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "../auth/ntlmssp/ntlmssp.h"
22 #include "smb_crypt.h"
23 #include "libsmb/libsmb.h"
24 #include "ntlmssp_wrap.h"
25 #include "libcli/auth/krb5_wrap.h"
26 #include "auth/gensec/gensec.h"
30 /******************************************************************************
31 Pull out the encryption context for this packet. 0 means global context.
32 ******************************************************************************/
34 NTSTATUS get_enc_ctx_num(const uint8_t *buf, uint16_t *p_enc_ctx_num)
36 if (smb_len_nbt(buf) < 8) {
37 return NT_STATUS_INVALID_BUFFER_SIZE;
41 if (buf[5] == 'S' && buf [6] == 'M' && buf[7] == 'B') {
42 /* Not an encrypted buffer. */
43 return NT_STATUS_NOT_FOUND;
46 *p_enc_ctx_num = SVAL(buf,6);
50 return NT_STATUS_INVALID_NETWORK_RESPONSE;
53 /*******************************************************************
54 Set the length and marker of an encrypted smb packet.
55 ********************************************************************/
57 static void smb_set_enclen(char *buf,int len,uint16_t enc_ctx_num)
59 _smb_setlen_nbt(buf,len);
63 SSVAL(buf,6,enc_ctx_num);
66 /******************************************************************************
67 Generic code for client and server.
68 Is encryption turned on ?
69 ******************************************************************************/
71 bool common_encryption_on(struct smb_trans_enc_state *es)
73 return ((es != NULL) && es->enc_on);
76 /******************************************************************************
77 Generic code for client and server.
78 NTLM decrypt an incoming buffer.
79 Abartlett tells me that SSPI puts the signature first before the encrypted
80 output, so cope with the same for compatibility.
81 ******************************************************************************/
83 static NTSTATUS common_ntlm_decrypt_buffer(struct auth_ntlmssp_state *auth_ntlmssp_state, char *buf)
85 struct gensec_security *gensec = auth_ntlmssp_state->gensec_security;
87 size_t buf_len = smb_len_nbt(buf) + 4; /* Don't forget the 4 length bytes. */
88 DATA_BLOB in_buf, out_buf;
92 return NT_STATUS_BUFFER_TOO_SMALL;
95 frame = talloc_stackframe();
97 in_buf = data_blob_const(buf + 8, buf_len - 8);
99 status = gensec_unwrap(gensec, frame, &in_buf, &out_buf);
101 if (!NT_STATUS_IS_OK(status)) {
102 DEBUG(0,("common_ntlm_decrypt_buffer: gensec_unwrap failed. Error %s\n",
108 if (out_buf.length > in_buf.length) {
109 DEBUG(0,("common_ntlm_decrypt_buffer: gensec_unwrap size (%u) too large (%u) !\n",
110 (unsigned int)out_buf.length,
111 (unsigned int)in_buf.length ));
113 return NT_STATUS_INVALID_PARAMETER;
116 memcpy(buf + 8, out_buf.data, out_buf.length);
118 /* Reset the length and overwrite the header. */
119 smb_setlen_nbt(buf, out_buf.length + 4);
126 /******************************************************************************
127 Generic code for client and server.
128 NTLM encrypt an outgoing buffer. Return the encrypted pointer in ppbuf_out.
129 Abartlett tells me that SSPI puts the signature first before the encrypted
130 output, so do the same for compatibility.
131 ******************************************************************************/
133 static NTSTATUS common_ntlm_encrypt_buffer(struct auth_ntlmssp_state *auth_ntlmssp_state,
134 uint16_t enc_ctx_num,
138 struct gensec_security *gensec = auth_ntlmssp_state->gensec_security;
140 DATA_BLOB in_buf, out_buf;
141 size_t buf_len = smb_len_nbt(buf) + 4; /* Don't forget the 4 length bytes. */
147 return NT_STATUS_BUFFER_TOO_SMALL;
149 in_buf = data_blob_const(buf + 8, buf_len - 8);
151 frame = talloc_stackframe();
153 status = gensec_wrap(gensec, frame, &in_buf, &out_buf);
154 if (!NT_STATUS_IS_OK(status)) {
155 DEBUG(0,("common_ntlm_encrypt_buffer: gensec_wrap failed. Error %s\n",
161 *ppbuf_out = (char *)malloc(out_buf.length + 8); /* We know this can't wrap. */
164 return NT_STATUS_NO_MEMORY;
167 memcpy(*ppbuf_out+8, out_buf.data, out_buf.length);
168 smb_set_enclen(*ppbuf_out, out_buf.length + 4, enc_ctx_num);
175 /******************************************************************************
176 Generic code for client and server.
177 gss-api decrypt an incoming buffer. We insist that the size of the
178 unwrapped buffer must be smaller or identical to the incoming buffer.
179 ******************************************************************************/
181 #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
182 static NTSTATUS common_gss_decrypt_buffer(struct smb_tran_enc_state_gss *gss_state, char *buf)
184 gss_ctx_id_t gss_ctx = gss_state->gss_ctx;
188 gss_buffer_desc in_buf, out_buf;
189 size_t buf_len = smb_len_nbt(buf) + 4; /* Don't forget the 4 length bytes. */
192 return NT_STATUS_BUFFER_TOO_SMALL;
195 in_buf.value = buf + 8;
196 in_buf.length = buf_len - 8;
198 ret = gss_unwrap(&minor,
202 &flags_got, /* did we get sign+seal ? */
205 if (ret != GSS_S_COMPLETE) {
206 NTSTATUS status = NT_STATUS_ACCESS_DENIED;
209 gss_err = gssapi_error_string(talloc_tos(),
212 DEBUG(0,("common_gss_decrypt_buffer: gss_unwrap failed. "
213 "Error [%d/%d] - %s - %s\n",
214 ret, minor, nt_errstr(status),
215 gss_err ? gss_err : "<unknown>"));
216 talloc_free(gss_err);
221 if (out_buf.length > in_buf.length) {
222 DEBUG(0,("common_gss_decrypt_buffer: gss_unwrap size (%u) too large (%u) !\n",
223 (unsigned int)out_buf.length,
224 (unsigned int)in_buf.length ));
225 gss_release_buffer(&minor, &out_buf);
226 return NT_STATUS_INVALID_PARAMETER;
229 memcpy(buf + 8, out_buf.value, out_buf.length);
230 /* Reset the length and overwrite the header. */
231 smb_setlen_nbt(buf, out_buf.length + 4);
233 gss_release_buffer(&minor, &out_buf);
237 /******************************************************************************
238 Generic code for client and server.
239 gss-api encrypt an outgoing buffer. Return the alloced encrypted pointer in buf_out.
240 ******************************************************************************/
242 static NTSTATUS common_gss_encrypt_buffer(struct smb_tran_enc_state_gss *gss_state,
243 uint16_t enc_ctx_num,
247 gss_ctx_id_t gss_ctx = gss_state->gss_ctx;
251 gss_buffer_desc in_buf, out_buf;
252 size_t buf_len = smb_len_nbt(buf) + 4; /* Don't forget the 4 length bytes. */
257 return NT_STATUS_BUFFER_TOO_SMALL;
260 in_buf.value = buf + 8;
261 in_buf.length = buf_len - 8;
263 ret = gss_wrap(&minor,
265 true, /* we want sign+seal. */
268 &flags_got, /* did we get sign+seal ? */
271 if (ret != GSS_S_COMPLETE) {
272 NTSTATUS status = NT_STATUS_ACCESS_DENIED;
275 gss_err = gssapi_error_string(talloc_tos(),
278 DEBUG(0,("common_gss_encrypt_buffer: gss_unwrap failed. "
279 "Error [%d/%d] - %s - %s\n",
280 ret, minor, nt_errstr(status),
281 gss_err ? gss_err : "<unknown>"));
282 talloc_free(gss_err);
288 /* Sign+seal not supported. */
289 gss_release_buffer(&minor, &out_buf);
290 return NT_STATUS_NOT_SUPPORTED;
293 /* Ya see - this is why I *hate* gss-api. I don't
294 * want to have to malloc another buffer of the
295 * same size + 8 bytes just to get a continuous
296 * header + buffer, but gss won't let me pass in
297 * a pre-allocated buffer. Bastards (and you know
298 * who you are....). I might fix this by
299 * going to "encrypt_and_send" passing in a file
300 * descriptor and doing scatter-gather write with
301 * TCP cork on Linux. But I shouldn't have to
305 *ppbuf_out = (char *)malloc(out_buf.length + 8); /* We know this can't wrap. */
307 gss_release_buffer(&minor, &out_buf);
308 return NT_STATUS_NO_MEMORY;
311 memcpy(*ppbuf_out+8, out_buf.value, out_buf.length);
312 smb_set_enclen(*ppbuf_out, out_buf.length + 4, enc_ctx_num);
314 gss_release_buffer(&minor, &out_buf);
319 /******************************************************************************
320 Generic code for client and server.
321 Encrypt an outgoing buffer. Return the alloced encrypted pointer in buf_out.
322 ******************************************************************************/
324 NTSTATUS common_encrypt_buffer(struct smb_trans_enc_state *es, char *buffer, char **buf_out)
326 if (!common_encryption_on(es)) {
327 /* Not encrypting. */
332 switch (es->smb_enc_type) {
333 case SMB_TRANS_ENC_NTLM:
334 return common_ntlm_encrypt_buffer(es->s.auth_ntlmssp_state, es->enc_ctx_num, buffer, buf_out);
335 #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
336 case SMB_TRANS_ENC_GSS:
337 return common_gss_encrypt_buffer(es->s.gss_state, es->enc_ctx_num, buffer, buf_out);
340 return NT_STATUS_NOT_SUPPORTED;
344 /******************************************************************************
345 Generic code for client and server.
346 Decrypt an incoming SMB buffer. Replaces the data within it.
347 New data must be less than or equal to the current length.
348 ******************************************************************************/
350 NTSTATUS common_decrypt_buffer(struct smb_trans_enc_state *es, char *buf)
352 if (!common_encryption_on(es)) {
353 /* Not decrypting. */
357 switch (es->smb_enc_type) {
358 case SMB_TRANS_ENC_NTLM:
359 return common_ntlm_decrypt_buffer(es->s.auth_ntlmssp_state, buf);
360 #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
361 case SMB_TRANS_ENC_GSS:
362 return common_gss_decrypt_buffer(es->s.gss_state, buf);
365 return NT_STATUS_NOT_SUPPORTED;
369 #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
370 /******************************************************************************
371 Shutdown a gss encryption state.
372 ******************************************************************************/
374 static void common_free_gss_state(struct smb_tran_enc_state_gss **pp_gss_state)
377 struct smb_tran_enc_state_gss *gss_state = *pp_gss_state;
379 if (gss_state->creds != GSS_C_NO_CREDENTIAL) {
380 gss_release_cred(&minor, &gss_state->creds);
382 if (gss_state->gss_ctx != GSS_C_NO_CONTEXT) {
383 gss_delete_sec_context(&minor, &gss_state->gss_ctx, NULL);
385 SAFE_FREE(*pp_gss_state);
389 /******************************************************************************
390 Shutdown an encryption state.
391 ******************************************************************************/
393 void common_free_encryption_state(struct smb_trans_enc_state **pp_es)
395 struct smb_trans_enc_state *es = *pp_es;
401 if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) {
402 if (es->s.auth_ntlmssp_state) {
403 TALLOC_FREE(es->s.auth_ntlmssp_state);
406 #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
407 if (es->smb_enc_type == SMB_TRANS_ENC_GSS) {
408 /* Free the gss context handle. */
409 if (es->s.gss_state) {
410 common_free_gss_state(&es->s.gss_state);
418 /******************************************************************************
419 Free an encryption-allocated buffer.
420 ******************************************************************************/
422 void common_free_enc_buffer(struct smb_trans_enc_state *es, char *buf)
424 uint16_t enc_ctx_num;
426 if (!common_encryption_on(es)) {
430 if (!NT_STATUS_IS_OK(get_enc_ctx_num((const uint8_t *)buf,