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,
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 <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
+#include "../auth/ntlmssp/ntlmssp.h"
+#include "smb_crypt.h"
+#include "libsmb/libsmb.h"
+#include "ntlmssp_wrap.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)
+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;
Is encryption turned on ?
******************************************************************************/
-BOOL common_encryption_on(struct smb_trans_enc_state *es)
+bool common_encryption_on(struct smb_trans_enc_state *es)
{
return ((es != NULL) && es->enc_on);
}
output, so cope with the same for compatibility.
******************************************************************************/
-NTSTATUS common_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf)
+static NTSTATUS common_ntlm_decrypt_buffer(struct auth_ntlmssp_state *auth_ntlmssp_state, char *buf)
{
NTSTATUS status;
size_t buf_len = smb_len(buf) + 4; /* Don't forget the 4 length bytes. */
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;
/* Point at the signature. */
sig = data_blob_const(inbuf+8, NTLMSSP_SIG_SIZE);
- status = ntlmssp_unseal_packet(ntlmssp_state,
+ status = auth_ntlmssp_unseal_packet(auth_ntlmssp_state,
(unsigned char *)inbuf + 8 + NTLMSSP_SIG_SIZE, /* 4 byte len + 0xFF 'E' <enc> <ctx> */
data_len,
(unsigned char *)inbuf + 8 + NTLMSSP_SIG_SIZE,
}
memcpy(buf + 8, inbuf + 8 + NTLMSSP_SIG_SIZE, data_len);
- SAFE_FREE(inbuf);
- /* 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;
}
output, so do the same for compatibility.
******************************************************************************/
-NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state,
+static NTSTATUS common_ntlm_encrypt_buffer(struct auth_ntlmssp_state *auth_ntlmssp_state,
uint16 enc_ctx_num,
char *buf,
char **ppbuf_out)
char *buf_out;
size_t data_len = smb_len(buf) - 4; /* Ignore the 0xFF SMB bytes. */
DATA_BLOB sig;
-
+ TALLOC_CTX *frame;
*ppbuf_out = NULL;
if (data_len == 0) {
return NT_STATUS_BUFFER_TOO_SMALL;
}
+ frame = talloc_stackframe();
/*
* We know smb_len can't return a value > 128k, so no int overflow
* check needed.
smb_set_enclen(buf_out, smb_len(buf) + NTLMSSP_SIG_SIZE, enc_ctx_num);
- sig = data_blob(NULL, NTLMSSP_SIG_SIZE);
+ ZERO_STRUCT(sig);
- status = ntlmssp_seal_packet(ntlmssp_state,
+ status = auth_ntlmssp_seal_packet(auth_ntlmssp_state,
+ frame,
(unsigned char *)buf_out + 8 + NTLMSSP_SIG_SIZE, /* 4 byte len + 0xFF 'S' <enc> <ctx> */
data_len,
(unsigned char *)buf_out + 8 + NTLMSSP_SIG_SIZE,
&sig);
if (!NT_STATUS_IS_OK(status)) {
- data_blob_free(&sig);
+ talloc_free(frame);
SAFE_FREE(buf_out);
return status;
}
/* First 16 data bytes are signature for SSPI compatibility. */
memcpy(buf_out + 8, sig.data, NTLMSSP_SIG_SIZE);
+ talloc_free(frame);
*ppbuf_out = buf_out;
return NT_STATUS_OK;
}
}
memcpy(buf + 8, out_buf.value, out_buf.length);
+ /* Reset the length and overwrite the header. */
smb_setlen(buf, out_buf.length + 4);
gss_release_buffer(&minor, &out_buf);
ret = gss_wrap(&minor,
gss_ctx,
- True, /* we want sign+seal. */
+ true, /* we want sign+seal. */
GSS_C_QOP_DEFAULT,
&in_buf,
&flags_got, /* did we get sign+seal ? */
* 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;
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);
+ return common_ntlm_encrypt_buffer(es->s.auth_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);
switch (es->smb_enc_type) {
case SMB_TRANS_ENC_NTLM:
- return common_ntlm_decrypt_buffer(es->s.ntlmssp_state, buf);
+ return common_ntlm_decrypt_buffer(es->s.auth_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);
}
if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) {
- if (es->s.ntlmssp_state) {
- ntlmssp_end(&es->s.ntlmssp_state);
+ if (es->s.auth_ntlmssp_state) {
+ TALLOC_FREE(es->s.auth_ntlmssp_state);
}
}
#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
void common_free_enc_buffer(struct smb_trans_enc_state *es, char *buf)
{
+ uint16_t enc_ctx_num;
+
if (!common_encryption_on(es)) {
return;
}
+ if (!NT_STATUS_IS_OK(get_enc_ctx_num((const uint8_t *)buf,
+ &enc_ctx_num))) {
+ return;
+ }
+
if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) {
SAFE_FREE(buf);
return;
}
#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);
-}