mirror of
https://github.com/samba-team/samba.git
synced 2025-01-11 05:18:09 +03:00
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>
This commit is contained in:
parent
2aab27fef5
commit
8332941953
@ -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);
|
||||
|
@ -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__ */
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user