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/include/client.h | 1 + source3/lib/util_sock.c | 4 +- source3/libsmb/clientgen.c | 13 +- source3/libsmb/smb_seal.c | 299 ++++++++++++++++++++++++++++++++------------- 4 files changed, 224 insertions(+), 93 deletions(-) (limited to 'source3') diff --git a/source3/include/client.h b/source3/include/client.h index 97922ba232..0f268834c6 100644 --- a/source3/include/client.h +++ b/source3/include/client.h @@ -83,6 +83,7 @@ enum smb_trans_enc_type { SMB_TRANS_ENC_NTLM, SMB_TRANS_ENC_KRB5 }; struct smb_trans_enc_state { enum smb_trans_enc_type smb_enc_type; + BOOL enc_on; union { NTLMSSP_STATE *ntlmssp_state; #if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 296405edd3..755ad39261 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -789,13 +789,13 @@ BOOL send_smb(int fd, char *buffer) if (ret <= 0) { DEBUG(0,("Error writing %d bytes to client. %d. (%s)\n", (int)len,(int)ret, strerror(errno) )); - srv_free_buffer(buf_out); + srv_free_enc_buffer(buf_out); return False; } nwritten += ret; } - srv_free_buffer(buf_out); + srv_free_enc_buffer(buf_out); return True; } diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index cdf36d9b9c..52ffdc24e7 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -164,6 +164,7 @@ BOOL cli_send_smb(struct cli_state *cli) size_t len; size_t nwritten=0; ssize_t ret; + char *buf_out; /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ if (cli->fd == -1) { @@ -172,7 +173,7 @@ BOOL cli_send_smb(struct cli_state *cli) cli_calculate_sign_mac(cli); - status = cli_encrypt_message(cli); + status = cli_encrypt_message(cli, &buf_out); if (!NT_STATUS_IS_OK(status)) { close(cli->fd); cli->fd = -1; @@ -182,11 +183,12 @@ BOOL cli_send_smb(struct cli_state *cli) return False; } - len = smb_len(cli->outbuf) + 4; + len = smb_len(buf_out) + 4; while (nwritten < len) { - ret = write_socket(cli->fd,cli->outbuf+nwritten,len - nwritten); + ret = write_socket(cli->fd,buf_out+nwritten,len - nwritten); if (ret <= 0) { + cli_free_enc_buffer(cli, buf_out); close(cli->fd); cli->fd = -1; cli->smb_rw_error = WRITE_ERROR; @@ -196,6 +198,9 @@ BOOL cli_send_smb(struct cli_state *cli) } nwritten += ret; } + + cli_free_enc_buffer(cli, buf_out); + /* Increment the mid so we can tell between responses. */ cli->mid++; if (!cli->mid) { @@ -447,6 +452,8 @@ void cli_shutdown(struct cli_state *cli) SAFE_FREE(cli->inbuf); cli_free_signing_context(cli); + cli_free_encryption_context(cli); + data_blob_free(&cli->secblob); data_blob_free(&cli->user_session_key); 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