From ecd496f06654e8316260c9a6ddab5e473f9cc452 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 17 Mar 2007 00:32:54 +0000 Subject: r21865: Add in the stubs for SMB transport encryption. Will flesh these out as I implement. Don't add to SAMBA_3_0_25, this is experimental code. NFSv4 you're now officially on notice... :-). Jeremy. (This used to be commit 5bfe638f2172e272741997100ee5ae8ff280494d) --- source3/libsmb/smb_seal.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 source3/libsmb/smb_seal.c (limited to 'source3/libsmb/smb_seal.c') diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c new file mode 100644 index 0000000000..eb35fc05f9 --- /dev/null +++ b/source3/libsmb/smb_seal.c @@ -0,0 +1,41 @@ +/* + 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 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" + +NTSTATUS cli_decrypt_message(struct cli_state *cli) +{ + return NT_STATUS_OK; +} + +NTSTATUS cli_encrypt_message(struct cli_state *cli) +{ + return NT_STATUS_OK; +} + +NTSTATUS srv_decrypt_buffer(char *buffer) +{ + return NT_STATUS_OK; +} + +NTSTATUS srv_encrypt_buffer(char *buffer) +{ + return NT_STATUS_OK; +} -- cgit From c48b610b516b72edd6232235a6f83d388f5a0552 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 19 Mar 2007 20:39:58 +0000 Subject: r21876: Start adding in the seal implementation - prototype code for the server side enc. (doesn't break anything). I'll keep updating this until I've got NTLM seal working on both client and server, then add in the gss level seal. Jeremy. (This used to be commit 530ac29abf23e920baa549e7cec55199edd8bd74) --- source3/libsmb/smb_seal.c | 178 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 176 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/smb_seal.c') diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index eb35fc05f9..90efa05f0b 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -30,12 +30,186 @@ NTSTATUS cli_encrypt_message(struct cli_state *cli) return NT_STATUS_OK; } -NTSTATUS srv_decrypt_buffer(char *buffer) +/* Server state if we're encrypting SMBs. If NULL then enc is off. */ + +static struct smb_trans_enc_state *srv_trans_enc_state; + +/****************************************************************************** + Is server encryption on ? +******************************************************************************/ + +BOOL srv_encryption_on(void) +{ + return srv_trans_enc_state != NULL; +} + +/****************************************************************************** + Free an encryption-allocated buffer. +******************************************************************************/ + +void srv_free_buffer(char *buf_out) { + if (!srv_trans_enc_state) { + return; + } + + if (srv_trans_enc_state->smb_enc_type == SMB_TRANS_ENC_NTLM) { + SAFE_FREE(buf_out); + return; + } + +#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) + /* gss-api free buffer.... */ +#endif +} + +/****************************************************************************** + gss-api decrypt an incoming buffer. +******************************************************************************/ + +#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) +static NTSTATUS srv_gss_decrypt_buffer(gss_ctx_id_t context_handle, char *buf) +{ + return NT_STATUS_NOT_SUPPORTED; +} +#endif + +/****************************************************************************** + NTLM decrypt an incoming buffer. +******************************************************************************/ + +static NTSTATUS srv_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf) +{ + NTSTATUS status; + size_t orig_len = smb_len(buf); + size_t new_len = orig_len - NTLMSSP_SIG_SIZE; + DATA_BLOB sig; + + if (orig_len < 8 + NTLMSSP_SIG_SIZE) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + + /* Save off the signature. */ + sig = data_blob(buf+orig_len-NTLMSSP_SIG_SIZE, NTLMSSP_SIG_SIZE); + + status = ntlmssp_unseal_packet(ntlmssp_state, + (unsigned char *)buf + 8, /* 4 byte len + 0xFF 'S' 'M' 'B' */ + new_len - 8, + (unsigned char *)buf, + new_len, + &sig); + + if (!NT_STATUS_IS_OK(status)) { + data_blob_free(&sig); + return status; + } + /* Reset the length. */ + smb_setlen(buf, new_len); return NT_STATUS_OK; } -NTSTATUS srv_encrypt_buffer(char *buffer) +/****************************************************************************** + Decrypt an incoming buffer. +******************************************************************************/ + +NTSTATUS srv_decrypt_buffer(char *buf) { + if (!srv_trans_enc_state) { + /* Not decrypting. */ + return NT_STATUS_OK; + } + if (srv_trans_enc_state->smb_enc_type == SMB_TRANS_ENC_NTLM) { + return srv_ntlm_decrypt_buffer(srv_trans_enc_state->ntlmssp_state, buf); + } else { +#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) + return srv_gss_decrypt_buffer(srv_trans_enc_state->context_handle, buf); +#else + return NT_STATUS_NOT_SUPPORTED; +#endif + } +} + +/****************************************************************************** + gss-api encrypt an outgoing buffer. Return the encrypted pointer in buf_out. +******************************************************************************/ + +#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) +static NTSTATUS srv_gss_encrypt_buffer(gss_ctx_id_t context_handle, char *buf, char **buf_out) +{ + return NT_STATUS_NOT_SUPPORTED; +} +#endif + +/****************************************************************************** + NTLM encrypt an outgoing buffer. Return the encrypted pointer in ppbuf_out. +******************************************************************************/ + +static NTSTATUS srv_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, char **ppbuf_out) +{ + NTSTATUS status; + char *buf_out; + size_t orig_len = smb_len(buf); + size_t new_len = orig_len + NTLMSSP_SIG_SIZE; + DATA_BLOB sig; + + *ppbuf_out = NULL; + + if (orig_len < 8) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + + /* + * We know smb_len can't return a value > 128k, so no int overflow + * check needed. + */ + + /* Copy the original buffer. */ + + buf_out = SMB_XMALLOC_ARRAY(char, new_len); + memcpy(buf_out, buf, orig_len); + /* Last 16 bytes undefined here... */ + + smb_setlen(buf_out, new_len); + + sig = data_blob(NULL, NTLMSSP_SIG_SIZE); + + status = ntlmssp_seal_packet(ntlmssp_state, + (unsigned char *)buf_out + 8, /* 4 byte len + 0xFF 'S' 'M' 'B' */ + orig_len - 8, + (unsigned char *)buf_out, + orig_len, + &sig); + + if (!NT_STATUS_IS_OK(status)) { + data_blob_free(&sig); + SAFE_FREE(buf_out); + return status; + } + + memcpy(buf_out+orig_len, sig.data, NTLMSSP_SIG_SIZE); + *ppbuf_out = buf_out; return NT_STATUS_OK; } + +/****************************************************************************** + Encrypt an outgoing buffer. Return the encrypted pointer in buf_out. +******************************************************************************/ + +NTSTATUS srv_encrypt_buffer(char *buffer, char **buf_out) +{ + if (!srv_trans_enc_state) { + /* Not encrypting. */ + *buf_out = buffer; + return NT_STATUS_OK; + } + + if (srv_trans_enc_state->smb_enc_type == SMB_TRANS_ENC_NTLM) { + return srv_ntlm_encrypt_buffer(srv_trans_enc_state->ntlmssp_state, buffer, buf_out); + } else { +#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) + return srv_gss_encrypt_buffer(srv_trans_enc_state->context_handle, buffer, buf_out); +#else + return NT_STATUS_NOT_SUPPORTED; +#endif + } +} -- cgit From 7ccf45684a1f83d7d48a4227aa56c53081d68283 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 19 Mar 2007 22:45:35 +0000 Subject: r21880: Make client and server calls into encryption code symetrical, depending on encryption context pointer. Jeremy. (This used to be commit d3f3ced6c8a03d971143baf878158d671dfcbc3b) --- source3/libsmb/smb_seal.c | 299 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 211 insertions(+), 88 deletions(-) (limited to 'source3/libsmb/smb_seal.c') diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index 90efa05f0b..2d1201ae7e 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -20,65 +20,22 @@ #include "includes.h" -NTSTATUS cli_decrypt_message(struct cli_state *cli) -{ - return NT_STATUS_OK; -} - -NTSTATUS cli_encrypt_message(struct cli_state *cli) -{ - return NT_STATUS_OK; -} - -/* Server state if we're encrypting SMBs. If NULL then enc is off. */ - -static struct smb_trans_enc_state *srv_trans_enc_state; - /****************************************************************************** - Is server encryption on ? + Generic code for client and server. + Is encryption turned on ? ******************************************************************************/ -BOOL srv_encryption_on(void) +static BOOL internal_encryption_on(struct smb_trans_enc_state *es) { - return srv_trans_enc_state != NULL; + return ((es != NULL) && es->enc_on); } /****************************************************************************** - Free an encryption-allocated buffer. -******************************************************************************/ - -void srv_free_buffer(char *buf_out) -{ - if (!srv_trans_enc_state) { - return; - } - - if (srv_trans_enc_state->smb_enc_type == SMB_TRANS_ENC_NTLM) { - SAFE_FREE(buf_out); - return; - } - -#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) - /* gss-api free buffer.... */ -#endif -} - -/****************************************************************************** - gss-api decrypt an incoming buffer. -******************************************************************************/ - -#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) -static NTSTATUS srv_gss_decrypt_buffer(gss_ctx_id_t context_handle, char *buf) -{ - return NT_STATUS_NOT_SUPPORTED; -} -#endif - -/****************************************************************************** + Generic code for client and server. NTLM decrypt an incoming buffer. ******************************************************************************/ -static NTSTATUS srv_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf) +static NTSTATUS internal_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf) { NTSTATUS status; size_t orig_len = smb_len(buf); @@ -109,42 +66,11 @@ static NTSTATUS srv_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf) } /****************************************************************************** - Decrypt an incoming buffer. -******************************************************************************/ - -NTSTATUS srv_decrypt_buffer(char *buf) -{ - if (!srv_trans_enc_state) { - /* Not decrypting. */ - return NT_STATUS_OK; - } - if (srv_trans_enc_state->smb_enc_type == SMB_TRANS_ENC_NTLM) { - return srv_ntlm_decrypt_buffer(srv_trans_enc_state->ntlmssp_state, buf); - } else { -#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) - return srv_gss_decrypt_buffer(srv_trans_enc_state->context_handle, buf); -#else - return NT_STATUS_NOT_SUPPORTED; -#endif - } -} - -/****************************************************************************** - gss-api encrypt an outgoing buffer. Return the encrypted pointer in buf_out. -******************************************************************************/ - -#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) -static NTSTATUS srv_gss_encrypt_buffer(gss_ctx_id_t context_handle, char *buf, char **buf_out) -{ - return NT_STATUS_NOT_SUPPORTED; -} -#endif - -/****************************************************************************** + Generic code for client and server. NTLM encrypt an outgoing buffer. Return the encrypted pointer in ppbuf_out. ******************************************************************************/ -static NTSTATUS srv_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, char **ppbuf_out) +static NTSTATUS internal_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, char **ppbuf_out) { NTSTATUS status; char *buf_out; @@ -192,24 +118,221 @@ static NTSTATUS srv_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, } /****************************************************************************** - Encrypt an outgoing buffer. Return the encrypted pointer in buf_out. + Generic code for client and server. + gss-api decrypt an incoming buffer. ******************************************************************************/ -NTSTATUS srv_encrypt_buffer(char *buffer, char **buf_out) +#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) +static NTSTATUS internal_gss_decrypt_buffer(gss_ctx_id_t context_handle, char *buf) +{ + return NT_STATUS_NOT_SUPPORTED; +} +#endif + +/****************************************************************************** + Generic code for client and server. + gss-api encrypt an outgoing buffer. Return the alloced encrypted pointer in buf_out. +******************************************************************************/ + +#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) +static NTSTATUS srv_gss_encrypt_buffer(gss_ctx_id_t context_handle, char *buf, char **buf_out) { - if (!srv_trans_enc_state) { + return NT_STATUS_NOT_SUPPORTED; +} +#endif + +/****************************************************************************** + Generic code for client and server. + Encrypt an outgoing buffer. Return the alloced encrypted pointer in buf_out. +******************************************************************************/ + +static NTSTATUS internal_encrypt_buffer(struct smb_trans_enc_state *es, char *buffer, char **buf_out) +{ + if (!internal_encryption_on(es)) { /* Not encrypting. */ *buf_out = buffer; return NT_STATUS_OK; } - if (srv_trans_enc_state->smb_enc_type == SMB_TRANS_ENC_NTLM) { - return srv_ntlm_encrypt_buffer(srv_trans_enc_state->ntlmssp_state, buffer, buf_out); + if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) { + return internal_ntlm_encrypt_buffer(es->ntlmssp_state, buffer, buf_out); } else { #if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) - return srv_gss_encrypt_buffer(srv_trans_enc_state->context_handle, buffer, buf_out); + return internal_gss_encrypt_buffer(es->context_handle, buffer, buf_out); #else return NT_STATUS_NOT_SUPPORTED; #endif } } + +/****************************************************************************** + 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. +******************************************************************************/ + +static NTSTATUS internal_decrypt_buffer(struct smb_trans_enc_state *es, char *buf) +{ + if (!internal_encryption_on(es)) { + /* Not decrypting. */ + return NT_STATUS_OK; + } + if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) { + return internal_ntlm_decrypt_buffer(es->ntlmssp_state, buf); + } else { +#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) + return internal_gss_decrypt_buffer(es->context_handle, buf); +#else + return NT_STATUS_NOT_SUPPORTED; +#endif + } +} + +/****************************************************************************** + Shutdown an encryption state. +******************************************************************************/ + +static void internal_free_encryption_context(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) { + ntlmssp_end(&es->ntlmssp_state); + } +#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) + if (es->smb_enc_type == SMB_TRANS_ENC_GSS) { + /* Free the gss context handle. */ + } +#endif + SAFE_FREE(es); + *pp_es = NULL; +} + +/****************************************************************************** + Free an encryption-allocated buffer. +******************************************************************************/ + +static void internal_free_enc_buffer(struct smb_trans_enc_state *es, char *buf) +{ + if (!internal_encryption_on(es)) { + return; + } + + if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) { + SAFE_FREE(buf); + return; + } + +#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) + /* gss-api free buffer.... */ +#endif +} + +/****************************************************************************** + Client side encryption. +******************************************************************************/ + +/****************************************************************************** + Is client encryption on ? +******************************************************************************/ + +BOOL cli_encryption_on(struct cli_state *cli) +{ + return internal_encryption_on(cli->trans_enc_state); +} + +/****************************************************************************** + Shutdown a client encryption state. +******************************************************************************/ + +void cli_free_encryption_context(struct cli_state *cli) +{ + return internal_free_encryption_context(&cli->trans_enc_state); +} + +/****************************************************************************** + Free an encryption-allocated buffer. +******************************************************************************/ + +void cli_free_enc_buffer(struct cli_state *cli, char *buf) +{ + return internal_free_enc_buffer(cli->trans_enc_state, buf); +} + +/****************************************************************************** + Decrypt an incoming buffer. +******************************************************************************/ + +NTSTATUS cli_decrypt_message(struct cli_state *cli) +{ + return internal_decrypt_buffer(cli->trans_enc_state, cli->inbuf); +} + +/****************************************************************************** + Encrypt an outgoing buffer. Return the encrypted pointer in buf_out. +******************************************************************************/ + +NTSTATUS cli_encrypt_message(struct cli_state *cli, char **buf_out) +{ + return internal_encrypt_buffer(cli->trans_enc_state, cli->outbuf, buf_out); +} + +/****************************************************************************** + Server side encryption. +******************************************************************************/ + +/****************************************************************************** + Global server state. +******************************************************************************/ + +static struct smb_trans_enc_state *partial_srv_trans_enc_state; +static struct smb_trans_enc_state *srv_trans_enc_state; + +/****************************************************************************** + Is server encryption on ? +******************************************************************************/ + +BOOL srv_encryption_on(void) +{ + return internal_encryption_on(srv_trans_enc_state); +} + +/****************************************************************************** + Shutdown a server encryption state. +******************************************************************************/ + +void srv_free_encryption_context(void) +{ + return internal_free_encryption_context(&srv_trans_enc_state); +} + +/****************************************************************************** + Free an encryption-allocated buffer. +******************************************************************************/ + +void srv_free_enc_buffer(char *buf) +{ + return internal_free_enc_buffer(srv_trans_enc_state, buf); +} + +/****************************************************************************** + Decrypt an incoming buffer. +******************************************************************************/ + +NTSTATUS srv_decrypt_buffer(char *buf) +{ + return internal_decrypt_buffer(srv_trans_enc_state, buf); +} + +/****************************************************************************** + Encrypt an outgoing buffer. Return the encrypted pointer in buf_out. +******************************************************************************/ + +NTSTATUS srv_encrypt_buffer(char *buffer, char **buf_out) +{ + return internal_encrypt_buffer(srv_trans_enc_state, buffer, buf_out); +} -- cgit From 296dcbac5897ad208c890720d3356a3ddc5f7794 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 20 Mar 2007 01:17:47 +0000 Subject: r21882: The server part of the code has to use an AUTH_NTLMSSP struct, not just an NTLMSSP - grr. This complicates the re-use of common client and server code but I think I've got it right. Not turned on of valgrinded yet, but you can see it start to take shape ! Jeremy. (This used to be commit 60fc9c0aedf42dcd9df2ef9f1df07eaf3bca9bce) --- source3/libsmb/smb_seal.c | 102 +++++++++++----------------------------------- 1 file changed, 24 insertions(+), 78 deletions(-) (limited to 'source3/libsmb/smb_seal.c') diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index 2d1201ae7e..10b9d8fdcb 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -25,7 +25,7 @@ Is encryption turned on ? ******************************************************************************/ -static BOOL internal_encryption_on(struct smb_trans_enc_state *es) +BOOL common_encryption_on(struct smb_trans_enc_state *es) { return ((es != NULL) && es->enc_on); } @@ -35,7 +35,7 @@ static BOOL internal_encryption_on(struct smb_trans_enc_state *es) NTLM decrypt an incoming buffer. ******************************************************************************/ -static NTSTATUS internal_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf) +NTSTATUS common_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf) { NTSTATUS status; size_t orig_len = smb_len(buf); @@ -70,7 +70,7 @@ static NTSTATUS internal_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char NTLM encrypt an outgoing buffer. Return the encrypted pointer in ppbuf_out. ******************************************************************************/ -static NTSTATUS internal_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, char **ppbuf_out) +NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, char **ppbuf_out) { NTSTATUS status; char *buf_out; @@ -123,7 +123,7 @@ static NTSTATUS internal_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char ******************************************************************************/ #if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) -static NTSTATUS internal_gss_decrypt_buffer(gss_ctx_id_t context_handle, char *buf) +NTSTATUS common_gss_decrypt_buffer(gss_ctx_id_t context_handle, char *buf) { return NT_STATUS_NOT_SUPPORTED; } @@ -135,7 +135,7 @@ static NTSTATUS internal_gss_decrypt_buffer(gss_ctx_id_t context_handle, char *b ******************************************************************************/ #if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) -static NTSTATUS srv_gss_encrypt_buffer(gss_ctx_id_t context_handle, char *buf, char **buf_out) +NTSTATUS common_gss_encrypt_buffer(gss_ctx_id_t context_handle, char *buf, char **buf_out) { return NT_STATUS_NOT_SUPPORTED; } @@ -146,19 +146,19 @@ static NTSTATUS srv_gss_encrypt_buffer(gss_ctx_id_t context_handle, char *buf, c Encrypt an outgoing buffer. Return the alloced encrypted pointer in buf_out. ******************************************************************************/ -static NTSTATUS internal_encrypt_buffer(struct smb_trans_enc_state *es, char *buffer, char **buf_out) +NTSTATUS common_encrypt_buffer(struct smb_trans_enc_state *es, char *buffer, char **buf_out) { - if (!internal_encryption_on(es)) { + if (!common_encryption_on(es)) { /* Not encrypting. */ *buf_out = buffer; return NT_STATUS_OK; } if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) { - return internal_ntlm_encrypt_buffer(es->ntlmssp_state, buffer, buf_out); + return common_ntlm_encrypt_buffer(es->ntlmssp_state, buffer, buf_out); } else { #if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) - return internal_gss_encrypt_buffer(es->context_handle, buffer, buf_out); + return common_gss_encrypt_buffer(es->context_handle, buffer, buf_out); #else return NT_STATUS_NOT_SUPPORTED; #endif @@ -171,17 +171,17 @@ static NTSTATUS internal_encrypt_buffer(struct smb_trans_enc_state *es, char *bu New data must be less than or equal to the current length. ******************************************************************************/ -static NTSTATUS internal_decrypt_buffer(struct smb_trans_enc_state *es, char *buf) +NTSTATUS common_decrypt_buffer(struct smb_trans_enc_state *es, char *buf) { - if (!internal_encryption_on(es)) { + if (!common_encryption_on(es)) { /* Not decrypting. */ return NT_STATUS_OK; } if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) { - return internal_ntlm_decrypt_buffer(es->ntlmssp_state, buf); + return common_ntlm_decrypt_buffer(es->ntlmssp_state, buf); } else { #if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) - return internal_gss_decrypt_buffer(es->context_handle, buf); + return common_gss_decrypt_buffer(es->context_handle, buf); #else return NT_STATUS_NOT_SUPPORTED; #endif @@ -192,7 +192,7 @@ static NTSTATUS internal_decrypt_buffer(struct smb_trans_enc_state *es, char *bu Shutdown an encryption state. ******************************************************************************/ -static void internal_free_encryption_context(struct smb_trans_enc_state **pp_es) +void common_free_encryption_state(struct smb_trans_enc_state **pp_es) { struct smb_trans_enc_state *es = *pp_es; @@ -201,7 +201,9 @@ static void internal_free_encryption_context(struct smb_trans_enc_state **pp_es) } if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) { - ntlmssp_end(&es->ntlmssp_state); + if (es->ntlmssp_state) { + ntlmssp_end(&es->ntlmssp_state); + } } #if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) if (es->smb_enc_type == SMB_TRANS_ENC_GSS) { @@ -216,9 +218,9 @@ static void internal_free_encryption_context(struct smb_trans_enc_state **pp_es) Free an encryption-allocated buffer. ******************************************************************************/ -static void internal_free_enc_buffer(struct smb_trans_enc_state *es, char *buf) +void common_free_enc_buffer(struct smb_trans_enc_state *es, char *buf) { - if (!internal_encryption_on(es)) { + if (!common_encryption_on(es)) { return; } @@ -242,7 +244,7 @@ static void internal_free_enc_buffer(struct smb_trans_enc_state *es, char *buf) BOOL cli_encryption_on(struct cli_state *cli) { - return internal_encryption_on(cli->trans_enc_state); + return common_encryption_on(cli->trans_enc_state); } /****************************************************************************** @@ -251,7 +253,7 @@ BOOL cli_encryption_on(struct cli_state *cli) void cli_free_encryption_context(struct cli_state *cli) { - return internal_free_encryption_context(&cli->trans_enc_state); + return common_free_encryption_state(&cli->trans_enc_state); } /****************************************************************************** @@ -260,7 +262,7 @@ void cli_free_encryption_context(struct cli_state *cli) void cli_free_enc_buffer(struct cli_state *cli, char *buf) { - return internal_free_enc_buffer(cli->trans_enc_state, buf); + return common_free_enc_buffer(cli->trans_enc_state, buf); } /****************************************************************************** @@ -269,7 +271,7 @@ void cli_free_enc_buffer(struct cli_state *cli, char *buf) NTSTATUS cli_decrypt_message(struct cli_state *cli) { - return internal_decrypt_buffer(cli->trans_enc_state, cli->inbuf); + return common_decrypt_buffer(cli->trans_enc_state, cli->inbuf); } /****************************************************************************** @@ -278,61 +280,5 @@ NTSTATUS cli_decrypt_message(struct cli_state *cli) NTSTATUS cli_encrypt_message(struct cli_state *cli, char **buf_out) { - return internal_encrypt_buffer(cli->trans_enc_state, cli->outbuf, buf_out); -} - -/****************************************************************************** - Server side encryption. -******************************************************************************/ - -/****************************************************************************** - Global server state. -******************************************************************************/ - -static struct smb_trans_enc_state *partial_srv_trans_enc_state; -static struct smb_trans_enc_state *srv_trans_enc_state; - -/****************************************************************************** - Is server encryption on ? -******************************************************************************/ - -BOOL srv_encryption_on(void) -{ - return internal_encryption_on(srv_trans_enc_state); -} - -/****************************************************************************** - Shutdown a server encryption state. -******************************************************************************/ - -void srv_free_encryption_context(void) -{ - return internal_free_encryption_context(&srv_trans_enc_state); -} - -/****************************************************************************** - Free an encryption-allocated buffer. -******************************************************************************/ - -void srv_free_enc_buffer(char *buf) -{ - return internal_free_enc_buffer(srv_trans_enc_state, buf); -} - -/****************************************************************************** - Decrypt an incoming buffer. -******************************************************************************/ - -NTSTATUS srv_decrypt_buffer(char *buf) -{ - return internal_decrypt_buffer(srv_trans_enc_state, buf); -} - -/****************************************************************************** - Encrypt an outgoing buffer. Return the encrypted pointer in buf_out. -******************************************************************************/ - -NTSTATUS srv_encrypt_buffer(char *buffer, char **buf_out) -{ - return internal_encrypt_buffer(srv_trans_enc_state, buffer, buf_out); + return common_encrypt_buffer(cli->trans_enc_state, cli->outbuf, buf_out); } -- cgit From efbdda540a5e0e4d8dff15b0a5891e38244c2c61 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 20 Mar 2007 02:20:16 +0000 Subject: r21883: Try and fix the build by removing the prototypes for functions that take a gss context handle in includes.h Jeremy. (This used to be commit 638b03242d4a6b1df2477dad19240ed61a14a5a3) --- source3/libsmb/smb_seal.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/smb_seal.c') diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index 10b9d8fdcb..e7b3e8f024 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -123,7 +123,7 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, cha ******************************************************************************/ #if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) -NTSTATUS common_gss_decrypt_buffer(gss_ctx_id_t context_handle, char *buf) + NTSTATUS common_gss_decrypt_buffer(gss_ctx_id_t context_handle, char *buf) { return NT_STATUS_NOT_SUPPORTED; } @@ -135,7 +135,7 @@ NTSTATUS common_gss_decrypt_buffer(gss_ctx_id_t context_handle, char *buf) ******************************************************************************/ #if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) -NTSTATUS common_gss_encrypt_buffer(gss_ctx_id_t context_handle, char *buf, char **buf_out) + NTSTATUS common_gss_encrypt_buffer(gss_ctx_id_t context_handle, char *buf, char **buf_out) { return NT_STATUS_NOT_SUPPORTED; } -- cgit From 6b0dcfa62d23980351e852eec05123c0a9823f1d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 20 Mar 2007 22:01:02 +0000 Subject: r21894: Some refactoring of server side encryption context. Support "raw" NTLM auth (no spnego). Jeremy. (This used to be commit 6b5ff7bd591b4f65e2eb767928db50ddf445f09a) --- source3/libsmb/smb_seal.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'source3/libsmb/smb_seal.c') diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index e7b3e8f024..06662e53fb 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -282,3 +282,15 @@ NTSTATUS cli_encrypt_message(struct cli_state *cli, char **buf_out) { return common_encrypt_buffer(cli->trans_enc_state, cli->outbuf, buf_out); } + +/****************************************************************************** + Start a raw ntlmssp encryption. +******************************************************************************/ + +NTSTATUS cli_ntlm_smb_encryption_on(struct cli_state *cli, + const char *user, + const char *pass, + const char *workgroup) +{ + +} -- cgit From 071db6fdbff694681fa1793ee678a9a0af3e266a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 21 Mar 2007 00:25:08 +0000 Subject: r21897: Add in a basic raw NTLM encrypt request. Now for testing. Jeremy. (This used to be commit 783a7b3085a155d9652cd725bf2960cd272cb554) --- source3/libsmb/smb_seal.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'source3/libsmb/smb_seal.c') diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index 06662e53fb..a509438f07 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -154,6 +154,12 @@ NTSTATUS common_encrypt_buffer(struct smb_trans_enc_state *es, char *buffer, cha return NT_STATUS_OK; } + /* Ignore session keepalives. */ + if(CVAL(buffer,0) == SMBkeepalive) { + *buf_out = buffer; + return NT_STATUS_OK; + } + if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) { return common_ntlm_encrypt_buffer(es->ntlmssp_state, buffer, buf_out); } else { @@ -177,6 +183,12 @@ NTSTATUS common_decrypt_buffer(struct smb_trans_enc_state *es, char *buf) /* Not decrypting. */ return NT_STATUS_OK; } + + /* Ignore session keepalives. */ + if(CVAL(buf,0) == SMBkeepalive) { + return NT_STATUS_OK; + } + if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) { return common_ntlm_decrypt_buffer(es->ntlmssp_state, buf); } else { @@ -282,15 +294,3 @@ NTSTATUS cli_encrypt_message(struct cli_state *cli, char **buf_out) { return common_encrypt_buffer(cli->trans_enc_state, cli->outbuf, buf_out); } - -/****************************************************************************** - Start a raw ntlmssp encryption. -******************************************************************************/ - -NTSTATUS cli_ntlm_smb_encryption_on(struct cli_state *cli, - const char *user, - const char *pass, - const char *workgroup) -{ - -} -- cgit From 6aff12a9f6c33b61fe9ab89d703677a3202185db Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 21 Mar 2007 02:02:09 +0000 Subject: r21903: Get the length calculations right (I always forget the 4 byte length isn't included in the length :-). We now have working NTLMSSP transport encryption with sign+seal. W00t! Jeremy. (This used to be commit d34584cb5c53c194693ce7236020ab83f60cd235) --- source3/libsmb/smb_seal.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) (limited to 'source3/libsmb/smb_seal.c') diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index a509438f07..bf7f337a97 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -38,30 +38,33 @@ BOOL common_encryption_on(struct smb_trans_enc_state *es) NTSTATUS common_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf) { NTSTATUS status; - size_t orig_len = smb_len(buf); - size_t new_len = orig_len - NTLMSSP_SIG_SIZE; + size_t buf_len = smb_len(buf) + 4; /* Don't forget the 4 length bytes. */ DATA_BLOB sig; - if (orig_len < 8 + NTLMSSP_SIG_SIZE) { + if (buf_len < 8 + NTLMSSP_SIG_SIZE) { return NT_STATUS_BUFFER_TOO_SMALL; } + /* Adjust for the signature. */ + buf_len -= NTLMSSP_SIG_SIZE; + /* Save off the signature. */ - sig = data_blob(buf+orig_len-NTLMSSP_SIG_SIZE, NTLMSSP_SIG_SIZE); + sig = data_blob(buf+buf_len, NTLMSSP_SIG_SIZE); status = ntlmssp_unseal_packet(ntlmssp_state, (unsigned char *)buf + 8, /* 4 byte len + 0xFF 'S' 'M' 'B' */ - new_len - 8, + buf_len - 8, (unsigned char *)buf, - new_len, + buf_len, &sig); if (!NT_STATUS_IS_OK(status)) { data_blob_free(&sig); return status; } + /* Reset the length. */ - smb_setlen(buf, new_len); + smb_setlen(buf, smb_len(buf) - NTLMSSP_SIG_SIZE); return NT_STATUS_OK; } @@ -74,13 +77,12 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, cha { NTSTATUS status; char *buf_out; - size_t orig_len = smb_len(buf); - size_t new_len = orig_len + NTLMSSP_SIG_SIZE; + size_t buf_len = smb_len(buf) + 4; /* Don't forget the 4 length bytes. */ DATA_BLOB sig; *ppbuf_out = NULL; - if (orig_len < 8) { + if (buf_len < 8) { return NT_STATUS_BUFFER_TOO_SMALL; } @@ -91,19 +93,19 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, cha /* Copy the original buffer. */ - buf_out = SMB_XMALLOC_ARRAY(char, new_len); - memcpy(buf_out, buf, orig_len); + buf_out = SMB_XMALLOC_ARRAY(char, buf_len + NTLMSSP_SIG_SIZE); + memcpy(buf_out, buf, buf_len); /* Last 16 bytes undefined here... */ - smb_setlen(buf_out, new_len); + smb_setlen(buf_out, smb_len(buf) + NTLMSSP_SIG_SIZE); sig = data_blob(NULL, NTLMSSP_SIG_SIZE); status = ntlmssp_seal_packet(ntlmssp_state, (unsigned char *)buf_out + 8, /* 4 byte len + 0xFF 'S' 'M' 'B' */ - orig_len - 8, + buf_len - 8, (unsigned char *)buf_out, - orig_len, + buf_len, &sig); if (!NT_STATUS_IS_OK(status)) { @@ -112,7 +114,7 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, cha return status; } - memcpy(buf_out+orig_len, sig.data, NTLMSSP_SIG_SIZE); + memcpy(buf_out+buf_len, sig.data, NTLMSSP_SIG_SIZE); *ppbuf_out = buf_out; return NT_STATUS_OK; } -- cgit From d8bb69515b49808b791585d69a50c5237614b1ad Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 21 Mar 2007 17:13:35 +0000 Subject: r21912: There's no point checksumming the packet length this already has to be right. This makes the signed+sealed area the same as it will be with gss calls. Now to go implement them. Jeremy. (This used to be commit 80810af7d1137b3ddd3073581d5ec99fadaa81a5) --- source3/libsmb/smb_seal.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libsmb/smb_seal.c') diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index bf7f337a97..7a27f88a2e 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -54,8 +54,8 @@ NTSTATUS common_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf) status = ntlmssp_unseal_packet(ntlmssp_state, (unsigned char *)buf + 8, /* 4 byte len + 0xFF 'S' 'M' 'B' */ buf_len - 8, - (unsigned char *)buf, - buf_len, + (unsigned char *)buf + 8, + buf_len - 8, &sig); if (!NT_STATUS_IS_OK(status)) { @@ -104,8 +104,8 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, cha status = ntlmssp_seal_packet(ntlmssp_state, (unsigned char *)buf_out + 8, /* 4 byte len + 0xFF 'S' 'M' 'B' */ buf_len - 8, - (unsigned char *)buf_out, - buf_len, + (unsigned char *)buf_out + 8, + buf_len - 8, &sig); if (!NT_STATUS_IS_OK(status)) { -- cgit From 56c777882f0e9fc64e69290db8f6db5fe90225fd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 21 Mar 2007 18:33:13 +0000 Subject: r21916: Fix couple of "return" calls on void functions. Ensure we ignore reqests to free keepalive buffers as we only copied these. Jeremy. (This used to be commit a184bdbe3c7bf0c44a8141898bfcb9971a332312) --- source3/libsmb/smb_seal.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/smb_seal.c') diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index 7a27f88a2e..9ea3a10350 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -238,6 +238,14 @@ void common_free_enc_buffer(struct smb_trans_enc_state *es, char *buf) return; } + /* We know this is an smb buffer, and we + * didn't malloc, only copy, for a keepalive, + * so ignore session keepalives. */ + + if(CVAL(buf,0) == SMBkeepalive) { + return; + } + if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) { SAFE_FREE(buf); return; @@ -267,7 +275,7 @@ BOOL cli_encryption_on(struct cli_state *cli) void cli_free_encryption_context(struct cli_state *cli) { - return common_free_encryption_state(&cli->trans_enc_state); + common_free_encryption_state(&cli->trans_enc_state); } /****************************************************************************** @@ -276,7 +284,7 @@ void cli_free_encryption_context(struct cli_state *cli) void cli_free_enc_buffer(struct cli_state *cli, char *buf) { - return common_free_enc_buffer(cli->trans_enc_state, buf); + common_free_enc_buffer(cli->trans_enc_state, buf); } /****************************************************************************** -- cgit From 42238c78bb8820a21cfb08fc29a5109ee1a62bab Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 21 Mar 2007 19:15:14 +0000 Subject: r21917: Start to do the gss versions of sign+seal. Jeremy. (This used to be commit a226645353a40047b72de1b96c3a7676a2bf1034) --- source3/libsmb/smb_seal.c | 97 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 77 insertions(+), 20 deletions(-) (limited to 'source3/libsmb/smb_seal.c') diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index 9ea3a10350..f16c1402a2 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -124,7 +124,7 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, cha gss-api decrypt an incoming buffer. ******************************************************************************/ -#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) +#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) NTSTATUS common_gss_decrypt_buffer(gss_ctx_id_t context_handle, char *buf) { return NT_STATUS_NOT_SUPPORTED; @@ -136,10 +136,65 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, cha gss-api encrypt an outgoing buffer. Return the alloced encrypted pointer in buf_out. ******************************************************************************/ -#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) - NTSTATUS common_gss_encrypt_buffer(gss_ctx_id_t context_handle, char *buf, char **buf_out) +#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) + NTSTATUS common_gss_encrypt_buffer(gss_ctx_id_t context_handle, char *buf, char **ppbuf_out) { - return NT_STATUS_NOT_SUPPORTED; + 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(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, + context_handle, + 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) { + /* Um - no mapping for gss-errs to NTSTATUS yet. */ + return NT_STATUS_UNSUCCESSFUL; + } + + 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 = SMB_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; + } + + smb_setlen(*ppbuf_out, out_buf.length + 8); + memcpy(*ppbuf_out+8, out_buf.value, out_buf.length); + gss_release_buffer(&minor, &out_buf); + return NT_STATUS_OK; } #endif @@ -162,14 +217,15 @@ NTSTATUS common_encrypt_buffer(struct smb_trans_enc_state *es, char *buffer, cha return NT_STATUS_OK; } - if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) { - return common_ntlm_encrypt_buffer(es->ntlmssp_state, buffer, buf_out); - } else { -#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) - return common_gss_encrypt_buffer(es->context_handle, buffer, buf_out); -#else - return NT_STATUS_NOT_SUPPORTED; + switch (es->smb_enc_type) { + case SMB_TRANS_ENC_NTLM: + return common_ntlm_encrypt_buffer(es->ntlmssp_state, buffer, buf_out); +#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) + case SMB_TRANS_ENC_GSS: + return common_gss_encrypt_buffer(es->context_handle, buffer, buf_out); #endif + default: + return NT_STATUS_NOT_SUPPORTED; } } @@ -191,14 +247,15 @@ NTSTATUS common_decrypt_buffer(struct smb_trans_enc_state *es, char *buf) return NT_STATUS_OK; } - if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) { - return common_ntlm_decrypt_buffer(es->ntlmssp_state, buf); - } else { -#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) - return common_gss_decrypt_buffer(es->context_handle, buf); -#else - return NT_STATUS_NOT_SUPPORTED; + switch (es->smb_enc_type) { + case SMB_TRANS_ENC_NTLM: + return common_ntlm_decrypt_buffer(es->ntlmssp_state, buf); +#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) + case SMB_TRANS_ENC_GSS: + return common_gss_decrypt_buffer(es->context_handle, buf); #endif + default: + return NT_STATUS_NOT_SUPPORTED; } } @@ -219,7 +276,7 @@ void common_free_encryption_state(struct smb_trans_enc_state **pp_es) ntlmssp_end(&es->ntlmssp_state); } } -#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) +#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) if (es->smb_enc_type == SMB_TRANS_ENC_GSS) { /* Free the gss context handle. */ } @@ -251,7 +308,7 @@ void common_free_enc_buffer(struct smb_trans_enc_state *es, char *buf) return; } -#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) +#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) /* gss-api free buffer.... */ #endif } -- cgit From 8c395be5e514a28f13608a462c0c0e8417e21160 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 21 Mar 2007 23:49:57 +0000 Subject: r21922: Fixed the build by rather horrid means. I really need to restructure libsmb/smb_signing.c so it isn't in the base libs path but lives in libsmb instead (like smb_seal.c does). Jeremy. (This used to be commit 1b828f051d0782201f697de15ff973bd6b097d5b) --- source3/libsmb/smb_seal.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/libsmb/smb_seal.c') diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index f16c1402a2..d08b27e7cd 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -163,8 +163,11 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, cha &out_buf); if (ret != GSS_S_COMPLETE) { + ADS_STATUS adss = ADS_ERROR_GSS(ret, minor); + DEBUG(0,("common_gss_encrypt_buffer: gss_wrap failed. Error %s\n", + ads_errstr(adss) )); /* Um - no mapping for gss-errs to NTSTATUS yet. */ - return NT_STATUS_UNSUCCESSFUL; + return ads_ntstatus(adss); } if (!flags_got) { -- cgit From 5a025d845a73c4ce5ebc0496b1257bb89ef401e6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 22 Mar 2007 00:08:22 +0000 Subject: r21923: Add in the gss decrypt. Jeremy. (This used to be commit 00f58951b4cace06e51e7eb404605c7f3d366f38) --- source3/libsmb/smb_seal.c | 48 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 3 deletions(-) (limited to 'source3/libsmb/smb_seal.c') diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index d08b27e7cd..63fa49046a 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -121,13 +121,54 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, cha /****************************************************************************** Generic code for client and server. - gss-api decrypt an incoming buffer. + 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) NTSTATUS common_gss_decrypt_buffer(gss_ctx_id_t context_handle, char *buf) { - return NT_STATUS_NOT_SUPPORTED; + 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(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, + context_handle, + &in_buf, + &out_buf, + &flags_got, /* did we get sign+seal ? */ + (gss_qop_t *) NULL); + + if (ret != GSS_S_COMPLETE) { + ADS_STATUS adss = ADS_ERROR_GSS(ret, minor); + DEBUG(0,("common_gss_encrypt_buffer: gss_unwrap failed. Error %s\n", + ads_errstr(adss) )); + /* Um - no mapping for gss-errs to NTSTATUS yet. */ + return ads_ntstatus(adss); + } + + if (out_buf.length > in_buf.length) { + DEBUG(0,("common_gss_encrypt_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); + smb_setlen(buf, out_buf.length + 4); + + gss_release_buffer(&minor, &out_buf); + return NT_STATUS_OK; } #endif @@ -194,8 +235,9 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, cha return NT_STATUS_NO_MEMORY; } - smb_setlen(*ppbuf_out, out_buf.length + 8); memcpy(*ppbuf_out+8, out_buf.value, out_buf.length); + smb_setlen(*ppbuf_out, out_buf.length + 4); + gss_release_buffer(&minor, &out_buf); return NT_STATUS_OK; } -- cgit From f93d75c932e7a48da8bcd589d7505bf5445b89df Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 22 Mar 2007 02:24:12 +0000 Subject: r21926: Fix missing enum specifier pointed out by Don McCall @ HP. Thanks Don ! Jeremy. (This used to be commit 662344d1ec3593689de7602afa518ed98e10dc37) --- source3/libsmb/smb_seal.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/libsmb/smb_seal.c') diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index 63fa49046a..95012d629e 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -264,10 +264,10 @@ NTSTATUS common_encrypt_buffer(struct smb_trans_enc_state *es, char *buffer, cha switch (es->smb_enc_type) { case SMB_TRANS_ENC_NTLM: - return common_ntlm_encrypt_buffer(es->ntlmssp_state, buffer, buf_out); + return common_ntlm_encrypt_buffer(es->s.ntlmssp_state, buffer, buf_out); #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) case SMB_TRANS_ENC_GSS: - return common_gss_encrypt_buffer(es->context_handle, buffer, buf_out); + return common_gss_encrypt_buffer(es->s.context_handle, buffer, buf_out); #endif default: return NT_STATUS_NOT_SUPPORTED; @@ -294,10 +294,10 @@ NTSTATUS common_decrypt_buffer(struct smb_trans_enc_state *es, char *buf) switch (es->smb_enc_type) { case SMB_TRANS_ENC_NTLM: - return common_ntlm_decrypt_buffer(es->ntlmssp_state, buf); + return common_ntlm_decrypt_buffer(es->s.ntlmssp_state, buf); #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) case SMB_TRANS_ENC_GSS: - return common_gss_decrypt_buffer(es->context_handle, buf); + return common_gss_decrypt_buffer(es->s.context_handle, buf); #endif default: return NT_STATUS_NOT_SUPPORTED; @@ -317,8 +317,8 @@ void common_free_encryption_state(struct smb_trans_enc_state **pp_es) } if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) { - if (es->ntlmssp_state) { - ntlmssp_end(&es->ntlmssp_state); + if (es->s.ntlmssp_state) { + ntlmssp_end(&es->s.ntlmssp_state); } } #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) -- cgit From 8b63654c2e63448cc21505d7996e1a4805e391df Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 27 Mar 2007 00:50:53 +0000 Subject: r21969: Start working on the gss-side of the server negotiation. Jeremy. (This used to be commit fbc569b530104679e47fe743963eb0c4384de6ae) --- source3/libsmb/smb_seal.c | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) (limited to 'source3/libsmb/smb_seal.c') diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index 95012d629e..f0e79b404c 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -126,8 +126,9 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, cha ******************************************************************************/ #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) - NTSTATUS common_gss_decrypt_buffer(gss_ctx_id_t context_handle, char *buf) + 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; @@ -142,7 +143,7 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, cha in_buf.length = buf_len - 8; ret = gss_unwrap(&minor, - context_handle, + gss_ctx, &in_buf, &out_buf, &flags_got, /* did we get sign+seal ? */ @@ -178,8 +179,9 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, cha ******************************************************************************/ #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) - NTSTATUS common_gss_encrypt_buffer(gss_ctx_id_t context_handle, char *buf, char **ppbuf_out) + NTSTATUS common_gss_encrypt_buffer(struct smb_tran_enc_state_gss *gss_state, 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; @@ -196,7 +198,7 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, cha in_buf.length = buf_len - 8; ret = gss_wrap(&minor, - context_handle, + gss_ctx, True, /* we want sign+seal. */ GSS_C_QOP_DEFAULT, &in_buf, @@ -267,7 +269,7 @@ NTSTATUS common_encrypt_buffer(struct smb_trans_enc_state *es, char *buffer, cha return common_ntlm_encrypt_buffer(es->s.ntlmssp_state, buffer, buf_out); #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) case SMB_TRANS_ENC_GSS: - return common_gss_encrypt_buffer(es->s.context_handle, buffer, buf_out); + return common_gss_encrypt_buffer(es->s.gss_state, buffer, buf_out); #endif default: return NT_STATUS_NOT_SUPPORTED; @@ -297,13 +299,29 @@ NTSTATUS common_decrypt_buffer(struct smb_trans_enc_state *es, char *buf) return common_ntlm_decrypt_buffer(es->s.ntlmssp_state, buf); #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) case SMB_TRANS_ENC_GSS: - return common_gss_decrypt_buffer(es->s.context_handle, buf); + 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; + + gss_release_cred(&minor, &gss_state->creds); + gss_delete_sec_context(&minor, &gss_state->gss_ctx, NULL); + SAFE_FREE(*pp_gss_state); +} +#endif + /****************************************************************************** Shutdown an encryption state. ******************************************************************************/ @@ -324,6 +342,9 @@ void common_free_encryption_state(struct smb_trans_enc_state **pp_es) #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); -- cgit From 4a66d0e232271968ba96da50274428916a393975 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 27 Mar 2007 21:13:31 +0000 Subject: r21991: I hate Steve French :-). Add support for encryption contexts.... Jeremy. (This used to be commit ae8f3649f773b8a8dcb55921536d038d3475322e) --- source3/libsmb/smb_seal.c | 111 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 82 insertions(+), 29 deletions(-) (limited to 'source3/libsmb/smb_seal.c') diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index f0e79b404c..c80b7f0a90 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -20,6 +20,27 @@ #include "includes.h" +/****************************************************************************** + Pull out the encryption context for this packet. 0 means global context. +******************************************************************************/ + +NTSTATUS get_enc_ctx_num(char *buf, uint16 *p_enc_ctx_num) +{ + if (smb_len(buf) < 8) { + return NT_STATUS_INVALID_BUFFER_SIZE; + } + + if (buf[4] == (char)0xFF && buf[5] == 'S') { + if (buf [6] == 'M' && buf[7] == 'B') { + /* Not an encrypted buffer. */ + return NT_STATUS_NOT_FOUND; + } + *p_enc_ctx_num = SVAL(buf,6); + return NT_STATUS_OK; + } + return NT_STATUS_INVALID_NETWORK_RESPONSE; +} + /****************************************************************************** Generic code for client and server. Is encryption turned on ? @@ -52,7 +73,7 @@ NTSTATUS common_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf) sig = data_blob(buf+buf_len, NTLMSSP_SIG_SIZE); status = ntlmssp_unseal_packet(ntlmssp_state, - (unsigned char *)buf + 8, /* 4 byte len + 0xFF 'S' 'M' 'B' */ + (unsigned char *)buf + 8, /* 4 byte len + 0xFF 'S' */ buf_len - 8, (unsigned char *)buf + 8, buf_len - 8, @@ -73,7 +94,10 @@ NTSTATUS common_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf) NTLM encrypt an outgoing buffer. Return the encrypted pointer in ppbuf_out. ******************************************************************************/ -NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, char **ppbuf_out) +NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, + uint16 enc_ctx_num, + char *buf, + char **ppbuf_out) { NTSTATUS status; char *buf_out; @@ -97,12 +121,12 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, cha memcpy(buf_out, buf, buf_len); /* Last 16 bytes undefined here... */ - smb_setlen(buf_out, smb_len(buf) + NTLMSSP_SIG_SIZE); + smb_set_enclen(buf_out, smb_len(buf) + NTLMSSP_SIG_SIZE, enc_ctx_num); sig = data_blob(NULL, NTLMSSP_SIG_SIZE); status = ntlmssp_seal_packet(ntlmssp_state, - (unsigned char *)buf_out + 8, /* 4 byte len + 0xFF 'S' 'M' 'B' */ + (unsigned char *)buf_out + 8, /* 4 byte len + 0xFF 'S' */ buf_len - 8, (unsigned char *)buf_out + 8, buf_len - 8, @@ -126,7 +150,7 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, cha ******************************************************************************/ #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) - NTSTATUS common_gss_decrypt_buffer(struct smb_tran_enc_state_gss *gss_state, char *buf) +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; @@ -179,7 +203,10 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, cha ******************************************************************************/ #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) - NTSTATUS common_gss_encrypt_buffer(struct smb_tran_enc_state_gss *gss_state, char *buf, char **ppbuf_out) +NTSTATUS common_gss_encrypt_buffer(struct smb_tran_enc_state_gss *gss_state, + uint16 enc_ctx_num, + char *buf, + char **ppbuf_out) { gss_ctx_id_t gss_ctx = gss_state->gss_ctx; OM_uint32 ret = 0; @@ -238,7 +265,7 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, cha } memcpy(*ppbuf_out+8, out_buf.value, out_buf.length); - smb_setlen(*ppbuf_out, out_buf.length + 4); + smb_set_enclen(*ppbuf_out, out_buf.length + 4, enc_ctx_num); gss_release_buffer(&minor, &out_buf); return NT_STATUS_OK; @@ -258,18 +285,12 @@ NTSTATUS common_encrypt_buffer(struct smb_trans_enc_state *es, char *buffer, cha return NT_STATUS_OK; } - /* Ignore session keepalives. */ - if(CVAL(buffer,0) == SMBkeepalive) { - *buf_out = buffer; - return NT_STATUS_OK; - } - switch (es->smb_enc_type) { case SMB_TRANS_ENC_NTLM: - return common_ntlm_encrypt_buffer(es->s.ntlmssp_state, buffer, buf_out); + return common_ntlm_encrypt_buffer(es->s.ntlmssp_state, 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, buffer, buf_out); + return common_gss_encrypt_buffer(es->s.gss_state, es->enc_ctx_num, buffer, buf_out); #endif default: return NT_STATUS_NOT_SUPPORTED; @@ -289,11 +310,6 @@ NTSTATUS common_decrypt_buffer(struct smb_trans_enc_state *es, char *buf) return NT_STATUS_OK; } - /* Ignore session keepalives. */ - if(CVAL(buf,0) == SMBkeepalive) { - return NT_STATUS_OK; - } - switch (es->smb_enc_type) { case SMB_TRANS_ENC_NTLM: return common_ntlm_decrypt_buffer(es->s.ntlmssp_state, buf); @@ -361,21 +377,19 @@ void common_free_enc_buffer(struct smb_trans_enc_state *es, char *buf) return; } - /* We know this is an smb buffer, and we - * didn't malloc, only copy, for a keepalive, - * so ignore session keepalives. */ - - if(CVAL(buf,0) == SMBkeepalive) { - return; - } - if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) { SAFE_FREE(buf); return; } #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) - /* gss-api free buffer.... */ + if (es->smb_enc_type == SMB_TRANS_ENC_GSS) { + OM_uint32 min; + gss_buffer_desc rel_buf; + rel_buf.value = buf; + rel_buf.length = smb_len(buf) + 4; + gss_release_buffer(&min, &rel_buf); + } #endif } @@ -389,6 +403,9 @@ void common_free_enc_buffer(struct smb_trans_enc_state *es, char *buf) BOOL cli_encryption_on(struct cli_state *cli) { + /* If we supported multiple encrytion contexts + * here we'd look up based on tid. + */ return common_encryption_on(cli->trans_enc_state); } @@ -407,6 +424,17 @@ void cli_free_encryption_context(struct cli_state *cli) void cli_free_enc_buffer(struct cli_state *cli, char *buf) { + /* We know this is an smb buffer, and we + * didn't malloc, only copy, for a keepalive, + * so ignore session keepalives. */ + + if(CVAL(buf,0) == SMBkeepalive) { + return; + } + + /* If we supported multiple encrytion contexts + * here we'd look up based on tid. + */ common_free_enc_buffer(cli->trans_enc_state, buf); } @@ -416,6 +444,23 @@ void cli_free_enc_buffer(struct cli_state *cli, char *buf) NTSTATUS cli_decrypt_message(struct cli_state *cli) { + NTSTATUS status; + uint16 enc_ctx_num; + + /* Ignore session keepalives. */ + if(CVAL(cli->inbuf,0) == SMBkeepalive) { + return NT_STATUS_OK; + } + + status = get_enc_ctx_num(cli->inbuf, &enc_ctx_num); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (enc_ctx_num != cli->trans_enc_state->enc_ctx_num) { + return NT_STATUS_INVALID_HANDLE; + } + return common_decrypt_buffer(cli->trans_enc_state, cli->inbuf); } @@ -425,5 +470,13 @@ NTSTATUS cli_decrypt_message(struct cli_state *cli) NTSTATUS cli_encrypt_message(struct cli_state *cli, char **buf_out) { + /* Ignore session keepalives. */ + if(CVAL(cli->inbuf,0) == SMBkeepalive) { + return NT_STATUS_OK; + } + + /* If we supported multiple encrytion contexts + * here we'd look up based on tid. + */ return common_encrypt_buffer(cli->trans_enc_state, cli->outbuf, buf_out); } -- cgit From 3215c09a8147e7df111e4e0817091285cd7240cb Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 27 Mar 2007 22:37:42 +0000 Subject: r21994: Ignore keepalives in the correct buffer (out not in :-). Jeremy. (This used to be commit 9785528ddf26c4943e8bdfcf7694314a52218520) --- source3/libsmb/smb_seal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/smb_seal.c') diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index c80b7f0a90..ed2c66013e 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -471,7 +471,7 @@ NTSTATUS cli_decrypt_message(struct cli_state *cli) NTSTATUS cli_encrypt_message(struct cli_state *cli, char **buf_out) { /* Ignore session keepalives. */ - if(CVAL(cli->inbuf,0) == SMBkeepalive) { + if(CVAL(cli->outbuf,0) == SMBkeepalive) { return NT_STATUS_OK; } -- cgit From e9157961d6c89318de4c7ff5a700aed640d91d92 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 28 Mar 2007 01:11:27 +0000 Subject: r21997: Implement the server side of gss seal negotiate. Jeremy. (This used to be commit 6b923acfee59e39eea69e9e9a00f1f6118ed4270) --- source3/libsmb/smb_seal.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/smb_seal.c') diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index ed2c66013e..891673ed15 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -332,8 +332,12 @@ 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; - gss_release_cred(&minor, &gss_state->creds); - gss_delete_sec_context(&minor, &gss_state->gss_ctx, NULL); + 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 -- cgit From b0bcb483697249123f92f5ac477c98b579135887 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 30 Mar 2007 22:19:51 +0000 Subject: r22013: Move to SSPI framing (sig first in NTLM). Jeremy (This used to be commit 22eaed76f01ea9d0184dcaf57adca23abc6330b9) --- source3/libsmb/smb_seal.c | 64 ++++++++++++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 26 deletions(-) (limited to 'source3/libsmb/smb_seal.c') diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index 891673ed15..fac451a6c5 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -30,13 +30,15 @@ NTSTATUS get_enc_ctx_num(char *buf, uint16 *p_enc_ctx_num) return NT_STATUS_INVALID_BUFFER_SIZE; } - if (buf[4] == (char)0xFF && buf[5] == 'S') { - if (buf [6] == 'M' && buf[7] == 'B') { + if (buf[4] == (char)0xFF) { + if (buf[5] == 'S' && buf [6] == 'M' && buf[7] == 'B') { /* Not an encrypted buffer. */ return NT_STATUS_NOT_FOUND; } - *p_enc_ctx_num = SVAL(buf,6); - return NT_STATUS_OK; + if (buf[5] == 'E') { + *p_enc_ctx_num = SVAL(buf,6); + return NT_STATUS_OK; + } } return NT_STATUS_INVALID_NETWORK_RESPONSE; } @@ -54,44 +56,55 @@ BOOL common_encryption_on(struct smb_trans_enc_state *es) /****************************************************************************** Generic code for client and server. NTLM decrypt an incoming buffer. + Abartlett tells me that SSPI puts the signature first before the encrypted + output, so cope with the same for compatibility. ******************************************************************************/ NTSTATUS common_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf) { NTSTATUS status; size_t buf_len = smb_len(buf) + 4; /* Don't forget the 4 length bytes. */ + size_t data_len; + char *inbuf; DATA_BLOB sig; if (buf_len < 8 + NTLMSSP_SIG_SIZE) { return NT_STATUS_BUFFER_TOO_SMALL; } + inbuf = smb_xmemdup(buf, buf_len); + /* Adjust for the signature. */ - buf_len -= NTLMSSP_SIG_SIZE; + data_len = buf_len - 8 - NTLMSSP_SIG_SIZE; - /* Save off the signature. */ - sig = data_blob(buf+buf_len, NTLMSSP_SIG_SIZE); + /* Point at the signature. */ + sig = data_blob_const(inbuf+8, NTLMSSP_SIG_SIZE); status = ntlmssp_unseal_packet(ntlmssp_state, - (unsigned char *)buf + 8, /* 4 byte len + 0xFF 'S' */ - buf_len - 8, - (unsigned char *)buf + 8, - buf_len - 8, + (unsigned char *)inbuf + 8 + NTLMSSP_SIG_SIZE, /* 4 byte len + 0xFF 'E' */ + data_len, + (unsigned char *)inbuf + 8 + NTLMSSP_SIG_SIZE, + data_len, &sig); if (!NT_STATUS_IS_OK(status)) { - data_blob_free(&sig); + SAFE_FREE(inbuf); return status; } + memcpy(buf + 8, inbuf + 8 + NTLMSSP_SIG_SIZE, data_len); + SAFE_FREE(inbuf); + /* Reset the length. */ - smb_setlen(buf, smb_len(buf) - NTLMSSP_SIG_SIZE); + smb_setlen(buf, data_len + 4); return NT_STATUS_OK; } /****************************************************************************** Generic code for client and server. NTLM encrypt an outgoing buffer. Return the encrypted pointer in ppbuf_out. + Abartlett tells me that SSPI puts the signature first before the encrypted + output, so do the same for compatibility. ******************************************************************************/ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, @@ -101,12 +114,12 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, { NTSTATUS status; char *buf_out; - size_t buf_len = smb_len(buf) + 4; /* Don't forget the 4 length bytes. */ + size_t data_len = smb_len(buf) - 4; /* Ignore the 0xFF SMB bytes. */ DATA_BLOB sig; *ppbuf_out = NULL; - if (buf_len < 8) { + if (data_len == 0) { return NT_STATUS_BUFFER_TOO_SMALL; } @@ -115,21 +128,21 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, * check needed. */ - /* Copy the original buffer. */ + buf_out = SMB_XMALLOC_ARRAY(char, 8 + NTLMSSP_SIG_SIZE + data_len); + + /* Copy the data from the original buffer. */ - buf_out = SMB_XMALLOC_ARRAY(char, buf_len + NTLMSSP_SIG_SIZE); - memcpy(buf_out, buf, buf_len); - /* Last 16 bytes undefined here... */ + memcpy(buf_out + 8 + NTLMSSP_SIG_SIZE, buf + 8, data_len); smb_set_enclen(buf_out, smb_len(buf) + NTLMSSP_SIG_SIZE, enc_ctx_num); sig = data_blob(NULL, NTLMSSP_SIG_SIZE); status = ntlmssp_seal_packet(ntlmssp_state, - (unsigned char *)buf_out + 8, /* 4 byte len + 0xFF 'S' */ - buf_len - 8, - (unsigned char *)buf_out + 8, - buf_len - 8, + (unsigned char *)buf_out + 8 + NTLMSSP_SIG_SIZE, /* 4 byte len + 0xFF 'S' */ + data_len, + (unsigned char *)buf_out + 8 + NTLMSSP_SIG_SIZE, + data_len, &sig); if (!NT_STATUS_IS_OK(status)) { @@ -138,7 +151,8 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, return status; } - memcpy(buf_out+buf_len, sig.data, NTLMSSP_SIG_SIZE); + /* First 16 data bytes are signature for SSPI compatibility. */ + memcpy(buf_out + 8, sig.data, NTLMSSP_SIG_SIZE); *ppbuf_out = buf_out; return NT_STATUS_OK; } @@ -195,14 +209,12 @@ NTSTATUS common_gss_decrypt_buffer(struct smb_tran_enc_state_gss *gss_state, cha gss_release_buffer(&minor, &out_buf); return NT_STATUS_OK; } -#endif /****************************************************************************** Generic code for client and server. gss-api encrypt an outgoing buffer. Return the alloced encrypted pointer in buf_out. ******************************************************************************/ -#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) NTSTATUS common_gss_encrypt_buffer(struct smb_tran_enc_state_gss *gss_state, uint16 enc_ctx_num, char *buf, -- cgit From 44ca85a506043e9d1b3ac2e66b0ae17d2d0b92da Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 30 Mar 2007 23:23:45 +0000 Subject: r22016: Try and fix the build - move things out of proto.h Jeremy. (This used to be commit 29933600cff458f6599e4604f9e861cd20fc8e38) --- source3/libsmb/smb_seal.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/smb_seal.c') diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index fac451a6c5..836bd0a38f 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -164,7 +164,7 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, ******************************************************************************/ #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) -NTSTATUS common_gss_decrypt_buffer(struct smb_tran_enc_state_gss *gss_state, char *buf) +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; @@ -215,7 +215,7 @@ NTSTATUS common_gss_decrypt_buffer(struct smb_tran_enc_state_gss *gss_state, cha gss-api encrypt an outgoing buffer. Return the alloced encrypted pointer in buf_out. ******************************************************************************/ -NTSTATUS common_gss_encrypt_buffer(struct smb_tran_enc_state_gss *gss_state, +static NTSTATUS common_gss_encrypt_buffer(struct smb_tran_enc_state_gss *gss_state, uint16 enc_ctx_num, char *buf, char **ppbuf_out) -- cgit From 5cee3be0140a7acbd3b75a4d7aa0fbaff8c12960 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 19 Apr 2007 01:26:38 +0000 Subject: r22358: Use gss error to NTSTATUS mapping function for errors. Jeremy. (This used to be commit 11fa0ca9e21d478a4b79b8ca1e92936b26b03fe0) --- source3/libsmb/smb_seal.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'source3/libsmb/smb_seal.c') diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index 836bd0a38f..19092bd8c8 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -191,8 +191,7 @@ static NTSTATUS common_gss_decrypt_buffer(struct smb_tran_enc_state_gss *gss_sta ADS_STATUS adss = ADS_ERROR_GSS(ret, minor); DEBUG(0,("common_gss_encrypt_buffer: gss_unwrap failed. Error %s\n", ads_errstr(adss) )); - /* Um - no mapping for gss-errs to NTSTATUS yet. */ - return ads_ntstatus(adss); + return map_nt_error_from_gss(ret, minor); } if (out_buf.length > in_buf.length) { @@ -248,8 +247,7 @@ static NTSTATUS common_gss_encrypt_buffer(struct smb_tran_enc_state_gss *gss_sta ADS_STATUS adss = ADS_ERROR_GSS(ret, minor); DEBUG(0,("common_gss_encrypt_buffer: gss_wrap failed. Error %s\n", ads_errstr(adss) )); - /* Um - no mapping for gss-errs to NTSTATUS yet. */ - return ads_ntstatus(adss); + return map_nt_error_from_gss(ret, minor); } if (!flags_got) { -- cgit From dc90cd89a7fef3b0a744ef1873193cf2c9d75cad Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 19 Apr 2007 20:50:49 +0000 Subject: r22389: Start preparing for multiple encryption contexts in the server. Allow server to reflect back to calling client the encryption context that was sent. Jeremy. (This used to be commit b49e90335d1e589916b5ab4992e3c4a2d221ca7e) --- source3/libsmb/smb_seal.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source3/libsmb/smb_seal.c') diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index 19092bd8c8..2e3e2f4ce3 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -93,10 +93,11 @@ NTSTATUS common_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf) } memcpy(buf + 8, inbuf + 8 + NTLMSSP_SIG_SIZE, data_len); - SAFE_FREE(inbuf); /* Reset the length. */ - smb_setlen(buf, data_len + 4); + smb_setlen(buf, data_len + 4, inbuf); + + SAFE_FREE(inbuf); return NT_STATUS_OK; } @@ -203,7 +204,7 @@ static NTSTATUS common_gss_decrypt_buffer(struct smb_tran_enc_state_gss *gss_sta } memcpy(buf + 8, out_buf.value, out_buf.length); - smb_setlen(buf, out_buf.length + 4); + smb_setlen(buf, out_buf.length + 4, out_buf.value); gss_release_buffer(&minor, &out_buf); return NT_STATUS_OK; -- cgit From 0829e1ad1c3646efecf50729f493b9ee72ef0517 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 19 Apr 2007 22:40:32 +0000 Subject: r22391: Looks bigger than it is. Make "inbuf" available to all callers of smb_setlen (via set_message() calls). This will allow the server to reflect back the correct encryption context. Jeremy. (This used to be commit 2d80a96120a5fe2fe726f00746d36d85044c4bdb) --- source3/libsmb/smb_seal.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/smb_seal.c') diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index 2e3e2f4ce3..dde69570ab 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -95,7 +95,7 @@ NTSTATUS common_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf) memcpy(buf + 8, inbuf + 8 + NTLMSSP_SIG_SIZE, data_len); /* Reset the length. */ - smb_setlen(buf, data_len + 4, inbuf); + smb_setlen(inbuf, buf, data_len + 4); SAFE_FREE(inbuf); return NT_STATUS_OK; @@ -204,7 +204,7 @@ static NTSTATUS common_gss_decrypt_buffer(struct smb_tran_enc_state_gss *gss_sta } memcpy(buf + 8, out_buf.value, out_buf.length); - smb_setlen(buf, out_buf.length + 4, out_buf.value); + smb_setlen(out_buf.value, buf, out_buf.length + 4); gss_release_buffer(&minor, &out_buf); return NT_STATUS_OK; -- cgit From 71921605995fa95d84301534760a6bc2db3fa74b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 7 May 2007 15:07:49 +0000 Subject: r22747: Fix some C++ warnings (This used to be commit a66a04e9f11f6c4462f2b56b447bae4eca7b177c) --- source3/libsmb/smb_seal.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb/smb_seal.c') diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index dde69570ab..81c6ff1bac 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -72,7 +72,7 @@ NTSTATUS common_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf) return NT_STATUS_BUFFER_TOO_SMALL; } - inbuf = smb_xmemdup(buf, buf_len); + inbuf = (char *)smb_xmemdup(buf, buf_len); /* Adjust for the signature. */ data_len = buf_len - 8 - NTLMSSP_SIG_SIZE; @@ -204,7 +204,7 @@ static NTSTATUS common_gss_decrypt_buffer(struct smb_tran_enc_state_gss *gss_sta } memcpy(buf + 8, out_buf.value, out_buf.length); - smb_setlen(out_buf.value, buf, out_buf.length + 4); + smb_setlen((char *)out_buf.value, buf, out_buf.length + 4); gss_release_buffer(&minor, &out_buf); return NT_STATUS_OK; @@ -269,7 +269,7 @@ static NTSTATUS common_gss_encrypt_buffer(struct smb_tran_enc_state_gss *gss_sta * bother :-*(. JRA. */ - *ppbuf_out = SMB_MALLOC(out_buf.length + 8); /* We know this can't wrap. */ + *ppbuf_out = (char *)SMB_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; -- cgit From d824b98f80ba186030cbb70b3a1e5daf80469ecd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 9 Jul 2007 19:25:36 +0000 Subject: r23779: Change from v2 or later to v3 or later. Jeremy. (This used to be commit 407e6e695b8366369b7c76af1ff76869b45347b3) --- source3/libsmb/smb_seal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/smb_seal.c') diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index 81c6ff1bac..4ae819cf86 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -5,7 +5,7 @@ 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 + 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, -- cgit From 5e54558c6dea67b56bbfaba5698f3a434d3dffb6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 00:52:41 +0000 Subject: r23784: use the GPLv3 boilerplate as recommended by the FSF and the license text (This used to be commit b0132e94fc5fef936aa766fb99a306b3628e9f07) --- source3/libsmb/smb_seal.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libsmb/smb_seal.c') diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index 4ae819cf86..33352b85ce 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -14,8 +14,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" -- cgit From e5a951325a6cac8567af3a66de6d2df577508ae4 Mon Sep 17 00:00:00 2001 From: "Gerald (Jerry) Carter" Date: Wed, 10 Oct 2007 15:34:30 -0500 Subject: [GLUE] Rsync SAMBA_3_2_0 SVN r25598 in order to create the v3-2-test branch. (This used to be commit 5c6c8e1fe93f340005110a7833946191659d88ab) --- source3/libsmb/smb_seal.c | 496 ---------------------------------------------- 1 file changed, 496 deletions(-) delete mode 100644 source3/libsmb/smb_seal.c (limited to 'source3/libsmb/smb_seal.c') diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c deleted file mode 100644 index 33352b85ce..0000000000 --- a/source3/libsmb/smb_seal.c +++ /dev/null @@ -1,496 +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 . -*/ - -#include "includes.h" - -/****************************************************************************** - Pull out the encryption context for this packet. 0 means global context. -******************************************************************************/ - -NTSTATUS get_enc_ctx_num(char *buf, uint16 *p_enc_ctx_num) -{ - if (smb_len(buf) < 8) { - return NT_STATUS_INVALID_BUFFER_SIZE; - } - - if (buf[4] == (char)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; -} - -/****************************************************************************** - 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. - NTLM decrypt an incoming buffer. - Abartlett tells me that SSPI puts the signature first before the encrypted - output, so cope with the same for compatibility. -******************************************************************************/ - -NTSTATUS common_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf) -{ - NTSTATUS status; - size_t buf_len = smb_len(buf) + 4; /* Don't forget the 4 length bytes. */ - size_t data_len; - char *inbuf; - DATA_BLOB sig; - - if (buf_len < 8 + NTLMSSP_SIG_SIZE) { - return NT_STATUS_BUFFER_TOO_SMALL; - } - - inbuf = (char *)smb_xmemdup(buf, buf_len); - - /* Adjust for the signature. */ - data_len = buf_len - 8 - NTLMSSP_SIG_SIZE; - - /* Point at the signature. */ - sig = data_blob_const(inbuf+8, NTLMSSP_SIG_SIZE); - - status = ntlmssp_unseal_packet(ntlmssp_state, - (unsigned char *)inbuf + 8 + NTLMSSP_SIG_SIZE, /* 4 byte len + 0xFF 'E' */ - data_len, - (unsigned char *)inbuf + 8 + NTLMSSP_SIG_SIZE, - data_len, - &sig); - - if (!NT_STATUS_IS_OK(status)) { - SAFE_FREE(inbuf); - return status; - } - - memcpy(buf + 8, inbuf + 8 + NTLMSSP_SIG_SIZE, data_len); - - /* Reset the length. */ - smb_setlen(inbuf, buf, data_len + 4); - - SAFE_FREE(inbuf); - return NT_STATUS_OK; -} - -/****************************************************************************** - Generic code for client and server. - NTLM encrypt an outgoing buffer. Return the encrypted pointer in ppbuf_out. - Abartlett tells me that SSPI puts the signature first before the encrypted - output, so do the same for compatibility. -******************************************************************************/ - -NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, - uint16 enc_ctx_num, - char *buf, - char **ppbuf_out) -{ - NTSTATUS status; - char *buf_out; - size_t data_len = smb_len(buf) - 4; /* Ignore the 0xFF SMB bytes. */ - DATA_BLOB sig; - - *ppbuf_out = NULL; - - if (data_len == 0) { - return NT_STATUS_BUFFER_TOO_SMALL; - } - - /* - * We know smb_len can't return a value > 128k, so no int overflow - * check needed. - */ - - buf_out = SMB_XMALLOC_ARRAY(char, 8 + NTLMSSP_SIG_SIZE + data_len); - - /* Copy the data from the original buffer. */ - - memcpy(buf_out + 8 + NTLMSSP_SIG_SIZE, buf + 8, data_len); - - smb_set_enclen(buf_out, smb_len(buf) + NTLMSSP_SIG_SIZE, enc_ctx_num); - - sig = data_blob(NULL, NTLMSSP_SIG_SIZE); - - status = ntlmssp_seal_packet(ntlmssp_state, - (unsigned char *)buf_out + 8 + NTLMSSP_SIG_SIZE, /* 4 byte len + 0xFF 'S' */ - data_len, - (unsigned char *)buf_out + 8 + NTLMSSP_SIG_SIZE, - data_len, - &sig); - - if (!NT_STATUS_IS_OK(status)) { - data_blob_free(&sig); - SAFE_FREE(buf_out); - return status; - } - - /* First 16 data bytes are signature for SSPI compatibility. */ - memcpy(buf_out + 8, sig.data, NTLMSSP_SIG_SIZE); - *ppbuf_out = buf_out; - 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(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) { - ADS_STATUS adss = ADS_ERROR_GSS(ret, minor); - DEBUG(0,("common_gss_encrypt_buffer: gss_unwrap failed. Error %s\n", - ads_errstr(adss) )); - return map_nt_error_from_gss(ret, minor); - } - - if (out_buf.length > in_buf.length) { - DEBUG(0,("common_gss_encrypt_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); - smb_setlen((char *)out_buf.value, 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 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(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) { - ADS_STATUS adss = ADS_ERROR_GSS(ret, minor); - DEBUG(0,("common_gss_encrypt_buffer: gss_wrap failed. Error %s\n", - ads_errstr(adss) )); - return map_nt_error_from_gss(ret, minor); - } - - 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 *)SMB_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_ntlm_encrypt_buffer(es->s.ntlmssp_state, 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_ntlm_decrypt_buffer(es->s.ntlmssp_state, 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.ntlmssp_state) { - ntlmssp_end(&es->s.ntlmssp_state); - } - } -#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) -{ - if (!common_encryption_on(es)) { - return; - } - - if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) { - SAFE_FREE(buf); - return; - } - -#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) - if (es->smb_enc_type == SMB_TRANS_ENC_GSS) { - OM_uint32 min; - gss_buffer_desc rel_buf; - rel_buf.value = buf; - rel_buf.length = smb_len(buf) + 4; - gss_release_buffer(&min, &rel_buf); - } -#endif -} - -/****************************************************************************** - Client side encryption. -******************************************************************************/ - -/****************************************************************************** - Is client encryption on ? -******************************************************************************/ - -BOOL cli_encryption_on(struct cli_state *cli) -{ - /* If we supported multiple encrytion contexts - * here we'd look up based on tid. - */ - return common_encryption_on(cli->trans_enc_state); -} - -/****************************************************************************** - Shutdown a client encryption state. -******************************************************************************/ - -void cli_free_encryption_context(struct cli_state *cli) -{ - common_free_encryption_state(&cli->trans_enc_state); -} - -/****************************************************************************** - Free an encryption-allocated buffer. -******************************************************************************/ - -void cli_free_enc_buffer(struct cli_state *cli, char *buf) -{ - /* We know this is an smb buffer, and we - * didn't malloc, only copy, for a keepalive, - * so ignore session keepalives. */ - - if(CVAL(buf,0) == SMBkeepalive) { - return; - } - - /* If we supported multiple encrytion contexts - * here we'd look up based on tid. - */ - common_free_enc_buffer(cli->trans_enc_state, buf); -} - -/****************************************************************************** - Decrypt an incoming buffer. -******************************************************************************/ - -NTSTATUS cli_decrypt_message(struct cli_state *cli) -{ - NTSTATUS status; - uint16 enc_ctx_num; - - /* Ignore session keepalives. */ - if(CVAL(cli->inbuf,0) == SMBkeepalive) { - return NT_STATUS_OK; - } - - status = get_enc_ctx_num(cli->inbuf, &enc_ctx_num); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - if (enc_ctx_num != cli->trans_enc_state->enc_ctx_num) { - return NT_STATUS_INVALID_HANDLE; - } - - return common_decrypt_buffer(cli->trans_enc_state, cli->inbuf); -} - -/****************************************************************************** - Encrypt an outgoing buffer. Return the encrypted pointer in buf_out. -******************************************************************************/ - -NTSTATUS cli_encrypt_message(struct cli_state *cli, char **buf_out) -{ - /* Ignore session keepalives. */ - if(CVAL(cli->outbuf,0) == SMBkeepalive) { - return NT_STATUS_OK; - } - - /* If we supported multiple encrytion contexts - * here we'd look up based on tid. - */ - return common_encrypt_buffer(cli->trans_enc_state, cli->outbuf, buf_out); -} -- cgit From afc93255d183eefb68e45b8ec6275f6a62cf9795 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 26 Dec 2007 17:12:36 -0800 Subject: Add SMB encryption. Still fixing client decrypt but negotiation works. Jeremy. (This used to be commit d78045601af787731f0737b8627450018902b104) --- source3/libsmb/smb_seal.c | 496 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 496 insertions(+) create mode 100644 source3/libsmb/smb_seal.c (limited to 'source3/libsmb/smb_seal.c') diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c new file mode 100644 index 0000000000..055a27d05a --- /dev/null +++ b/source3/libsmb/smb_seal.c @@ -0,0 +1,496 @@ +/* + 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 . +*/ + +#include "includes.h" + +/****************************************************************************** + Pull out the encryption context for this packet. 0 means global context. +******************************************************************************/ + +NTSTATUS get_enc_ctx_num(const char *buf, uint16 *p_enc_ctx_num) +{ + if (smb_len(buf) < 8) { + return NT_STATUS_INVALID_BUFFER_SIZE; + } + + if (buf[4] == (char)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; +} + +/****************************************************************************** + 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. + NTLM decrypt an incoming buffer. + Abartlett tells me that SSPI puts the signature first before the encrypted + output, so cope with the same for compatibility. +******************************************************************************/ + +NTSTATUS common_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf) +{ + NTSTATUS status; + size_t buf_len = smb_len(buf) + 4; /* Don't forget the 4 length bytes. */ + size_t data_len; + char *inbuf; + DATA_BLOB sig; + + if (buf_len < 8 + NTLMSSP_SIG_SIZE) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + + inbuf = (char *)smb_xmemdup(buf, buf_len); + + /* Adjust for the signature. */ + data_len = buf_len - 8 - NTLMSSP_SIG_SIZE; + + /* Point at the signature. */ + sig = data_blob_const(inbuf+8, NTLMSSP_SIG_SIZE); + + status = ntlmssp_unseal_packet(ntlmssp_state, + (unsigned char *)inbuf + 8 + NTLMSSP_SIG_SIZE, /* 4 byte len + 0xFF 'E' */ + data_len, + (unsigned char *)inbuf + 8 + NTLMSSP_SIG_SIZE, + data_len, + &sig); + + if (!NT_STATUS_IS_OK(status)) { + SAFE_FREE(inbuf); + return status; + } + + memcpy(buf + 8, inbuf + 8 + NTLMSSP_SIG_SIZE, data_len); + + /* Reset the length. */ + _smb_setlen(buf,data_len + 4); + + SAFE_FREE(inbuf); + return NT_STATUS_OK; +} + +/****************************************************************************** + Generic code for client and server. + NTLM encrypt an outgoing buffer. Return the encrypted pointer in ppbuf_out. + Abartlett tells me that SSPI puts the signature first before the encrypted + output, so do the same for compatibility. +******************************************************************************/ + +NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, + uint16 enc_ctx_num, + char *buf, + char **ppbuf_out) +{ + NTSTATUS status; + char *buf_out; + size_t data_len = smb_len(buf) - 4; /* Ignore the 0xFF SMB bytes. */ + DATA_BLOB sig; + + *ppbuf_out = NULL; + + if (data_len == 0) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + + /* + * We know smb_len can't return a value > 128k, so no int overflow + * check needed. + */ + + buf_out = SMB_XMALLOC_ARRAY(char, 8 + NTLMSSP_SIG_SIZE + data_len); + + /* Copy the data from the original buffer. */ + + memcpy(buf_out + 8 + NTLMSSP_SIG_SIZE, buf + 8, data_len); + + smb_set_enclen(buf_out, smb_len(buf) + NTLMSSP_SIG_SIZE, enc_ctx_num); + + sig = data_blob(NULL, NTLMSSP_SIG_SIZE); + + status = ntlmssp_seal_packet(ntlmssp_state, + (unsigned char *)buf_out + 8 + NTLMSSP_SIG_SIZE, /* 4 byte len + 0xFF 'S' */ + data_len, + (unsigned char *)buf_out + 8 + NTLMSSP_SIG_SIZE, + data_len, + &sig); + + if (!NT_STATUS_IS_OK(status)) { + data_blob_free(&sig); + SAFE_FREE(buf_out); + return status; + } + + /* First 16 data bytes are signature for SSPI compatibility. */ + memcpy(buf_out + 8, sig.data, NTLMSSP_SIG_SIZE); + *ppbuf_out = buf_out; + 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(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) { + ADS_STATUS adss = ADS_ERROR_GSS(ret, minor); + DEBUG(0,("common_gss_encrypt_buffer: gss_unwrap failed. Error %s\n", + ads_errstr(adss) )); + return map_nt_error_from_gss(ret, minor); + } + + if (out_buf.length > in_buf.length) { + DEBUG(0,("common_gss_encrypt_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); + _smb_setlen(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 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(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) { + ADS_STATUS adss = ADS_ERROR_GSS(ret, minor); + DEBUG(0,("common_gss_encrypt_buffer: gss_wrap failed. Error %s\n", + ads_errstr(adss) )); + return map_nt_error_from_gss(ret, minor); + } + + 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 *)SMB_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_ntlm_encrypt_buffer(es->s.ntlmssp_state, 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_ntlm_decrypt_buffer(es->s.ntlmssp_state, 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.ntlmssp_state) { + ntlmssp_end(&es->s.ntlmssp_state); + } + } +#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) +{ + if (!common_encryption_on(es)) { + return; + } + + if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) { + SAFE_FREE(buf); + return; + } + +#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) + if (es->smb_enc_type == SMB_TRANS_ENC_GSS) { + OM_uint32 min; + gss_buffer_desc rel_buf; + rel_buf.value = buf; + rel_buf.length = smb_len(buf) + 4; + gss_release_buffer(&min, &rel_buf); + } +#endif +} + +/****************************************************************************** + Client side encryption. +******************************************************************************/ + +/****************************************************************************** + Is client encryption on ? +******************************************************************************/ + +bool cli_encryption_on(struct cli_state *cli) +{ + /* If we supported multiple encrytion contexts + * here we'd look up based on tid. + */ + return common_encryption_on(cli->trans_enc_state); +} + +/****************************************************************************** + Shutdown a client encryption state. +******************************************************************************/ + +void cli_free_encryption_context(struct cli_state *cli) +{ + common_free_encryption_state(&cli->trans_enc_state); +} + +/****************************************************************************** + Free an encryption-allocated buffer. +******************************************************************************/ + +void cli_free_enc_buffer(struct cli_state *cli, char *buf) +{ + /* We know this is an smb buffer, and we + * didn't malloc, only copy, for a keepalive, + * so ignore session keepalives. */ + + if(CVAL(buf,0) == SMBkeepalive) { + return; + } + + /* If we supported multiple encrytion contexts + * here we'd look up based on tid. + */ + common_free_enc_buffer(cli->trans_enc_state, buf); +} + +/****************************************************************************** + Decrypt an incoming buffer. +******************************************************************************/ + +NTSTATUS cli_decrypt_message(struct cli_state *cli) +{ + NTSTATUS status; + uint16 enc_ctx_num; + + /* Ignore session keepalives. */ + if(CVAL(cli->inbuf,0) == SMBkeepalive) { + return NT_STATUS_OK; + } + + status = get_enc_ctx_num(cli->inbuf, &enc_ctx_num); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (enc_ctx_num != cli->trans_enc_state->enc_ctx_num) { + return NT_STATUS_INVALID_HANDLE; + } + + return common_decrypt_buffer(cli->trans_enc_state, cli->inbuf); +} + +/****************************************************************************** + Encrypt an outgoing buffer. Return the encrypted pointer in buf_out. +******************************************************************************/ + +NTSTATUS cli_encrypt_message(struct cli_state *cli, char **buf_out) +{ + /* Ignore session keepalives. */ + if(CVAL(cli->outbuf,0) == SMBkeepalive) { + return NT_STATUS_OK; + } + + /* If we supported multiple encrytion contexts + * here we'd look up based on tid. + */ + return common_encrypt_buffer(cli->trans_enc_state, cli->outbuf, buf_out); +} -- cgit From 9254bb4ef1c3c3a52ea8e935edb0e7a86ec3ea7a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 4 Jan 2008 12:56:23 -0800 Subject: Refactor the crypto code after a very helpful conversation with Volker. Mostly making sure we have data on the incoming packet type, not stored in the smb header. Jeremy. (This used to be commit c4e5a505043965eec77b5bb9bc60957e8f3b97c8) --- source3/libsmb/smb_seal.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'source3/libsmb/smb_seal.c') diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index 055a27d05a..b5befbf7cd 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -23,13 +23,13 @@ Pull out the encryption context for this packet. 0 means global context. ******************************************************************************/ -NTSTATUS get_enc_ctx_num(const char *buf, uint16 *p_enc_ctx_num) +NTSTATUS get_enc_ctx_num(const uint8_t *buf, uint16 *p_enc_ctx_num) { if (smb_len(buf) < 8) { return NT_STATUS_INVALID_BUFFER_SIZE; } - if (buf[4] == (char)0xFF) { + if (buf[4] == 0xFF) { if (buf[5] == 'S' && buf [6] == 'M' && buf[7] == 'B') { /* Not an encrypted buffer. */ return NT_STATUS_NOT_FOUND; @@ -93,8 +93,8 @@ NTSTATUS common_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf) memcpy(buf + 8, inbuf + 8 + NTLMSSP_SIG_SIZE, data_len); - /* Reset the length. */ - _smb_setlen(buf,data_len + 4); + /* Reset the length and overwrite the header. */ + smb_setlen(buf,data_len + 4); SAFE_FREE(inbuf); return NT_STATUS_OK; @@ -203,7 +203,8 @@ static NTSTATUS common_gss_decrypt_buffer(struct smb_tran_enc_state_gss *gss_sta } memcpy(buf + 8, out_buf.value, out_buf.length); - _smb_setlen(buf, out_buf.length + 4); + /* Reset the length and overwrite the header. */ + smb_setlen(buf, out_buf.length + 4); gss_release_buffer(&minor, &out_buf); return NT_STATUS_OK; @@ -440,9 +441,9 @@ void cli_free_enc_buffer(struct cli_state *cli, char *buf) { /* We know this is an smb buffer, and we * didn't malloc, only copy, for a keepalive, - * so ignore session keepalives. */ + * so ignore non-session messages. */ - if(CVAL(buf,0) == SMBkeepalive) { + if(CVAL(buf,0)) { return; } @@ -461,12 +462,12 @@ NTSTATUS cli_decrypt_message(struct cli_state *cli) NTSTATUS status; uint16 enc_ctx_num; - /* Ignore session keepalives. */ - if(CVAL(cli->inbuf,0) == SMBkeepalive) { + /* Ignore non-session messages. */ + if(CVAL(cli->inbuf,0)) { return NT_STATUS_OK; } - status = get_enc_ctx_num(cli->inbuf, &enc_ctx_num); + status = get_enc_ctx_num((const uint8_t *)cli->inbuf, &enc_ctx_num); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -484,8 +485,8 @@ NTSTATUS cli_decrypt_message(struct cli_state *cli) NTSTATUS cli_encrypt_message(struct cli_state *cli, char **buf_out) { - /* Ignore session keepalives. */ - if(CVAL(cli->outbuf,0) == SMBkeepalive) { + /* Ignore non-session messages. */ + if(CVAL(cli->outbuf,0)) { return NT_STATUS_OK; } -- cgit From 4b5169f590425334d9ae3f2b7be2201e2e0b747e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 12 Feb 2008 11:54:37 +0100 Subject: Add explicit buf arg to cli_encrypt_message and cli_calculate_sign_mac (This used to be commit db6ae9ed2326e6cd68475375d049084cf1d5a98c) --- source3/libsmb/smb_seal.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb/smb_seal.c') diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index b5befbf7cd..a81ae9afd5 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -483,15 +483,15 @@ NTSTATUS cli_decrypt_message(struct cli_state *cli) Encrypt an outgoing buffer. Return the encrypted pointer in buf_out. ******************************************************************************/ -NTSTATUS cli_encrypt_message(struct cli_state *cli, char **buf_out) +NTSTATUS cli_encrypt_message(struct cli_state *cli, char *buf, char **buf_out) { /* Ignore non-session messages. */ - if(CVAL(cli->outbuf,0)) { + if (CVAL(buf,0)) { return NT_STATUS_OK; } /* If we supported multiple encrytion contexts * here we'd look up based on tid. */ - return common_encrypt_buffer(cli->trans_enc_state, cli->outbuf, buf_out); + return common_encrypt_buffer(cli->trans_enc_state, buf, buf_out); } -- cgit