summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--auth/ntlmssp/ntlmssp.c25
-rw-r--r--auth/ntlmssp/ntlmssp.h2
-rw-r--r--auth/ntlmssp/ntlmssp_sign.c40
3 files changed, 55 insertions, 12 deletions
diff --git a/auth/ntlmssp/ntlmssp.c b/auth/ntlmssp/ntlmssp.c
index 091fdab9e4a..4abab88627a 100644
--- a/auth/ntlmssp/ntlmssp.c
+++ b/auth/ntlmssp/ntlmssp.c
@@ -179,6 +179,30 @@ NTSTATUS gensec_ntlmssp_update(struct gensec_security *gensec_security,
return NT_STATUS_OK;
}
+static NTSTATUS gensec_ntlmssp_may_reset_crypto(struct gensec_security *gensec_security,
+ bool full_reset)
+{
+ struct gensec_ntlmssp_context *gensec_ntlmssp =
+ talloc_get_type_abort(gensec_security->private_data,
+ struct gensec_ntlmssp_context);
+ struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
+ NTSTATUS status;
+ bool reset_seqnums = full_reset;
+
+ if (!gensec_ntlmssp_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
+ return NT_STATUS_OK;
+ }
+
+ status = ntlmssp_sign_reset(ntlmssp_state, reset_seqnums);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(1, ("Could not reset NTLMSSP signing/sealing system (error was: %s)\n",
+ nt_errstr(status)));
+ return status;
+ }
+
+ return NT_STATUS_OK;
+}
+
static const char *gensec_ntlmssp_oids[] = {
GENSEC_OID_NTLMSSP,
NULL
@@ -193,6 +217,7 @@ static const struct gensec_security_ops gensec_ntlmssp_security_ops = {
.server_start = gensec_ntlmssp_server_start,
.magic = gensec_ntlmssp_magic,
.update = gensec_ntlmssp_update,
+ .may_reset_crypto= gensec_ntlmssp_may_reset_crypto,
.sig_size = gensec_ntlmssp_sig_size,
.sign_packet = gensec_ntlmssp_sign_packet,
.check_packet = gensec_ntlmssp_check_packet,
diff --git a/auth/ntlmssp/ntlmssp.h b/auth/ntlmssp/ntlmssp.h
index 8c254f36e83..bb8807df425 100644
--- a/auth/ntlmssp/ntlmssp.h
+++ b/auth/ntlmssp/ntlmssp.h
@@ -130,6 +130,8 @@ NTSTATUS ntlmssp_unwrap(struct ntlmssp_state *ntlmssp_stae,
TALLOC_CTX *out_mem_ctx,
const DATA_BLOB *in,
DATA_BLOB *out);
+NTSTATUS ntlmssp_sign_reset(struct ntlmssp_state *ntlmssp_state,
+ bool reset_seqnums);
NTSTATUS ntlmssp_sign_init(struct ntlmssp_state *ntlmssp_state);
bool ntlmssp_blob_matches_magic(const DATA_BLOB *blob);
diff --git a/auth/ntlmssp/ntlmssp_sign.c b/auth/ntlmssp/ntlmssp_sign.c
index 2f8c6de75d9..a9757258803 100644
--- a/auth/ntlmssp/ntlmssp_sign.c
+++ b/auth/ntlmssp/ntlmssp_sign.c
@@ -503,20 +503,14 @@ NTSTATUS ntlmssp_unwrap(struct ntlmssp_state *ntlmssp_state,
/**
Initialise the state for NTLMSSP signing.
*/
-NTSTATUS ntlmssp_sign_init(struct ntlmssp_state *ntlmssp_state)
+NTSTATUS ntlmssp_sign_reset(struct ntlmssp_state *ntlmssp_state,
+ bool reset_seqnums)
{
DEBUG(3, ("NTLMSSP Sign/Seal - Initialising with flags:\n"));
debug_ntlmssp_flags(ntlmssp_state->neg_flags);
- if (ntlmssp_state->session_key.length < 8) {
- DEBUG(3, ("NO session key, cannot intialise signing\n"));
- return NT_STATUS_NO_USER_SESSION_KEY;
- }
-
- ntlmssp_state->crypt = talloc_zero(ntlmssp_state,
- union ntlmssp_crypt_state);
if (ntlmssp_state->crypt == NULL) {
- return NT_STATUS_NO_MEMORY;
+ return NT_STATUS_INVALID_PARAMETER_MIX;
}
if (ntlmssp_state->force_wrap_seal &&
@@ -606,7 +600,9 @@ NTSTATUS ntlmssp_sign_init(struct ntlmssp_state *ntlmssp_state)
&ntlmssp_state->crypt->ntlm2.sending.seal_state);
/* SEND: seq num */
- ntlmssp_state->crypt->ntlm2.sending.seq_num = 0;
+ if (reset_seqnums) {
+ ntlmssp_state->crypt->ntlm2.sending.seq_num = 0;
+ }
/* RECV: sign key */
calc_ntlmv2_key(ntlmssp_state->crypt->ntlm2.receiving.sign_key,
@@ -626,7 +622,9 @@ NTSTATUS ntlmssp_sign_init(struct ntlmssp_state *ntlmssp_state)
&ntlmssp_state->crypt->ntlm2.receiving.seal_state);
/* RECV: seq num */
- ntlmssp_state->crypt->ntlm2.receiving.seq_num = 0;
+ if (reset_seqnums) {
+ ntlmssp_state->crypt->ntlm2.receiving.seq_num = 0;
+ }
} else {
uint8_t weak_session_key[8];
DATA_BLOB seal_session_key = ntlmssp_state->session_key;
@@ -676,8 +674,26 @@ NTSTATUS ntlmssp_sign_init(struct ntlmssp_state *ntlmssp_state)
dump_arc4_state("NTLMv1 arc4 state:\n",
&ntlmssp_state->crypt->ntlm.seal_state);
- ntlmssp_state->crypt->ntlm.seq_num = 0;
+ if (reset_seqnums) {
+ ntlmssp_state->crypt->ntlm.seq_num = 0;
+ }
}
return NT_STATUS_OK;
}
+
+NTSTATUS ntlmssp_sign_init(struct ntlmssp_state *ntlmssp_state)
+{
+ if (ntlmssp_state->session_key.length < 8) {
+ DEBUG(3, ("NO session key, cannot intialise signing\n"));
+ return NT_STATUS_NO_USER_SESSION_KEY;
+ }
+
+ ntlmssp_state->crypt = talloc_zero(ntlmssp_state,
+ union ntlmssp_crypt_state);
+ if (ntlmssp_state->crypt == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ return ntlmssp_sign_reset(ntlmssp_state, true);
+}