summaryrefslogtreecommitdiffstats
path: root/auth
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2013-12-31 10:11:18 +0100
committerStefan Metzmacher <metze@samba.org>2014-01-07 00:27:11 +0100
commit03006d0e4471465f071517097145806fbe46fdba (patch)
tree8e29dd7cfda6faaecfa1c42e659281825a947aaa /auth
parent616cd009955b1722e6749019e2c1cac8bbb94e52 (diff)
downloadsamba-03006d0e4471465f071517097145806fbe46fdba.tar.gz
samba-03006d0e4471465f071517097145806fbe46fdba.tar.xz
samba-03006d0e4471465f071517097145806fbe46fdba.zip
auth/gensec: implement GENSEC_FEATURE_SIGN_PKT_HEADER in schannel.c
Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Diffstat (limited to 'auth')
-rw-r--r--auth/gensec/schannel.c56
1 files changed, 46 insertions, 10 deletions
diff --git a/auth/gensec/schannel.c b/auth/gensec/schannel.c
index c60ab4f57b..3d30e83b3a 100644
--- a/auth/gensec/schannel.c
+++ b/auth/gensec/schannel.c
@@ -34,6 +34,7 @@
#include "lib/crypto/crypto.h"
struct schannel_state {
+ struct gensec_security *gensec;
uint64_t seq_num;
bool initiator;
struct netlogon_creds_CredentialState *creds;
@@ -50,17 +51,19 @@ struct schannel_state {
RSIVAL(_buf, 4, _seq_num_high); \
} while(0)
-static struct schannel_state *netsec_create_state(TALLOC_CTX *mem_ctx,
+static struct schannel_state *netsec_create_state(
+ struct gensec_security *gensec,
struct netlogon_creds_CredentialState *creds,
bool initiator)
{
struct schannel_state *state;
- state = talloc(mem_ctx, struct schannel_state);
+ state = talloc(gensec, struct schannel_state);
if (state == NULL) {
return NULL;
}
+ state->gensec = gensec;
state->initiator = initiator;
state->seq_num = 0;
state->creds = netlogon_creds_copy(state, creds);
@@ -69,6 +72,8 @@ static struct schannel_state *netsec_create_state(TALLOC_CTX *mem_ctx,
return NULL;
}
+ gensec->private_data = state;
+
return state;
}
@@ -273,6 +278,7 @@ static void netsec_do_sign(struct schannel_state *state,
static NTSTATUS netsec_incoming_packet(struct schannel_state *state,
bool do_unseal,
uint8_t *data, size_t length,
+ const uint8_t *whole_pdu, size_t pdu_length,
const DATA_BLOB *sig)
{
uint32_t min_sig_size = 0;
@@ -284,6 +290,8 @@ static NTSTATUS netsec_incoming_packet(struct schannel_state *state,
uint32_t confounder_ofs = 0;
uint8_t seq_num[8];
int ret;
+ const uint8_t *sign_data = NULL;
+ size_t sign_length = 0;
netsec_offset_and_sizes(state,
do_unseal,
@@ -312,8 +320,16 @@ static NTSTATUS netsec_incoming_packet(struct schannel_state *state,
false);
}
+ if (state->gensec->want_features & GENSEC_FEATURE_SIGN_PKT_HEADER) {
+ sign_data = whole_pdu;
+ sign_length = pdu_length;
+ } else {
+ sign_data = data;
+ sign_length = length;
+ }
+
netsec_do_sign(state, confounder,
- data, length,
+ sign_data, sign_length,
header, checksum);
ret = memcmp(checksum, sig->data+16, checksum_length);
@@ -353,6 +369,7 @@ static NTSTATUS netsec_outgoing_packet(struct schannel_state *state,
TALLOC_CTX *mem_ctx,
bool do_seal,
uint8_t *data, size_t length,
+ const uint8_t *whole_pdu, size_t pdu_length,
DATA_BLOB *sig)
{
uint32_t min_sig_size = 0;
@@ -364,6 +381,8 @@ static NTSTATUS netsec_outgoing_packet(struct schannel_state *state,
uint8_t *confounder = NULL;
uint32_t confounder_ofs = 0;
uint8_t seq_num[8];
+ const uint8_t *sign_data = NULL;
+ size_t sign_length = 0;
netsec_offset_and_sizes(state,
do_seal,
@@ -381,8 +400,16 @@ static NTSTATUS netsec_outgoing_packet(struct schannel_state *state,
confounder = NULL;
}
+ if (state->gensec->want_features & GENSEC_FEATURE_SIGN_PKT_HEADER) {
+ sign_data = whole_pdu;
+ sign_length = pdu_length;
+ } else {
+ sign_data = data;
+ sign_length = length;
+ }
+
netsec_do_sign(state, confounder,
- data, length,
+ sign_data, sign_length,
header, checksum);
if (do_seal) {
@@ -457,7 +484,6 @@ static NTSTATUS schannel_update(struct gensec_security *gensec_security, TALLOC_
if (state == NULL) {
return NT_STATUS_NO_MEMORY;
}
- gensec_security->private_data = state;
bind_schannel.MessageType = NL_NEGOTIATE_REQUEST;
#if 0
@@ -553,7 +579,6 @@ static NTSTATUS schannel_update(struct gensec_security *gensec_security, TALLOC_
if (state == NULL) {
return NT_STATUS_NO_MEMORY;
}
- gensec_security->private_data = state;
bind_schannel_ack.MessageType = NL_NEGOTIATE_RESPONSE;
bind_schannel_ack.Flags = 0;
@@ -608,6 +633,9 @@ static bool schannel_have_feature(struct gensec_security *gensec_security,
if (feature & GENSEC_FEATURE_DCE_STYLE) {
return true;
}
+ if (feature & GENSEC_FEATURE_SIGN_PKT_HEADER) {
+ return true;
+ }
return false;
}
@@ -625,7 +653,9 @@ static NTSTATUS schannel_unseal_packet(struct gensec_security *gensec_security,
return netsec_incoming_packet(state, true,
discard_const_p(uint8_t, data),
- length, sig);
+ length,
+ whole_pdu, pdu_length,
+ sig);
}
/*
@@ -642,7 +672,9 @@ static NTSTATUS schannel_check_packet(struct gensec_security *gensec_security,
return netsec_incoming_packet(state, false,
discard_const_p(uint8_t, data),
- length, sig);
+ length,
+ whole_pdu, pdu_length,
+ sig);
}
/*
seal a packet
@@ -658,7 +690,9 @@ static NTSTATUS schannel_seal_packet(struct gensec_security *gensec_security,
struct schannel_state);
return netsec_outgoing_packet(state, mem_ctx, true,
- data, length, sig);
+ data, length,
+ whole_pdu, pdu_length,
+ sig);
}
/*
@@ -676,7 +710,9 @@ static NTSTATUS schannel_sign_packet(struct gensec_security *gensec_security,
return netsec_outgoing_packet(state, mem_ctx, false,
discard_const_p(uint8_t, data),
- length, sig);
+ length,
+ whole_pdu, pdu_length,
+ sig);
}
static const struct gensec_security_ops gensec_schannel_security_ops = {