summaryrefslogtreecommitdiff
path: root/auth
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2017-06-14 15:40:41 +0200
committerAndreas Schneider <asn@cryptomilk.org>2017-07-25 13:51:11 +0200
commit75e6728bcf25d24392f1dba28444c6696632107b (patch)
treef61b904b789bb433d339b4dbc708cfa8b15981ee /auth
parent2d1fcde331a9f1f43850a9bfcb046d245672af46 (diff)
downloadsamba-75e6728bcf25d24392f1dba28444c6696632107b.tar.gz
auth/spnego: split gensec_spnego_server_negTokenTarg() into subfunctions
Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Andreas Schneider <asn@samba.org>
Diffstat (limited to 'auth')
-rw-r--r--auth/gensec/spnego.c125
1 files changed, 96 insertions, 29 deletions
diff --git a/auth/gensec/spnego.c b/auth/gensec/spnego.c
index c279a9ed69b..d2cae261400 100644
--- a/auth/gensec/spnego.c
+++ b/auth/gensec/spnego.c
@@ -1452,20 +1452,16 @@ static NTSTATUS gensec_spnego_server_negTokenInit(struct gensec_security *gensec
ev, spnego_in, out_mem_ctx, out);
}
-static NTSTATUS gensec_spnego_server_negTokenTarg(struct gensec_security *gensec_security,
- struct spnego_state *spnego_state,
- struct tevent_context *ev,
- struct spnego_data *spnego_in,
- TALLOC_CTX *out_mem_ctx,
- DATA_BLOB *out)
+static NTSTATUS gensec_spnego_server_negTokenTarg_start(
+ struct gensec_security *gensec_security,
+ struct spnego_state *spnego_state,
+ struct spnego_neg_state *n,
+ struct spnego_data *spnego_in,
+ TALLOC_CTX *in_mem_ctx,
+ DATA_BLOB *in_next)
{
const struct spnego_negTokenTarg *ta = &spnego_in->negTokenTarg;
- DATA_BLOB sub_in = ta->responseToken;
- DATA_BLOB mech_list_mic = data_blob_null;
- DATA_BLOB sub_out = data_blob_null;
NTSTATUS status;
- bool have_sign = true;
- bool new_spnego = false;
spnego_state->num_targs++;
@@ -1494,26 +1490,78 @@ static NTSTATUS gensec_spnego_server_negTokenTarg(struct gensec_security *gensec
spnego_state->needs_mic_check = false;
spnego_state->done_mic_check = true;
- goto server_response;
+ return NT_STATUS_OK;
}
if (!spnego_state->sub_sec_ready) {
- status = gensec_update_ev(spnego_state->sub_sec_security,
- out_mem_ctx, ev,
- sub_in, &sub_out);
- if (GENSEC_UPDATE_IS_NTERROR(status)) {
- DEBUG(2, ("SPNEGO login failed: %s\n",
- nt_errstr(status)));
- return status;
- }
- if (NT_STATUS_IS_OK(status)) {
- spnego_state->sub_sec_ready = true;
- }
- if (!NT_STATUS_IS_OK(status)) {
- goto server_response;
- }
- } else {
- status = NT_STATUS_OK;
+ *in_next = ta->responseToken;
+ return NT_STATUS_MORE_PROCESSING_REQUIRED;
+ }
+
+ return NT_STATUS_OK;
+}
+
+static NTSTATUS gensec_spnego_server_negTokenTarg_step(
+ struct gensec_security *gensec_security,
+ struct spnego_state *spnego_state,
+ struct spnego_neg_state *n,
+ struct spnego_data *spnego_in,
+ NTSTATUS last_status,
+ TALLOC_CTX *in_mem_ctx,
+ DATA_BLOB *in_next)
+{
+ if (GENSEC_UPDATE_IS_NTERROR(last_status)) {
+ DBG_NOTICE("SPNEGO(%s) login failed: %s\n",
+ spnego_state->sub_sec_security->ops->name,
+ nt_errstr(last_status));
+ return last_status;
+ }
+
+ /*
+ * This should never be reached!
+ * The step function is only called on errors!
+ */
+ smb_panic(__location__);
+ return NT_STATUS_INTERNAL_ERROR;
+}
+
+static NTSTATUS gensec_spnego_server_negTokenTarg_finish(
+ struct gensec_security *gensec_security,
+ struct spnego_state *spnego_state,
+ struct spnego_neg_state *n,
+ struct spnego_data *spnego_in,
+ NTSTATUS sub_status,
+ const DATA_BLOB sub_out,
+ TALLOC_CTX *out_mem_ctx,
+ DATA_BLOB *out)
+{
+ const struct spnego_negTokenTarg *ta = &spnego_in->negTokenTarg;
+ DATA_BLOB mech_list_mic = data_blob_null;
+ NTSTATUS status;
+ bool have_sign = true;
+ bool new_spnego = false;
+
+ status = sub_status;
+
+ if (!spnego_state->sub_sec_ready) {
+ /*
+ * We're not yet ready to deal with signatures.
+ */
+ goto server_response;
+ }
+
+ if (spnego_state->done_mic_check) {
+ /*
+ * We already checked the mic,
+ * either the in last round here
+ * in gensec_spnego_server_negTokenTarg_finish()
+ * or during this round in
+ * gensec_spnego_server_negTokenTarg_start().
+ *
+ * Both cases we're sure we don't have to
+ * call gensec_sign_packet().
+ */
+ goto server_response;
}
have_sign = gensec_have_feature(spnego_state->sub_sec_security,
@@ -1551,7 +1599,7 @@ static NTSTATUS gensec_spnego_server_negTokenTarg(struct gensec_security *gensec
if (spnego_state->needs_mic_sign) {
status = gensec_sign_packet(spnego_state->sub_sec_security,
- out_mem_ctx,
+ n,
spnego_state->mech_types.data,
spnego_state->mech_types.length,
spnego_state->mech_types.data,
@@ -1578,6 +1626,25 @@ static NTSTATUS gensec_spnego_server_negTokenTarg(struct gensec_security *gensec
out);
}
+static const struct spnego_neg_ops gensec_spnego_server_negTokenTarg_ops = {
+ .name = "server_negTokenTarg",
+ .start_fn = gensec_spnego_server_negTokenTarg_start,
+ .step_fn = gensec_spnego_server_negTokenTarg_step,
+ .finish_fn = gensec_spnego_server_negTokenTarg_finish,
+};
+
+static NTSTATUS gensec_spnego_server_negTokenTarg(struct gensec_security *gensec_security,
+ struct spnego_state *spnego_state,
+ struct tevent_context *ev,
+ struct spnego_data *spnego_in,
+ TALLOC_CTX *out_mem_ctx,
+ DATA_BLOB *out)
+{
+ return gensec_spnego_neg_loop(gensec_security, spnego_state,
+ &gensec_spnego_server_negTokenTarg_ops,
+ ev, spnego_in, out_mem_ctx, out);
+}
+
struct gensec_spnego_update_state {
struct tevent_context *ev;
struct gensec_security *gensec;