diff options
author | Stefan Metzmacher <metze@samba.org> | 2016-12-30 17:54:12 +0100 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2017-05-21 21:05:09 +0200 |
commit | 8332941953c9cc42308e32f6a409c2db39c2936f (patch) | |
tree | 4af167f0cd5f8ba67059fbcb6ca90a99dc1161a8 /auth | |
parent | 2aab27fef576776520daec90fa546f3e8aff8524 (diff) | |
download | samba-8332941953c9cc42308e32f6a409c2db39c2936f.tar.gz |
auth/gensec: add gensec_child_* helper functions
They will be used to simplify the spnego backend
and maybe of some use for a future negoex backend.
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Diffstat (limited to 'auth')
-rw-r--r-- | auth/gensec/gensec.c | 9 | ||||
-rw-r--r-- | auth/gensec/gensec_internal.h | 46 | ||||
-rw-r--r-- | auth/gensec/gensec_start.c | 49 | ||||
-rw-r--r-- | auth/gensec/gensec_util.c | 196 |
4 files changed, 300 insertions, 0 deletions
diff --git a/auth/gensec/gensec.c b/auth/gensec/gensec.c index 23d762b2a73..9b1661eebcd 100644 --- a/auth/gensec/gensec.c +++ b/auth/gensec/gensec.c @@ -330,6 +330,10 @@ _PUBLIC_ NTSTATUS gensec_update_ev(struct gensec_security *gensec_security, struct tevent_req *subreq = NULL; bool ok; + if (gensec_security->child_security != NULL) { + return NT_STATUS_INVALID_PARAMETER; + } + if (ops->update_send == NULL) { if (ev == NULL) { @@ -480,6 +484,11 @@ _PUBLIC_ struct tevent_req *gensec_update_send(TALLOC_CTX *mem_ctx, state->ops = gensec_security->ops; state->gensec_security = gensec_security; + if (gensec_security->child_security != NULL) { + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + return tevent_req_post(req, ev); + } + if (state->ops->update_send == NULL) { state->in = in; state->im = tevent_create_immediate(state); diff --git a/auth/gensec/gensec_internal.h b/auth/gensec/gensec_internal.h index 26c9817d5df..9c160d3d084 100644 --- a/auth/gensec/gensec_internal.h +++ b/auth/gensec/gensec_internal.h @@ -114,6 +114,7 @@ struct gensec_security { * PAC is found) */ struct auth4_context *auth_context; + struct gensec_security *parent_security; struct gensec_security *child_security; }; @@ -129,4 +130,49 @@ NTSTATUS gensec_may_reset_crypto(struct gensec_security *gensec_security, const char *gensec_final_auth_type(struct gensec_security *gensec_security); +NTSTATUS gensec_child_ready(struct gensec_security *parent, + struct gensec_security *child); +void gensec_child_want_feature(struct gensec_security *gensec_security, + uint32_t feature); +bool gensec_child_have_feature(struct gensec_security *gensec_security, + uint32_t feature); +NTSTATUS gensec_child_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); +NTSTATUS gensec_child_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); +NTSTATUS gensec_child_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); +NTSTATUS gensec_child_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); +NTSTATUS gensec_child_wrap(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + const DATA_BLOB *in, + DATA_BLOB *out); +NTSTATUS gensec_child_unwrap(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + const DATA_BLOB *in, + DATA_BLOB *out); +size_t gensec_child_sig_size(struct gensec_security *gensec_security, + size_t data_size); +size_t gensec_child_max_input_size(struct gensec_security *gensec_security); +size_t gensec_child_max_wrapped_size(struct gensec_security *gensec_security); +NTSTATUS gensec_child_session_key(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + DATA_BLOB *session_key); +NTSTATUS gensec_child_session_info(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + struct auth_session_info **session_info); +NTTIME gensec_child_expire_time(struct gensec_security *gensec_security); +const char *gensec_child_final_auth_type(struct gensec_security *gensec_security); + #endif /* __GENSEC_H__ */ diff --git a/auth/gensec/gensec_start.c b/auth/gensec/gensec_start.c index f10f86d5037..c1affd6218a 100644 --- a/auth/gensec/gensec_start.c +++ b/auth/gensec/gensec_start.c @@ -545,6 +545,25 @@ _PUBLIC_ const char **gensec_security_oids(struct gensec_security *gensec_securi return gensec_security_oids_from_ops(gensec_security, mem_ctx, ops, skip); } +static int gensec_security_destructor(struct gensec_security *gctx) +{ + if (gctx->parent_security != NULL) { + if (gctx->parent_security->child_security == gctx) { + gctx->parent_security->child_security = NULL; + } + gctx->parent_security = NULL; + } + + if (gctx->child_security != NULL) { + if (gctx->child_security->parent_security == gctx) { + gctx->child_security->parent_security = NULL; + } + gctx->child_security = NULL; + } + + return 0; +} + /** Start the GENSEC system, returning a context pointer. @param mem_ctx The parent TALLOC memory context. @@ -571,6 +590,7 @@ static NTSTATUS gensec_start(TALLOC_CTX *mem_ctx, * from it */ (*gensec_security)->auth_context = talloc_reference(*gensec_security, auth_context); + talloc_set_destructor((*gensec_security), gensec_security_destructor); return NT_STATUS_OK; } @@ -586,6 +606,10 @@ _PUBLIC_ NTSTATUS gensec_subcontext_start(TALLOC_CTX *mem_ctx, struct gensec_security *parent, struct gensec_security **gensec_security) { + if (parent->child_security != NULL) { + return NT_STATUS_INTERNAL_ERROR; + } + (*gensec_security) = talloc_zero(mem_ctx, struct gensec_security); NT_STATUS_HAVE_NO_MEMORY(*gensec_security); @@ -601,6 +625,23 @@ _PUBLIC_ NTSTATUS gensec_subcontext_start(TALLOC_CTX *mem_ctx, (*gensec_security)->settings = talloc_reference(*gensec_security, parent->settings); (*gensec_security)->auth_context = talloc_reference(*gensec_security, parent->auth_context); + talloc_set_destructor((*gensec_security), gensec_security_destructor); + return NT_STATUS_OK; +} + +_PUBLIC_ NTSTATUS gensec_child_ready(struct gensec_security *parent, + struct gensec_security *child) +{ + if (parent->child_security != NULL) { + return NT_STATUS_INTERNAL_ERROR; + } + + if (child->parent_security != NULL) { + return NT_STATUS_INTERNAL_ERROR; + } + + parent->child_security = child; + child->parent_security = parent; return NT_STATUS_OK; } @@ -670,6 +711,14 @@ static NTSTATUS gensec_start_mech(struct gensec_security *gensec_security) talloc_unlink(gensec_security, gensec_security->private_data); gensec_security->private_data = NULL; + if (gensec_security->child_security != NULL) { + /* + * The talloc_unlink(.., gensec_security->private_data) + * should have cleared this via + * gensec_security_destructor(). + */ + return NT_STATUS_INTERNAL_ERROR; + } if (gensec_security->credentials) { const char *forced_mech = cli_credentials_get_forced_sasl_mech(gensec_security->credentials); diff --git a/auth/gensec/gensec_util.c b/auth/gensec/gensec_util.c index da2e2e5f4b8..ca5e581f63f 100644 --- a/auth/gensec/gensec_util.c +++ b/auth/gensec/gensec_util.c @@ -110,3 +110,199 @@ NTSTATUS gensec_magic_check_krb5_oid(struct gensec_security *unused, return NT_STATUS_INVALID_PARAMETER; } } + +void gensec_child_want_feature(struct gensec_security *gensec_security, + uint32_t feature) +{ + struct gensec_security *child_security = gensec_security->child_security; + + gensec_security->want_features |= feature; + if (child_security == NULL) { + return; + } + gensec_want_feature(child_security, feature); +} + +bool gensec_child_have_feature(struct gensec_security *gensec_security, + uint32_t feature) +{ + struct gensec_security *child_security = gensec_security->child_security; + + 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. + */ + return true; + } + + if (child_security == NULL) { + return false; + } + + return gensec_have_feature(child_security, feature); +} + +NTSTATUS gensec_child_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) +{ + if (gensec_security->child_security == NULL) { + return NT_STATUS_INVALID_PARAMETER; + } + + return gensec_unseal_packet(gensec_security->child_security, + data, length, + whole_pdu, pdu_length, + sig); +} + +NTSTATUS gensec_child_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) +{ + if (gensec_security->child_security == NULL) { + return NT_STATUS_INVALID_PARAMETER; + } + + return gensec_check_packet(gensec_security->child_security, + data, length, + whole_pdu, pdu_length, + sig); +} + +NTSTATUS gensec_child_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) +{ + if (gensec_security->child_security == NULL) { + return NT_STATUS_INVALID_PARAMETER; + } + + return gensec_seal_packet(gensec_security->child_security, + mem_ctx, + data, length, + whole_pdu, pdu_length, + sig); +} + +NTSTATUS gensec_child_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) +{ + if (gensec_security->child_security == NULL) { + return NT_STATUS_INVALID_PARAMETER; + } + + return gensec_sign_packet(gensec_security->child_security, + mem_ctx, + data, length, + whole_pdu, pdu_length, + sig); +} + +NTSTATUS gensec_child_wrap(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + const DATA_BLOB *in, + DATA_BLOB *out) +{ + if (gensec_security->child_security == NULL) { + return NT_STATUS_INVALID_PARAMETER; + } + + return gensec_wrap(gensec_security->child_security, + mem_ctx, in, out); +} + +NTSTATUS gensec_child_unwrap(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + const DATA_BLOB *in, + DATA_BLOB *out) +{ + if (gensec_security->child_security == NULL) { + return NT_STATUS_INVALID_PARAMETER; + } + + return gensec_unwrap(gensec_security->child_security, + mem_ctx, in, out); +} + +size_t gensec_child_sig_size(struct gensec_security *gensec_security, + size_t data_size) +{ + if (gensec_security->child_security == NULL) { + return 0; + } + + return gensec_sig_size(gensec_security->child_security, data_size); +} + +size_t gensec_child_max_input_size(struct gensec_security *gensec_security) +{ + if (gensec_security->child_security == NULL) { + return 0; + } + + return gensec_max_input_size(gensec_security->child_security); +} + +size_t gensec_child_max_wrapped_size(struct gensec_security *gensec_security) +{ + if (gensec_security->child_security == NULL) { + return 0; + } + + return gensec_max_wrapped_size(gensec_security->child_security); +} + +NTSTATUS gensec_child_session_key(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + DATA_BLOB *session_key) +{ + if (gensec_security->child_security == NULL) { + return NT_STATUS_INVALID_PARAMETER; + } + + return gensec_session_key(gensec_security->child_security, + mem_ctx, + session_key); +} + +NTSTATUS gensec_child_session_info(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + struct auth_session_info **session_info) +{ + if (gensec_security->child_security == NULL) { + return NT_STATUS_INVALID_PARAMETER; + } + + return gensec_session_info(gensec_security->child_security, + mem_ctx, + session_info); +} + +NTTIME gensec_child_expire_time(struct gensec_security *gensec_security) +{ + if (gensec_security->child_security == NULL) { + return GENSEC_EXPIRE_TIME_INFINITY; + } + + return gensec_expire_time(gensec_security->child_security); +} + +const char *gensec_child_final_auth_type(struct gensec_security *gensec_security) +{ + if (gensec_security->child_security == NULL) { + return "NONE"; + } + + return gensec_final_auth_type(gensec_security->child_security); +} |