summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2010-05-25 20:55:40 +1000
committerGünther Deschner <gd@samba.org>2010-05-31 15:11:27 +0200
commitd6fa371b92681a327a86239721fc5990d91ad74f (patch)
tree4f2cdef8f42b544a05237670bab6b0a5cca56f99
parentebae21f0235b957c8faeeb51c926724909d353e9 (diff)
downloadsamba-d6fa371b92681a327a86239721fc5990d91ad74f.tar.gz
samba-d6fa371b92681a327a86239721fc5990d91ad74f.tar.bz2
samba-d6fa371b92681a327a86239721fc5990d91ad74f.zip
s3:ntlmssp Use a TALLOC_CTX for ntlmssp_sign_packet() and ntlmssp_seal_packet()
This ensures the results can't be easily left to leak. Andrew Bartlett Signed-off-by: Stefan Metzmacher <metze@samba.org> Signed-off-by: Günther Deschner <gd@samba.org>
-rw-r--r--source3/auth/auth_ntlmssp.c6
-rw-r--r--source3/include/proto.h4
-rw-r--r--source3/libads/sasl.c6
-rw-r--r--source3/libsmb/ntlmssp_sign.c38
-rw-r--r--source3/libsmb/smb_seal.c8
-rw-r--r--source3/rpc_client/cli_pipe.c15
-rw-r--r--source3/rpc_server/srv_pipe.c16
7 files changed, 67 insertions, 26 deletions
diff --git a/source3/auth/auth_ntlmssp.c b/source3/auth/auth_ntlmssp.c
index b455bc505f..e0e0003f9d 100644
--- a/source3/auth/auth_ntlmssp.c
+++ b/source3/auth/auth_ntlmssp.c
@@ -31,11 +31,12 @@ struct auth_ntlmssp_state {
};
NTSTATUS auth_ntlmssp_sign_packet(struct auth_ntlmssp_state *auth_ntlmssp_state,
+ TALLOC_CTX *sig_mem_ctx,
const uint8_t *data, size_t length,
const uint8_t *whole_pdu, size_t pdu_length,
DATA_BLOB *sig)
{
- return ntlmssp_sign_packet(auth_ntlmssp_state->ntlmssp_state, data, length, whole_pdu, pdu_length, sig);
+ return ntlmssp_sign_packet(auth_ntlmssp_state->ntlmssp_state, sig_mem_ctx, data, length, whole_pdu, pdu_length, sig);
}
NTSTATUS auth_ntlmssp_check_packet(struct auth_ntlmssp_state *auth_ntlmssp_state,
@@ -47,11 +48,12 @@ NTSTATUS auth_ntlmssp_check_packet(struct auth_ntlmssp_state *auth_ntlmssp_state
}
NTSTATUS auth_ntlmssp_seal_packet(struct auth_ntlmssp_state *auth_ntlmssp_state,
+ TALLOC_CTX *sig_mem_ctx,
uint8_t *data, size_t length,
const uint8_t *whole_pdu, size_t pdu_length,
DATA_BLOB *sig)
{
- return ntlmssp_seal_packet(auth_ntlmssp_state->ntlmssp_state, data, length, whole_pdu, pdu_length, sig);
+ return ntlmssp_seal_packet(auth_ntlmssp_state->ntlmssp_state, sig_mem_ctx, data, length, whole_pdu, pdu_length, sig);
}
NTSTATUS auth_ntlmssp_unseal_packet(struct auth_ntlmssp_state *auth_ntlmssp_state,
diff --git a/source3/include/proto.h b/source3/include/proto.h
index d479edbc9f..472e1793ca 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -67,6 +67,7 @@ void auth_ntlmssp_end(struct auth_ntlmssp_state **auth_ntlmssp_state);
NTSTATUS auth_ntlmssp_update(struct auth_ntlmssp_state *auth_ntlmssp_state,
const DATA_BLOB request, DATA_BLOB *reply) ;
NTSTATUS auth_ntlmssp_sign_packet(struct auth_ntlmssp_state *auth_ntlmssp_state,
+ TALLOC_CTX *sig_mem_ctx,
const uint8_t *data, size_t length,
const uint8_t *whole_pdu, size_t pdu_length,
DATA_BLOB *sig);
@@ -75,6 +76,7 @@ NTSTATUS auth_ntlmssp_check_packet(struct auth_ntlmssp_state *auth_ntlmssp_state
const uint8_t *whole_pdu, size_t pdu_length,
const DATA_BLOB *sig) ;
NTSTATUS auth_ntlmssp_seal_packet(struct auth_ntlmssp_state *auth_ntlmssp_state,
+ TALLOC_CTX *sig_mem_ctx,
uint8_t *data, size_t length,
const uint8_t *whole_pdu, size_t pdu_length,
DATA_BLOB *sig);
@@ -3162,6 +3164,7 @@ NTSTATUS ntlmssp_client_start(TALLOC_CTX *mem_ctx,
/* The following definitions come from libsmb/ntlmssp_sign.c */
NTSTATUS ntlmssp_sign_packet(struct ntlmssp_state *ntlmssp_state,
+ TALLOC_CTX *sig_mem_ctx,
const uint8_t *data, size_t length,
const uint8_t *whole_pdu, size_t pdu_length,
DATA_BLOB *sig);
@@ -3170,6 +3173,7 @@ NTSTATUS ntlmssp_check_packet(struct ntlmssp_state *ntlmssp_state,
const uint8_t *whole_pdu, size_t pdu_length,
const DATA_BLOB *sig) ;
NTSTATUS ntlmssp_seal_packet(struct ntlmssp_state *ntlmssp_state,
+ TALLOC_CTX *sig_mem_ctx,
uint8_t *data, size_t length,
const uint8_t *whole_pdu, size_t pdu_length,
DATA_BLOB *sig);
diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c
index 8f7f6c11df..04b9a71d76 100644
--- a/source3/libads/sasl.c
+++ b/source3/libads/sasl.c
@@ -30,19 +30,23 @@ static ADS_STATUS ads_sasl_ntlmssp_wrap(ADS_STRUCT *ads, uint8 *buf, uint32 len)
ADS_STATUS status;
NTSTATUS nt_status;
DATA_BLOB sig;
+ TALLOC_CTX *frame;
uint8 *dptr = ads->ldap.out.buf + (4 + NTLMSSP_SIG_SIZE);
+ frame = talloc_stackframe();
/* copy the data to the right location */
memcpy(dptr, buf, len);
/* create the signature and may encrypt the data */
if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL) {
nt_status = ntlmssp_seal_packet(ntlmssp_state,
+ frame,
dptr, len,
dptr, len,
&sig);
} else {
nt_status = ntlmssp_sign_packet(ntlmssp_state,
+ frame,
dptr, len,
dptr, len,
&sig);
@@ -54,7 +58,7 @@ static ADS_STATUS ads_sasl_ntlmssp_wrap(ADS_STRUCT *ads, uint8 *buf, uint32 len)
memcpy(ads->ldap.out.buf + 4,
sig.data, NTLMSSP_SIG_SIZE);
- data_blob_free(&sig);
+ TALLOC_FREE(frame);
/* set how many bytes must be written to the underlying socket */
ads->ldap.out.left = 4 + NTLMSSP_SIG_SIZE + len;
diff --git a/source3/libsmb/ntlmssp_sign.c b/source3/libsmb/ntlmssp_sign.c
index 20730928cc..8ae244b70b 100644
--- a/source3/libsmb/ntlmssp_sign.c
+++ b/source3/libsmb/ntlmssp_sign.c
@@ -81,6 +81,7 @@ union ntlmssp_crypt_state {
};
static NTSTATUS ntlmssp_make_packet_signature(struct ntlmssp_state *ntlmssp_state,
+ TALLOC_CTX *sig_mem_ctx,
const uint8_t *data, size_t length,
const uint8_t *whole_pdu, size_t pdu_length,
enum ntlmssp_direction direction,
@@ -91,7 +92,7 @@ static NTSTATUS ntlmssp_make_packet_signature(struct ntlmssp_state *ntlmssp_stat
uint8_t digest[16];
uint8_t seq_num[4];
- *sig = data_blob(NULL, NTLMSSP_SIG_SIZE);
+ *sig = data_blob_talloc(sig_mem_ctx, NULL, NTLMSSP_SIG_SIZE);
if (!sig->data) {
return NT_STATUS_NO_MEMORY;
}
@@ -151,7 +152,7 @@ static NTSTATUS ntlmssp_make_packet_signature(struct ntlmssp_state *ntlmssp_stat
crc = crc32_calc_buffer(data, length);
- ok = msrpc_gen(ntlmssp_state,
+ ok = msrpc_gen(sig_mem_ctx,
sig, "dddd",
NTLMSSP_SIGN_VERSION, 0, crc,
ntlmssp_state->crypt->ntlm.seq_num);
@@ -170,6 +171,7 @@ static NTSTATUS ntlmssp_make_packet_signature(struct ntlmssp_state *ntlmssp_stat
}
NTSTATUS ntlmssp_sign_packet(struct ntlmssp_state *ntlmssp_state,
+ TALLOC_CTX *sig_mem_ctx,
const uint8_t *data, size_t length,
const uint8_t *whole_pdu, size_t pdu_length,
DATA_BLOB *sig)
@@ -187,6 +189,7 @@ NTSTATUS ntlmssp_sign_packet(struct ntlmssp_state *ntlmssp_state,
}
nt_status = ntlmssp_make_packet_signature(ntlmssp_state,
+ sig_mem_ctx,
data, length,
whole_pdu, pdu_length,
NTLMSSP_SEND, sig, true);
@@ -207,6 +210,7 @@ NTSTATUS ntlmssp_check_packet(struct ntlmssp_state *ntlmssp_state,
{
DATA_BLOB local_sig;
NTSTATUS nt_status;
+ TALLOC_CTX *tmp_ctx;
if (!ntlmssp_state->session_key.length) {
DEBUG(3, ("NO session key, cannot check packet signature\n"));
@@ -218,7 +222,13 @@ NTSTATUS ntlmssp_check_packet(struct ntlmssp_state *ntlmssp_state,
(unsigned long)sig->length));
}
+ tmp_ctx = talloc_new(ntlmssp_state);
+ if (!tmp_ctx) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
nt_status = ntlmssp_make_packet_signature(ntlmssp_state,
+ tmp_ctx,
data, length,
whole_pdu, pdu_length,
NTLMSSP_RECEIVE,
@@ -227,7 +237,7 @@ NTSTATUS ntlmssp_check_packet(struct ntlmssp_state *ntlmssp_state,
if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(0,("NTLMSSP packet sig creation failed with %s\n",
nt_errstr(nt_status)));
- data_blob_free(&local_sig);
+ talloc_free(tmp_ctx);
return nt_status;
}
@@ -241,7 +251,7 @@ NTSTATUS ntlmssp_check_packet(struct ntlmssp_state *ntlmssp_state,
dump_data(5, sig->data, sig->length);
DEBUG(0, ("NTLMSSP NTLM2 packet check failed due to invalid signature!\n"));
- data_blob_free(&local_sig);
+ talloc_free(tmp_ctx);
return NT_STATUS_ACCESS_DENIED;
}
} else {
@@ -254,14 +264,14 @@ NTSTATUS ntlmssp_check_packet(struct ntlmssp_state *ntlmssp_state,
dump_data(5, sig->data, sig->length);
DEBUG(0, ("NTLMSSP NTLM1 packet check failed due to invalid signature!\n"));
- data_blob_free(&local_sig);
+ talloc_free(tmp_ctx);
return NT_STATUS_ACCESS_DENIED;
}
}
dump_data_pw("checked ntlmssp signature\n", sig->data, sig->length);
DEBUG(10,("ntlmssp_check_packet: NTLMSSP signature OK !\n"));
- data_blob_free(&local_sig);
+ talloc_free(tmp_ctx);
return NT_STATUS_OK;
}
@@ -271,6 +281,7 @@ NTSTATUS ntlmssp_check_packet(struct ntlmssp_state *ntlmssp_state,
*/
NTSTATUS ntlmssp_seal_packet(struct ntlmssp_state *ntlmssp_state,
+ TALLOC_CTX *sig_mem_ctx,
uint8_t *data, size_t length,
const uint8_t *whole_pdu, size_t pdu_length,
DATA_BLOB *sig)
@@ -297,6 +308,7 @@ NTSTATUS ntlmssp_seal_packet(struct ntlmssp_state *ntlmssp_state,
* updated with each iteration
*/
nt_status = ntlmssp_make_packet_signature(ntlmssp_state,
+ sig_mem_ctx,
data, length,
whole_pdu, pdu_length,
NTLMSSP_SEND,
@@ -317,7 +329,7 @@ NTSTATUS ntlmssp_seal_packet(struct ntlmssp_state *ntlmssp_state,
crc = crc32_calc_buffer(data, length);
- ok = msrpc_gen(ntlmssp_state,
+ ok = msrpc_gen(sig_mem_ctx,
sig, "dddd",
NTLMSSP_SIGN_VERSION, 0, crc,
ntlmssp_state->crypt->ntlm.seq_num);
@@ -362,6 +374,7 @@ NTSTATUS ntlmssp_unseal_packet(struct ntlmssp_state *ntlmssp_state,
const uint8_t *whole_pdu, size_t pdu_length,
const DATA_BLOB *sig)
{
+ NTSTATUS status;
if (!ntlmssp_state->session_key.length) {
DEBUG(3, ("NO session key, cannot unseal packet\n"));
return NT_STATUS_NO_USER_SESSION_KEY;
@@ -380,7 +393,16 @@ NTSTATUS ntlmssp_unseal_packet(struct ntlmssp_state *ntlmssp_state,
data, length);
dump_data_pw("ntlmv1 clear data\n", data, length);
}
- return ntlmssp_check_packet(ntlmssp_state, data, length, whole_pdu, pdu_length, sig);
+ status = ntlmssp_check_packet(ntlmssp_state,
+ data, length,
+ whole_pdu, pdu_length,
+ sig);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(1,("NTLMSSP packet check for unseal failed due to invalid signature on %llu bytes of input:\n",
+ (unsigned long long)length));
+ }
+ return status;
}
/**
diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c
index cff237bc8b..92d7fef651 100644
--- a/source3/libsmb/smb_seal.c
+++ b/source3/libsmb/smb_seal.c
@@ -117,13 +117,14 @@ NTSTATUS common_ntlm_encrypt_buffer(struct ntlmssp_state *ntlmssp_state,
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.
@@ -140,6 +141,7 @@ NTSTATUS common_ntlm_encrypt_buffer(struct ntlmssp_state *ntlmssp_state,
ZERO_STRUCT(sig);
status = ntlmssp_seal_packet(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,
@@ -147,14 +149,14 @@ NTSTATUS common_ntlm_encrypt_buffer(struct ntlmssp_state *ntlmssp_state,
&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);
- data_blob_free(&sig);
+ talloc_free(frame);
*ppbuf_out = buf_out;
return NT_STATUS_OK;
}
diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c
index 0cd4d60b5d..e248133de3 100644
--- a/source3/rpc_client/cli_pipe.c
+++ b/source3/rpc_client/cli_pipe.c
@@ -1976,11 +1976,14 @@ static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
NTSTATUS status;
DATA_BLOB auth_blob = data_blob_null;
uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
+ TALLOC_CTX *frame;
if (!cli->auth->a_u.ntlmssp_state) {
return NT_STATUS_INVALID_PARAMETER;
}
+ frame = talloc_stackframe();
+
/* Init and marshall the auth header. */
init_rpc_hdr_auth(&auth_info,
map_pipe_auth_type_to_rpc_auth_type(
@@ -1991,7 +1994,7 @@ static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
- data_blob_free(&auth_blob);
+ talloc_free(frame);
return NT_STATUS_NO_MEMORY;
}
@@ -1999,13 +2002,14 @@ static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
case DCERPC_AUTH_LEVEL_PRIVACY:
/* Data portion is encrypted. */
status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
+ frame,
(unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
data_and_pad_len,
(unsigned char *)prs_data_p(outgoing_pdu),
(size_t)prs_offset(outgoing_pdu),
&auth_blob);
if (!NT_STATUS_IS_OK(status)) {
- data_blob_free(&auth_blob);
+ talloc_free(frame);
return status;
}
break;
@@ -2013,13 +2017,14 @@ static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
case DCERPC_AUTH_LEVEL_INTEGRITY:
/* Data is signed. */
status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
+ frame,
(unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
data_and_pad_len,
(unsigned char *)prs_data_p(outgoing_pdu),
(size_t)prs_offset(outgoing_pdu),
&auth_blob);
if (!NT_STATUS_IS_OK(status)) {
- data_blob_free(&auth_blob);
+ talloc_free(frame);
return status;
}
break;
@@ -2036,11 +2041,11 @@ static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
(unsigned int)NTLMSSP_SIG_SIZE));
- data_blob_free(&auth_blob);
+ talloc_free(frame);
return NT_STATUS_NO_MEMORY;
}
- data_blob_free(&auth_blob);
+ talloc_free(frame);
return NT_STATUS_OK;
}
diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c
index ce087a4e03..50914acfbd 100644
--- a/source3/rpc_server/srv_pipe.c
+++ b/source3/rpc_server/srv_pipe.c
@@ -68,6 +68,7 @@ static bool create_next_pdu_ntlmssp(pipes_struct *p)
RPC_HDR_AUTH auth_info;
uint8 auth_type, auth_level;
struct auth_ntlmssp_state *a = p->auth.a_u.auth_ntlmssp_state;
+ TALLOC_CTX *frame;
/*
* If we're in the fault state, keep returning fault PDU's until
@@ -222,11 +223,12 @@ static bool create_next_pdu_ntlmssp(pipes_struct *p)
/* Generate the sign blob. */
+ frame = talloc_stackframe();
switch (p->auth.auth_level) {
case DCERPC_AUTH_LEVEL_PRIVACY:
/* Data portion is encrypted. */
status = auth_ntlmssp_seal_packet(
- a,
+ a, frame,
(uint8_t *)prs_data_p(&p->out_data.frag)
+ RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
data_len + ss_padding_len,
@@ -234,7 +236,7 @@ static bool create_next_pdu_ntlmssp(pipes_struct *p)
(size_t)prs_offset(&p->out_data.frag),
&auth_blob);
if (!NT_STATUS_IS_OK(status)) {
- data_blob_free(&auth_blob);
+ talloc_free(frame);
prs_mem_free(&p->out_data.frag);
return False;
}
@@ -242,7 +244,7 @@ static bool create_next_pdu_ntlmssp(pipes_struct *p)
case DCERPC_AUTH_LEVEL_INTEGRITY:
/* Data is signed. */
status = auth_ntlmssp_sign_packet(
- a,
+ a, frame,
(unsigned char *)prs_data_p(&p->out_data.frag)
+ RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
data_len + ss_padding_len,
@@ -250,12 +252,13 @@ static bool create_next_pdu_ntlmssp(pipes_struct *p)
(size_t)prs_offset(&p->out_data.frag),
&auth_blob);
if (!NT_STATUS_IS_OK(status)) {
- data_blob_free(&auth_blob);
+ talloc_free(frame);
prs_mem_free(&p->out_data.frag);
return False;
}
break;
default:
+ talloc_free(frame);
prs_mem_free(&p->out_data.frag);
return False;
}
@@ -265,12 +268,11 @@ static bool create_next_pdu_ntlmssp(pipes_struct *p)
NTLMSSP_SIG_SIZE)) {
DEBUG(0,("create_next_pdu_ntlmssp: failed to add %u bytes auth blob.\n",
(unsigned int)NTLMSSP_SIG_SIZE));
- data_blob_free(&auth_blob);
+ talloc_free(frame);
prs_mem_free(&p->out_data.frag);
return False;
}
-
- data_blob_free(&auth_blob);
+ talloc_free(frame);
/*
* Setup the counts for this PDU.