From: Stefan Metzmacher Date: Tue, 11 Feb 2020 14:26:07 +0000 (+0100) Subject: auth/gensec: add gensec_set_channel_bindings() function X-Git-Tag: tdb-1.4.11~976 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e912ba579b1469c78ca65345ec1fe8376c74272c;p=thirdparty%2Fsamba.git auth/gensec: add gensec_set_channel_bindings() function BUG: https://bugzilla.samba.org/show_bug.cgi?id=15621 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett --- diff --git a/auth/gensec/gensec.c b/auth/gensec/gensec.c index 26b5865bff5..8785e69be63 100644 --- a/auth/gensec/gensec.c +++ b/auth/gensec/gensec.c @@ -854,3 +854,66 @@ _PUBLIC_ const char *gensec_get_target_principal(struct gensec_security *gensec_ return NULL; } + +static int gensec_channel_bindings_destructor(struct gensec_channel_bindings *cb) +{ + data_blob_clear_free(&cb->initiator_address); + data_blob_clear_free(&cb->acceptor_address); + data_blob_clear_free(&cb->application_data); + *cb = (struct gensec_channel_bindings) { .initiator_addrtype = 0, }; + return 0; +} + +_PUBLIC_ NTSTATUS gensec_set_channel_bindings(struct gensec_security *gensec_security, + uint32_t initiator_addrtype, + const DATA_BLOB *initiator_address, + uint32_t acceptor_addrtype, + const DATA_BLOB *acceptor_address, + const DATA_BLOB *application_data) +{ + struct gensec_channel_bindings *cb = NULL; + + if (gensec_security->subcontext) { + return NT_STATUS_INTERNAL_ERROR; + } + + if (gensec_security->channel_bindings != NULL) { + return NT_STATUS_ALREADY_REGISTERED; + } + + cb = talloc_zero(gensec_security, struct gensec_channel_bindings); + if (cb == NULL) { + return NT_STATUS_NO_MEMORY; + } + talloc_set_destructor(cb, gensec_channel_bindings_destructor); + + cb->initiator_addrtype = initiator_addrtype; + if (initiator_address != NULL) { + cb->initiator_address = data_blob_dup_talloc(cb, + *initiator_address); + if (cb->initiator_address.length != initiator_address->length) { + TALLOC_FREE(cb); + return NT_STATUS_NO_MEMORY; + } + } + cb->acceptor_addrtype = acceptor_addrtype; + if (acceptor_address != NULL) { + cb->acceptor_address = data_blob_dup_talloc(cb, + *acceptor_address); + if (cb->acceptor_address.length != acceptor_address->length) { + TALLOC_FREE(cb); + return NT_STATUS_NO_MEMORY; + } + } + if (application_data != NULL) { + cb->application_data = data_blob_dup_talloc(cb, + *application_data); + if (cb->application_data.length != application_data->length) { + TALLOC_FREE(cb); + return NT_STATUS_NO_MEMORY; + } + } + + gensec_security->channel_bindings = cb; + return NT_STATUS_OK; +} diff --git a/auth/gensec/gensec.h b/auth/gensec/gensec.h index 29d5e92c130..25242384f55 100644 --- a/auth/gensec/gensec.h +++ b/auth/gensec/gensec.h @@ -70,6 +70,7 @@ struct gensec_target { #define GENSEC_FEATURE_NO_AUTHZ_LOG 0x00000800 #define GENSEC_FEATURE_SMB_TRANSPORT 0x00001000 #define GENSEC_FEATURE_LDAPS_TRANSPORT 0x00002000 +#define GENSEC_FEATURE_CB_OPTIONAL 0x00004000 #define GENSEC_EXPIRE_TIME_INFINITY (NTTIME)0x8000000000000000LL @@ -313,6 +314,13 @@ bool gensec_setting_bool(struct gensec_settings *settings, const char *mechanism NTSTATUS gensec_set_target_principal(struct gensec_security *gensec_security, const char *principal); const char *gensec_get_target_principal(struct gensec_security *gensec_security); +NTSTATUS gensec_set_channel_bindings(struct gensec_security *gensec_security, + uint32_t initiator_addrtype, + const DATA_BLOB *initiator_address, + uint32_t acceptor_addrtype, + const DATA_BLOB *acceptor_address, + const DATA_BLOB *application_data); + NTSTATUS gensec_generate_session_info_pac(TALLOC_CTX *mem_ctx, struct gensec_security *gensec_security, struct smb_krb5_context *smb_krb5_context, diff --git a/auth/gensec/gensec_internal.h b/auth/gensec/gensec_internal.h index 8efb1bdff0f..4d8eca99881 100644 --- a/auth/gensec/gensec_internal.h +++ b/auth/gensec/gensec_internal.h @@ -95,6 +95,23 @@ struct gensec_security_ops_wrapper { const char *oid; }; +/* + * typedef struct gss_channel_bindings_struct { + * OM_uint32 initiator_addrtype; + * gss_buffer_desc initiator_address; + * OM_uint32 acceptor_addrtype; + * gss_buffer_desc acceptor_address; + * gss_buffer_desc application_data; + * } *gss_channel_bindings_t; + */ +struct gensec_channel_bindings { + uint32_t initiator_addrtype; + DATA_BLOB initiator_address; + uint32_t acceptor_addrtype; + DATA_BLOB acceptor_address; + DATA_BLOB application_data; +}; + struct gensec_security { const struct gensec_security_ops *ops; void *private_data; @@ -106,6 +123,7 @@ struct gensec_security { uint32_t max_update_size; uint8_t dcerpc_auth_level; struct tsocket_address *local_addr, *remote_addr; + struct gensec_channel_bindings *channel_bindings; struct gensec_settings *settings; /* When we are a server, this may be filled in to provide an diff --git a/auth/gensec/gensec_start.c b/auth/gensec/gensec_start.c index bcf98bd5968..4405aca278d 100644 --- a/auth/gensec/gensec_start.c +++ b/auth/gensec/gensec_start.c @@ -732,6 +732,7 @@ _PUBLIC_ NTSTATUS gensec_subcontext_start(TALLOC_CTX *mem_ctx, (*gensec_security)->auth_context = talloc_reference(*gensec_security, parent->auth_context); (*gensec_security)->settings = talloc_reference(*gensec_security, parent->settings); (*gensec_security)->auth_context = talloc_reference(*gensec_security, parent->auth_context); + (*gensec_security)->channel_bindings = talloc_reference(*gensec_security, parent->channel_bindings); talloc_set_destructor((*gensec_security), gensec_security_destructor); return NT_STATUS_OK;