diff options
author | Stefan Metzmacher <metze@samba.org> | 2011-10-19 13:47:39 +0200 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2011-10-21 10:22:39 +0200 |
commit | 75d146d3ed4196b0856ea6eb56482a1a67fdf707 (patch) | |
tree | 6b4f87364d14870be8b8a06be4e05c21d2c646e3 /source3/libsmb | |
parent | 321204eaeb05107b9a6d5ed464a11cd5018c97c6 (diff) | |
download | samba-75d146d3ed4196b0856ea6eb56482a1a67fdf707.tar.gz samba-75d146d3ed4196b0856ea6eb56482a1a67fdf707.tar.bz2 samba-75d146d3ed4196b0856ea6eb56482a1a67fdf707.zip |
libcli/smb: move smb_seal.c to the toplevel
metze
Autobuild-User: Stefan Metzmacher <metze@samba.org>
Autobuild-Date: Fri Oct 21 10:22:39 CEST 2011 on sn-devel-104
Diffstat (limited to 'source3/libsmb')
-rw-r--r-- | source3/libsmb/async_smb.c | 2 | ||||
-rw-r--r-- | source3/libsmb/clientgen.c | 2 | ||||
-rw-r--r-- | source3/libsmb/clifsinfo.c | 2 | ||||
-rw-r--r-- | source3/libsmb/smb_seal.c | 429 |
4 files changed, 3 insertions, 432 deletions
diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c index 43dfa22b9d..3786638a0d 100644 --- a/source3/libsmb/async_smb.c +++ b/source3/libsmb/async_smb.c @@ -23,7 +23,7 @@ #include "../lib/util/tevent_ntstatus.h" #include "../lib/util/tevent_unix.h" #include "async_smb.h" -#include "smb_crypt.h" +#include "../libcli/smb/smb_seal.h" #include "libsmb/nmblib.h" #include "read_smb.h" diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index e8f4fbd2fc..f5123eaf65 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -22,7 +22,7 @@ #include "libsmb/libsmb.h" #include "../lib/util/tevent_ntstatus.h" #include "smb_signing.h" -#include "smb_crypt.h" +#include "../libcli/smb/smb_seal.h" #include "async_smb.h" /******************************************************************* diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c index 2469200353..a5b7838b2a 100644 --- a/source3/libsmb/clifsinfo.c +++ b/source3/libsmb/clifsinfo.c @@ -24,7 +24,7 @@ #include "../auth/ntlmssp/ntlmssp.h" #include "../lib/util/tevent_ntstatus.h" #include "async_smb.h" -#include "smb_crypt.h" +#include "../libcli/smb/smb_seal.h" #include "trans2.h" #include "ntlmssp_wrap.h" #include "auth/gensec/gensec.h" diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c deleted file mode 100644 index e27f609d39..0000000000 --- a/source3/libsmb/smb_seal.c +++ /dev/null @@ -1,429 +0,0 @@ -/* - Unix SMB/CIFS implementation. - SMB Transport encryption (sealing) code. - Copyright (C) Jeremy Allison 2007. - - 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 3 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, see <http://www.gnu.org/licenses/>. -*/ - -#include "includes.h" -#include "smb_crypt.h" -#include "libsmb/libsmb.h" -#include "libcli/auth/krb5_wrap.h" -#include "auth/gensec/gensec.h" - -#undef malloc - -/****************************************************************************** - Pull out the encryption context for this packet. 0 means global context. -******************************************************************************/ - -NTSTATUS get_enc_ctx_num(const uint8_t *buf, uint16_t *p_enc_ctx_num) -{ - if (smb_len_nbt(buf) < 8) { - return NT_STATUS_INVALID_BUFFER_SIZE; - } - - if (buf[4] == 0xFF) { - if (buf[5] == 'S' && buf [6] == 'M' && buf[7] == 'B') { - /* Not an encrypted buffer. */ - return NT_STATUS_NOT_FOUND; - } - if (buf[5] == 'E') { - *p_enc_ctx_num = SVAL(buf,6); - return NT_STATUS_OK; - } - } - return NT_STATUS_INVALID_NETWORK_RESPONSE; -} - -/******************************************************************* - Set the length and marker of an encrypted smb packet. -********************************************************************/ - -static void smb_set_enclen(char *buf,int len,uint16_t enc_ctx_num) -{ - _smb_setlen_nbt(buf,len); - - SCVAL(buf,4,0xFF); - SCVAL(buf,5,'E'); - SSVAL(buf,6,enc_ctx_num); -} - -/****************************************************************************** - Generic code for client and server. - Is encryption turned on ? -******************************************************************************/ - -bool common_encryption_on(struct smb_trans_enc_state *es) -{ - return ((es != NULL) && es->enc_on); -} - -/****************************************************************************** - Generic code for client and server. - GENSEC decrypt an incoming buffer. -******************************************************************************/ - -static NTSTATUS common_gensec_decrypt_buffer(struct gensec_security *gensec, - char *buf) -{ - NTSTATUS status; - size_t buf_len = smb_len_nbt(buf) + 4; /* Don't forget the 4 length bytes. */ - DATA_BLOB in_buf, out_buf; - TALLOC_CTX *frame; - - if (buf_len < 8) { - return NT_STATUS_BUFFER_TOO_SMALL; - } - - frame = talloc_stackframe(); - - in_buf = data_blob_const(buf + 8, buf_len - 8); - - status = gensec_unwrap(gensec, frame, &in_buf, &out_buf); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("common_gensec_decrypt_buffer: gensec_unwrap failed. Error %s\n", - nt_errstr(status))); - TALLOC_FREE(frame); - return status; - } - - if (out_buf.length > in_buf.length) { - DEBUG(0,("common_gensec_decrypt_buffer: gensec_unwrap size (%u) too large (%u) !\n", - (unsigned int)out_buf.length, - (unsigned int)in_buf.length )); - TALLOC_FREE(frame); - return NT_STATUS_INVALID_PARAMETER; - } - - memcpy(buf + 8, out_buf.data, out_buf.length); - - /* Reset the length and overwrite the header. */ - smb_setlen_nbt(buf, out_buf.length + 4); - - TALLOC_FREE(frame); - - return NT_STATUS_OK; -} - -/****************************************************************************** - Generic code for client and server. - NTLM encrypt an outgoing buffer. Return the encrypted pointer in ppbuf_out. -******************************************************************************/ - -static NTSTATUS common_gensec_encrypt_buffer(struct gensec_security *gensec, - uint16_t enc_ctx_num, - char *buf, - char **ppbuf_out) -{ - NTSTATUS status; - DATA_BLOB in_buf, out_buf; - size_t buf_len = smb_len_nbt(buf) + 4; /* Don't forget the 4 length bytes. */ - TALLOC_CTX *frame; - - *ppbuf_out = NULL; - - if (buf_len < 8) { - return NT_STATUS_BUFFER_TOO_SMALL; - } - in_buf = data_blob_const(buf + 8, buf_len - 8); - - frame = talloc_stackframe(); - - status = gensec_wrap(gensec, frame, &in_buf, &out_buf); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("common_gensec_encrypt_buffer: gensec_wrap failed. Error %s\n", - nt_errstr(status))); - TALLOC_FREE(frame); - return status; - } - - *ppbuf_out = (char *)malloc(out_buf.length + 8); /* We know this can't wrap. */ - if (!*ppbuf_out) { - TALLOC_FREE(frame); - return NT_STATUS_NO_MEMORY; - } - - memcpy(*ppbuf_out+8, out_buf.data, out_buf.length); - smb_set_enclen(*ppbuf_out, out_buf.length + 4, enc_ctx_num); - - TALLOC_FREE(frame); - - return NT_STATUS_OK; -} - -/****************************************************************************** - Generic code for client and server. - gss-api decrypt an incoming buffer. We insist that the size of the - unwrapped buffer must be smaller or identical to the incoming buffer. -******************************************************************************/ - -#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) -static NTSTATUS common_gss_decrypt_buffer(struct smb_tran_enc_state_gss *gss_state, char *buf) -{ - gss_ctx_id_t gss_ctx = gss_state->gss_ctx; - OM_uint32 ret = 0; - OM_uint32 minor = 0; - int flags_got = 0; - gss_buffer_desc in_buf, out_buf; - size_t buf_len = smb_len_nbt(buf) + 4; /* Don't forget the 4 length bytes. */ - - if (buf_len < 8) { - return NT_STATUS_BUFFER_TOO_SMALL; - } - - in_buf.value = buf + 8; - in_buf.length = buf_len - 8; - - ret = gss_unwrap(&minor, - gss_ctx, - &in_buf, - &out_buf, - &flags_got, /* did we get sign+seal ? */ - (gss_qop_t *) NULL); - - if (ret != GSS_S_COMPLETE) { - NTSTATUS status = NT_STATUS_ACCESS_DENIED; - char *gss_err; - - gss_err = gssapi_error_string(talloc_tos(), - ret, minor, - GSS_C_NULL_OID); - DEBUG(0,("common_gss_decrypt_buffer: gss_unwrap failed. " - "Error [%d/%d] - %s - %s\n", - ret, minor, nt_errstr(status), - gss_err ? gss_err : "<unknown>")); - talloc_free(gss_err); - - return status; - } - - if (out_buf.length > in_buf.length) { - DEBUG(0,("common_gss_decrypt_buffer: gss_unwrap size (%u) too large (%u) !\n", - (unsigned int)out_buf.length, - (unsigned int)in_buf.length )); - gss_release_buffer(&minor, &out_buf); - return NT_STATUS_INVALID_PARAMETER; - } - - memcpy(buf + 8, out_buf.value, out_buf.length); - /* Reset the length and overwrite the header. */ - smb_setlen_nbt(buf, out_buf.length + 4); - - gss_release_buffer(&minor, &out_buf); - return NT_STATUS_OK; -} - -/****************************************************************************** - Generic code for client and server. - gss-api encrypt an outgoing buffer. Return the alloced encrypted pointer in buf_out. -******************************************************************************/ - -static NTSTATUS common_gss_encrypt_buffer(struct smb_tran_enc_state_gss *gss_state, - uint16_t enc_ctx_num, - char *buf, - char **ppbuf_out) -{ - gss_ctx_id_t gss_ctx = gss_state->gss_ctx; - OM_uint32 ret = 0; - OM_uint32 minor = 0; - int flags_got = 0; - gss_buffer_desc in_buf, out_buf; - size_t buf_len = smb_len_nbt(buf) + 4; /* Don't forget the 4 length bytes. */ - - *ppbuf_out = NULL; - - if (buf_len < 8) { - return NT_STATUS_BUFFER_TOO_SMALL; - } - - in_buf.value = buf + 8; - in_buf.length = buf_len - 8; - - ret = gss_wrap(&minor, - gss_ctx, - true, /* we want sign+seal. */ - GSS_C_QOP_DEFAULT, - &in_buf, - &flags_got, /* did we get sign+seal ? */ - &out_buf); - - if (ret != GSS_S_COMPLETE) { - NTSTATUS status = NT_STATUS_ACCESS_DENIED; - char *gss_err; - - gss_err = gssapi_error_string(talloc_tos(), - ret, minor, - GSS_C_NULL_OID); - DEBUG(0,("common_gss_encrypt_buffer: gss_unwrap failed. " - "Error [%d/%d] - %s - %s\n", - ret, minor, nt_errstr(status), - gss_err ? gss_err : "<unknown>")); - talloc_free(gss_err); - - return status; - } - - if (!flags_got) { - /* Sign+seal not supported. */ - gss_release_buffer(&minor, &out_buf); - return NT_STATUS_NOT_SUPPORTED; - } - - /* Ya see - this is why I *hate* gss-api. I don't - * want to have to malloc another buffer of the - * same size + 8 bytes just to get a continuous - * header + buffer, but gss won't let me pass in - * a pre-allocated buffer. Bastards (and you know - * who you are....). I might fix this by - * going to "encrypt_and_send" passing in a file - * descriptor and doing scatter-gather write with - * TCP cork on Linux. But I shouldn't have to - * bother :-*(. JRA. - */ - - *ppbuf_out = (char *)malloc(out_buf.length + 8); /* We know this can't wrap. */ - if (!*ppbuf_out) { - gss_release_buffer(&minor, &out_buf); - return NT_STATUS_NO_MEMORY; - } - - memcpy(*ppbuf_out+8, out_buf.value, out_buf.length); - smb_set_enclen(*ppbuf_out, out_buf.length + 4, enc_ctx_num); - - gss_release_buffer(&minor, &out_buf); - return NT_STATUS_OK; -} -#endif - -/****************************************************************************** - Generic code for client and server. - Encrypt an outgoing buffer. Return the alloced encrypted pointer in buf_out. -******************************************************************************/ - -NTSTATUS common_encrypt_buffer(struct smb_trans_enc_state *es, char *buffer, char **buf_out) -{ - if (!common_encryption_on(es)) { - /* Not encrypting. */ - *buf_out = buffer; - return NT_STATUS_OK; - } - - switch (es->smb_enc_type) { - case SMB_TRANS_ENC_NTLM: - return common_gensec_encrypt_buffer(es->s.gensec_security, es->enc_ctx_num, buffer, buf_out); -#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) - case SMB_TRANS_ENC_GSS: - return common_gss_encrypt_buffer(es->s.gss_state, es->enc_ctx_num, buffer, buf_out); -#endif - default: - return NT_STATUS_NOT_SUPPORTED; - } -} - -/****************************************************************************** - Generic code for client and server. - Decrypt an incoming SMB buffer. Replaces the data within it. - New data must be less than or equal to the current length. -******************************************************************************/ - -NTSTATUS common_decrypt_buffer(struct smb_trans_enc_state *es, char *buf) -{ - if (!common_encryption_on(es)) { - /* Not decrypting. */ - return NT_STATUS_OK; - } - - switch (es->smb_enc_type) { - case SMB_TRANS_ENC_NTLM: - return common_gensec_decrypt_buffer(es->s.gensec_security, buf); -#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) - case SMB_TRANS_ENC_GSS: - return common_gss_decrypt_buffer(es->s.gss_state, buf); -#endif - default: - return NT_STATUS_NOT_SUPPORTED; - } -} - -#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) -/****************************************************************************** - Shutdown a gss encryption state. -******************************************************************************/ - -static void common_free_gss_state(struct smb_tran_enc_state_gss **pp_gss_state) -{ - OM_uint32 minor = 0; - struct smb_tran_enc_state_gss *gss_state = *pp_gss_state; - - if (gss_state->creds != GSS_C_NO_CREDENTIAL) { - gss_release_cred(&minor, &gss_state->creds); - } - if (gss_state->gss_ctx != GSS_C_NO_CONTEXT) { - gss_delete_sec_context(&minor, &gss_state->gss_ctx, NULL); - } - SAFE_FREE(*pp_gss_state); -} -#endif - -/****************************************************************************** - Shutdown an encryption state. -******************************************************************************/ - -void common_free_encryption_state(struct smb_trans_enc_state **pp_es) -{ - struct smb_trans_enc_state *es = *pp_es; - - if (es == NULL) { - return; - } - - if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) { - if (es->s.gensec_security) { - TALLOC_FREE(es->s.gensec_security); - } - } -#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) - if (es->smb_enc_type == SMB_TRANS_ENC_GSS) { - /* Free the gss context handle. */ - if (es->s.gss_state) { - common_free_gss_state(&es->s.gss_state); - } - } -#endif - SAFE_FREE(es); - *pp_es = NULL; -} - -/****************************************************************************** - Free an encryption-allocated buffer. -******************************************************************************/ - -void common_free_enc_buffer(struct smb_trans_enc_state *es, char *buf) -{ - uint16_t enc_ctx_num; - - if (!common_encryption_on(es)) { - return; - } - - if (!NT_STATUS_IS_OK(get_enc_ctx_num((const uint8_t *)buf, - &enc_ctx_num))) { - return; - } - - SAFE_FREE(buf); -} |