From 2e0f749758d14a9be11a6b833a6e9c86bdada452 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 13 Jun 2017 16:59:02 +0200 Subject: [PATCH] auth/spnego: move gensec_spnego_update_in() after gensec_spnego_update_send() Signed-off-by: Stefan Metzmacher Reviewed-by: Andreas Schneider --- auth/gensec/spnego.c | 175 ++++++++++++++++++++++--------------------- 1 file changed, 89 insertions(+), 86 deletions(-) diff --git a/auth/gensec/spnego.c b/auth/gensec/spnego.c index cb2c227cd60..628652c5f5c 100644 --- a/auth/gensec/spnego.c +++ b/auth/gensec/spnego.c @@ -1238,92 +1238,6 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA return NT_STATUS_INVALID_PARAMETER; } -static NTSTATUS gensec_spnego_update_in(struct gensec_security *gensec_security, - const DATA_BLOB in, DATA_BLOB *full_in) -{ - struct spnego_state *spnego_state = (struct spnego_state *)gensec_security->private_data; - size_t expected; - bool ok; - - *full_in = data_blob_null; - - if (spnego_state->in_needed == 0) { - size_t size = 0; - int ret; - - /* - * try to work out the size of the full - * input token, it might be fragmented - */ - ret = asn1_peek_full_tag(in, ASN1_APPLICATION(0), &size); - if ((ret != 0) && (ret != EAGAIN)) { - ret = asn1_peek_full_tag(in, ASN1_CONTEXT(1), &size); - } - - if ((ret == 0) || (ret == EAGAIN)) { - spnego_state->in_needed = size; - } else { - /* - * If it is not an asn1 message - * just call the next layer. - */ - spnego_state->in_needed = in.length; - } - } - - if (spnego_state->in_needed > UINT16_MAX) { - /* - * limit the incoming message to 0xFFFF - * to avoid DoS attacks. - */ - return NT_STATUS_INVALID_BUFFER_SIZE; - } - - if ((spnego_state->in_needed > 0) && (in.length == 0)) { - /* - * If we reach this, we know we got at least - * part of an asn1 message, getting 0 means - * the remote peer wants us to spin. - */ - return NT_STATUS_INVALID_PARAMETER; - } - - expected = spnego_state->in_needed - spnego_state->in_frag.length; - if (in.length > expected) { - /* - * we got more than expected - */ - return NT_STATUS_INVALID_PARAMETER; - } - - if (in.length == spnego_state->in_needed) { - /* - * if the in.length contains the full blob - * we are done. - * - * Note: this implies spnego_state->in_frag.length == 0, - * but we do not need to check this explicitly - * because we already know that we did not get - * more than expected. - */ - *full_in = in; - return NT_STATUS_OK; - } - - ok = data_blob_append(spnego_state, &spnego_state->in_frag, - in.data, in.length); - if (!ok) { - return NT_STATUS_NO_MEMORY; - } - - if (spnego_state->in_needed > spnego_state->in_frag.length) { - return NT_STATUS_MORE_PROCESSING_REQUIRED; - } - - *full_in = spnego_state->in_frag; - return NT_STATUS_OK; -} - static NTSTATUS gensec_spnego_update_out(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, DATA_BLOB *_out) @@ -1412,6 +1326,9 @@ static void gensec_spnego_update_cleanup(struct tevent_req *req, } } +static NTSTATUS gensec_spnego_update_in(struct gensec_security *gensec_security, + const DATA_BLOB in, DATA_BLOB *full_in); + static struct tevent_req *gensec_spnego_update_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct gensec_security *gensec_security, @@ -1502,6 +1419,92 @@ static struct tevent_req *gensec_spnego_update_send(TALLOC_CTX *mem_ctx, return tevent_req_post(req, ev); } +static NTSTATUS gensec_spnego_update_in(struct gensec_security *gensec_security, + const DATA_BLOB in, DATA_BLOB *full_in) +{ + struct spnego_state *spnego_state = (struct spnego_state *)gensec_security->private_data; + size_t expected; + bool ok; + + *full_in = data_blob_null; + + if (spnego_state->in_needed == 0) { + size_t size = 0; + int ret; + + /* + * try to work out the size of the full + * input token, it might be fragmented + */ + ret = asn1_peek_full_tag(in, ASN1_APPLICATION(0), &size); + if ((ret != 0) && (ret != EAGAIN)) { + ret = asn1_peek_full_tag(in, ASN1_CONTEXT(1), &size); + } + + if ((ret == 0) || (ret == EAGAIN)) { + spnego_state->in_needed = size; + } else { + /* + * If it is not an asn1 message + * just call the next layer. + */ + spnego_state->in_needed = in.length; + } + } + + if (spnego_state->in_needed > UINT16_MAX) { + /* + * limit the incoming message to 0xFFFF + * to avoid DoS attacks. + */ + return NT_STATUS_INVALID_BUFFER_SIZE; + } + + if ((spnego_state->in_needed > 0) && (in.length == 0)) { + /* + * If we reach this, we know we got at least + * part of an asn1 message, getting 0 means + * the remote peer wants us to spin. + */ + return NT_STATUS_INVALID_PARAMETER; + } + + expected = spnego_state->in_needed - spnego_state->in_frag.length; + if (in.length > expected) { + /* + * we got more than expected + */ + return NT_STATUS_INVALID_PARAMETER; + } + + if (in.length == spnego_state->in_needed) { + /* + * if the in.length contains the full blob + * we are done. + * + * Note: this implies spnego_state->in_frag.length == 0, + * but we do not need to check this explicitly + * because we already know that we did not get + * more than expected. + */ + *full_in = in; + return NT_STATUS_OK; + } + + ok = data_blob_append(spnego_state, &spnego_state->in_frag, + in.data, in.length); + if (!ok) { + return NT_STATUS_NO_MEMORY; + } + + if (spnego_state->in_needed > spnego_state->in_frag.length) { + return NT_STATUS_MORE_PROCESSING_REQUIRED; + } + + *full_in = spnego_state->in_frag; + return NT_STATUS_OK; +} + static NTSTATUS gensec_spnego_update_recv(struct tevent_req *req, TALLOC_CTX *out_mem_ctx, DATA_BLOB *out) -- 2.34.1