From 06fa3ae313bb36da87f056cc993f201369a30c2b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 30 Dec 2016 18:05:17 +0100 Subject: [PATCH] auth/spnego: let spnego.c use the new gensec_child_* helper functions This means we no longer allow operations on a half finished authentication, it's activated by gensec_child_ready(). Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett --- auth/gensec/spnego.c | 294 +++++---------------------------------------------- 1 file changed, 26 insertions(+), 268 deletions(-) diff --git a/auth/gensec/spnego.c b/auth/gensec/spnego.c index ed7f3d71d68..db791ce4ca8 100644 --- a/auth/gensec/spnego.c +++ b/auth/gensec/spnego.c @@ -124,183 +124,6 @@ static NTSTATUS gensec_spnego_server_start(struct gensec_security *gensec_securi return NT_STATUS_OK; } -/* - wrappers for the spnego_*() functions -*/ -static NTSTATUS gensec_spnego_unseal_packet(struct gensec_security *gensec_security, - uint8_t *data, size_t length, - const uint8_t *whole_pdu, size_t pdu_length, - const DATA_BLOB *sig) -{ - struct spnego_state *spnego_state = (struct spnego_state *)gensec_security->private_data; - - if (spnego_state->state_position != SPNEGO_DONE - && spnego_state->state_position != SPNEGO_FALLBACK) { - return NT_STATUS_INVALID_PARAMETER; - } - - return gensec_unseal_packet(spnego_state->sub_sec_security, - data, length, - whole_pdu, pdu_length, - sig); -} - -static NTSTATUS gensec_spnego_check_packet(struct gensec_security *gensec_security, - const uint8_t *data, size_t length, - const uint8_t *whole_pdu, size_t pdu_length, - const DATA_BLOB *sig) -{ - struct spnego_state *spnego_state = (struct spnego_state *)gensec_security->private_data; - - if (spnego_state->state_position != SPNEGO_DONE - && spnego_state->state_position != SPNEGO_FALLBACK) { - return NT_STATUS_INVALID_PARAMETER; - } - - return gensec_check_packet(spnego_state->sub_sec_security, - data, length, - whole_pdu, pdu_length, - sig); -} - -static NTSTATUS gensec_spnego_seal_packet(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - uint8_t *data, size_t length, - const uint8_t *whole_pdu, size_t pdu_length, - DATA_BLOB *sig) -{ - struct spnego_state *spnego_state = (struct spnego_state *)gensec_security->private_data; - - if (spnego_state->state_position != SPNEGO_DONE - && spnego_state->state_position != SPNEGO_FALLBACK) { - return NT_STATUS_INVALID_PARAMETER; - } - - return gensec_seal_packet(spnego_state->sub_sec_security, - mem_ctx, - data, length, - whole_pdu, pdu_length, - sig); -} - -static NTSTATUS gensec_spnego_sign_packet(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - const uint8_t *data, size_t length, - const uint8_t *whole_pdu, size_t pdu_length, - DATA_BLOB *sig) -{ - struct spnego_state *spnego_state = (struct spnego_state *)gensec_security->private_data; - - if (spnego_state->state_position != SPNEGO_DONE - && spnego_state->state_position != SPNEGO_FALLBACK) { - return NT_STATUS_INVALID_PARAMETER; - } - - return gensec_sign_packet(spnego_state->sub_sec_security, - mem_ctx, - data, length, - whole_pdu, pdu_length, - sig); -} - -static NTSTATUS gensec_spnego_wrap(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - const DATA_BLOB *in, - DATA_BLOB *out) -{ - struct spnego_state *spnego_state = (struct spnego_state *)gensec_security->private_data; - - if (spnego_state->state_position != SPNEGO_DONE - && spnego_state->state_position != SPNEGO_FALLBACK) { - DEBUG(1, ("gensec_spnego_wrap: wrong state for wrap\n")); - return NT_STATUS_INVALID_PARAMETER; - } - - return gensec_wrap(spnego_state->sub_sec_security, - mem_ctx, in, out); -} - -static NTSTATUS gensec_spnego_unwrap(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - const DATA_BLOB *in, - DATA_BLOB *out) -{ - struct spnego_state *spnego_state = (struct spnego_state *)gensec_security->private_data; - - if (spnego_state->state_position != SPNEGO_DONE - && spnego_state->state_position != SPNEGO_FALLBACK) { - DEBUG(1, ("gensec_spnego_unwrap: wrong state for unwrap\n")); - return NT_STATUS_INVALID_PARAMETER; - } - - return gensec_unwrap(spnego_state->sub_sec_security, - mem_ctx, in, out); -} - -static size_t gensec_spnego_sig_size(struct gensec_security *gensec_security, size_t data_size) -{ - struct spnego_state *spnego_state = (struct spnego_state *)gensec_security->private_data; - - if (spnego_state->state_position != SPNEGO_DONE - && spnego_state->state_position != SPNEGO_FALLBACK) { - return 0; - } - - return gensec_sig_size(spnego_state->sub_sec_security, data_size); -} - -static size_t gensec_spnego_max_input_size(struct gensec_security *gensec_security) -{ - struct spnego_state *spnego_state = (struct spnego_state *)gensec_security->private_data; - - if (spnego_state->state_position != SPNEGO_DONE - && spnego_state->state_position != SPNEGO_FALLBACK) { - return 0; - } - - return gensec_max_input_size(spnego_state->sub_sec_security); -} - -static size_t gensec_spnego_max_wrapped_size(struct gensec_security *gensec_security) -{ - struct spnego_state *spnego_state = (struct spnego_state *)gensec_security->private_data; - - if (spnego_state->state_position != SPNEGO_DONE - && spnego_state->state_position != SPNEGO_FALLBACK) { - return 0; - } - - return gensec_max_wrapped_size(spnego_state->sub_sec_security); -} - -static NTSTATUS gensec_spnego_session_key(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - DATA_BLOB *session_key) -{ - struct spnego_state *spnego_state = (struct spnego_state *)gensec_security->private_data; - if (!spnego_state->sub_sec_security) { - return NT_STATUS_INVALID_PARAMETER; - } - - return gensec_session_key(spnego_state->sub_sec_security, - mem_ctx, - session_key); -} - -static NTSTATUS gensec_spnego_session_info(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - struct auth_session_info **session_info) -{ - struct spnego_state *spnego_state = (struct spnego_state *)gensec_security->private_data; - if (!spnego_state->sub_sec_security) { - return NT_STATUS_INVALID_PARAMETER; - } - - return gensec_session_info(spnego_state->sub_sec_security, - mem_ctx, - session_info); -} - /** Fallback to another GENSEC mechanism, based on magic strings * * This is the 'fallback' case, where we don't get SPNEGO, and have to @@ -1513,24 +1336,23 @@ static NTSTATUS gensec_spnego_update_out(struct gensec_security *gensec_security *_out = data_blob_null; - if (spnego_state->out_frag.length == 0) { - return spnego_state->out_status; - } - - /* - * There is still more data to be delivered - * to the remote peer. - */ - if (spnego_state->out_frag.length <= spnego_state->out_max_length) { /* * Fast path, we can deliver everything */ *_out = spnego_state->out_frag; - talloc_steal(out_mem_ctx, _out->data); - spnego_state->out_frag = data_blob_null; - return spnego_state->out_status; + if (spnego_state->out_frag.length > 0) { + talloc_steal(out_mem_ctx, _out->data); + spnego_state->out_frag = data_blob_null; + } + + if (!NT_STATUS_IS_OK(spnego_state->out_status)) { + return spnego_state->out_status; + } + + return gensec_child_ready(gensec_security, + spnego_state->sub_sec_security); } out = spnego_state->out_frag; @@ -1595,8 +1417,6 @@ static NTSTATUS gensec_spnego_update_wrapper(struct gensec_security *gensec_secu if (NT_STATUS_IS_OK(status)) { bool reset_full = true; - gensec_security->child_security = spnego_state->sub_sec_security; - reset_full = !spnego_state->done_mic_check; status = gensec_may_reset_crypto(spnego_state->sub_sec_security, @@ -1614,68 +1434,6 @@ static NTSTATUS gensec_spnego_update_wrapper(struct gensec_security *gensec_secu out); } -static void gensec_spnego_want_feature(struct gensec_security *gensec_security, - uint32_t feature) -{ - struct spnego_state *spnego_state = (struct spnego_state *)gensec_security->private_data; - - gensec_security->want_features |= feature; - if (!spnego_state || !spnego_state->sub_sec_security) { - return; - } - - gensec_want_feature(spnego_state->sub_sec_security, - feature); -} - -static bool gensec_spnego_have_feature(struct gensec_security *gensec_security, - uint32_t feature) -{ - struct spnego_state *spnego_state = (struct spnego_state *)gensec_security->private_data; - - if (feature & GENSEC_FEATURE_SIGN_PKT_HEADER) { - /* - * All mechs with sub (child) mechs need to provide DCERPC - * header signing! This is required because the negotiation - * of header signing is done before the authentication - * is completed. - * - * Currently all our backends support DCERPC with: - * GENSEC_FEATURE_SIGN_PKT_HEADER. - */ - return true; - } - - if (!spnego_state->sub_sec_security) { - return false; - } - - return gensec_have_feature(spnego_state->sub_sec_security, - feature); -} - -static NTTIME gensec_spnego_expire_time(struct gensec_security *gensec_security) -{ - struct spnego_state *spnego_state = (struct spnego_state *)gensec_security->private_data; - - if (!spnego_state->sub_sec_security) { - return GENSEC_EXPIRE_TIME_INFINITY; - } - - return gensec_expire_time(spnego_state->sub_sec_security); -} - -static const char *gensec_spnego_final_auth_type(struct gensec_security *gensec_security) -{ - struct spnego_state *spnego_state = (struct spnego_state *)gensec_security->private_data; - - if (!spnego_state->sub_sec_security) { - return "NONE"; - } else { - return gensec_final_auth_type(spnego_state->sub_sec_security); - } -} - static const char *gensec_spnego_oids[] = { GENSEC_OID_SPNEGO, NULL @@ -1689,21 +1447,21 @@ static const struct gensec_security_ops gensec_spnego_security_ops = { .client_start = gensec_spnego_client_start, .server_start = gensec_spnego_server_start, .update = gensec_spnego_update_wrapper, - .seal_packet = gensec_spnego_seal_packet, - .sign_packet = gensec_spnego_sign_packet, - .sig_size = gensec_spnego_sig_size, - .max_wrapped_size = gensec_spnego_max_wrapped_size, - .max_input_size = gensec_spnego_max_input_size, - .check_packet = gensec_spnego_check_packet, - .unseal_packet = gensec_spnego_unseal_packet, - .wrap = gensec_spnego_wrap, - .unwrap = gensec_spnego_unwrap, - .session_key = gensec_spnego_session_key, - .session_info = gensec_spnego_session_info, - .want_feature = gensec_spnego_want_feature, - .have_feature = gensec_spnego_have_feature, - .expire_time = gensec_spnego_expire_time, - .final_auth_type = gensec_spnego_final_auth_type, + .seal_packet = gensec_child_seal_packet, + .sign_packet = gensec_child_sign_packet, + .sig_size = gensec_child_sig_size, + .max_wrapped_size = gensec_child_max_wrapped_size, + .max_input_size = gensec_child_max_input_size, + .check_packet = gensec_child_check_packet, + .unseal_packet = gensec_child_unseal_packet, + .wrap = gensec_child_wrap, + .unwrap = gensec_child_unwrap, + .session_key = gensec_child_session_key, + .session_info = gensec_child_session_info, + .want_feature = gensec_child_want_feature, + .have_feature = gensec_child_have_feature, + .expire_time = gensec_child_expire_time, + .final_auth_type = gensec_child_final_auth_type, .enabled = true, .priority = GENSEC_SPNEGO }; -- 2.11.4.GIT