diff options
Diffstat (limited to 'third_party/heimdal/lib/gssapi/mech')
94 files changed, 12428 insertions, 0 deletions
diff --git a/third_party/heimdal/lib/gssapi/mech/compat.h b/third_party/heimdal/lib/gssapi/mech/compat.h new file mode 100644 index 0000000..d23a6e9 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/compat.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2010, PADL Software Pty Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of PADL Software nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +typedef OM_uint32 GSSAPI_CALLCONV _gss_inquire_saslname_for_mech_t ( + OM_uint32 *, /* minor_status */ + const gss_OID, /* desired_mech */ + gss_buffer_t, /* sasl_mech_name */ + gss_buffer_t, /* mech_name */ + gss_buffer_t /* mech_description */ + ); + +typedef OM_uint32 GSSAPI_CALLCONV _gss_inquire_mech_for_saslname_t ( + OM_uint32 *, /* minor_status */ + const gss_buffer_t, /* sasl_mech_name */ + gss_OID * /* mech_type */ + ); + +typedef OM_uint32 GSSAPI_CALLCONV _gss_inquire_attrs_for_mech_t ( + OM_uint32 *, /* minor_status */ + gss_const_OID, /* mech */ + gss_OID_set *, /* mech_attrs */ + gss_OID_set * /* known_mech_attrs */ + ); + +typedef OM_uint32 GSSAPI_CALLCONV _gss_acquire_cred_with_password_t + (OM_uint32 *, /* minor_status */ + gss_const_name_t, /* desired_name */ + const gss_buffer_t, /* password */ + OM_uint32, /* time_req */ + const gss_OID_set, /* desired_mechs */ + gss_cred_usage_t, /* cred_usage */ + gss_cred_id_t *, /* output_cred_handle */ + gss_OID_set *, /* actual_mechs */ + OM_uint32 * /* time_rec */ + ); + +typedef OM_uint32 GSSAPI_CALLCONV _gss_add_cred_with_password_t ( + OM_uint32 *, /* minor_status */ + gss_const_cred_id_t, /* input_cred_handle */ + gss_const_name_t, /* desired_name */ + const gss_OID, /* desired_mech */ + const gss_buffer_t, /* password */ + gss_cred_usage_t, /* cred_usage */ + OM_uint32, /* initiator_time_req */ + OM_uint32, /* acceptor_time_req */ + gss_cred_id_t *, /* output_cred_handle */ + gss_OID_set *, /* actual_mechs */ + OM_uint32 *, /* initiator_time_rec */ + OM_uint32 * /* acceptor_time_rec */ + ); + +/* + * API-as-SPI compatibility for compatibility with MIT mechanisms; + * native Heimdal mechanisms should not use these. + */ +struct gss_mech_compat_desc_struct { + _gss_inquire_saslname_for_mech_t *gmc_inquire_saslname_for_mech; + _gss_inquire_mech_for_saslname_t *gmc_inquire_mech_for_saslname; + _gss_inquire_attrs_for_mech_t *gmc_inquire_attrs_for_mech; + _gss_acquire_cred_with_password_t *gmc_acquire_cred_with_password; +#if 0 + _gss_add_cred_with_password_t *gmc_add_cred_with_password; +#endif +}; + diff --git a/third_party/heimdal/lib/gssapi/mech/context.c b/third_party/heimdal/lib/gssapi/mech/context.c new file mode 100644 index 0000000..83e2cef --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/context.c @@ -0,0 +1,361 @@ +/* + * Copyright (c) 2009 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Portions Copyright (c) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "mech_locl.h" +#include "heim_threads.h" +#include <krb5.h> +#include "krb5_locl.h" +#include "negoex_err.h" + +struct mg_thread_ctx { + gss_OID mech; + OM_uint32 min_stat; + gss_buffer_desc min_error; + krb5_context context; +}; + +static HEIMDAL_MUTEX context_mutex = HEIMDAL_MUTEX_INITIALIZER; +static int created_key; +static HEIMDAL_thread_key context_key; + + +static void +destroy_context(void *ptr) +{ + struct mg_thread_ctx *mg = ptr; + OM_uint32 junk; + + if (mg == NULL) + return; + + gss_release_buffer(&junk, &mg->min_error); + + if (mg->context) + krb5_free_context(mg->context); + + free(mg); +} + + +static struct mg_thread_ctx * +_gss_mechglue_thread(void) +{ + struct mg_thread_ctx *ctx; + int ret = 0; + + HEIMDAL_MUTEX_lock(&context_mutex); + + if (!created_key) { + HEIMDAL_key_create(&context_key, destroy_context, ret); + if (ret) { + HEIMDAL_MUTEX_unlock(&context_mutex); + return NULL; + } + created_key = 1; + } + HEIMDAL_MUTEX_unlock(&context_mutex); + + ctx = HEIMDAL_getspecific(context_key); + if (ctx == NULL) { + + ctx = calloc(1, sizeof(*ctx)); + if (ctx == NULL) + return NULL; + + ret = krb5_init_context(&ctx->context); + if (ret) { + free(ctx); + return NULL; + } + + krb5_add_et_list(ctx->context, initialize_ngex_error_table_r); + + HEIMDAL_setspecific(context_key, ctx, ret); + if (ret) { + krb5_free_context(ctx->context); + free(ctx); + return NULL; + } + } + return ctx; +} + +krb5_context +_gss_mg_krb5_context(void) +{ + struct mg_thread_ctx *mg; + + mg = _gss_mechglue_thread(); + + return mg ? mg->context : NULL; +} + +OM_uint32 +_gss_mg_get_error(const gss_OID mech, + OM_uint32 value, + gss_buffer_t string) +{ + struct mg_thread_ctx *mg; + + mg = _gss_mechglue_thread(); + if (mg == NULL) + return GSS_S_BAD_STATUS; + + if (value != mg->min_stat || mg->min_error.length == 0) { + _mg_buffer_zero(string); + return GSS_S_BAD_STATUS; + } + string->value = malloc(mg->min_error.length); + if (string->value == NULL) { + _mg_buffer_zero(string); + return GSS_S_FAILURE; + } + string->length = mg->min_error.length; + memcpy(string->value, mg->min_error.value, mg->min_error.length); + return GSS_S_COMPLETE; +} + +void +_gss_mg_error(struct gssapi_mech_interface_desc *m, OM_uint32 min) +{ + OM_uint32 major_status, minor_status; + OM_uint32 message_content = 0; + struct mg_thread_ctx *mg; + + /* + * Mechs without gss_display_status() does + * gss_mg_collect_error() by themself. + */ + if (m->gm_display_status == NULL) + return ; + + mg = _gss_mechglue_thread(); + if (mg == NULL) + return; + + gss_release_buffer(&minor_status, &mg->min_error); + + mg->mech = &m->gm_mech_oid; + mg->min_stat = min; + + major_status = m->gm_display_status(&minor_status, + min, + GSS_C_MECH_CODE, + &m->gm_mech_oid, + &message_content, + &mg->min_error); + if (major_status != GSS_S_COMPLETE) { + _mg_buffer_zero(&mg->min_error); + } else { + _gss_mg_log(5, "_gss_mg_error: captured %.*s (%d) from underlying mech %s", + (int)mg->min_error.length, (const char *)mg->min_error.value, + (int)min, m->gm_name); + } +} + +void +gss_mg_collect_error(gss_OID mech, OM_uint32 maj, OM_uint32 min) +{ + gssapi_mech_interface m = __gss_get_mechanism(mech); + if (m == NULL) + return; + _gss_mg_error(m, min); +} + +OM_uint32 +gss_mg_set_error_string(gss_OID mech, + OM_uint32 maj, OM_uint32 min, + const char *fmt, ...) +{ + struct mg_thread_ctx *mg; + char *str = NULL; + OM_uint32 junk; + va_list ap; + int vasprintf_ret; + + mg = _gss_mechglue_thread(); + if (mg == NULL) + return maj; + + va_start(ap, fmt); + vasprintf_ret = vasprintf(&str, fmt, ap); + va_end(ap); + + if (vasprintf_ret >= 0 && str) { + gss_release_buffer(&junk, &mg->min_error); + + mg->mech = mech; + mg->min_stat = min; + + mg->min_error.value = str; + mg->min_error.length = strlen(str); + + _gss_mg_log(5, "gss_mg_set_error_string: %.*s (%d/%d)", + (int)mg->min_error.length, (const char *)mg->min_error.value, + (int)maj, (int)min); + } + return maj; +} + +static void *log_ctx = NULL; +static void (*log_func)(void *ctx, int level, const char *fmt, va_list) = NULL; + +void GSSAPI_LIB_CALL +gss_set_log_function(void *ctx, void (*func)(void * ctx, int level, const char *fmt, va_list)) +{ + if (log_func == NULL) { + log_func = func; + log_ctx = ctx; + } +} + +int +_gss_mg_log_level(int level) +{ + struct mg_thread_ctx *mg; + + mg = _gss_mechglue_thread(); + if (mg == NULL) + return 0; + + return _krb5_have_debug(mg->context, level); +} + +/* + * TODO: refactor logging so that it no longer depends on libkrb5 + * and can be configured independently. + */ +void +_gss_mg_log(int level, const char *fmt, ...) +{ + struct mg_thread_ctx *mg; + va_list ap; + + if (!_gss_mg_log_level(level)) + return; + + mg = _gss_mechglue_thread(); + if (mg == NULL) + return; + + if (mg->context && _krb5_have_debug(mg->context, level)) { + va_start(ap, fmt); + krb5_vlog(mg->context, heim_get_debug_dest(mg->context->hcontext), + level, fmt, ap); + va_end(ap); + } + + if (log_func) { + va_start(ap, fmt); + log_func(log_ctx, level, fmt, ap); + va_end(ap); + } +} + +void +_gss_mg_log_name(int level, + struct _gss_name *name, + gss_OID mech_type, + const char *fmt, ...) +{ + struct _gss_mechanism_name *mn = NULL; + gssapi_mech_interface m; + OM_uint32 junk; + + if (!_gss_mg_log_level(level)) + return; + + m = __gss_get_mechanism(mech_type); + if (m == NULL) + return; + + if (_gss_find_mn(&junk, name, mech_type, &mn) == GSS_S_COMPLETE) { + OM_uint32 maj_stat = GSS_S_COMPLETE; + gss_buffer_desc namebuf; + int ret; + + if (mn == NULL) { + namebuf.value = "no name"; + namebuf.length = strlen((char *)namebuf.value); + } else { + maj_stat = m->gm_display_name(&junk, mn->gmn_name, + &namebuf, NULL); + } + if (maj_stat == GSS_S_COMPLETE) { + char *str = NULL; + va_list ap; + + va_start(ap, fmt); + ret = vasprintf(&str, fmt, ap); + va_end(ap); + + if (ret >= 0 && str) + _gss_mg_log(level, "%s %.*s", str, + (int)namebuf.length, (char *)namebuf.value); + free(str); + if (mn != NULL) + gss_release_buffer(&junk, &namebuf); + } + } + +} + +void +_gss_mg_log_cred(int level, + struct _gss_cred *cred, + const char *fmt, ...) +{ + struct _gss_mechanism_cred *mc; + char *str; + va_list ap; + int ret; + + if (!_gss_mg_log_level(level)) + return; + + va_start(ap, fmt); + ret = vasprintf(&str, fmt, ap); + va_end(ap); + + if (ret >=0 && cred) { + HEIM_TAILQ_FOREACH(mc, &cred->gc_mc, gmc_link) { + _gss_mg_log(1, "%s: %s", str, mc->gmc_mech->gm_name); + } + } else { + _gss_mg_log(1, "%s: GSS_C_NO_CREDENTIAL", str); + } + free(str); +} + diff --git a/third_party/heimdal/lib/gssapi/mech/context.h b/third_party/heimdal/lib/gssapi/mech/context.h new file mode 100644 index 0000000..5029171 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/context.h @@ -0,0 +1,51 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/context.h,v 1.1 2005/12/29 14:40:20 dfr Exp $ + * $Id$ + */ + +#include <gssapi_mech.h> + +struct _gss_context { + gss_buffer_desc gc_input; + char *gc_free_this; + size_t gc_target_len; + size_t gc_oid_offset; + gssapi_mech_interface gc_mech; + gss_ctx_id_t gc_ctx; + uint8_t gc_initial; +}; + +#define EXPORT_CONTEXT_VERSION_MASK 0x03 +#define EXPORT_CONTEXT_FLAGS_MASK 0xfc +#define EXPORT_CONTEXT_FLAG_ACCUMULATING 0x04 +#define EXPORT_CONTEXT_FLAG_MECH_CTX 0x08 + +void +_gss_mg_error(gssapi_mech_interface, OM_uint32); + +OM_uint32 +_gss_mg_get_error(const gss_OID, OM_uint32, gss_buffer_t); diff --git a/third_party/heimdal/lib/gssapi/mech/cred.c b/third_party/heimdal/lib/gssapi/mech/cred.c new file mode 100644 index 0000000..92cc61a --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/cred.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2011 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Portions Copyright (c) 2011 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of KTH nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "mech_locl.h" +#include "heim_threads.h" +#include "heimbase.h" + +static OM_uint32 +release_mech_cred(OM_uint32 *minor, struct _gss_mechanism_cred *mc) +{ + OM_uint32 major; + + if (mc->gmc_mech->gm_release_cred != NULL) + major = mc->gmc_mech->gm_release_cred(minor, &mc->gmc_cred); + else + major = GSS_S_COMPLETE; + + free(mc); + + return major; +} + + +void +_gss_mg_release_cred(struct _gss_cred *cred) +{ + struct _gss_mechanism_cred *mc, *next; + OM_uint32 junk; + + HEIM_TAILQ_FOREACH_SAFE(mc, &cred->gc_mc, gmc_link, next) { + HEIM_TAILQ_REMOVE(&cred->gc_mc, mc, gmc_link); + release_mech_cred(&junk, mc); + } + gss_release_oid_set(&junk, &cred->gc_neg_mechs); + free(cred); +} + +struct _gss_cred * +_gss_mg_alloc_cred(void) +{ + struct _gss_cred *cred; + cred = calloc(1, sizeof(struct _gss_cred)); + if (cred == NULL) + return NULL; + HEIM_TAILQ_INIT(&cred->gc_mc); + + return cred; +} + diff --git a/third_party/heimdal/lib/gssapi/mech/cred.h b/third_party/heimdal/lib/gssapi/mech/cred.h new file mode 100644 index 0000000..eed4a82 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/cred.h @@ -0,0 +1,65 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/cred.h,v 1.1 2005/12/29 14:40:20 dfr Exp $ + * $Id$ + */ + +struct _gss_mechanism_cred { + HEIM_TAILQ_ENTRY(_gss_mechanism_cred) gmc_link; + gssapi_mech_interface gmc_mech; /* mechanism ops for MC */ + gss_OID gmc_mech_oid; /* mechanism oid for MC */ + gss_cred_id_t gmc_cred; /* underlying MC */ +}; +HEIM_TAILQ_HEAD(_gss_mechanism_cred_list, _gss_mechanism_cred); + +struct _gss_cred { + struct _gss_mechanism_cred_list gc_mc; + gss_OID_set gc_neg_mechs; +}; + +struct _gss_cred * +_gss_mg_alloc_cred(void); + +void +_gss_mg_release_cred(struct _gss_cred *cred); + +struct _gss_mechanism_cred * +_gss_copy_cred(struct _gss_mechanism_cred *mc); + +struct _gss_mechanism_name; + +OM_uint32 +_gss_mg_add_mech_cred(OM_uint32 *minor_status, + gssapi_mech_interface m, + const struct _gss_mechanism_cred *mc, + const struct _gss_mechanism_name *mn, + gss_cred_usage_t cred_usage, + OM_uint32 initiator_time_req, + OM_uint32 acceptor_time_req, + gss_const_key_value_set_t cred_store, + struct _gss_mechanism_cred **output_cred_handle, + OM_uint32 *initiator_time_rec, + OM_uint32 *acceptor_time_rec); diff --git a/third_party/heimdal/lib/gssapi/mech/doxygen.c b/third_party/heimdal/lib/gssapi/mech/doxygen.c new file mode 100644 index 0000000..4ead9f1 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/doxygen.c @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2009 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*! @mainpage Heimdal GSS-API Library + * + * Heimdal implements the following mechanisms: + * + * - Kerberos 5 + * - SPNEGO + * - NTLM + * + * @sa + * + * - @ref gssapi_services_intro + * - @ref gssapi_mechs + * - @ref gssapi_api_INvsMN + * - The project web page: http://www.h5l.org/ + */ + +/** + * @page gssapi_services_intro Introduction to GSS-API services + * @section gssapi_services GSS-API services + * + * @subsection gssapi_services_context Context creation + * + * - delegation + * - mutual authentication + * - anonymous + * - use per message before context creation has completed + * + * return status: + * - support conf + * - support int + * + * @subsection gssapi_context_flags Context creation flags + * + * - GSS_C_DELEG_FLAG + * - GSS_C_MUTUAL_FLAG + * - GSS_C_REPLAY_FLAG + * - GSS_C_SEQUENCE_FLAG + * - GSS_C_CONF_FLAG + * - GSS_C_INTEG_FLAG + * - GSS_C_ANON_FLAG + * - GSS_C_PROT_READY_FLAG + * - GSS_C_TRANS_FLAG + * - GSS_C_DCE_STYLE + * - GSS_C_IDENTIFY_FLAG + * - GSS_C_EXTENDED_ERROR_FLAG + * - GSS_C_DELEG_POLICY_FLAG + * + * + * @subsection gssapi_services_permessage Per-message services + * + * - conf + * - int + * - message integrity + * - replay detection + * - out of sequence + * + */ + +/** + * @page gssapi_mechs_intro GSS-API mechanisms + * @section gssapi_mechs GSS-API mechanisms + * + * - Kerberos 5 - GSS_KRB5_MECHANISM + * - SPNEGO - GSS_SPNEGO_MECHANISM + * - NTLM - GSS_NTLM_MECHANISM + + */ + + +/** + * @page internalVSmechname Internal names and mechanism names + * @section gssapi_api_INvsMN Name forms + * + * There are two name representations in GSS-API: Internal form and + * Contiguous string ("flat") form. Functions gss_export_name() and + * gss_import_name() can be used to convert between the two forms. + * + * - The contiguous string form is described by an oid specificing the + * type and an octet string. A special form of the contiguous + * string form is the exported name object. The exported name + * defined for each mechanism, is something that can be stored and + * compared later. The exported name is what should be used for + * ACLs comparisons. + * + * - The Internal form is opaque to the application programmer and + * is implementation-dependent. + * + * - There is also a special form of the Internal Name (IN), and that is + * the Mechanism Name (MN). In the mechanism name all the generic + * information is stripped of and only contain the information for + * one mechanism. In GSS-API some function return MN and some + * require MN as input. Each of these function is marked up as such. + * + * @FIXME Describe relationship between import_name, canonicalize_name, + * export_name and friends. Also, update for RFC2743 language + * ("contiguous" and "flat" are gone, leaving just "exported name + * token", "internal", and "MN"). + */ + +/** @defgroup gssapi Heimdal GSS-API functions */ diff --git a/third_party/heimdal/lib/gssapi/mech/gss_accept_sec_context.c b/third_party/heimdal/lib/gssapi/mech/gss_accept_sec_context.c new file mode 100644 index 0000000..1cb0b36 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_accept_sec_context.c @@ -0,0 +1,519 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_accept_sec_context.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" + +/* + * accumulate_token() tries to assemble a complete GSS token which may + * be fed to it in pieces. Microsoft does this when tokens are too large + * in CIFS, e.g. It may occur in other places as well. It is specified in: + * + * [MS-SPNG]: Simple and Protected GSS-API Negotiation + * Mechanism (SPNEGO) Extension + * + * https://winprotocoldoc.blob.core.windows.net/ + * productionwindowsarchives/MS-SPNG/%5bMS-SPNG%5d.pdf + * + * Sections 3.1.5.4 to 3.1.5.9. + * + * We only accumulate if we see the appropriate application tag in the + * first byte of 0x60 because in the absence of this, we cannot interpret + * the following bytes as a DER length. + * + * We only allocate an accumulating buffer if we detect that the token + * is split between multiple packets as this is the uncommon case and + * we want to optimise for the common case. If we aren't accumulating, + * we simply return success. + * + * Our return value is GSS_S_CONTINUE_NEEDED if we need more input. + * We return GSS_S_COMPLETE if we are either finished accumulating or + * if we decide that we do not understand this token. We only return + * an error if we think that we should understand the token and still + * fail to understand it. + */ + +static OM_uint32 +accumulate_token(struct _gss_context *ctx, gss_buffer_t input_token) +{ + unsigned char *p = input_token->value; + size_t len = input_token->length; + gss_buffer_t gci; + size_t l; + + /* + * Token must start with [APPLICATION 0] SEQUENCE. + * But if it doesn't assume it is DCE-STYLE Kerberos! + */ + if (!ctx->gc_target_len) { + free(ctx->gc_free_this); + ctx->gc_free_this = NULL; + _mg_buffer_zero(&ctx->gc_input); + + /* + * Let's prepare gc_input for the case where + * we aren't accumulating. + */ + + ctx->gc_input.length = len; + ctx->gc_input.value = p; + + if (len == 0) + return GSS_S_COMPLETE; + + /* Not our DER w/ a length */ + if (*p != 0x60) + return GSS_S_COMPLETE; + + if (der_get_length(p+1, len-1, &ctx->gc_target_len, &l) != 0) + return GSS_S_DEFECTIVE_TOKEN; + + _gss_mg_log(10, "gss-asc: DER length: %zu", + ctx->gc_target_len); + + ctx->gc_oid_offset = l + 1; + ctx->gc_target_len += ctx->gc_oid_offset; + + _gss_mg_log(10, "gss-asc: total length: %zu", + ctx->gc_target_len); + + if (ctx->gc_target_len == ASN1_INDEFINITE || + ctx->gc_target_len < len) + return GSS_S_DEFECTIVE_TOKEN; + + /* We've got it all, short-circuit the accumulating */ + if (ctx->gc_target_len == len) + goto done; + + _gss_mg_log(10, "gss-asc: accumulating partial token"); + + ctx->gc_input.length = 0; + ctx->gc_input.value = calloc(ctx->gc_target_len, 1); + if (!ctx->gc_input.value) + return GSS_S_FAILURE; + ctx->gc_free_this = ctx->gc_input.value; + } + + if (len == 0) + return GSS_S_DEFECTIVE_TOKEN; + + gci = &ctx->gc_input; + + if (ctx->gc_target_len > gci->length) { + if (gci->length + len > ctx->gc_target_len) { + _gss_mg_log(10, "gss-asc: accumulation exceeded " + "target length: bailing"); + return GSS_S_DEFECTIVE_TOKEN; + } + memcpy((char *)gci->value + gci->length, p, len); + gci->length += len; + } + + if (gci->length != ctx->gc_target_len) { + _gss_mg_log(10, "gss-asc: collected %zu/%zu bytes", + gci->length, ctx->gc_target_len); + return GSS_S_CONTINUE_NEEDED; + } + +done: + _gss_mg_log(10, "gss-asc: received complete %zu byte token", + ctx->gc_target_len); + ctx->gc_target_len = 0; + + return GSS_S_COMPLETE; +} + +static void +log_oid(const char *str, gss_OID mech) +{ + OM_uint32 maj, min; + gss_buffer_desc buf; + + maj = gss_oid_to_str(&min, mech, &buf); + if (maj == GSS_S_COMPLETE) { + _gss_mg_log(10, "%s: %.*s", str, (int)buf.length, + (char *)buf.value); + gss_release_buffer(&min, &buf); + } +} + +static OM_uint32 +choose_mech(struct _gss_context *ctx) +{ + gss_OID_desc mech; + gss_OID mech_oid; + unsigned char *p = ctx->gc_input.value; + size_t len = ctx->gc_input.length; + + if (len == 0) { + /* + * There is the a wierd mode of SPNEGO (in CIFS and + * SASL GSS-SPENGO where the first token is zero + * length and the acceptor returns a mech_list, lets + * hope that is what is happening now. + * + * http://msdn.microsoft.com/en-us/library/cc213114.aspx + * "NegTokenInit2 Variation for Server-Initiation" + */ + mech_oid = &__gss_spnego_mechanism_oid_desc; + goto gss_get_mechanism; + } + + p += ctx->gc_oid_offset; + len -= ctx->gc_oid_offset; + + /* + * Decode the OID for the mechanism. Simplify life by + * assuming that the OID length is less than 128 bytes. + */ + if (len < 2 || *p != 0x06) + goto bail; + if ((p[1] & 0x80) || p[1] > (len - 2)) + goto bail; + mech.length = p[1]; + p += 2; + len -= 2; + mech.elements = p; + + mech_oid = _gss_mg_support_mechanism(&mech); + if (mech_oid == GSS_C_NO_OID) + return GSS_S_COMPLETE; + +gss_get_mechanism: + /* + * If mech_oid == GSS_C_NO_OID then the mech is non-standard + * and we have to try all mechs (that we have a cred element + * for, if we have a cred). + */ + if (mech_oid != GSS_C_NO_OID) { + log_oid("mech oid", mech_oid); + ctx->gc_mech = __gss_get_mechanism(mech_oid); + if (!ctx->gc_mech) { + _gss_mg_log(10, "mechanism client used is unknown"); + return (GSS_S_BAD_MECH); + } + _gss_mg_log(10, "using mech \"%s\"", ctx->gc_mech->gm_name); + return GSS_S_COMPLETE; + } + +bail: + _gss_mg_log(10, "no mech oid found"); + return GSS_S_COMPLETE; +} + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_accept_sec_context(OM_uint32 *minor_status, + gss_ctx_id_t *context_handle, + gss_const_cred_id_t acceptor_cred_handle, + const gss_buffer_t input_token, + const gss_channel_bindings_t input_chan_bindings, + gss_name_t *src_name, + gss_OID *mech_type, + gss_buffer_t output_token, + OM_uint32 *ret_flags, + OM_uint32 *time_rec, + gss_cred_id_t *delegated_cred_handle) +{ + OM_uint32 major_status, mech_ret_flags, junk; + gssapi_mech_interface m = NULL; + struct _gss_context *ctx = (struct _gss_context *) *context_handle; + struct _gss_cred *cred = (struct _gss_cred *) acceptor_cred_handle; + struct _gss_mechanism_cred *mc; + gss_buffer_desc defective_token_error; + gss_const_cred_id_t acceptor_mc; + gss_cred_id_t delegated_mc = GSS_C_NO_CREDENTIAL; + gss_name_t src_mn = GSS_C_NO_NAME; + gss_OID mech_ret_type = GSS_C_NO_OID; + int initial; + + defective_token_error.length = 0; + defective_token_error.value = NULL; + + *minor_status = 0; + if (src_name) + *src_name = GSS_C_NO_NAME; + if (mech_type) + *mech_type = GSS_C_NO_OID; + if (ret_flags) + *ret_flags = 0; + if (time_rec) + *time_rec = 0; + if (delegated_cred_handle) + *delegated_cred_handle = GSS_C_NO_CREDENTIAL; + _mg_buffer_zero(output_token); + + if (!*context_handle) { + ctx = calloc(sizeof(*ctx), 1); + if (!ctx) { + *minor_status = ENOMEM; + return (GSS_S_DEFECTIVE_TOKEN); + } + *context_handle = (gss_ctx_id_t)ctx; + ctx->gc_initial = 1; + } + + major_status = accumulate_token(ctx, input_token); + if (major_status != GSS_S_COMPLETE) + return major_status; + + /* + * If we get here, then we have a complete token. Please note + * that we may have a major_status of GSS_S_DEFECTIVE_TOKEN. This + * + */ + + initial = ctx->gc_initial; + ctx->gc_initial = 0; + + if (major_status == GSS_S_COMPLETE && initial) { + major_status = choose_mech(ctx); + if (major_status != GSS_S_COMPLETE) + return major_status; + } + m = ctx->gc_mech; + + if (initial && !m && acceptor_cred_handle == GSS_C_NO_CREDENTIAL) { + /* + * No header, not a standard mechanism. Try all the mechanisms + * (because default credential). + */ + struct _gss_mech_switch *ms; + + _gss_load_mech(); + acceptor_mc = GSS_C_NO_CREDENTIAL; + HEIM_TAILQ_FOREACH(ms, &_gss_mechs, gm_link) { + m = &ms->gm_mech; + mech_ret_flags = 0; + major_status = m->gm_accept_sec_context(minor_status, + &ctx->gc_ctx, + acceptor_mc, + &ctx->gc_input, + input_chan_bindings, + &src_mn, + &mech_ret_type, + output_token, + &mech_ret_flags, + time_rec, + &delegated_mc); + if (major_status == GSS_S_DEFECTIVE_TOKEN) { + /* + * Try to retain and output one error token for + * GSS_S_DEFECTIVE_TOKEN. The first one. + */ + if (output_token->length && + defective_token_error.length == 0) { + defective_token_error = *output_token; + output_token->length = 0; + output_token->value = NULL; + } + gss_release_buffer(&junk, output_token); + continue; + } + gss_release_buffer(&junk, &defective_token_error); + ctx->gc_mech = m; + goto got_one; + } + m = NULL; + acceptor_mc = GSS_C_NO_CREDENTIAL; + } else if (initial && !m) { + /* + * No header, not a standard mechanism. Try all the mechanisms + * that we have a credential element for if we have a + * non-default credential. + */ + HEIM_TAILQ_FOREACH(mc, &cred->gc_mc, gmc_link) { + m = mc->gmc_mech; + acceptor_mc = (m->gm_flags & GM_USE_MG_CRED) ? + acceptor_cred_handle : mc->gmc_cred; + mech_ret_flags = 0; + major_status = m->gm_accept_sec_context(minor_status, + &ctx->gc_ctx, + acceptor_mc, + &ctx->gc_input, + input_chan_bindings, + &src_mn, + &mech_ret_type, + output_token, + &mech_ret_flags, + time_rec, + &delegated_mc); + if (major_status == GSS_S_DEFECTIVE_TOKEN) { + if (output_token->length && + defective_token_error.length == 0) { + defective_token_error = *output_token; + output_token->length = 0; + output_token->value = NULL; + } + gss_release_buffer(&junk, output_token); + continue; + } + gss_release_buffer(&junk, &defective_token_error); + ctx->gc_mech = m; + goto got_one; + } + m = NULL; + acceptor_mc = GSS_C_NO_CREDENTIAL; + } + + if (m == NULL) { + gss_delete_sec_context(&junk, context_handle, NULL); + _gss_mg_log(10, "No mechanism accepted the non-standard initial security context token"); + *output_token = defective_token_error; + return GSS_S_BAD_MECH; + } + + if (m->gm_flags & GM_USE_MG_CRED) { + acceptor_mc = acceptor_cred_handle; + } else if (cred) { + HEIM_TAILQ_FOREACH(mc, &cred->gc_mc, gmc_link) + if (mc->gmc_mech == m) + break; + if (!mc) { + gss_delete_sec_context(&junk, context_handle, NULL); + _gss_mg_log(10, "gss-asc: client sent mech %s " + "but no credential was matching", + m->gm_name); + HEIM_TAILQ_FOREACH(mc, &cred->gc_mc, gmc_link) + _gss_mg_log(10, "gss-asc: available creds were %s", mc->gmc_mech->gm_name); + return (GSS_S_BAD_MECH); + } + acceptor_mc = mc->gmc_cred; + } else { + acceptor_mc = GSS_C_NO_CREDENTIAL; + } + + mech_ret_flags = 0; + major_status = m->gm_accept_sec_context(minor_status, + &ctx->gc_ctx, + acceptor_mc, + &ctx->gc_input, + input_chan_bindings, + &src_mn, + &mech_ret_type, + output_token, + &mech_ret_flags, + time_rec, + &delegated_mc); + +got_one: + if (major_status != GSS_S_COMPLETE && + major_status != GSS_S_CONTINUE_NEEDED) + { + _gss_mg_error(m, *minor_status); + gss_delete_sec_context(&junk, context_handle, NULL); + return (major_status); + } + + if (mech_type) + *mech_type = mech_ret_type; + + if (src_name && src_mn) { + if (ctx->gc_mech->gm_flags & GM_USE_MG_NAME) { + /* Negotiation mechanisms use mechglue names as names */ + *src_name = src_mn; + src_mn = GSS_C_NO_NAME; + } else { + /* + * Make a new name and mark it as an MN. + * + * Note that _gss_create_name() consumes `src_mn' but doesn't + * take a pointer, so it can't set it to GSS_C_NO_NAME. + */ + struct _gss_name *name = _gss_create_name(src_mn, m); + + if (!name) { + m->gm_release_name(minor_status, &src_mn); + gss_delete_sec_context(&junk, context_handle, NULL); + return (GSS_S_FAILURE); + } + *src_name = (gss_name_t) name; + src_mn = GSS_C_NO_NAME; + } + } else if (src_mn) { + if (ctx->gc_mech->gm_flags & GM_USE_MG_NAME) { + _gss_mg_release_name((struct _gss_name *)src_mn); + src_mn = GSS_C_NO_NAME; + } else { + m->gm_release_name(minor_status, &src_mn); + } + } + + if (mech_ret_flags & GSS_C_DELEG_FLAG) { + if (!delegated_cred_handle) { + if (m->gm_flags & GM_USE_MG_CRED) + gss_release_cred(minor_status, &delegated_mc); + else + m->gm_release_cred(minor_status, &delegated_mc); + mech_ret_flags &= + ~(GSS_C_DELEG_FLAG|GSS_C_DELEG_POLICY_FLAG); + } else if ((m->gm_flags & GM_USE_MG_CRED) != 0) { + /* + * If credential is uses mechglue cred, assume it + * returns one too. + */ + *delegated_cred_handle = delegated_mc; + } else if (gss_oid_equal(mech_ret_type, &m->gm_mech_oid) == 0) { + /* + * If the returned mech_type is not the same + * as the mech, assume its pseudo mech type + * and the returned type is already a + * mech-glue object + */ + *delegated_cred_handle = delegated_mc; + + } else if (delegated_mc) { + struct _gss_cred *dcred; + struct _gss_mechanism_cred *dmc; + + dcred = _gss_mg_alloc_cred(); + if (!dcred) { + *minor_status = ENOMEM; + gss_delete_sec_context(&junk, context_handle, NULL); + return (GSS_S_FAILURE); + } + dmc = malloc(sizeof(struct _gss_mechanism_cred)); + if (!dmc) { + free(dcred); + *minor_status = ENOMEM; + gss_delete_sec_context(&junk, context_handle, NULL); + return (GSS_S_FAILURE); + } + dmc->gmc_mech = m; + dmc->gmc_mech_oid = &m->gm_mech_oid; + dmc->gmc_cred = delegated_mc; + HEIM_TAILQ_INSERT_TAIL(&dcred->gc_mc, dmc, gmc_link); + + *delegated_cred_handle = (gss_cred_id_t) dcred; + } + } + + _gss_mg_log(10, "gss-asc: return %d/%d", (int)major_status, (int)*minor_status); + + if (ret_flags) + *ret_flags = mech_ret_flags; + return (major_status); +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_acquire_cred.c b/third_party/heimdal/lib/gssapi/mech/gss_acquire_cred.c new file mode 100644 index 0000000..fd92a25 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_acquire_cred.c @@ -0,0 +1,50 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_acquire_cred.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_acquire_cred(OM_uint32 *minor_status, + gss_const_name_t desired_name, + OM_uint32 time_req, + const gss_OID_set desired_mechs, + gss_cred_usage_t cred_usage, + gss_cred_id_t *output_cred_handle, + gss_OID_set *actual_mechs, + OM_uint32 *time_rec) +{ + return gss_acquire_cred_from(minor_status, + desired_name, + time_req, + desired_mechs, + cred_usage, + GSS_C_NO_CRED_STORE, + output_cred_handle, + actual_mechs, + time_rec); +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_acquire_cred_from.c b/third_party/heimdal/lib/gssapi/mech/gss_acquire_cred_from.c new file mode 100644 index 0000000..5bb956c --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_acquire_cred_from.c @@ -0,0 +1,302 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Portions Copyright (c) 2009 Apple Inc. All rights reserved. + * Portions Copyright (c) 2011, 2018 PADL Software Pty Ltd. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_acquire_cred.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" + +/* + * Shim for gss_acquire_cred_with_password() + */ +static const char * +find_password_in_cred_store(gss_const_key_value_set_t cred_store) +{ + size_t i; + + if (cred_store == GSS_C_NO_CRED_STORE) + return NULL; + + for (i = 0; i < cred_store->count; i++) { + if (strcmp(cred_store->elements[i].key, "password") == 0) + return cred_store->elements[i].value; + } + + return NULL; +} + +static OM_uint32 +acquire_mech_cred(OM_uint32 *minor_status, + gssapi_mech_interface m, + const struct _gss_mechanism_name *mn, + OM_uint32 time_req, + gss_cred_usage_t cred_usage, + gss_const_key_value_set_t cred_store, + struct _gss_mechanism_cred **out, + OM_uint32 *time_rec) +{ + OM_uint32 major_status; + struct _gss_mechanism_cred *mc; + gss_OID_set_desc mech; + const char *spassword; + + *out = NULL; + if (time_rec) + *time_rec = 0; + + mc = calloc(1, sizeof(struct _gss_mechanism_cred)); + if (mc == NULL) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + mc->gmc_mech = m; + mc->gmc_mech_oid = &m->gm_mech_oid; + + mech.count = 1; + mech.elements = mc->gmc_mech_oid; + + if (m->gm_acquire_cred_from) { + major_status = m->gm_acquire_cred_from(minor_status, + mn ? mn->gmn_name : GSS_C_NO_NAME, + time_req, + &mech, + cred_usage, + cred_store, + &mc->gmc_cred, + NULL, + time_rec); + } else if ((cred_store == GSS_C_NO_CRED_STORE || cred_store->count == 0) && + m->gm_acquire_cred) { + major_status = m->gm_acquire_cred(minor_status, + mn ? mn->gmn_name : GSS_C_NO_NAME, + time_req, + &mech, + cred_usage, + &mc->gmc_cred, + NULL, + time_rec); + } else if (m->gm_compat && + m->gm_compat->gmc_acquire_cred_with_password && + (spassword = find_password_in_cred_store(cred_store)) != NULL) { + gss_buffer_desc password; + + password.length = strlen(spassword); + password.value = rk_UNCONST(spassword); + + /* compat glue for loadable mechanisms that implement API-as-SPI */ + major_status = m->gm_compat->gmc_acquire_cred_with_password(minor_status, + mn ? mn->gmn_name : GSS_C_NO_NAME, + &password, + time_req, + &mech, + cred_usage, + &mc->gmc_cred, + NULL, + time_rec); + } else + major_status = GSS_S_UNAVAILABLE; + + heim_assert(major_status == GSS_S_COMPLETE || mc->gmc_cred == NULL, + "gss_acquire_cred_from: mech succeeded but did not return a credential"); + + if (major_status == GSS_S_COMPLETE) + *out = mc; + else + free(mc); + + return major_status; +} + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_acquire_cred_from(OM_uint32 *minor_status, + gss_const_name_t desired_name, + OM_uint32 time_req, + const gss_OID_set desired_mechs, + gss_cred_usage_t cred_usage, + gss_const_key_value_set_t cred_store, + gss_cred_id_t *output_cred_handle, + gss_OID_set *actual_mechs, + OM_uint32 *time_rec) +{ + OM_uint32 major_status, minor; + struct _gss_name *name = (struct _gss_name *)desired_name; + gssapi_mech_interface m; + struct _gss_cred *cred = NULL; + size_t i; + OM_uint32 min_time = GSS_C_INDEFINITE; + gss_OID_set mechs = GSS_C_NO_OID_SET; + + *minor_status = 0; + if (output_cred_handle == NULL) + return GSS_S_CALL_INACCESSIBLE_READ; + *output_cred_handle = GSS_C_NO_CREDENTIAL; + if (actual_mechs) + *actual_mechs = GSS_C_NO_OID_SET; + if (time_rec) + *time_rec = 0; + + _gss_load_mech(); + + if (desired_mechs != GSS_C_NO_OID_SET) { + int only_mg_cred_mechs = -1; + + for (i = 0; i < desired_mechs->count; i++) { + m = __gss_get_mechanism(&desired_mechs->elements[i]); + if (m != NULL) { + if ((m->gm_flags & GM_USE_MG_CRED) == 0) + only_mg_cred_mechs = 0; + else if (only_mg_cred_mechs == -1) + only_mg_cred_mechs = 1; + } + } + /* + * Now SPNEGO supports GM_USE_MG_CRED it's no longer necessary + * to specifically acquire SPNEGO credentials. If the caller + * did not specify any concrete mechanisms then we will acquire + * credentials for all of them. + */ + if (only_mg_cred_mechs == -1) { + *minor_status = 0; + major_status = GSS_S_BAD_MECH; + goto cleanup; + } else if (only_mg_cred_mechs == 0) + mechs = desired_mechs; + else + mechs = _gss_mech_oids; + } else + mechs = _gss_mech_oids; + + cred = _gss_mg_alloc_cred(); + if (cred == NULL) { + *minor_status = ENOMEM; + major_status = GSS_S_FAILURE; + goto cleanup; + } + + if (actual_mechs) { + major_status = gss_create_empty_oid_set(minor_status, actual_mechs); + if (GSS_ERROR(major_status)) + goto cleanup; + } + + major_status = GSS_S_UNAVAILABLE; /* in case of no mechs */ + + for (i = 0; i < mechs->count; i++) { + struct _gss_mechanism_name *mn = NULL; + struct _gss_mechanism_cred *mc = NULL; + OM_uint32 cred_time; + + m = __gss_get_mechanism(&mechs->elements[i]); + if (m == NULL || (m->gm_flags & GM_USE_MG_CRED) != 0) + continue; + + if (desired_name != GSS_C_NO_NAME) { + major_status = _gss_find_mn(minor_status, name, + &mechs->elements[i], &mn); + if (major_status != GSS_S_COMPLETE) + continue; + } + + major_status = acquire_mech_cred(minor_status, m, mn, + time_req, cred_usage, + cred_store, &mc, &cred_time); + if (major_status != GSS_S_COMPLETE) { + if (mechs->count == 1) + _gss_mg_error(m, *minor_status); + continue; + } + + _gss_mg_log_name(10, name, &mechs->elements[i], + "gss_acquire_cred %s name: %ld/%ld", + m->gm_name, + (long)major_status, (long)*minor_status); + + HEIM_TAILQ_INSERT_TAIL(&cred->gc_mc, mc, gmc_link); + + if (cred_time < min_time) + min_time = cred_time; + if (actual_mechs != NULL) { + major_status = gss_add_oid_set_member(minor_status, + mc->gmc_mech_oid, + actual_mechs); + if (GSS_ERROR(major_status)) + goto cleanup; + } + } + + /* + * If we didn't manage to create a single credential, return + * an error. + */ + if (!HEIM_TAILQ_FIRST(&cred->gc_mc)) { + if (mechs->count > 1) { + *minor_status = 0; + major_status = GSS_S_NO_CRED; + } + heim_assert(major_status != GSS_S_COMPLETE, + "lack of credentials must result in an error"); + goto cleanup; + } + + /* add all GM_USE_MG_CRED mechs such as SPNEGO */ + if (actual_mechs != NULL) { + struct _gss_mech_switch *ms; + + HEIM_TAILQ_FOREACH(ms, &_gss_mechs, gm_link) { + m = &ms->gm_mech; + + if ((m->gm_flags & GM_USE_MG_CRED) == 0) + continue; + + major_status = gss_add_oid_set_member(minor_status, + &m->gm_mech_oid, + actual_mechs); + if (GSS_ERROR(major_status)) + goto cleanup; + } + } + + *minor_status = 0; + major_status = GSS_S_COMPLETE; + + *output_cred_handle = (gss_cred_id_t)cred; + if (time_rec) + *time_rec = min_time; + + _gss_mg_log_cred(10, cred, "gss_acquire_cred_from"); + +cleanup: + if (major_status != GSS_S_COMPLETE) { + gss_release_cred(&minor, (gss_cred_id_t *)&cred); + if (actual_mechs) + gss_release_oid_set(&minor, actual_mechs); + } + + return major_status; +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_acquire_cred_impersonate_name.c b/third_party/heimdal/lib/gssapi/mech/gss_acquire_cred_impersonate_name.c new file mode 100644 index 0000000..ec027ed --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_acquire_cred_impersonate_name.c @@ -0,0 +1,51 @@ +/*- + * Copyright 2021, Dr Robert Harvey Crowston. <crowston@protonmail.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_acquire_cred_impersonate_name( + OM_uint32 *minor_status, + gss_const_cred_id_t icred_handle, + gss_const_name_t desired_name, + OM_uint32 time_req, + gss_OID_set desired_mechs, + gss_cred_usage_t cred_usage, + gss_cred_id_t *ocred_handle, + gss_OID_set *actual_mechs, + OM_uint32 *time_rec) +{ + *minor_status = 0; + + if (ocred_handle == NULL) + return GSS_S_CALL_INACCESSIBLE_WRITE; + + *ocred_handle = GSS_C_NO_CREDENTIAL; + + /* Not implemented. */ + return GSS_S_UNAVAILABLE; +} + diff --git a/third_party/heimdal/lib/gssapi/mech/gss_acquire_cred_with_password.c b/third_party/heimdal/lib/gssapi/mech/gss_acquire_cred_with_password.c new file mode 100644 index 0000000..4e6138b --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_acquire_cred_with_password.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2011, PADL Software Pty Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of PADL Software nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_acquire_cred_with_password(OM_uint32 *minor_status, + gss_const_name_t desired_name, + const gss_buffer_t password, + OM_uint32 time_req, + const gss_OID_set desired_mechs, + gss_cred_usage_t cred_usage, + gss_cred_id_t *output_cred_handle, + gss_OID_set *actual_mechs, + OM_uint32 *time_rec) +{ + OM_uint32 major_status; + gss_key_value_element_desc kv; + gss_key_value_set_desc store; + char *spassword = NULL; + + *output_cred_handle = GSS_C_NO_CREDENTIAL; + + if (password == GSS_C_NO_BUFFER || password->value == NULL) + return GSS_S_CALL_INACCESSIBLE_READ; + + spassword = malloc(password->length + 1); + if (spassword == NULL) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + memcpy(spassword, password->value, password->length); + spassword[password->length] = '\0'; + + kv.key = "password"; + kv.value = spassword; + + store.count = 1; + store.elements = &kv; + + major_status = gss_acquire_cred_from(minor_status, + desired_name, + time_req, + desired_mechs, + cred_usage, + &store, + output_cred_handle, + actual_mechs, + time_rec); + if (spassword) { + memset_s(spassword, password->length, 0, password->length); + free(spassword); + } + + return major_status; +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_add_cred.c b/third_party/heimdal/lib/gssapi/mech/gss_add_cred.c new file mode 100644 index 0000000..6d44f5c --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_add_cred.c @@ -0,0 +1,58 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * Copyright (c) 2018 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_add_cred.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_add_cred(OM_uint32 *minor_status, + gss_const_cred_id_t input_cred_handle, + gss_const_name_t desired_name, + const gss_OID desired_mech, + gss_cred_usage_t cred_usage, + OM_uint32 initiator_time_req, + OM_uint32 acceptor_time_req, + gss_cred_id_t *output_cred_handle, + gss_OID_set *actual_mechs, + OM_uint32 *initiator_time_rec, + OM_uint32 *acceptor_time_rec) +{ + return gss_add_cred_from(minor_status, + rk_UNCONST(input_cred_handle), + desired_name, + desired_mech, + cred_usage, + initiator_time_req, + acceptor_time_req, + GSS_C_NO_CRED_STORE, + output_cred_handle, + actual_mechs, + initiator_time_rec, + acceptor_time_rec); +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_add_cred_from.c b/third_party/heimdal/lib/gssapi/mech/gss_add_cred_from.c new file mode 100644 index 0000000..9f761e8 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_add_cred_from.c @@ -0,0 +1,292 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * Copyright (c) 2018 Kungliga Tekniska Högskolan + * Copyright (c) 2018 AuriStor, Inc. + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_add_cred.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" + +OM_uint32 +_gss_mg_add_mech_cred(OM_uint32 *minor_status, + gssapi_mech_interface m, + const struct _gss_mechanism_cred *mc, + const struct _gss_mechanism_name *mn, + gss_cred_usage_t cred_usage, + OM_uint32 initiator_time_req, + OM_uint32 acceptor_time_req, + gss_const_key_value_set_t cred_store, + struct _gss_mechanism_cred **out, + OM_uint32 *initiator_time_rec, + OM_uint32 *acceptor_time_rec) +{ + OM_uint32 major_status; + struct _gss_mechanism_cred *new_mc = NULL; + + if (out) { + *out = NULL; + + new_mc = calloc(1, sizeof(struct _gss_mechanism_cred)); + if (new_mc == NULL) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + new_mc->gmc_mech = m; + new_mc->gmc_mech_oid = &m->gm_mech_oid; + } + + if (m->gm_add_cred_from) { + major_status = m->gm_add_cred_from(minor_status, + mc ? mc->gmc_cred : GSS_C_NO_CREDENTIAL, + mn ? mn->gmn_name : GSS_C_NO_NAME, + &m->gm_mech_oid, + cred_usage, + initiator_time_req, + acceptor_time_req, + cred_store, + new_mc ? &new_mc->gmc_cred : NULL, + NULL, + initiator_time_rec, + acceptor_time_rec); + } else if (cred_store == GSS_C_NO_CRED_STORE && m->gm_add_cred) { + major_status = m->gm_add_cred(minor_status, + mc ? mc->gmc_cred : GSS_C_NO_CREDENTIAL, + mn ? mn->gmn_name : GSS_C_NO_NAME, + &m->gm_mech_oid, + cred_usage, + initiator_time_req, + acceptor_time_req, + new_mc ? &new_mc->gmc_cred : NULL, + NULL, + initiator_time_rec, + acceptor_time_rec); + } else + major_status = GSS_S_UNAVAILABLE; + + if (major_status == GSS_S_COMPLETE && out) { + heim_assert(new_mc->gmc_cred != GSS_C_NO_CREDENTIAL, + "mechanism gss_add_cred did not return a cred"); + *out = new_mc; + } else + free(new_mc); + + return major_status; +} + +static OM_uint32 +add_mech_cred_internal(OM_uint32 *minor_status, + gss_const_name_t desired_name, + gssapi_mech_interface m, + gss_cred_usage_t cred_usage, + OM_uint32 initiator_time_req, + OM_uint32 acceptor_time_req, + gss_const_key_value_set_t cred_store, + struct _gss_cred *mut_cred, + OM_uint32 *initiator_time_rec, + OM_uint32 *acceptor_time_rec) +{ + OM_uint32 major_status; + struct _gss_mechanism_cred *mc; + struct _gss_mechanism_name *mn; + + heim_assert((m->gm_flags & GM_USE_MG_CRED) == 0, + "add_mech_cred_internal must be called with concrete mechanism"); + + if (desired_name != GSS_C_NO_NAME) { + major_status = _gss_find_mn(minor_status, + (struct _gss_name *)desired_name, + &m->gm_mech_oid, &mn); + if (major_status != GSS_S_COMPLETE) + return major_status; + } else + mn = NULL; + + /* + * If we have an existing mechanism credential for mechanism m, then + * add the desired credential to it; otherwise, create a new one and + * add it to mut_cred. + */ + HEIM_TAILQ_FOREACH(mc, &mut_cred->gc_mc, gmc_link) { + if (gss_oid_equal(&m->gm_mech_oid, mc->gmc_mech_oid)) + break; + } + + if (mc) { + major_status = _gss_mg_add_mech_cred(minor_status, m, + mc, mn, cred_usage, + initiator_time_req, acceptor_time_req, + cred_store, NULL, + initiator_time_rec, acceptor_time_rec); + } else { + struct _gss_mechanism_cred *new_mc = NULL; + + major_status = _gss_mg_add_mech_cred(minor_status, m, + NULL, mn, cred_usage, + initiator_time_req, acceptor_time_req, + cred_store, &new_mc, + initiator_time_rec, acceptor_time_rec); + if (major_status == GSS_S_COMPLETE) + HEIM_TAILQ_INSERT_TAIL(&mut_cred->gc_mc, new_mc, gmc_link); + } + + return major_status; +} + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_add_cred_from(OM_uint32 *minor_status, + gss_cred_id_t input_cred_handle, + gss_const_name_t desired_name, + const gss_OID desired_mech, + gss_cred_usage_t cred_usage, + OM_uint32 initiator_time_req, + OM_uint32 acceptor_time_req, + gss_const_key_value_set_t cred_store, + gss_cred_id_t *output_cred_handle, + gss_OID_set *actual_mechs, + OM_uint32 *initiator_time_rec, + OM_uint32 *acceptor_time_rec) +{ + OM_uint32 major_status; + gssapi_mech_interface m; + gss_cred_id_t release_cred = GSS_C_NO_CREDENTIAL; + struct _gss_cred *mut_cred; + OM_uint32 junk; + + *minor_status = 0; + + /* Input validation */ + if (output_cred_handle) + *output_cred_handle = GSS_C_NO_CREDENTIAL; + if (initiator_time_rec) + *initiator_time_rec = 0; + if (acceptor_time_rec) + *acceptor_time_rec = 0; + if (actual_mechs) + *actual_mechs = GSS_C_NO_OID_SET; + if ((m = __gss_get_mechanism(desired_mech)) == NULL) + return GSS_S_BAD_MECH; + if (input_cred_handle == GSS_C_NO_CREDENTIAL && + output_cred_handle == NULL) { + return GSS_S_CALL_INACCESSIBLE_WRITE; + } + + /* Setup mut_cred to be the credential we mutate */ + if (input_cred_handle != GSS_C_NO_CREDENTIAL && + output_cred_handle != NULL) { + gss_cred_id_t new_cred; + + /* Duplicate the input credential */ + major_status = gss_duplicate_cred(minor_status, input_cred_handle, + &new_cred); + if (major_status != GSS_S_COMPLETE) + return major_status; + mut_cred = (struct _gss_cred *)new_cred; + release_cred = (gss_cred_id_t)mut_cred; + } else if (input_cred_handle != GSS_C_NO_CREDENTIAL) { + /* Mutate the input credentials */ + mut_cred = rk_UNCONST(input_cred_handle); + } else { + mut_cred = _gss_mg_alloc_cred(); + if (mut_cred == NULL) { + *minor_status = ENOMEM; + return GSS_S_UNAVAILABLE; + } + release_cred = (gss_cred_id_t)mut_cred; + } + + if (m->gm_flags & GM_USE_MG_CRED) { + struct _gss_mech_switch *ms; + OM_uint32 initiator_time_min = GSS_C_INDEFINITE; + OM_uint32 acceptor_time_min = GSS_C_INDEFINITE; + + major_status = GSS_S_UNAVAILABLE; /* in case of no mechs */ + + if (input_cred_handle == GSS_C_NO_CREDENTIAL) { + HEIM_TAILQ_FOREACH(ms, &_gss_mechs, gm_link) { + m = &ms->gm_mech; /* for _gss_mg_error() */ + + if (m->gm_flags & GM_USE_MG_CRED) + continue; + + major_status = add_mech_cred_internal(minor_status, desired_name, m, + cred_usage, + initiator_time_req, acceptor_time_req, + cred_store, mut_cred, + initiator_time_rec, acceptor_time_rec); + if (major_status != GSS_S_COMPLETE) + continue; + + if (initiator_time_rec && *initiator_time_rec < initiator_time_min) + initiator_time_min = *initiator_time_rec; + if (acceptor_time_rec && *acceptor_time_rec < acceptor_time_min) + acceptor_time_min = *acceptor_time_rec; + } + } else { + OM_uint32 lifetime; + gss_cred_usage_t usage = GSS_C_BOTH; + + major_status = gss_inquire_cred(minor_status, input_cred_handle, + NULL, &lifetime, &usage, NULL); + if (major_status == GSS_S_COMPLETE) { + if (usage == GSS_C_BOTH || usage == GSS_C_INITIATE) + initiator_time_min = lifetime; + if (usage == GSS_C_BOTH || usage == GSS_C_ACCEPT) + acceptor_time_min = lifetime; + } + } + + if (initiator_time_rec) + *initiator_time_rec = initiator_time_min; + if (acceptor_time_rec) + *acceptor_time_rec = acceptor_time_min; + } else { + major_status = add_mech_cred_internal(minor_status, desired_name, m, + cred_usage, + initiator_time_req, acceptor_time_req, + cred_store, mut_cred, + initiator_time_rec, acceptor_time_rec); + } + + if (major_status != GSS_S_COMPLETE) + _gss_mg_error(m, *minor_status); + + /* Lastly, we have to inquire the cred to get the actual_mechs */ + if (major_status == GSS_S_COMPLETE && actual_mechs != NULL) { + major_status = gss_inquire_cred(minor_status, + (gss_const_cred_id_t)mut_cred, NULL, + NULL, NULL, actual_mechs); + } + if (major_status == GSS_S_COMPLETE) { + if (output_cred_handle != NULL) + *output_cred_handle = (gss_cred_id_t)mut_cred; + } else { + gss_release_cred(&junk, &release_cred); + } + return major_status; +} + diff --git a/third_party/heimdal/lib/gssapi/mech/gss_add_cred_with_password.c b/third_party/heimdal/lib/gssapi/mech/gss_add_cred_with_password.c new file mode 100644 index 0000000..eeb5949 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_add_cred_with_password.c @@ -0,0 +1,88 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_add_cred.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_add_cred_with_password(OM_uint32 *minor_status, + gss_const_cred_id_t input_cred_handle, + gss_const_name_t desired_name, + const gss_OID desired_mech, + const gss_buffer_t password, + gss_cred_usage_t cred_usage, + OM_uint32 initiator_time_req, + OM_uint32 acceptor_time_req, + gss_cred_id_t *output_cred_handle, + gss_OID_set *actual_mechs, + OM_uint32 *initiator_time_rec, + OM_uint32 *acceptor_time_rec) +{ + OM_uint32 major_status; + gss_key_value_element_desc kv; + gss_key_value_set_desc store; + char *spassword = NULL; + + *output_cred_handle = GSS_C_NO_CREDENTIAL; + + if (password == GSS_C_NO_BUFFER || password->value == NULL) + return GSS_S_CALL_INACCESSIBLE_READ; + + spassword = malloc(password->length + 1); + if (spassword == NULL) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + memcpy(spassword, password->value, password->length); + spassword[password->length] = '\0'; + + kv.key = "password"; + kv.value = spassword; + + store.count = 1; + store.elements = &kv; + + major_status = gss_add_cred_from(minor_status, + rk_UNCONST(input_cred_handle), + desired_name, + desired_mech, + cred_usage, + initiator_time_req, + acceptor_time_req, + &store, + output_cred_handle, + actual_mechs, + initiator_time_rec, + acceptor_time_rec); + + if (spassword) { + memset_s(spassword, password->length, 0, password->length); + free(spassword); + } + + return major_status; +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_add_oid_set_member.c b/third_party/heimdal/lib/gssapi/mech/gss_add_oid_set_member.c new file mode 100644 index 0000000..8574224 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_add_oid_set_member.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 1997 - 2001, 2003 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "mech_locl.h" + +/** + * Add a oid to the oid set. + * + * If there is a duplicate member of the oid, the new member is not + * added to to the set. + * + * @param minor_status minor status code. + * @param member_oid member to add to the oid set + * @param oid_set oid set to add the member too + * + * @returns a gss_error code, see gss_display_status() about printing + * the error code. + * + * @ingroup gssapi + */ + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_add_oid_set_member (OM_uint32 * minor_status, + const gss_OID member_oid, + gss_OID_set * oid_set) +{ + gss_OID tmp, interned_oid; + size_t n; + OM_uint32 res; + int present; + + res = gss_test_oid_set_member(minor_status, member_oid, *oid_set, &present); + if (res != GSS_S_COMPLETE) + return res; + + if (present) { + *minor_status = 0; + return GSS_S_COMPLETE; + } + + n = (*oid_set)->count + 1; + tmp = realloc ((*oid_set)->elements, n * sizeof(gss_OID_desc)); + if (tmp == NULL) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + (*oid_set)->elements = tmp; + + res = _gss_intern_oid(minor_status, member_oid, &interned_oid); + if (res != GSS_S_COMPLETE) + return res; + + (*oid_set)->count = n; + (*oid_set)->elements[n-1] = *interned_oid; + *minor_status = 0; + return GSS_S_COMPLETE; +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_aeap.c b/third_party/heimdal/lib/gssapi/mech/gss_aeap.c new file mode 100644 index 0000000..dbcd611 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_aeap.c @@ -0,0 +1,334 @@ +/* + * AEAD support + */ + +#include "mech_locl.h" + +/** + * Encrypts or sign the data. + * + * This is a more complicated version of gss_wrap(), it allows the + * caller to use AEAD data (signed header/trailer) and allow greater + * controll over where the encrypted data is placed. + * + * The maximum packet size is gss_context_stream_sizes.max_msg_size. + * + * The caller needs provide the folloing buffers when using in conf_req_flag=1 mode: + * + * - HEADER (of size gss_context_stream_sizes.header) + * { DATA or SIGN_ONLY } (optional, zero or more) + * PADDING (of size gss_context_stream_sizes.blocksize, if zero padding is zero, can be omitted) + * TRAILER (of size gss_context_stream_sizes.trailer) + * + * - on DCE-RPC mode, the caller can skip PADDING and TRAILER if the + * DATA elements is padded to a block bountry and header is of at + * least size gss_context_stream_sizes.header + gss_context_stream_sizes.trailer. + * + * HEADER, PADDING, TRAILER will be shrunken to the size required to transmit any of them too large. + * + * To generate gss_wrap() compatible packets, use: HEADER | DATA | PADDING | TRAILER + * + * When used in conf_req_flag=0, + * + * - HEADER (of size gss_context_stream_sizes.header) + * { DATA or SIGN_ONLY } (optional, zero or more) + * PADDING (of size gss_context_stream_sizes.blocksize, if zero padding is zero, can be omitted) + * TRAILER (of size gss_context_stream_sizes.trailer) + * + * + * The input sizes of HEADER, PADDING and TRAILER can be fetched using gss_wrap_iov_length() or + * gss_context_query_attributes(). + * + * @ingroup gssapi + */ + + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_wrap_iov(OM_uint32 * minor_status, + gss_ctx_id_t context_handle, + int conf_req_flag, + gss_qop_t qop_req, + int * conf_state, + gss_iov_buffer_desc *iov, + int iov_count) +{ + struct _gss_context *ctx = (struct _gss_context *) context_handle; + gssapi_mech_interface m; + + if (minor_status) + *minor_status = 0; + if (conf_state) + *conf_state = 0; + if (ctx == NULL) + return GSS_S_NO_CONTEXT; + if (iov == NULL && iov_count != 0) + return GSS_S_CALL_INACCESSIBLE_READ; + + m = ctx->gc_mech; + + if (m->gm_wrap_iov == NULL) + return GSS_S_UNAVAILABLE; + + return (m->gm_wrap_iov)(minor_status, ctx->gc_ctx, + conf_req_flag, qop_req, conf_state, + iov, iov_count); +} + +/** + * Decrypt or verifies the signature on the data. + * + * + * @ingroup gssapi + */ + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_unwrap_iov(OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + int *conf_state, + gss_qop_t *qop_state, + gss_iov_buffer_desc *iov, + int iov_count) +{ + struct _gss_context *ctx = (struct _gss_context *) context_handle; + gssapi_mech_interface m; + + if (minor_status) + *minor_status = 0; + if (conf_state) + *conf_state = 0; + if (qop_state) + *qop_state = 0; + if (ctx == NULL) + return GSS_S_NO_CONTEXT; + if (iov == NULL && iov_count != 0) + return GSS_S_CALL_INACCESSIBLE_READ; + + m = ctx->gc_mech; + + if (m->gm_unwrap_iov == NULL) + return GSS_S_UNAVAILABLE; + + return (m->gm_unwrap_iov)(minor_status, ctx->gc_ctx, + conf_state, qop_state, + iov, iov_count); +} + +/** + * Update the length fields in iov buffer for the types: + * - GSS_IOV_BUFFER_TYPE_HEADER + * - GSS_IOV_BUFFER_TYPE_PADDING + * - GSS_IOV_BUFFER_TYPE_TRAILER + * + * Consider using gss_context_query_attributes() to fetch the data instead. + * + * @ingroup gssapi + */ + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_wrap_iov_length(OM_uint32 * minor_status, + gss_ctx_id_t context_handle, + int conf_req_flag, + gss_qop_t qop_req, + int *conf_state, + gss_iov_buffer_desc *iov, + int iov_count) +{ + struct _gss_context *ctx = (struct _gss_context *) context_handle; + gssapi_mech_interface m; + + if (minor_status) + *minor_status = 0; + if (conf_state) + *conf_state = 0; + if (ctx == NULL) + return GSS_S_NO_CONTEXT; + if (iov == NULL && iov_count != 0) + return GSS_S_CALL_INACCESSIBLE_READ; + + m = ctx->gc_mech; + + if (m->gm_wrap_iov_length == NULL) + return GSS_S_UNAVAILABLE; + + return (m->gm_wrap_iov_length)(minor_status, ctx->gc_ctx, + conf_req_flag, qop_req, conf_state, + iov, iov_count); +} + +/** + * Free all buffer allocated by gss_wrap_iov() or gss_unwrap_iov() by + * looking at the GSS_IOV_BUFFER_FLAG_ALLOCATED flag. + * + * @ingroup gssapi + */ + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_release_iov_buffer(OM_uint32 *minor_status, + gss_iov_buffer_desc *iov, + int iov_count) +{ + OM_uint32 junk; + int i; + + if (minor_status) + *minor_status = 0; + if (iov == NULL && iov_count != 0) + return GSS_S_CALL_INACCESSIBLE_READ; + + for (i = 0; i < iov_count; i++) { + if ((iov[i].type & GSS_IOV_BUFFER_FLAG_ALLOCATED) == 0) + continue; + gss_release_buffer(&junk, &iov[i].buffer); + iov[i].type &= ~GSS_IOV_BUFFER_FLAG_ALLOCATED; + } + return GSS_S_COMPLETE; +} + +/** + * Query the context for parameters. + * + * SSPI equivalent if this function is QueryContextAttributes. + * + * - GSS_C_ATTR_STREAM_SIZES data is a gss_context_stream_sizes. + * + * @ingroup gssapi + */ + +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_attr_stream_sizes_oid_desc = + {10, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x03")}; + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_context_query_attributes(OM_uint32 *minor_status, + gss_const_ctx_id_t context_handle, + const gss_OID attribute, + void *data, + size_t len) +{ + if (minor_status) + *minor_status = 0; + + if (gss_oid_equal(GSS_C_ATTR_STREAM_SIZES, attribute)) { + memset(data, 0, len); + return GSS_S_COMPLETE; + } + + return GSS_S_FAILURE; +} + +/* + * AEAD wrap API for a single piece of associated data, for compatibility + * with MIT and as specified by draft-howard-gssapi-aead-00.txt. + * + * @ingroup gssapi + */ +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_wrap_aead(OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + int conf_req_flag, + gss_qop_t qop_req, + gss_buffer_t input_assoc_buffer, + gss_buffer_t input_payload_buffer, + int *conf_state, + gss_buffer_t output_message_buffer) +{ + OM_uint32 major_status, tmp, flags = 0; + gss_iov_buffer_desc iov[5]; + size_t i; + unsigned char *p; + + memset(iov, 0, sizeof(iov)); + + iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER; + + iov[1].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY; + if (input_assoc_buffer) + iov[1].buffer = *input_assoc_buffer; + + iov[2].type = GSS_IOV_BUFFER_TYPE_DATA; + if (input_payload_buffer) + iov[2].buffer.length = input_payload_buffer->length; + + gss_inquire_context(minor_status, context_handle, NULL, NULL, + NULL, NULL, &flags, NULL, NULL); + + /* krb5 mech rejects padding/trailer if DCE-style is set */ + iov[3].type = (flags & GSS_C_DCE_STYLE) ? GSS_IOV_BUFFER_TYPE_EMPTY + : GSS_IOV_BUFFER_TYPE_PADDING; + iov[4].type = (flags & GSS_C_DCE_STYLE) ? GSS_IOV_BUFFER_TYPE_EMPTY + : GSS_IOV_BUFFER_TYPE_TRAILER; + + major_status = gss_wrap_iov_length(minor_status, context_handle, + conf_req_flag, qop_req, conf_state, + iov, 5); + if (GSS_ERROR(major_status)) + return major_status; + + for (i = 0, output_message_buffer->length = 0; i < 5; i++) { + if (GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_SIGN_ONLY) + continue; + + output_message_buffer->length += iov[i].buffer.length; + } + + output_message_buffer->value = malloc(output_message_buffer->length); + if (output_message_buffer->value == NULL) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + for (i = 0, p = output_message_buffer->value; i < 5; i++) { + if (GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_SIGN_ONLY) + continue; + else if (GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_DATA) + memcpy(p, input_payload_buffer->value, input_payload_buffer->length); + + iov[i].buffer.value = p; + p += iov[i].buffer.length; + } + + major_status = gss_wrap_iov(minor_status, context_handle, conf_req_flag, + qop_req, conf_state, iov, 5); + if (GSS_ERROR(major_status)) + gss_release_buffer(&tmp, output_message_buffer); + + return major_status; +} + +/* + * AEAD unwrap for a single piece of associated data, for compatibility + * with MIT and as specified by draft-howard-gssapi-aead-00.txt. + * + * @ingroup gssapi + */ +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_unwrap_aead(OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + gss_buffer_t input_message_buffer, + gss_buffer_t input_assoc_buffer, + gss_buffer_t output_payload_buffer, + int *conf_state, + gss_qop_t *qop_state) +{ + OM_uint32 major_status, tmp; + gss_iov_buffer_desc iov[3]; + + memset(iov, 0, sizeof(iov)); + + iov[0].type = GSS_IOV_BUFFER_TYPE_STREAM; + iov[0].buffer = *input_message_buffer; + + iov[1].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY; + if (input_assoc_buffer) + iov[1].buffer = *input_assoc_buffer; + + iov[2].type = GSS_IOV_BUFFER_TYPE_DATA | GSS_IOV_BUFFER_FLAG_ALLOCATE; + + major_status = gss_unwrap_iov(minor_status, context_handle, conf_state, + qop_state, iov, 3); + if (GSS_ERROR(major_status)) + gss_release_iov_buffer(&tmp, &iov[2], 1); + else + *output_payload_buffer = iov[2].buffer; + + return major_status; +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_authorize_localname.c b/third_party/heimdal/lib/gssapi/mech/gss_authorize_localname.c new file mode 100644 index 0000000..b72b7bd --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_authorize_localname.c @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2011, PADL Software Pty Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of PADL Software nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "mech_locl.h" + +gss_buffer_desc GSSAPI_LIB_VARIABLE __gss_c_attr_local_login_user = { + sizeof("local-login-user") - 1, + "local-login-user" +}; + +static OM_uint32 +mech_authorize_localname(OM_uint32 *minor_status, + const struct _gss_name *name, + const struct _gss_name *user) +{ + OM_uint32 major_status = GSS_S_NAME_NOT_MN; + struct _gss_mechanism_name *mn; + + HEIM_TAILQ_FOREACH(mn, &name->gn_mn, gmn_link) { + gssapi_mech_interface m = mn->gmn_mech; + + if (m->gm_authorize_localname == NULL) { + major_status = GSS_S_UNAVAILABLE; + continue; + } + + major_status = m->gm_authorize_localname(minor_status, + mn->gmn_name, + &user->gn_value, + user->gn_type); + if (major_status != GSS_S_UNAUTHORIZED) + break; + } + + return major_status; +} + +/* + * Naming extensions based local login authorization. + */ +static OM_uint32 +attr_authorize_localname(OM_uint32 *minor_status, + const struct _gss_name *name, + const struct _gss_name *user) +{ + OM_uint32 major_status = GSS_S_UNAVAILABLE; + int more = -1; + + if (!gss_oid_equal(user->gn_type, GSS_C_NT_USER_NAME)) + return GSS_S_BAD_NAMETYPE; + + while (more != 0 && major_status != GSS_S_COMPLETE) { + OM_uint32 tmpMajor, tmpMinor; + gss_buffer_desc value; + gss_buffer_desc display_value; + int authenticated = 0, complete = 0; + + tmpMajor = gss_get_name_attribute(minor_status, + (gss_name_t)name, + GSS_C_ATTR_LOCAL_LOGIN_USER, + &authenticated, + &complete, + &value, + &display_value, + &more); + if (GSS_ERROR(tmpMajor)) { + major_status = tmpMajor; + break; + } + + /* If attribute is present, return an authoritative error code. */ + if (authenticated && + value.length == user->gn_value.length && + memcmp(value.value, user->gn_value.value, user->gn_value.length) == 0) + major_status = GSS_S_COMPLETE; + else + major_status = GSS_S_UNAUTHORIZED; + + gss_release_buffer(&tmpMinor, &value); + gss_release_buffer(&tmpMinor, &display_value); + } + + return major_status; +} + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_authorize_localname(OM_uint32 *minor_status, + gss_const_name_t gss_name, + gss_const_name_t gss_user) + +{ + OM_uint32 major_status; + const struct _gss_name *name = (const struct _gss_name *) gss_name; + const struct _gss_name *user = (const struct _gss_name *) gss_user; + int mechAvailable = 0; + + *minor_status = 0; + + if (gss_name == GSS_C_NO_NAME || gss_user == GSS_C_NO_NAME) + return GSS_S_CALL_INACCESSIBLE_READ; + + /* + * We should check that the user name is not a mechanism name, but + * as Heimdal always calls the mechanism's gss_import_name(), it's + * not possible to make this check. + */ +#if 0 + if (HEIM_TAILQ_FIRST(&user->gn_mn) != NULL) + return GSS_S_BAD_NAME; +#endif + + /* If mech returns yes, we return yes */ + major_status = mech_authorize_localname(minor_status, name, user); + if (major_status == GSS_S_COMPLETE) + return GSS_S_COMPLETE; + else if (major_status != GSS_S_UNAVAILABLE) + mechAvailable = 1; + + /* If attribute exists, it is authoritative */ + major_status = attr_authorize_localname(minor_status, name, user); + if (major_status == GSS_S_COMPLETE || major_status == GSS_S_UNAUTHORIZED) + return major_status; + + /* If mechanism did not implement SPI, compare the local name */ + if (mechAvailable == 0) { + int match = 0; + + major_status = gss_compare_name(minor_status, gss_name, + gss_user, &match); + if (major_status == GSS_S_COMPLETE && match == 0) + major_status = GSS_S_UNAUTHORIZED; + } + + return major_status; +} + +GSSAPI_LIB_FUNCTION int GSSAPI_LIB_CALL +gss_userok(gss_const_name_t name, + const char *user) +{ + OM_uint32 major_status, minor_status; + gss_buffer_desc userBuf; + gss_name_t userName; + + userBuf.value = (void *)user; + userBuf.length = strlen(user); + + major_status = gss_import_name(&minor_status, &userBuf, + GSS_C_NT_USER_NAME, &userName); + if (GSS_ERROR(major_status)) + return 0; + + major_status = gss_authorize_localname(&minor_status, name, userName); + + gss_release_name(&minor_status, &userName); + + return (major_status == GSS_S_COMPLETE); +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_buffer_set.c b/third_party/heimdal/lib/gssapi/mech/gss_buffer_set.c new file mode 100644 index 0000000..48fb720 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_buffer_set.c @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2004, PADL Software Pty Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of PADL Software nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_create_empty_buffer_set + (OM_uint32 * minor_status, + gss_buffer_set_t *buffer_set) +{ + gss_buffer_set_t set; + + set = (gss_buffer_set_desc *) malloc(sizeof(*set)); + if (set == GSS_C_NO_BUFFER_SET) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + set->count = 0; + set->elements = NULL; + + *buffer_set = set; + + *minor_status = 0; + return GSS_S_COMPLETE; +} + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_add_buffer_set_member + (OM_uint32 * minor_status, + const gss_buffer_t member_buffer, + gss_buffer_set_t *buffer_set) +{ + gss_buffer_set_t set; + gss_buffer_t p; + OM_uint32 ret; + + if (*buffer_set == GSS_C_NO_BUFFER_SET) { + ret = gss_create_empty_buffer_set(minor_status, + buffer_set); + if (ret) { + return ret; + } + } + + set = *buffer_set; + set->elements = realloc(set->elements, + (set->count + 1) * sizeof(set->elements[0])); + if (set->elements == NULL) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + p = &set->elements[set->count]; + + p->value = malloc(member_buffer->length); + if (p->value == NULL) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + memcpy(p->value, member_buffer->value, member_buffer->length); + p->length = member_buffer->length; + + set->count++; + + *minor_status = 0; + return GSS_S_COMPLETE; +} + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_release_buffer_set(OM_uint32 * minor_status, + gss_buffer_set_t *buffer_set) +{ + size_t i; + OM_uint32 minor; + + *minor_status = 0; + + if (*buffer_set == GSS_C_NO_BUFFER_SET) + return GSS_S_COMPLETE; + + for (i = 0; i < (*buffer_set)->count; i++) + gss_release_buffer(&minor, &((*buffer_set)->elements[i])); + + free((*buffer_set)->elements); + + (*buffer_set)->elements = NULL; + (*buffer_set)->count = 0; + + free(*buffer_set); + *buffer_set = GSS_C_NO_BUFFER_SET; + + return GSS_S_COMPLETE; +} + diff --git a/third_party/heimdal/lib/gssapi/mech/gss_canonicalize_name.c b/third_party/heimdal/lib/gssapi/mech/gss_canonicalize_name.c new file mode 100644 index 0000000..859c688 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_canonicalize_name.c @@ -0,0 +1,104 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Portions Copyright (c) 2009 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_canonicalize_name.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" + +/** + * gss_canonicalize_name takes a Internal Name (IN) and converts in into a + * mechanism specific Mechanism Name (MN). + * + * The input name may multiple name, or generic name types. + * + * If the input_name if of the GSS_C_NT_USER_NAME, and the Kerberos + * mechanism is specified, the resulting MN type is a + * GSS_KRB5_NT_PRINCIPAL_NAME. + * + * For more information about @ref internalVSmechname. + * + * @param minor_status minor status code. + * @param input_name name to covert, unchanged by gss_canonicalize_name(). + * @param mech_type the type to convert Name too. + * @param output_name the resulting type, release with + * gss_release_name(), independent of input_name. + * + * @returns a gss_error code, see gss_display_status() about printing + * the error code. + * + * @ingroup gssapi + */ + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_canonicalize_name(OM_uint32 *minor_status, + gss_const_name_t input_name, + const gss_OID mech_type, + gss_name_t *output_name) +{ + OM_uint32 major_status; + struct _gss_name *name = (struct _gss_name *) input_name; + struct _gss_mechanism_name *mn; + gssapi_mech_interface m; + gss_name_t new_canonical_name; + + *minor_status = 0; + *output_name = GSS_C_NO_NAME; + + if ((m = __gss_get_mechanism(mech_type)) == NULL || + (m->gm_flags & GM_USE_MG_NAME)) + return GSS_S_BAD_MECH; + + major_status = _gss_find_mn(minor_status, name, mech_type, &mn); + if (major_status) + return major_status; + if (mn == NULL) + return GSS_S_BAD_NAME; + + m = mn->gmn_mech; + major_status = m->gm_canonicalize_name(minor_status, + mn->gmn_name, mech_type, &new_canonical_name); + if (major_status) { + _gss_mg_error(m, *minor_status); + return (major_status); + } + + /* + * Now we make a new name and mark it as an MN. + */ + *minor_status = 0; + name = _gss_create_name(new_canonical_name, m); + if (!name) { + m->gm_release_name(minor_status, &new_canonical_name); + *minor_status = ENOMEM; + return (GSS_S_FAILURE); + } + + *output_name = (gss_name_t) name; + + return (GSS_S_COMPLETE); +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_compare_name.c b/third_party/heimdal/lib/gssapi/mech/gss_compare_name.c new file mode 100644 index 0000000..97ef578 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_compare_name.c @@ -0,0 +1,102 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Portions Copyright (c) 2009 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_compare_name.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_compare_name(OM_uint32 *minor_status, + gss_const_name_t name1_arg, + gss_const_name_t name2_arg, + int *name_equal) +{ + struct _gss_name *name1 = (struct _gss_name *) name1_arg; + struct _gss_name *name2 = (struct _gss_name *) name2_arg; + + /* + * First check the implementation-independant name if both + * names have one. Otherwise, try to find common mechanism + * names and compare them. + */ + if (name1->gn_value.value && name2->gn_value.value && + name1->gn_type == GSS_C_NO_OID && name2->gn_type == GSS_C_NO_OID) { + *name_equal = + name1->gn_value.length == name2->gn_value.length && + memcmp(name1->gn_value.value, name2->gn_value.value, + name1->gn_value.length) == 0; + } else if (name1->gn_value.value && name2->gn_value.value && + name1->gn_type != GSS_C_NO_OID && + name2->gn_type != GSS_C_NO_OID) { + *name_equal = 1; + /* RFC 2743: anonymous names always compare false */ + if (gss_oid_equal(name1->gn_type, GSS_C_NT_ANONYMOUS) || + gss_oid_equal(name2->gn_type, GSS_C_NT_ANONYMOUS) || + !gss_oid_equal(name1->gn_type, name2->gn_type)) { + *name_equal = 0; + } else if (name1->gn_value.length != name2->gn_value.length || + memcmp(name1->gn_value.value, name2->gn_value.value, + name1->gn_value.length) != 0) { + *name_equal = 0; + } + } else { + struct _gss_mechanism_name *mn1; + struct _gss_mechanism_name *mn2; + + HEIM_TAILQ_FOREACH(mn1, &name1->gn_mn, gmn_link) { + OM_uint32 major_status; + + major_status = _gss_find_mn(minor_status, name2, + mn1->gmn_mech_oid, &mn2); + if (major_status == GSS_S_COMPLETE && mn2) { + return (mn1->gmn_mech->gm_compare_name( + minor_status, + mn1->gmn_name, + mn2->gmn_name, + name_equal)); + } + } + HEIM_TAILQ_FOREACH(mn2, &name2->gn_mn, gmn_link) { + OM_uint32 major_status; + + major_status = _gss_find_mn(minor_status, name1, + mn2->gmn_mech_oid, &mn1); + if (major_status == GSS_S_COMPLETE && mn1) { + return (mn2->gmn_mech->gm_compare_name( + minor_status, + mn2->gmn_name, + mn1->gmn_name, + name_equal)); + } + } + *name_equal = 0; + } + + *minor_status = 0; + return (GSS_S_COMPLETE); +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_context_time.c b/third_party/heimdal/lib/gssapi/mech/gss_context_time.c new file mode 100644 index 0000000..a5b646c --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_context_time.c @@ -0,0 +1,40 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_context_time.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_context_time(OM_uint32 *minor_status, + gss_const_ctx_id_t context_handle, + OM_uint32 *time_rec) +{ + struct _gss_context *ctx = (struct _gss_context *) context_handle; + gssapi_mech_interface m = ctx->gc_mech; + + return (m->gm_context_time(minor_status, ctx->gc_ctx, time_rec)); +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_create_empty_oid_set.c b/third_party/heimdal/lib/gssapi/mech/gss_create_empty_oid_set.c new file mode 100644 index 0000000..8d880f5 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_create_empty_oid_set.c @@ -0,0 +1,51 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_create_empty_oid_set.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_create_empty_oid_set(OM_uint32 *minor_status, + gss_OID_set *oid_set) +{ + gss_OID_set set; + + *minor_status = 0; + *oid_set = GSS_C_NO_OID_SET; + + set = malloc(sizeof(gss_OID_set_desc)); + if (!set) { + *minor_status = ENOMEM; + return (GSS_S_FAILURE); + } + + set->count = 0; + set->elements = 0; + *oid_set = set; + + return (GSS_S_COMPLETE); +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_cred.c b/third_party/heimdal/lib/gssapi/mech/gss_cred.c new file mode 100644 index 0000000..00561ce --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_cred.c @@ -0,0 +1,326 @@ +/* + * Copyright (c) 2017 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of KTH nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "mech_locl.h" +#include <krb5.h> + +static OM_uint32 +store_mech_oid_and_oid_set(OM_uint32 *minor_status, + krb5_storage *sp, + gss_const_OID mech, + gss_const_OID_set oids) +{ + OM_uint32 ret; + size_t i, len; + + ret = _gss_mg_store_oid(minor_status, sp, mech); + if (ret) + return ret; + + for (i = 0, len = 0; i < oids->count; i++) + len += 4 + oids->elements[i].length; + + *minor_status = krb5_store_uint32(sp, len); + if (*minor_status) + return GSS_S_FAILURE; + + for (i = 0; i < oids->count; i++) { + ret = _gss_mg_store_oid(minor_status, sp, &oids->elements[i]); + if (ret) + return ret; + } + + return GSS_S_COMPLETE; +} + + +/* + * format: any number of: + * mech-len: int32 + * mech-data: char * (not alligned) + * cred-len: int32 + * cred-data char * (not alligned) + * + * where neg_mechs is encoded for GSS_SPNEGO_MECHANISM +*/ + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_export_cred(OM_uint32 * minor_status, + gss_cred_id_t cred_handle, + gss_buffer_t token) +{ + struct _gss_cred *cred = (struct _gss_cred *)cred_handle; + struct _gss_mechanism_cred *mc; + gss_buffer_desc buffer; + krb5_error_code ret; + krb5_ssize_t bytes; + krb5_storage *sp; + OM_uint32 major; + krb5_data data; + + _mg_buffer_zero(token); + + if (cred == NULL) { + *minor_status = 0; + return GSS_S_NO_CRED; + } + + HEIM_TAILQ_FOREACH(mc, &cred->gc_mc, gmc_link) { + if (mc->gmc_mech->gm_export_cred == NULL) { + *minor_status = 0; + gss_mg_set_error_string(&mc->gmc_mech->gm_mech_oid, + GSS_S_NO_CRED, *minor_status, + "Credential doesn't support exporting"); + return GSS_S_NO_CRED; + } + } + + sp = krb5_storage_emem(); + if (sp == NULL) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + HEIM_TAILQ_FOREACH(mc, &cred->gc_mc, gmc_link) { + major = mc->gmc_mech->gm_export_cred(minor_status, + mc->gmc_cred, &buffer); + if (major) { + krb5_storage_free(sp); + return major; + } + + if (buffer.length) { + bytes = krb5_storage_write(sp, buffer.value, buffer.length); + if (bytes < 0 || (size_t)bytes != buffer.length) { + _gss_secure_release_buffer(minor_status, &buffer); + krb5_storage_free(sp); + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + } + _gss_secure_release_buffer(minor_status, &buffer); + } + + if (cred->gc_neg_mechs != GSS_C_NO_OID_SET) { + major = store_mech_oid_and_oid_set(minor_status, sp, + GSS_SPNEGO_MECHANISM, + cred->gc_neg_mechs); + if (major != GSS_S_COMPLETE) { + krb5_storage_free(sp); + return major; + } + } + + ret = krb5_storage_to_data(sp, &data); + krb5_storage_free(sp); + if (ret) { + *minor_status = ret; + return GSS_S_FAILURE; + } + + if (data.length == 0) { + *minor_status = 0; + gss_mg_set_error_string(GSS_C_NO_OID, + GSS_S_NO_CRED, *minor_status, + "Credential was not exportable"); + return GSS_S_NO_CRED; + } + + token->value = data.data; + token->length = data.length; + + return GSS_S_COMPLETE; +} + +static OM_uint32 +import_oid_set(OM_uint32 *minor_status, + gss_const_buffer_t token, + gss_OID_set *oids) +{ + OM_uint32 major, junk; + krb5_storage *sp = NULL; + + *oids = GSS_C_NO_OID_SET; + + if (token->length == 0) + return GSS_S_COMPLETE; + + major = gss_create_empty_oid_set(minor_status, oids); + if (major != GSS_S_COMPLETE) + goto out; + + sp = krb5_storage_from_readonly_mem(token->value, token->length); + if (sp == NULL) { + *minor_status = ENOMEM; + major = GSS_S_FAILURE; + goto out; + } + + while (1) { + gss_OID oid; + + major = _gss_mg_ret_oid(minor_status, sp, &oid); + if (*minor_status == (OM_uint32)HEIM_ERR_EOF) + break; + else if (major) + goto out; + + major = gss_add_oid_set_member(minor_status, oid, oids); + if (major != GSS_S_COMPLETE) + goto out; + } + + major = GSS_S_COMPLETE; + *minor_status = 0; + +out: + if (major != GSS_S_COMPLETE) + gss_release_oid_set(&junk, oids); + krb5_storage_free(sp); + + return major; +} + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_import_cred(OM_uint32 * minor_status, + gss_buffer_t token, + gss_cred_id_t * cred_handle) +{ + gssapi_mech_interface m; + struct _gss_cred *cred; + krb5_storage *sp = NULL; + OM_uint32 major, junk; + + *cred_handle = GSS_C_NO_CREDENTIAL; + + if (token->length == 0) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + sp = krb5_storage_from_readonly_mem(token->value, token->length); + if (sp == NULL) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + cred = _gss_mg_alloc_cred(); + if (cred == NULL) { + krb5_storage_free(sp); + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + *cred_handle = (gss_cred_id_t)cred; + + while(1) { + struct _gss_mechanism_cred *mc; + gss_buffer_desc buffer; + gss_cred_id_t mcred; + gss_OID oid; + + major = _gss_mg_ret_oid(minor_status, sp, &oid); + if (*minor_status == (OM_uint32)HEIM_ERR_EOF) + break; + else if (major != GSS_S_COMPLETE) + goto out; + + m = __gss_get_mechanism(oid); + if (!m) { + *minor_status = 0; + major = GSS_S_BAD_MECH; + goto out; + } + + if (m->gm_import_cred == NULL) { + *minor_status = 0; + major = GSS_S_BAD_MECH; + goto out; + } + + major = _gss_mg_ret_buffer(minor_status, sp, &buffer); + if (major != GSS_S_COMPLETE) + goto out; + + if (buffer.value == NULL) { + major = GSS_S_DEFECTIVE_TOKEN; + goto out; + } + + if (gss_oid_equal(&m->gm_mech_oid, GSS_SPNEGO_MECHANISM)) { + major = import_oid_set(minor_status, &buffer, &cred->gc_neg_mechs); + gss_release_buffer(&junk, &buffer); + if (major != GSS_S_COMPLETE) + goto out; + else + continue; + } + + major = m->gm_import_cred(minor_status, &buffer, &mcred); + gss_release_buffer(&junk, &buffer); + if (major != GSS_S_COMPLETE) + goto out; + + mc = calloc(1, sizeof(struct _gss_mechanism_cred)); + if (mc == NULL) { + *minor_status = EINVAL; + major = GSS_S_FAILURE; + goto out; + } + + mc->gmc_mech = m; + mc->gmc_mech_oid = &m->gm_mech_oid; + mc->gmc_cred = mcred; + + HEIM_TAILQ_INSERT_TAIL(&cred->gc_mc, mc, gmc_link); + } + krb5_storage_free(sp); + sp = NULL; + + if (HEIM_TAILQ_EMPTY(&cred->gc_mc)) { + major = GSS_S_NO_CRED; + goto out; + } + + return GSS_S_COMPLETE; + + out: + if (sp) + krb5_storage_free(sp); + + gss_release_cred(&junk, cred_handle); + + return major; + +} + diff --git a/third_party/heimdal/lib/gssapi/mech/gss_decapsulate_token.c b/third_party/heimdal/lib/gssapi/mech/gss_decapsulate_token.c new file mode 100644 index 0000000..5d9eca0 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_decapsulate_token.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2006 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_decapsulate_token(gss_const_buffer_t input_token, + gss_const_OID oid, + gss_buffer_t output_token) +{ + GSSAPIContextToken ct; + heim_oid o; + OM_uint32 status; + int ret; + size_t size; + + _mg_buffer_zero(output_token); + + ret = der_get_oid (oid->elements, oid->length, &o, &size); + if (ret) + return GSS_S_FAILURE; + + ret = decode_GSSAPIContextToken(input_token->value, input_token->length, + &ct, NULL); + if (ret) { + der_free_oid(&o); + return GSS_S_DEFECTIVE_TOKEN; + } + + if (der_heim_oid_cmp(&ct.thisMech, &o) == 0) { + status = GSS_S_COMPLETE; + output_token->value = ct.innerContextToken.data; + output_token->length = ct.innerContextToken.length; + der_free_oid(&ct.thisMech); + } else { + free_GSSAPIContextToken(&ct); + status = GSS_S_BAD_MECH; + } + der_free_oid(&o); + + return status; +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_delete_name_attribute.c b/third_party/heimdal/lib/gssapi/mech/gss_delete_name_attribute.c new file mode 100644 index 0000000..a1ca5da --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_delete_name_attribute.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2010, PADL Software Pty Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of PADL Software nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_delete_name_attribute(OM_uint32 *minor_status, + gss_name_t input_name, + gss_buffer_t attr) +{ + OM_uint32 major_status = GSS_S_UNAVAILABLE; + struct _gss_name *name = (struct _gss_name *) input_name; + struct _gss_mechanism_name *mn; + + *minor_status = 0; + + if (input_name == GSS_C_NO_NAME) + return GSS_S_BAD_NAME; + + HEIM_TAILQ_FOREACH(mn, &name->gn_mn, gmn_link) { + gssapi_mech_interface m = mn->gmn_mech; + + if (!m->gm_delete_name_attribute) + continue; + + major_status = m->gm_delete_name_attribute(minor_status, + mn->gmn_name, + attr); + if (GSS_ERROR(major_status)) + _gss_mg_error(m, *minor_status); + else + break; + } + + return major_status; +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_delete_sec_context.c b/third_party/heimdal/lib/gssapi/mech/gss_delete_sec_context.c new file mode 100644 index 0000000..8e1f98c --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_delete_sec_context.c @@ -0,0 +1,62 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_delete_sec_context.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_delete_sec_context(OM_uint32 *minor_status, + gss_ctx_id_t *context_handle, + gss_buffer_t output_token) +{ + OM_uint32 major_status; + struct _gss_context *ctx = (struct _gss_context *) *context_handle; + + if (output_token) + _mg_buffer_zero(output_token); + + *minor_status = 0; + major_status = GSS_S_COMPLETE; + + if (!ctx) + return GSS_S_COMPLETE; + + free(ctx->gc_free_this); + + /* + * If we have an implementation ctx, delete it, + * otherwise fake an empty token. + */ + if (ctx->gc_ctx) { + major_status = ctx->gc_mech->gm_delete_sec_context( + minor_status, &ctx->gc_ctx, output_token); + } + free(ctx); + *context_handle = GSS_C_NO_CONTEXT; + + return major_status; +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_destroy_cred.c b/third_party/heimdal/lib/gssapi/mech/gss_destroy_cred.c new file mode 100644 index 0000000..5b7fafc --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_destroy_cred.c @@ -0,0 +1,74 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Portions Copyright (c) 2009 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "mech_locl.h" +#include <heim_threads.h> + +/** + * Destroy a credential + * + * gss_release_cred() frees the memory, gss_destroy_cred() removes the credentials from memory/disk and then call gss_release_cred() on the credential. + * + * @param min_stat minor status code + * @param cred_handle credentail to destory + * + * @returns a gss_error code, see gss_display_status() about printing + * the error code. + * + * @ingroup gssapi + */ + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_destroy_cred(OM_uint32 *minor_status, + gss_cred_id_t *cred_handle) +{ + struct _gss_cred *cred; + struct _gss_mechanism_cred *mc, *next; + + OM_uint32 junk; + + if (cred_handle == NULL) + return GSS_S_CALL_INACCESSIBLE_READ; + if (*cred_handle == GSS_C_NO_CREDENTIAL) + return GSS_S_COMPLETE; + + cred = (struct _gss_cred *)*cred_handle; + *cred_handle = GSS_C_NO_CREDENTIAL; + + HEIM_TAILQ_FOREACH_SAFE(mc, &cred->gc_mc, gmc_link, next) { + HEIM_TAILQ_REMOVE(&cred->gc_mc, mc, gmc_link); + if (mc->gmc_mech->gm_destroy_cred) + mc->gmc_mech->gm_destroy_cred(&junk, &mc->gmc_cred); + else + mc->gmc_mech->gm_release_cred(&junk, &mc->gmc_cred); + free(mc); + } + free(cred); + + return GSS_S_COMPLETE; +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_display_name.c b/third_party/heimdal/lib/gssapi/mech/gss_display_name.c new file mode 100644 index 0000000..fadd68b --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_display_name.c @@ -0,0 +1,82 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_display_name.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_display_name(OM_uint32 *minor_status, + gss_const_name_t input_name, + gss_buffer_t output_name_buffer, + gss_OID *output_name_type) +{ + OM_uint32 major_status; + struct _gss_name *name = (struct _gss_name *) input_name; + struct _gss_mechanism_name *mn; + + _mg_buffer_zero(output_name_buffer); + if (output_name_type) + *output_name_type = GSS_C_NO_OID; + + if (name == NULL) { + *minor_status = 0; + return (GSS_S_BAD_NAME); + } + + /* + * If we know it, copy the buffer used to import the name in + * the first place. Otherwise, ask all the MNs in turn if + * they can display the thing. + */ + if (name->gn_value.value) { + output_name_buffer->value = malloc(name->gn_value.length); + if (!output_name_buffer->value) { + *minor_status = ENOMEM; + return (GSS_S_FAILURE); + } + output_name_buffer->length = name->gn_value.length; + memcpy(output_name_buffer->value, name->gn_value.value, + output_name_buffer->length); + if (output_name_type) + *output_name_type = name->gn_type; + + *minor_status = 0; + return (GSS_S_COMPLETE); + } else { + HEIM_TAILQ_FOREACH(mn, &name->gn_mn, gmn_link) { + major_status = mn->gmn_mech->gm_display_name( + minor_status, mn->gmn_name, + output_name_buffer, + output_name_type); + if (major_status == GSS_S_COMPLETE) + return (GSS_S_COMPLETE); + } + } + + *minor_status = 0; + return (GSS_S_FAILURE); +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_display_name_ext.c b/third_party/heimdal/lib/gssapi/mech/gss_display_name_ext.c new file mode 100644 index 0000000..80ea72b --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_display_name_ext.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2010, PADL Software Pty Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of PADL Software nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_display_name_ext(OM_uint32 *minor_status, + gss_name_t input_name, + gss_OID display_as_name_type, + gss_buffer_t display_name) +{ + OM_uint32 major_status = GSS_S_UNAVAILABLE; + struct _gss_name *name = (struct _gss_name *) input_name; + struct _gss_mechanism_name *mn; + + *minor_status = 0; + _mg_buffer_zero(display_name); + + if (input_name == GSS_C_NO_NAME) + return GSS_S_BAD_NAME; + + HEIM_TAILQ_FOREACH(mn, &name->gn_mn, gmn_link) { + gssapi_mech_interface m = mn->gmn_mech; + + if (!m->gm_display_name_ext) + continue; + + major_status = m->gm_display_name_ext(minor_status, + mn->gmn_name, + display_as_name_type, + display_name); + if (GSS_ERROR(major_status)) + _gss_mg_error(m, *minor_status); + else + break; + } + + return major_status; +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_display_status.c b/third_party/heimdal/lib/gssapi/mech/gss_display_status.c new file mode 100644 index 0000000..dca5d1b --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_display_status.c @@ -0,0 +1,227 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_display_status.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ +/* + * Copyright (c) 1998 - 2005 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "mech_locl.h" + +static const char * +calling_error(OM_uint32 v) +{ + static const char *msgs[] = { + NULL, /* 0 */ + "A required input parameter could not be read.", /* */ + "A required output parameter could not be written.", /* */ + "A parameter was malformed" + }; + + v >>= GSS_C_CALLING_ERROR_OFFSET; + + if (v == 0) + return ""; + else if (v >= sizeof(msgs)/sizeof(*msgs)) + return "unknown calling error"; + else + return msgs[v]; +} + +static const char * +routine_error(OM_uint32 v) +{ + static const char *msgs[] = { + "Function completed successfully", /* 0 */ + "An unsupported mechanism was requested", + "An invalid name was supplied", + "A supplied name was of an unsupported type", + "Incorrect channel bindings were supplied", + "An invalid status code was supplied", + "A token had an invalid MIC", + "No credentials were supplied, or the credentials were unavailable or inaccessible.", + "No context has been established", + "A token was invalid", + "A credential was invalid", + "The referenced credentials have expired", + "The context has expired", + "Miscellaneous failure (see text)", + "The quality-of-protection requested could not be provide", + "The operation is forbidden by local security policy", + "The operation or option is not available", + "The requested credential element already exists", + "The provided name was not a mechanism name.", + }; + + v >>= GSS_C_ROUTINE_ERROR_OFFSET; + + if (v >= sizeof(msgs)/sizeof(*msgs)) + return "unknown routine error"; + else + return msgs[v]; +} + +static const char * +supplementary_error(OM_uint32 v) +{ + static const char *msgs[] = { + "normal completion", + "continuation call to routine required", + "duplicate per-message token detected", + "timed-out per-message token detected", + "reordered (early) per-message token detected", + "skipped predecessor token(s) detected" + }; + + v >>= GSS_C_SUPPLEMENTARY_OFFSET; + + if (v >= sizeof(msgs)/sizeof(*msgs)) + return "unknown routine error"; + else + return msgs[v]; +} + +/** + * Convert a GSS-API status code to text + * + * @param minor_status minor status code + * @param status_value status value to convert + * @param status_type One of: + * GSS_C_GSS_CODE - status_value is a GSS status code, + * GSS_C_MECH_CODE - status_value is a mechanism status code + * @param mech_type underlying mechanism. Use GSS_C_NO_OID to obtain the + * system default. + * @param message_context state information to extract further messages from the + * status_value + * @param status_string the allocated text representation. Release with + * gss_release_buffer() + * + * @returns a gss_error code. + * + * @ingroup gssapi + */ +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_display_status(OM_uint32 *minor_status, + OM_uint32 status_value, + int status_type, + const gss_OID mech_type, + OM_uint32 *message_context, + gss_buffer_t status_string) +{ + OM_uint32 major_status; + + _mg_buffer_zero(status_string); + *message_context = 0; + + *minor_status = 0; + switch (status_type) { + case GSS_C_GSS_CODE: { + char *buf = NULL; + int e; + + if (GSS_SUPPLEMENTARY_INFO(status_value)) + e = asprintf(&buf, "%s", supplementary_error( + GSS_SUPPLEMENTARY_INFO(status_value))); + else + e = asprintf (&buf, "%s %s", + calling_error(GSS_CALLING_ERROR(status_value)), + routine_error(GSS_ROUTINE_ERROR(status_value))); + + if (e < 0 || buf == NULL) + break; + + status_string->length = strlen(buf); + status_string->value = buf; + + return GSS_S_COMPLETE; + } + case GSS_C_MECH_CODE: { + OM_uint32 maj_junk, min_junk; + gss_buffer_desc oid; + char *buf = NULL; + int e; + + major_status = _gss_mg_get_error(mech_type, status_value, + status_string); + if (major_status == GSS_S_COMPLETE) { + *message_context = 0; + *minor_status = 0; + return GSS_S_COMPLETE; + } + + maj_junk = gss_oid_to_str(&min_junk, mech_type, &oid); + if (maj_junk != GSS_S_COMPLETE) { + oid.value = rk_UNCONST("unknown"); + oid.length = 7; + } + + e = asprintf (&buf, "unknown mech-code %lu for mech %.*s", + (unsigned long)status_value, + (int)oid.length, (char *)oid.value); + if (maj_junk == GSS_S_COMPLETE) + gss_release_buffer(&min_junk, &oid); + + if (e < 0 || buf == NULL) + break; + + status_string->length = strlen(buf); + status_string->value = buf; + + return GSS_S_COMPLETE; + } + } + _mg_buffer_zero(status_string); + return (GSS_S_BAD_STATUS); +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_duplicate_cred.c b/third_party/heimdal/lib/gssapi/mech/gss_duplicate_cred.c new file mode 100644 index 0000000..0c25ce9 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_duplicate_cred.c @@ -0,0 +1,153 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * Copyright (c) 2018 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_add_cred.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" + +static OM_uint32 +copy_cred_element(OM_uint32 *minor_status, + struct _gss_mechanism_cred *mc, + struct _gss_mechanism_cred **out) +{ + gssapi_mech_interface m = mc->gmc_mech; + OM_uint32 major_status, tmp; + struct _gss_mechanism_cred *new_mc; + OM_uint32 initiator_lifetime, acceptor_lifetime; + gss_cred_usage_t cred_usage; + gss_cred_id_t dup_cred = GSS_C_NO_CREDENTIAL; + + *out = NULL; + + if (m->gm_duplicate_cred) { + major_status = m->gm_duplicate_cred(minor_status, + mc->gmc_cred, &dup_cred); + } else if (m->gm_import_cred && m->gm_export_cred) { + gss_buffer_desc export; + + major_status = m->gm_export_cred(minor_status, mc->gmc_cred, &export); + if (major_status == GSS_S_COMPLETE) { + major_status = m->gm_import_cred(minor_status, &export, &dup_cred); + _gss_secure_release_buffer(&tmp, &export); + } + } else { + struct _gss_mechanism_name mn; + + mn.gmn_mech = m; + mn.gmn_mech_oid = mc->gmc_mech_oid; + mn.gmn_name = GSS_C_NO_NAME; + + /* This path won't work for ephemeral creds or cred stores */ + major_status = m->gm_inquire_cred_by_mech(minor_status, mc->gmc_cred, + mc->gmc_mech_oid, &mn.gmn_name, + &initiator_lifetime, + &acceptor_lifetime, &cred_usage); + if (major_status == GSS_S_COMPLETE) { + major_status = _gss_mg_add_mech_cred(minor_status, + m, + NULL, /* mc */ + &mn, + cred_usage, + initiator_lifetime, + acceptor_lifetime, + GSS_C_NO_CRED_STORE, + &new_mc, + NULL, + NULL); + m->gm_release_name(&tmp, &mn.gmn_name); + } + } + + if (major_status == GSS_S_COMPLETE) { + new_mc = calloc(1, sizeof(*new_mc)); + if (new_mc == NULL) { + *minor_status = ENOMEM; + m->gm_release_cred(&tmp, &dup_cred); + return GSS_S_FAILURE; + } + + new_mc->gmc_mech = m; + new_mc->gmc_mech_oid = mc->gmc_mech_oid; + new_mc->gmc_cred = dup_cred; + + *out = new_mc; + } else + _gss_mg_error(m, *minor_status); + + return major_status; +} + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_duplicate_cred(OM_uint32 *minor_status, + gss_const_cred_id_t input_cred_handle, + gss_cred_id_t *output_cred_handle) +{ + struct _gss_mechanism_cred *mc; + struct _gss_cred *new_cred; + struct _gss_cred *cred = (struct _gss_cred *)input_cred_handle; + OM_uint32 major_status, junk; + + if (input_cred_handle == GSS_C_NO_CREDENTIAL) { + /* + * "Copy" the default credential by acquiring a cred handle for the + * default credential's name, GSS_C_NO_NAME. + */ + return gss_acquire_cred(minor_status, GSS_C_NO_NAME, GSS_C_INDEFINITE, + GSS_C_NO_OID_SET, GSS_C_BOTH, + output_cred_handle, NULL, NULL); + } + + *output_cred_handle = GSS_C_NO_CREDENTIAL; + new_cred = _gss_mg_alloc_cred(); + if (!new_cred) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + *minor_status = 0; + major_status = GSS_S_NO_CRED; + + HEIM_TAILQ_FOREACH(mc, &cred->gc_mc, gmc_link) { + struct _gss_mechanism_cred *copy_mc; + + major_status = copy_cred_element(minor_status, mc, ©_mc); + if (major_status != GSS_S_COMPLETE) + break; + + HEIM_TAILQ_INSERT_TAIL(&new_cred->gc_mc, copy_mc, gmc_link); + } + + if (major_status != GSS_S_COMPLETE) { + gss_cred_id_t release_cred = (gss_cred_id_t)new_cred; + gss_release_cred(&junk, &release_cred); + new_cred = NULL; + } + + *output_cred_handle = (gss_cred_id_t)new_cred; + return major_status; +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_duplicate_name.c b/third_party/heimdal/lib/gssapi/mech/gss_duplicate_name.c new file mode 100644 index 0000000..e8d1e32 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_duplicate_name.c @@ -0,0 +1,93 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_duplicate_name.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_duplicate_name(OM_uint32 *minor_status, + gss_const_name_t src_name, + gss_name_t *dest_name) +{ + OM_uint32 major_status; + struct _gss_name *name = (struct _gss_name *) src_name; + struct _gss_name *new_name; + struct _gss_mechanism_name *mn; + + *minor_status = 0; + *dest_name = GSS_C_NO_NAME; + + /* + * If this name has a value (i.e. it didn't come from + * gss_canonicalize_name(), we re-import the thing. Otherwise, + * we make copy of each mech names. + */ + if (name->gn_value.value) { + major_status = gss_import_name(minor_status, + &name->gn_value, name->gn_type, dest_name); + if (major_status != GSS_S_COMPLETE) + return (major_status); + new_name = (struct _gss_name *) *dest_name; + + HEIM_TAILQ_FOREACH(mn, &name->gn_mn, gmn_link) { + struct _gss_mechanism_name *mn2; + _gss_find_mn(minor_status, new_name, + mn->gmn_mech_oid, &mn2); + } + } else { + new_name = _gss_create_name(NULL, NULL); + if (!new_name) { + *minor_status = ENOMEM; + return (GSS_S_FAILURE); + } + *dest_name = (gss_name_t) new_name; + + HEIM_TAILQ_FOREACH(mn, &name->gn_mn, gmn_link) { + struct _gss_mechanism_name *new_mn; + + new_mn = malloc(sizeof(*new_mn)); + if (!new_mn) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + new_mn->gmn_mech = mn->gmn_mech; + new_mn->gmn_mech_oid = mn->gmn_mech_oid; + + major_status = + mn->gmn_mech->gm_duplicate_name(minor_status, + mn->gmn_name, &new_mn->gmn_name); + if (major_status != GSS_S_COMPLETE) { + free(new_mn); + continue; + } + HEIM_TAILQ_INSERT_TAIL(&new_name->gn_mn, new_mn, gmn_link); + } + + } + + return (GSS_S_COMPLETE); +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_duplicate_oid.c b/third_party/heimdal/lib/gssapi/mech/gss_duplicate_oid.c new file mode 100644 index 0000000..29a9cf8 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_duplicate_oid.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 1997 - 2003 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_duplicate_oid ( + OM_uint32 *minor_status, + gss_OID src_oid, + gss_OID *dest_oid + ) +{ + *minor_status = 0; + + if (src_oid == GSS_C_NO_OID) { + *dest_oid = GSS_C_NO_OID; + return GSS_S_COMPLETE; + } + + return _gss_intern_oid(minor_status, src_oid, dest_oid); +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_duplicate_oid_set.c b/third_party/heimdal/lib/gssapi/mech/gss_duplicate_oid_set.c new file mode 100644 index 0000000..ae0ab8d --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_duplicate_oid_set.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2020 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_duplicate_oid_set(OM_uint32 *minor_status, + gss_OID_set src_oid_set, + gss_OID_set *dest_oid_set) +{ + OM_uint32 major_status, junk; + size_t i; + + *dest_oid_set = GSS_C_NO_OID_SET; + + major_status = gss_create_empty_oid_set(minor_status, dest_oid_set); + + for (i = 0; major_status == GSS_S_COMPLETE && i < src_oid_set->count; i++) + major_status = gss_add_oid_set_member(minor_status, + &src_oid_set->elements[i], + dest_oid_set); + + if (major_status != GSS_S_COMPLETE) + gss_release_oid_set(&junk, dest_oid_set); + + return major_status; +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_encapsulate_token.c b/third_party/heimdal/lib/gssapi/mech/gss_encapsulate_token.c new file mode 100644 index 0000000..1b1f973 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_encapsulate_token.c @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2006 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_encapsulate_token(gss_const_buffer_t input_token, + gss_const_OID oid, + gss_buffer_t output_token) +{ + GSSAPIContextToken ct; + int ret; + size_t size; + + ret = der_get_oid (oid->elements, oid->length, &ct.thisMech, &size); + if (ret) { + _mg_buffer_zero(output_token); + return GSS_S_FAILURE; + } + + ct.innerContextToken.data = input_token->value; + ct.innerContextToken.length = input_token->length; + + ASN1_MALLOC_ENCODE(GSSAPIContextToken, + output_token->value, output_token->length, + &ct, &size, ret); + der_free_oid(&ct.thisMech); + if (ret) { + _mg_buffer_zero(output_token); + return GSS_S_FAILURE; + } + if (output_token->length != size) + abort(); + + return GSS_S_COMPLETE; +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_export_name.c b/third_party/heimdal/lib/gssapi/mech/gss_export_name.c new file mode 100644 index 0000000..92b7a8f --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_export_name.c @@ -0,0 +1,113 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Portions Copyright (c) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_export_name.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" + +/** + * Convert a GGS-API name from internal form to contiguous string. + * + * @sa gss_import_name(), @ref internalVSmechname. + * + * @param minor_status minor status code + * @param input_name input name in internal name form + * @param exported_name output name in contiguos string form + * + * @returns a gss_error code, see gss_display_status() about printing + * the error code. + * + * @ingroup gssapi + */ +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_export_name(OM_uint32 *minor_status, + gss_const_name_t input_name, + gss_buffer_t exported_name) +{ + struct _gss_name *name = (struct _gss_name *) input_name; + struct _gss_mechanism_name *mn; + + _mg_buffer_zero(exported_name); + + /* + * If this name already has any attached MNs, export the first + * one, otherwise export based on the first mechanism in our + * list. + */ + mn = HEIM_TAILQ_FIRST(&name->gn_mn); + if (!mn) { + *minor_status = 0; + return (GSS_S_NAME_NOT_MN); + } + + return mn->gmn_mech->gm_export_name(minor_status, + mn->gmn_name, exported_name); +} + +OM_uint32 +gss_mg_export_name(OM_uint32 *minor_status, + const gss_const_OID mech, + const void *name, + size_t length, + gss_buffer_t exported_name) +{ + uint8_t *buf; + + exported_name->length = 10 + length + mech->length; + exported_name->value = malloc(exported_name->length); + if (exported_name->value == NULL) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + /* TOK, MECH_OID_LEN, DER(MECH_OID), NAME_LEN, NAME */ + + buf = exported_name->value; + memcpy(buf, "\x04\x01", 2); + buf += 2; + buf[0] = ((mech->length + 2) >> 8) & 0xff; + buf[1] = (mech->length + 2) & 0xff; + buf+= 2; + buf[0] = 0x06; + buf[1] = (mech->length) & 0xFF; + buf+= 2; + + memcpy(buf, mech->elements, mech->length); + buf += mech->length; + + buf[0] = (length >> 24) & 0xff; + buf[1] = (length >> 16) & 0xff; + buf[2] = (length >> 8) & 0xff; + buf[3] = (length) & 0xff; + buf += 4; + + memcpy (buf, name, length); + + *minor_status = 0; + return GSS_S_COMPLETE; +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_export_name_composite.c b/third_party/heimdal/lib/gssapi/mech/gss_export_name_composite.c new file mode 100644 index 0000000..d833ebb --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_export_name_composite.c @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2010, PADL Software Pty Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of PADL Software nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_export_name_composite(OM_uint32 *minor_status, + gss_name_t input_name, + gss_buffer_t exp_composite_name) +{ + OM_uint32 major_status = GSS_S_UNAVAILABLE; + struct _gss_name *name = (struct _gss_name *) input_name; + struct _gss_mechanism_name *mn; + + *minor_status = 0; + _mg_buffer_zero(exp_composite_name); + + if (input_name == GSS_C_NO_NAME) + return GSS_S_BAD_NAME; + + HEIM_TAILQ_FOREACH(mn, &name->gn_mn, gmn_link) { + gssapi_mech_interface m = mn->gmn_mech; + + if (!m->gm_export_name_composite) + continue; + + major_status = m->gm_export_name_composite(minor_status, + mn->gmn_name, + exp_composite_name); + if (GSS_ERROR(major_status)) + _gss_mg_error(m, *minor_status); + else + break; + } + + return major_status; +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_export_sec_context.c b/third_party/heimdal/lib/gssapi/mech/gss_export_sec_context.c new file mode 100644 index 0000000..c030980 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_export_sec_context.c @@ -0,0 +1,147 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_export_sec_context.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_export_sec_context(OM_uint32 *minor_status, + gss_ctx_id_t *context_handle, + gss_buffer_t interprocess_token) +{ + OM_uint32 major_status = GSS_S_FAILURE, tmp_minor; + krb5_storage *sp; + krb5_data data; + krb5_error_code kret; + struct _gss_context *ctx; + gssapi_mech_interface m; + gss_buffer_desc buf = GSS_C_EMPTY_BUFFER; + unsigned char verflags; + + *minor_status = 0; + + if (!interprocess_token) + return GSS_S_CALL_INACCESSIBLE_READ; + + _mg_buffer_zero(interprocess_token); + + if (context_handle == NULL) + return GSS_S_NO_CONTEXT; + + ctx = (struct _gss_context *) *context_handle; + if (ctx == NULL) + return GSS_S_NO_CONTEXT; + + sp = krb5_storage_emem(); + if (sp == NULL) { + *minor_status = ENOMEM; + goto failure; + } + krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_PACKED); + + verflags = 0x00; /* Version 0 */ + + if (ctx->gc_target_len) + verflags |= EXPORT_CONTEXT_FLAG_ACCUMULATING; + + if (ctx->gc_ctx) + verflags |= EXPORT_CONTEXT_FLAG_MECH_CTX; + + kret = krb5_store_uint8(sp, verflags); + if (kret) { + *minor_status = kret; + goto failure; + } + + if (ctx->gc_target_len) { + _gss_mg_log(10, "gss-esc: exporting partial token %zu/%zu", + ctx->gc_input.length, ctx->gc_target_len); + kret = krb5_store_uint8(sp, ctx->gc_initial); + if (kret) { + *minor_status = kret; + goto failure; + } + kret = krb5_store_uint32(sp, ctx->gc_target_len); + if (kret) { + *minor_status = kret; + goto failure; + } + major_status = _gss_mg_store_buffer(minor_status, sp, + &ctx->gc_input); + if (major_status != GSS_S_COMPLETE) + goto failure; + } else if (ctx->gc_ctx == GSS_C_NO_CONTEXT) { + gss_delete_sec_context(&tmp_minor, context_handle, + GSS_C_NO_BUFFER); + return GSS_S_NO_CONTEXT; + } + + if (ctx->gc_ctx) { + m = ctx->gc_mech; + + major_status = m->gm_export_sec_context(minor_status, + &ctx->gc_ctx, &buf); + + if (major_status != GSS_S_COMPLETE) { + _gss_mg_error(m, *minor_status); + goto failure; + } + + major_status = _gss_mg_store_oid(minor_status, sp, + &m->gm_mech_oid); + if (major_status != GSS_S_COMPLETE) + goto failure; + + major_status = _gss_mg_store_buffer(minor_status, sp, &buf); + if (major_status != GSS_S_COMPLETE) + goto failure; + } + + kret = krb5_storage_to_data(sp, &data); + if (kret) { + *minor_status = kret; + goto failure; + } + + interprocess_token->length = data.length; + interprocess_token->value = data.data; + + major_status = GSS_S_COMPLETE; + + _gss_mg_log(1, "gss-esc: token length %zu", data.length); + +failure: + if (major_status == GSS_S_COMPLETE && *minor_status == 0) + gss_delete_sec_context(&tmp_minor, context_handle, + GSS_C_NO_BUFFER); + else if (*minor_status) + major_status = GSS_S_FAILURE; + + _gss_secure_release_buffer(minor_status, &buf); + krb5_storage_free(sp); + return major_status; +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_get_mic.c b/third_party/heimdal/lib/gssapi/mech/gss_get_mic.c new file mode 100644 index 0000000..8663053 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_get_mic.c @@ -0,0 +1,51 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_get_mic.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_get_mic(OM_uint32 *minor_status, + gss_const_ctx_id_t context_handle, + gss_qop_t qop_req, + const gss_buffer_t message_buffer, + gss_buffer_t message_token) +{ + struct _gss_context *ctx = (struct _gss_context *) context_handle; + gssapi_mech_interface m; + + _mg_buffer_zero(message_token); + if (ctx == NULL) { + *minor_status = 0; + return GSS_S_NO_CONTEXT; + } + + m = ctx->gc_mech; + + return (m->gm_get_mic(minor_status, ctx->gc_ctx, qop_req, + message_buffer, message_token)); +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_get_name_attribute.c b/third_party/heimdal/lib/gssapi/mech/gss_get_name_attribute.c new file mode 100644 index 0000000..1b7bee5 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_get_name_attribute.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2010, PADL Software Pty Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of PADL Software nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_get_name_attribute(OM_uint32 *minor_status, + gss_name_t input_name, + gss_buffer_t attr, + int *authenticated, + int *complete, + gss_buffer_t value, + gss_buffer_t display_value, + int *more) +{ + OM_uint32 major_status = GSS_S_UNAVAILABLE; + struct _gss_name *name = (struct _gss_name *) input_name; + struct _gss_mechanism_name *mn; + + *minor_status = 0; + if (authenticated != NULL) + *authenticated = 0; + if (complete != NULL) + *complete = 0; + _mg_buffer_zero(value); + _mg_buffer_zero(display_value); + + if (input_name == GSS_C_NO_NAME) + return GSS_S_BAD_NAME; + + _gss_mg_check_name(input_name); + + HEIM_TAILQ_FOREACH(mn, &name->gn_mn, gmn_link) { + gssapi_mech_interface m = mn->gmn_mech; + + if (!m->gm_get_name_attribute) + continue; + + major_status = m->gm_get_name_attribute(minor_status, + mn->gmn_name, + attr, + authenticated, + complete, + value, + display_value, + more); + if (GSS_ERROR(major_status)) + _gss_mg_error(m, *minor_status); + else + break; + } + + return major_status; +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_get_neg_mechs.c b/third_party/heimdal/lib/gssapi/mech/gss_get_neg_mechs.c new file mode 100644 index 0000000..cbc3786 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_get_neg_mechs.c @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2018, PADL Software Pty Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of PADL Software nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_get_neg_mechs(OM_uint32 *minor_status, + gss_const_cred_id_t cred_handle, + gss_OID_set *mechs) +{ + struct _gss_cred *cred = (struct _gss_cred *)cred_handle; + + if (minor_status == NULL) + return GSS_S_CALL_INACCESSIBLE_WRITE; + + *minor_status = 0; + + if (mechs == NULL) + return GSS_S_CALL_INACCESSIBLE_WRITE; + + if (cred->gc_neg_mechs != GSS_C_NO_OID_SET) + return gss_duplicate_oid_set(minor_status, cred->gc_neg_mechs, mechs); + + return GSS_S_UNAVAILABLE; +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_import_name.c b/third_party/heimdal/lib/gssapi/mech/gss_import_name.c new file mode 100644 index 0000000..54930bf --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_import_name.c @@ -0,0 +1,323 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_import_name.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" + +static OM_uint32 +_gss_import_export_name(OM_uint32 *minor_status, + const gss_buffer_t input_name_buffer, + const gss_OID name_type, + gss_name_t *output_name) +{ + OM_uint32 major_status; + unsigned char *p = input_name_buffer->value; + size_t len = input_name_buffer->length; + size_t t; + gss_OID_desc mech_oid; + gssapi_mech_interface m; + struct _gss_name *name; + gss_name_t new_canonical_name; + int composite = 0; + + *minor_status = 0; + *output_name = 0; + + /* + * Make sure that TOK_ID is {4, 1}. + */ + if (len < 2) + return (GSS_S_BAD_NAME); + if (p[0] != 4) + return (GSS_S_BAD_NAME); + switch (p[1]) { + case 1: /* non-composite name */ + break; + case 2: /* composite name */ + composite = 1; + break; + default: + return (GSS_S_BAD_NAME); + } + p += 2; + len -= 2; + + /* + * If the name token is a composite token (TOK_ID 0x04 0x02) then per + * RFC6680 everything after that is implementation-specific. This + * mech-glue is pluggable however, so we need the format of the rest of + * the header to be stable, otherwise we couldn't reliably determine + * what mechanism the token is for and we'd have to try all of them. + * + * So... we keep the same format for the exported composite name token + * as for normal exported name tokens (see RFC2743, section 3.2), with + * the TOK_ID 0x04 0x02, but only up to the mechanism OID. We don't + * enforce that there be a NAME_LEN in the exported composite name + * token, or that it match the length of the remainder of the token. + * + * FYI, at least one out-of-tree mechanism implements exported + * composite name tokens as the same as exported name tokens with + * attributes appended and the NAME_LEN not modified to match. + */ + + /* + * Get the mech length and the name length and sanity + * check the size of of the buffer. + */ + if (len < 2) + return (GSS_S_BAD_NAME); + t = (p[0] << 8) + p[1]; + p += 2; + len -= 2; + + /* + * Check the DER encoded OID to make sure it agrees with the + * length we just decoded. + */ + if (p[0] != 6) /* 6=OID */ + return (GSS_S_BAD_NAME); + p++; + len--; + t--; + if (p[0] & 0x80) { + int digits = p[0]; + p++; + len--; + t--; + mech_oid.length = 0; + while (digits--) { + mech_oid.length = (mech_oid.length << 8) | p[0]; + p++; + len--; + t--; + } + } else { + mech_oid.length = p[0]; + p++; + len--; + t--; + } + if (mech_oid.length != t) + return (GSS_S_BAD_NAME); + + mech_oid.elements = p; + + if (!composite) { + if (len < t + 4) + return (GSS_S_BAD_NAME); + p += t; + len -= t; + + t = ((unsigned long)p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; + /* p += 4; // we're done using `p' now */ + len -= 4; + + if (len != t) + return (GSS_S_BAD_NAME); + } + + m = __gss_get_mechanism(&mech_oid); + if (!m || !m->gm_import_name) + return (GSS_S_BAD_MECH); + + /* + * Ask the mechanism to import the name. + */ + major_status = m->gm_import_name(minor_status, + input_name_buffer, name_type, &new_canonical_name); + if (major_status != GSS_S_COMPLETE) { + _gss_mg_error(m, *minor_status); + return major_status; + } + + /* + * Now we make a new name and mark it as an MN. + */ + name = _gss_create_name(new_canonical_name, m); + if (!name) { + m->gm_release_name(minor_status, &new_canonical_name); + return (GSS_S_FAILURE); + } + + *output_name = (gss_name_t) name; + + *minor_status = 0; + return (GSS_S_COMPLETE); +} + +/** + * Convert a GGS-API name from contiguous string to internal form. + * + * Type of name and their format: + * - GSS_C_NO_OID + * - GSS_C_NT_USER_NAME + * - GSS_C_NT_HOSTBASED_SERVICE + * - GSS_C_NT_EXPORT_NAME + * - GSS_C_NT_COMPOSITE_EXPORT + * - GSS_C_NT_ANONYMOUS + * - GSS_KRB5_NT_PRINCIPAL_NAME + * + * @sa gss_export_name(), @ref internalVSmechname. + * + * @param minor_status minor status code + * @param input_name_buffer import name buffer + * @param input_name_type type of the import name buffer + * @param output_name the resulting type, release with + * gss_release_name(), independent of input_name + * + * @returns a gss_error code, see gss_display_status() about printing + * the error code. + * + * @ingroup gssapi + */ + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_import_name(OM_uint32 *minor_status, + const gss_buffer_t input_name_buffer, + const gss_OID input_name_type, + gss_name_t *output_name) +{ + struct _gss_mechanism_name *mn; + gss_OID name_type = input_name_type; + OM_uint32 major_status, ms; + struct _gss_name *name; + struct _gss_mech_switch *m; + gss_name_t rname; + + if (input_name_buffer == GSS_C_NO_BUFFER) + return GSS_S_CALL_INACCESSIBLE_READ; + if (output_name == NULL) + return GSS_S_CALL_INACCESSIBLE_WRITE; + + *output_name = GSS_C_NO_NAME; + + /* Allow empty names since that's valid (ANONYMOUS for example) */ + + _gss_load_mech(); + + /* + * If this is an exported name, we need to parse it to find + * the mechanism and then import it as an MN. See RFC 2743 + * section 3.2 for a description of the format. + */ + if (gss_oid_equal(name_type, GSS_C_NT_EXPORT_NAME) || + gss_oid_equal(name_type, GSS_C_NT_COMPOSITE_EXPORT)) { + return _gss_import_export_name(minor_status, input_name_buffer, + name_type, output_name); + } + + + *minor_status = 0; + name = _gss_create_name(NULL, NULL); + if (!name) { + *minor_status = ENOMEM; + return (GSS_S_FAILURE); + } + + if (name_type != GSS_C_NO_OID) { + major_status = _gss_intern_oid(minor_status, + name_type, &name->gn_type); + if (major_status) { + rname = (gss_name_t)name; + gss_release_name(&ms, (gss_name_t *)&rname); + return (GSS_S_FAILURE); + } + } else + name->gn_type = GSS_C_NO_OID; + + major_status = _gss_copy_buffer(minor_status, + input_name_buffer, &name->gn_value); + if (major_status) + goto out; + + /* + * Walk over the mechs and import the name into a mech name + * for those supported this nametype. + */ + + HEIM_TAILQ_FOREACH(m, &_gss_mechs, gm_link) { + int present = 0; + + if ((m->gm_mech.gm_flags & GM_USE_MG_NAME)) + continue; + + if (name_type != GSS_C_NO_OID) { + major_status = gss_test_oid_set_member(minor_status, + name_type, m->gm_name_types, &present); + + if (GSS_ERROR(major_status) || present == 0) + continue; + } + + mn = malloc(sizeof(struct _gss_mechanism_name)); + if (!mn) { + *minor_status = ENOMEM; + major_status = GSS_S_FAILURE; + goto out; + } + + major_status = (*m->gm_mech.gm_import_name)(minor_status, + &name->gn_value, + name->gn_type, + &mn->gmn_name); + if (major_status != GSS_S_COMPLETE) { + _gss_mg_error(&m->gm_mech, *minor_status); + free(mn); + /** + * If we failed to import the name in a mechanism, it + * will be ignored as long as its possible to import + * name in some other mechanism. We will catch the + * failure later though in gss_init_sec_context() or + * another function. + */ + continue; + } + + mn->gmn_mech = &m->gm_mech; + mn->gmn_mech_oid = m->gm_mech_oid; + HEIM_TAILQ_INSERT_TAIL(&name->gn_mn, mn, gmn_link); + } + + /* + * If we can't find a mn for the name, bail out already here. + */ + + mn = HEIM_TAILQ_FIRST(&name->gn_mn); + if (!mn) { + *minor_status = 0; + major_status = GSS_S_NAME_NOT_MN; + goto out; + } + + *output_name = (gss_name_t) name; + return (GSS_S_COMPLETE); + + out: + rname = (gss_name_t)name; + gss_release_name(&ms, &rname); + return major_status; +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_import_sec_context.c b/third_party/heimdal/lib/gssapi/mech/gss_import_sec_context.c new file mode 100644 index 0000000..39b717e --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_import_sec_context.c @@ -0,0 +1,147 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_import_sec_context.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_import_sec_context(OM_uint32 *minor_status, + const gss_buffer_t interprocess_token, + gss_ctx_id_t *context_handle) +{ + OM_uint32 ret = GSS_S_FAILURE, tmp_minor; + krb5_storage *sp; + gssapi_mech_interface m; + struct _gss_context *ctx = NULL; + gss_buffer_desc buf = GSS_C_EMPTY_BUFFER; + unsigned char verflags; + + _gss_mg_log(10, "gss-isc called"); + + if (!context_handle) { + *minor_status = EFAULT; + return GSS_S_CALL_INACCESSIBLE_WRITE; + } + + *minor_status = 0; + *context_handle = GSS_C_NO_CONTEXT; + + sp = krb5_storage_from_mem(interprocess_token->value, + interprocess_token->length); + if (!sp) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_PACKED); + + ctx = calloc(1, sizeof(struct _gss_context)); + if (!ctx) { + *minor_status = ENOMEM; + goto failure; + } + + if (krb5_ret_uint8(sp, &verflags)) + goto failure; + + if ((verflags & EXPORT_CONTEXT_VERSION_MASK) != 0) { + _gss_mg_log(10, "gss-isc failed, token version %d not recognised", + (int)(verflags & EXPORT_CONTEXT_VERSION_MASK)); + /* We don't recognise the version */ + goto failure; + } + + if (verflags & EXPORT_CONTEXT_FLAG_ACCUMULATING) { + uint32_t target_len; + + if (krb5_ret_uint8(sp, &ctx->gc_initial)) + goto failure; + + if (krb5_ret_uint32(sp, &target_len)) + goto failure; + + ret = _gss_mg_ret_buffer(minor_status, sp, &buf); + if (ret != GSS_S_COMPLETE) + goto failure; + + ctx->gc_free_this = ctx->gc_input.value = calloc(target_len, 1); + if (ctx->gc_input.value == NULL) + goto failure; + + ctx->gc_target_len = target_len; + ctx->gc_input.length = buf.length; + if (buf.value) + memcpy(ctx->gc_input.value, buf.value, buf.length); + + gss_release_buffer(&tmp_minor, &buf); + } + + if (verflags & EXPORT_CONTEXT_FLAG_MECH_CTX) { + gss_OID mech_oid; + + ret = _gss_mg_ret_oid(minor_status, sp, &mech_oid); + if (ret != GSS_S_COMPLETE) + goto failure; + + if (mech_oid == GSS_C_NO_OID) { + ret = GSS_S_BAD_MECH; + goto failure; + } + + m = __gss_get_mechanism(mech_oid); + if (m == NULL) { + ret = GSS_S_DEFECTIVE_TOKEN; + goto failure; + } + ctx->gc_mech = m; + + ret = _gss_mg_ret_buffer(minor_status, sp, &buf); + if (ret != GSS_S_COMPLETE) + goto failure; + + if (buf.value == NULL) { + ret = GSS_S_DEFECTIVE_TOKEN; + goto failure; + } + + ret = m->gm_import_sec_context(minor_status, &buf, &ctx->gc_ctx); + if (ret != GSS_S_COMPLETE) { + _gss_mg_error(m, *minor_status); + goto failure; + } + } + + *context_handle = (gss_ctx_id_t) ctx; + ctx = NULL; + + ret = GSS_S_COMPLETE; + +failure: + free(ctx); + krb5_storage_free(sp); + _gss_secure_release_buffer(&tmp_minor, &buf); + return ret; +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_indicate_mechs.c b/third_party/heimdal/lib/gssapi/mech/gss_indicate_mechs.c new file mode 100644 index 0000000..9eef62e --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_indicate_mechs.c @@ -0,0 +1,74 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_indicate_mechs.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_indicate_mechs(OM_uint32 *minor_status, + gss_OID_set *mech_set) +{ + struct _gss_mech_switch *m; + OM_uint32 major_status, junk; + gss_OID_set set; + size_t i; + + _gss_load_mech(); + + major_status = gss_create_empty_oid_set(minor_status, mech_set); + if (major_status) + return (major_status); + + /* XXX We ignore ENOMEM from gss_add_oid_set_member() */ + HEIM_TAILQ_FOREACH(m, &_gss_mechs, gm_link) { + if (m->gm_mech.gm_indicate_mechs) { + major_status = m->gm_mech.gm_indicate_mechs( + minor_status, &set); + if (major_status) + continue; + major_status = GSS_S_COMPLETE; + for (i = 0; i < set->count; i++) { + major_status = gss_add_oid_set_member( + minor_status, &set->elements[i], mech_set); + if (major_status) + break; + } + gss_release_oid_set(minor_status, &set); + } else { + major_status = gss_add_oid_set_member( + minor_status, m->gm_mech_oid, mech_set); + } + if (major_status) + break; + } + + if (major_status) + gss_release_oid_set(&junk, mech_set); + + *minor_status = 0; + return major_status; +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_init_sec_context.c b/third_party/heimdal/lib/gssapi/mech/gss_init_sec_context.c new file mode 100644 index 0000000..6d28938 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_init_sec_context.c @@ -0,0 +1,281 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Portions Copyright (c) 2009 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_init_sec_context.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" + +gss_cred_id_t +_gss_mg_find_mech_cred( + gss_const_cred_id_t cred_handle, + gss_const_OID mech_type) +{ + struct _gss_cred *cred = (struct _gss_cred *)cred_handle; + struct _gss_mechanism_cred *mc; + + if (cred == NULL) + return GSS_C_NO_CREDENTIAL; + + HEIM_TAILQ_FOREACH(mc, &cred->gc_mc, gmc_link) { + if (gss_oid_equal(mech_type, mc->gmc_mech_oid)) + return mc->gmc_cred; + } + return GSS_C_NO_CREDENTIAL; +} + +static void +log_init_sec_context(struct _gss_context *ctx, + struct _gss_name *target, + OM_uint32 req_flags, + struct _gss_cred *cred, + gss_OID mech_type, + gss_buffer_t input_token) +{ + gssapi_mech_interface m; + + if (ctx) + m = ctx->gc_mech; + else + m = __gss_get_mechanism(mech_type); + if (m == NULL) + return; + + mech_type = &m->gm_mech_oid; + + _gss_mg_log(1, "gss_isc: %s %sfirst flags %08x, %s cred, %stoken", + m->gm_name, + (ctx == NULL) ? "" : "not ", + req_flags, + (cred != NULL) ? "specific" : "default", + (input_token != NULL && input_token->length) ? "" : "no "); + + _gss_mg_log_cred(1, cred, "gss_isc cred"); + + /* print target name */ + _gss_mg_log_name(1, target, mech_type, "gss_isc: target"); +} + +/** + * As the initiator build a context with an acceptor. + * + * Returns in the major + * - GSS_S_COMPLETE - if the context if build + * - GSS_S_CONTINUE_NEEDED - if the caller needs to continue another + * round of gss_i nit_sec_context + * - error code - any other error code + * + * @param minor_status minor status code. + * + * @param initiator_cred_handle the credential to use when building + * the context, if GSS_C_NO_CREDENTIAL is passed, the default + * credential for the mechanism will be used. + * + * @param context_handle a pointer to a context handle, will be + * returned as long as there is not an error. + * + * @param target_name the target name of acceptor, created using + * gss_import_name(). The name is can be of any name types the + * mechanism supports, check supported name types with + * gss_inquire_names_for_mech(). + * + * @param input_mech_type mechanism type to use, if GSS_C_NO_OID is + * used, Kerberos (GSS_KRB5_MECHANISM) will be tried. Other + * available mechanism are listed in the @ref gssapi_mechs_intro + * section. + * + * @param req_flags flags using when building the context, see @ref + * gssapi_context_flags + * + * @param time_req time requested this context should be valid in + * seconds, common used value is GSS_C_INDEFINITE + * + * @param input_chan_bindings Channel bindings used, if not exepected + * otherwise, used GSS_C_NO_CHANNEL_BINDINGS + * + * @param input_token input token sent from the acceptor, for the + * initial packet the buffer of { NULL, 0 } should be used. + * + * @param actual_mech_type the actual mech used, MUST NOT be freed + * since it pointing to static memory. + * + * @param output_token if there is an output token, regardless of + * complete, continue_needed, or error it should be sent to the + * acceptor + * + * @param ret_flags return what flags was negotitated, caller should + * check if they are accetable. For example, if + * GSS_C_MUTUAL_FLAG was negotiated with the acceptor or not. + * + * @param time_rec amount of time this context is valid for + * + * @returns a gss_error code, see gss_display_status() about printing + * the error code. + * + * @ingroup gssapi + */ + + + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_init_sec_context(OM_uint32 * minor_status, + gss_const_cred_id_t initiator_cred_handle, + gss_ctx_id_t * context_handle, + gss_const_name_t target_name, + const gss_OID input_mech_type, + OM_uint32 req_flags, + OM_uint32 time_req, + const gss_channel_bindings_t input_chan_bindings, + const gss_buffer_t input_token, + gss_OID * actual_mech_type, + gss_buffer_t output_token, + OM_uint32 * ret_flags, + OM_uint32 * time_rec) +{ + OM_uint32 major_status; + gssapi_mech_interface m; + gss_const_name_t mn_inner = GSS_C_NO_NAME; + struct _gss_name *name = (struct _gss_name *) target_name; + struct _gss_mechanism_name *mn; + struct _gss_context *ctx = (struct _gss_context *) *context_handle; + gss_const_cred_id_t cred_handle; + int allocated_ctx; + gss_OID mech_type = input_mech_type; + + *minor_status = 0; + + _mg_buffer_zero(output_token); + if (actual_mech_type) + *actual_mech_type = GSS_C_NO_OID; + if (ret_flags) + *ret_flags = 0; + if (time_rec) + *time_rec = 0; + + if (mech_type == GSS_C_NO_OID) + mech_type = GSS_KRB5_MECHANISM; + + _gss_mg_check_name(target_name); + + if (_gss_mg_log_level(1)) + log_init_sec_context(ctx, name, req_flags, + (struct _gss_cred *)initiator_cred_handle, + input_mech_type, input_token); + + /* + * If we haven't allocated a context yet, do so now and lookup + * the mechanism switch table. If we have one already, make + * sure we use the same mechanism switch as before. + */ + if (!ctx) { + ctx = malloc(sizeof(struct _gss_context)); + if (!ctx) { + *minor_status = ENOMEM; + return (GSS_S_FAILURE); + } + memset(ctx, 0, sizeof(struct _gss_context)); + m = ctx->gc_mech = __gss_get_mechanism(mech_type); + if (!m) { + free(ctx); + *minor_status = 0; + gss_mg_set_error_string(mech_type, GSS_S_BAD_MECH, + *minor_status, + "Unsupported mechanism requested"); + return (GSS_S_BAD_MECH); + } + allocated_ctx = 1; + } else { + m = ctx->gc_mech; + mech_type = &ctx->gc_mech->gm_mech_oid; + allocated_ctx = 0; + } + + /* + * Find the MN for this mechanism. + */ + if ((m->gm_flags & GM_USE_MG_NAME)) { + mn_inner = target_name; + } else { + major_status = _gss_find_mn(minor_status, name, mech_type, &mn); + if (major_status != GSS_S_COMPLETE) { + if (allocated_ctx) + free(ctx); + return major_status; + } + if (mn) + mn_inner = mn->gmn_name; + } + + /* + * If we have a cred, find the cred for this mechanism. + */ + if (m->gm_flags & GM_USE_MG_CRED) + cred_handle = initiator_cred_handle; + else + cred_handle = _gss_mg_find_mech_cred(initiator_cred_handle, mech_type); + + if (initiator_cred_handle != GSS_C_NO_CREDENTIAL && + cred_handle == NULL) { + *minor_status = 0; + if (allocated_ctx) + free(ctx); + gss_mg_set_error_string(mech_type, GSS_S_UNAVAILABLE, + *minor_status, + "Credential for the requested mechanism " + "not found in credential handle"); + return GSS_S_UNAVAILABLE; + } + + major_status = m->gm_init_sec_context(minor_status, + cred_handle, + &ctx->gc_ctx, + mn_inner, + mech_type, + req_flags, + time_req, + input_chan_bindings, + input_token, + actual_mech_type, + output_token, + ret_flags, + time_rec); + + if (major_status != GSS_S_COMPLETE + && major_status != GSS_S_CONTINUE_NEEDED) { + if (allocated_ctx) + free(ctx); + _mg_buffer_zero(output_token); + _gss_mg_error(m, *minor_status); + } else { + *context_handle = (gss_ctx_id_t) ctx; + } + + _gss_mg_log(1, "gss_isc: %s maj_stat: %d/%d", + m->gm_name, (int)major_status, (int)*minor_status); + + return (major_status); +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_inquire_context.c b/third_party/heimdal/lib/gssapi/mech/gss_inquire_context.c new file mode 100644 index 0000000..6140696 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_inquire_context.c @@ -0,0 +1,120 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_inquire_context.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_inquire_context(OM_uint32 *minor_status, + gss_const_ctx_id_t context_handle, + gss_name_t *src_name, + gss_name_t *targ_name, + OM_uint32 *lifetime_rec, + gss_OID *mech_type, + OM_uint32 *ctx_flags, + int *locally_initiated, + int *xopen) +{ + OM_uint32 major_status; + struct _gss_context *ctx = (struct _gss_context *) context_handle; + gssapi_mech_interface m; + struct _gss_name *name; + gss_name_t src_mn, targ_mn; + + if (locally_initiated) + *locally_initiated = 0; + if (xopen) + *xopen = 0; + if (lifetime_rec) + *lifetime_rec = 0; + + if (src_name) + *src_name = GSS_C_NO_NAME; + if (targ_name) + *targ_name = GSS_C_NO_NAME; + if (mech_type) + *mech_type = GSS_C_NO_OID; + src_mn = targ_mn = GSS_C_NO_NAME; + + if (ctx == NULL || ctx->gc_ctx == NULL) { + *minor_status = 0; + return GSS_S_NO_CONTEXT; + } + + m = ctx->gc_mech; + + major_status = m->gm_inquire_context(minor_status, + ctx->gc_ctx, + src_name ? &src_mn : NULL, + targ_name ? &targ_mn : NULL, + lifetime_rec, + mech_type, + ctx_flags, + locally_initiated, + xopen); + + if (major_status != GSS_S_COMPLETE) { + _gss_mg_error(m, *minor_status); + return (major_status); + } + + if (src_name && (m->gm_flags & GM_USE_MG_NAME)) { + *src_name = src_mn; + src_mn = GSS_C_NO_NAME; + } else if (src_name && src_mn) { + /* _gss_create_name() consumes `src_mn' on success */ + name = _gss_create_name(src_mn, m); + if (!name) { + if (mech_type) + *mech_type = GSS_C_NO_OID; + m->gm_release_name(minor_status, &src_mn); + *minor_status = 0; + return (GSS_S_FAILURE); + } + *src_name = (gss_name_t) name; + src_mn = GSS_C_NO_NAME; + } + + if (targ_name && (m->gm_flags & GM_USE_MG_NAME)) { + *targ_name = targ_mn; + } else if (targ_name && targ_mn) { + name = _gss_create_name(targ_mn, m); + if (!name) { + if (mech_type) + *mech_type = GSS_C_NO_OID; + if (src_name) + gss_release_name(minor_status, src_name); + m->gm_release_name(minor_status, &targ_mn); + *minor_status = 0; + return (GSS_S_FAILURE); + } + *targ_name = (gss_name_t) name; + targ_mn = GSS_C_NO_NAME; + } + + return (GSS_S_COMPLETE); +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_inquire_cred.c b/third_party/heimdal/lib/gssapi/mech/gss_inquire_cred.c new file mode 100644 index 0000000..305cae2 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_inquire_cred.c @@ -0,0 +1,218 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_inquire_cred.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" + +#define AUSAGE 1 +#define IUSAGE 2 + +static void +updateusage(gss_cred_usage_t usage, int *usagemask) +{ + if (usage == GSS_C_BOTH) + *usagemask |= AUSAGE | IUSAGE; + else if (usage == GSS_C_ACCEPT) + *usagemask |= AUSAGE; + else if (usage == GSS_C_INITIATE) + *usagemask |= IUSAGE; +} + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_inquire_cred(OM_uint32 *minor_status, + gss_const_cred_id_t cred_handle, + gss_name_t *name_ret, + OM_uint32 *lifetime, + gss_cred_usage_t *cred_usage, + gss_OID_set *mechanisms) +{ + OM_uint32 major_status; + struct _gss_mech_switch *m; + struct _gss_cred *cred = (struct _gss_cred *) cred_handle; + struct _gss_name *name; + struct _gss_mechanism_name *mn; + OM_uint32 min_lifetime; + int found = FALSE; + int usagemask = 0; + gss_cred_usage_t usage; + + _gss_load_mech(); + + *minor_status = 0; + if (name_ret) + *name_ret = GSS_C_NO_NAME; + if (lifetime) + *lifetime = 0; + if (cred_usage) + *cred_usage = 0; + if (mechanisms) + *mechanisms = GSS_C_NO_OID_SET; + + if (name_ret) { + name = _gss_create_name(NULL, NULL); + if (name == NULL) { + *minor_status = ENOMEM; + return (GSS_S_FAILURE); + } + } else { + name = NULL; + } + + if (mechanisms) { + major_status = gss_create_empty_oid_set(minor_status, + mechanisms); + if (major_status) { + if (name) free(name); + return (major_status); + } + } + + min_lifetime = GSS_C_INDEFINITE; + if (cred) { + struct _gss_mechanism_cred *mc; + + HEIM_TAILQ_FOREACH(mc, &cred->gc_mc, gmc_link) { + gss_name_t mc_name = GSS_C_NO_NAME; + OM_uint32 mc_lifetime = GSS_C_INDEFINITE; + + heim_assert((mc->gmc_mech->gm_flags & GM_USE_MG_CRED) == 0, + "should not have mech creds for GM_USE_MG_CRED mechs"); + + if (mc->gmc_mech->gm_inquire_cred == NULL) + continue; + + major_status = mc->gmc_mech->gm_inquire_cred(minor_status, + mc->gmc_cred, &mc_name, &mc_lifetime, &usage, NULL); + if (major_status) + continue; + + updateusage(usage, &usagemask); + if (name) { + mn = malloc(sizeof(struct _gss_mechanism_name)); + if (!mn) { + mc->gmc_mech->gm_release_name(minor_status, + &mc_name); + continue; + } + mn->gmn_mech = mc->gmc_mech; + mn->gmn_mech_oid = mc->gmc_mech_oid; + mn->gmn_name = mc_name; + HEIM_TAILQ_INSERT_TAIL(&name->gn_mn, mn, gmn_link); + } else { + mc->gmc_mech->gm_release_name(minor_status, + &mc_name); + } + + if (mc_lifetime < min_lifetime) + min_lifetime = mc_lifetime; + + if (mechanisms) + gss_add_oid_set_member(minor_status, + mc->gmc_mech_oid, mechanisms); + found = TRUE; + } + } else { + HEIM_TAILQ_FOREACH(m, &_gss_mechs, gm_link) { + gss_name_t mc_name; + OM_uint32 mc_lifetime; + + if (m->gm_mech.gm_inquire_cred == NULL || + (m->gm_mech.gm_flags & GM_USE_MG_CRED)) + continue; + + major_status = m->gm_mech.gm_inquire_cred(minor_status, + GSS_C_NO_CREDENTIAL, &mc_name, &mc_lifetime, + &usage, NULL); + if (major_status) + continue; + + updateusage(usage, &usagemask); + if (name && mc_name) { + mn = malloc( + sizeof(struct _gss_mechanism_name)); + if (!mn) { + m->gm_mech.gm_release_name( + minor_status, &mc_name); + continue; + } + mn->gmn_mech = &m->gm_mech; + mn->gmn_mech_oid = m->gm_mech_oid; + mn->gmn_name = mc_name; + HEIM_TAILQ_INSERT_TAIL(&name->gn_mn, mn, gmn_link); + } else if (mc_name) { + m->gm_mech.gm_release_name(minor_status, + &mc_name); + } + + if (mc_lifetime < min_lifetime) + min_lifetime = mc_lifetime; + + if (mechanisms) + gss_add_oid_set_member(minor_status, + m->gm_mech_oid, mechanisms); + found = TRUE; + } + } + + if (found && mechanisms) { + /* GM_USE_MG_CRED mechs (SPNEGO) always can be used */ + HEIM_TAILQ_FOREACH(m, &_gss_mechs, gm_link) { + if ((m->gm_mech.gm_flags & GM_USE_MG_CRED) == 0) + continue; + + gss_add_oid_set_member(minor_status, + m->gm_mech_oid, mechanisms); + } + } + + if (found == FALSE || min_lifetime == 0) { + gss_name_t n = (gss_name_t)name; + if (n) + gss_release_name(minor_status, &n); + gss_release_oid_set(minor_status, mechanisms); + *minor_status = 0; + if (min_lifetime == 0) + return (GSS_S_CREDENTIALS_EXPIRED); + + return (GSS_S_NO_CRED); + } + + *minor_status = 0; + if (name_ret) + *name_ret = (gss_name_t) name; + if (lifetime) + *lifetime = min_lifetime; + if (cred_usage) { + if ((usagemask & (AUSAGE|IUSAGE)) == (AUSAGE|IUSAGE)) + *cred_usage = GSS_C_BOTH; + else if (usagemask & IUSAGE) + *cred_usage = GSS_C_INITIATE; + else if (usagemask & AUSAGE) + *cred_usage = GSS_C_ACCEPT; + } + return (GSS_S_COMPLETE); +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_inquire_cred_by_mech.c b/third_party/heimdal/lib/gssapi/mech/gss_inquire_cred_by_mech.c new file mode 100644 index 0000000..10ba9b7 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_inquire_cred_by_mech.c @@ -0,0 +1,92 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_inquire_cred_by_mech.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_inquire_cred_by_mech(OM_uint32 *minor_status, + gss_const_cred_id_t cred_handle, + const gss_OID mech_type, + gss_name_t *cred_name, + OM_uint32 *initiator_lifetime, + OM_uint32 *acceptor_lifetime, + gss_cred_usage_t *cred_usage) +{ + OM_uint32 major_status; + gssapi_mech_interface m; + struct _gss_mechanism_cred *mcp; + gss_cred_id_t mc; + gss_name_t mn; + struct _gss_name *name; + + *minor_status = 0; + if (cred_name) + *cred_name = GSS_C_NO_NAME; + if (initiator_lifetime) + *initiator_lifetime = 0; + if (acceptor_lifetime) + *acceptor_lifetime = 0; + if (cred_usage) + *cred_usage = 0; + + m = __gss_get_mechanism(mech_type); + if (m == NULL || m->gm_inquire_cred_by_mech == NULL) + return (GSS_S_NO_CRED); + + if (cred_handle != GSS_C_NO_CREDENTIAL) { + struct _gss_cred *cred = (struct _gss_cred *) cred_handle; + HEIM_TAILQ_FOREACH(mcp, &cred->gc_mc, gmc_link) + if (mcp->gmc_mech == m) + break; + if (!mcp) + return (GSS_S_NO_CRED); + mc = mcp->gmc_cred; + } else { + mc = GSS_C_NO_CREDENTIAL; + } + + major_status = m->gm_inquire_cred_by_mech(minor_status, mc, mech_type, + &mn, initiator_lifetime, acceptor_lifetime, cred_usage); + if (major_status != GSS_S_COMPLETE) { + _gss_mg_error(m, *minor_status); + return (major_status); + } + + if (cred_name) { + name = _gss_create_name(mn, m); + if (!name) { + m->gm_release_name(minor_status, &mn); + return (GSS_S_NO_CRED); + } + *cred_name = (gss_name_t) name; + } else + m->gm_release_name(minor_status, &mn); + + + return (GSS_S_COMPLETE); +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_inquire_cred_by_oid.c b/third_party/heimdal/lib/gssapi/mech/gss_inquire_cred_by_oid.c new file mode 100644 index 0000000..4e7c73f --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_inquire_cred_by_oid.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2004, PADL Software Pty Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of PADL Software nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_inquire_cred_by_oid (OM_uint32 *minor_status, + gss_const_cred_id_t cred_handle, + const gss_OID desired_object, + gss_buffer_set_t *data_set) +{ + struct _gss_cred *cred = (struct _gss_cred *) cred_handle; + OM_uint32 status = GSS_S_COMPLETE; + struct _gss_mechanism_cred *mc; + gssapi_mech_interface m; + gss_buffer_set_t set = GSS_C_NO_BUFFER_SET; + + *minor_status = 0; + *data_set = GSS_C_NO_BUFFER_SET; + + if (cred == NULL) + return GSS_S_NO_CRED; + + status = GSS_S_FAILURE; + + HEIM_TAILQ_FOREACH(mc, &cred->gc_mc, gmc_link) { + gss_buffer_set_t rset = GSS_C_NO_BUFFER_SET; + size_t i; + + m = mc->gmc_mech; + if (m == NULL) { + _gss_secure_release_buffer_set(minor_status, &set); + *minor_status = 0; + return GSS_S_BAD_MECH; + } + + if (m->gm_inquire_cred_by_oid == NULL) + continue; + + status = m->gm_inquire_cred_by_oid(minor_status, + mc->gmc_cred, desired_object, &rset); + if (status != GSS_S_COMPLETE) { + _gss_mg_error(m, *minor_status); + continue; + } + + for (i = 0; rset != NULL && i < rset->count; i++) { + status = gss_add_buffer_set_member(minor_status, + &rset->elements[i], &set); + if (status != GSS_S_COMPLETE) + break; + } + _gss_secure_release_buffer_set(minor_status, &rset); + } + if (set == GSS_C_NO_BUFFER_SET && status == GSS_S_COMPLETE) + status = GSS_S_FAILURE; + *data_set = set; + *minor_status = 0; + return status; +} + diff --git a/third_party/heimdal/lib/gssapi/mech/gss_inquire_mechs_for_name.c b/third_party/heimdal/lib/gssapi/mech/gss_inquire_mechs_for_name.c new file mode 100644 index 0000000..f75dbaa --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_inquire_mechs_for_name.c @@ -0,0 +1,76 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_inquire_mechs_for_name.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_inquire_mechs_for_name(OM_uint32 *minor_status, + gss_const_name_t input_name, + gss_OID_set *mech_types) +{ + OM_uint32 major_status; + struct _gss_name *name = (struct _gss_name *) input_name; + struct _gss_mech_switch *m; + gss_OID_set name_types; + int present; + + *minor_status = 0; + + _gss_load_mech(); + + major_status = gss_create_empty_oid_set(minor_status, mech_types); + if (major_status) + return (major_status); + + /* + * We go through all the loaded mechanisms and see if this + * name's type is supported by the mechanism. If it is, add + * the mechanism to the set. + */ + HEIM_TAILQ_FOREACH(m, &_gss_mechs, gm_link) { + major_status = gss_inquire_names_for_mech(minor_status, + m->gm_mech_oid, &name_types); + if (major_status) { + gss_release_oid_set(minor_status, mech_types); + return (major_status); + } + gss_test_oid_set_member(minor_status, + name->gn_type, name_types, &present); + gss_release_oid_set(minor_status, &name_types); + if (present) { + major_status = gss_add_oid_set_member(minor_status, + m->gm_mech_oid, mech_types); + if (major_status) { + gss_release_oid_set(minor_status, mech_types); + return (major_status); + } + } + } + + return (GSS_S_COMPLETE); +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_inquire_name.c b/third_party/heimdal/lib/gssapi/mech/gss_inquire_name.c new file mode 100644 index 0000000..f109a9f --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_inquire_name.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2010, PADL Software Pty Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of PADL Software nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_inquire_name(OM_uint32 *minor_status, + gss_name_t input_name, + int *name_is_MN, + gss_OID *MN_mech, + gss_buffer_set_t *attrs) +{ + OM_uint32 major_status = GSS_S_UNAVAILABLE; + struct _gss_name *name = (struct _gss_name *) input_name; + struct _gss_mechanism_name *mn; + + *minor_status = 0; + if (name_is_MN != NULL) + *name_is_MN = 0; + if (MN_mech != NULL) + *MN_mech = GSS_C_NO_OID; + if (attrs != NULL) + *attrs = GSS_C_NO_BUFFER_SET; + + if (input_name == GSS_C_NO_NAME) + return GSS_S_BAD_NAME; + + HEIM_TAILQ_FOREACH(mn, &name->gn_mn, gmn_link) { + gssapi_mech_interface m = mn->gmn_mech; + + if (!m->gm_inquire_name) + continue; + + major_status = m->gm_inquire_name(minor_status, + mn->gmn_name, + NULL, + MN_mech, + attrs); + if (major_status == GSS_S_COMPLETE) { + if (name_is_MN != NULL) + *name_is_MN = 1; + if (MN_mech != NULL && *MN_mech == GSS_C_NO_OID) + *MN_mech = &m->gm_mech_oid; + break; + } + _gss_mg_error(m, *minor_status); + } + + return major_status; +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_inquire_names_for_mech.c b/third_party/heimdal/lib/gssapi/mech/gss_inquire_names_for_mech.c new file mode 100644 index 0000000..595ab73 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_inquire_names_for_mech.c @@ -0,0 +1,73 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_inquire_names_for_mech.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_inquire_names_for_mech(OM_uint32 *minor_status, + const gss_OID mechanism, + gss_OID_set *name_types) +{ + OM_uint32 major_status; + gssapi_mech_interface m = __gss_get_mechanism(mechanism); + + *minor_status = 0; + *name_types = GSS_C_NO_OID_SET; + if (!m) + return (GSS_S_BAD_MECH); + + /* + * If the implementation can do it, ask it for a list of + * names, otherwise fake it. + */ + if (m->gm_inquire_names_for_mech) { + return (m->gm_inquire_names_for_mech(minor_status, + mechanism, name_types)); + } else { + major_status = gss_create_empty_oid_set(minor_status, + name_types); + if (major_status) + return (major_status); + major_status = gss_add_oid_set_member(minor_status, + GSS_C_NT_HOSTBASED_SERVICE, name_types); + if (major_status) { + OM_uint32 junk; + gss_release_oid_set(&junk, name_types); + return (major_status); + } + major_status = gss_add_oid_set_member(minor_status, + GSS_C_NT_USER_NAME, name_types); + if (major_status) { + OM_uint32 junk; + gss_release_oid_set(&junk, name_types); + return (major_status); + } + } + + return (GSS_S_COMPLETE); +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_inquire_sec_context_by_oid.c b/third_party/heimdal/lib/gssapi/mech/gss_inquire_sec_context_by_oid.c new file mode 100644 index 0000000..55ff671 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_inquire_sec_context_by_oid.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2004, PADL Software Pty Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of PADL Software nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_inquire_sec_context_by_oid (OM_uint32 *minor_status, + gss_const_ctx_id_t context_handle, + const gss_OID desired_object, + gss_buffer_set_t *data_set) +{ + struct _gss_context *ctx = (struct _gss_context *) context_handle; + OM_uint32 major_status; + gssapi_mech_interface m; + + *minor_status = 0; + *data_set = GSS_C_NO_BUFFER_SET; + if (ctx == NULL) + return GSS_S_NO_CONTEXT; + + /* + * select the approprate underlying mechanism routine and + * call it. + */ + + m = ctx->gc_mech; + + if (m == NULL) + return GSS_S_BAD_MECH; + + if (m->gm_inquire_sec_context_by_oid != NULL) { + major_status = m->gm_inquire_sec_context_by_oid(minor_status, + ctx->gc_ctx, desired_object, data_set); + if (major_status != GSS_S_COMPLETE) + _gss_mg_error(m, *minor_status); + } else + major_status = GSS_S_BAD_MECH; + + return major_status; +} + diff --git a/third_party/heimdal/lib/gssapi/mech/gss_krb5.c b/third_party/heimdal/lib/gssapi/mech/gss_krb5.c new file mode 100644 index 0000000..78c3056 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_krb5.c @@ -0,0 +1,927 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_krb5.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" +#include "krb5/gsskrb5_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_krb5_copy_ccache(OM_uint32 *minor_status, + gss_cred_id_t cred, + krb5_ccache out) +{ + gss_key_value_element_desc cred_store_kvs[1]; + gss_key_value_set_desc cred_store; + krb5_context context; + OM_uint32 major = GSS_S_FAILURE; + char *fullname = NULL; + + GSSAPI_KRB5_INIT(&context); + *minor_status = krb5_cc_get_full_name(context, out, &fullname); + if (*minor_status == 0) { + cred_store_kvs[0].key = "ccache"; + cred_store_kvs[0].value = fullname; + cred_store.count = 1; + cred_store.elements = cred_store_kvs; + major = gss_store_cred_into2(minor_status, cred, GSS_C_INITIATE, + GSS_KRB5_MECHANISM, + GSS_C_STORE_CRED_OVERWRITE, &cred_store, + NULL, NULL, NULL); + free(fullname); + } + return major; +} + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_krb5_import_cred(OM_uint32 *minor_status, + krb5_ccache id, + krb5_principal keytab_principal, + krb5_keytab keytab, + gss_cred_id_t *cred) +{ + gss_buffer_desc buffer; + OM_uint32 major_status; + krb5_context context; + krb5_error_code ret; + krb5_storage *sp; + krb5_data data; + char *str; + + *cred = GSS_C_NO_CREDENTIAL; + + ret = krb5_init_context(&context); + if (ret) { + *minor_status = ret; + return GSS_S_FAILURE; + } + + sp = krb5_storage_emem(); + if (sp == NULL) { + *minor_status = ENOMEM; + major_status = GSS_S_FAILURE; + goto out; + } + + if (id) { + ret = krb5_cc_get_full_name(context, id, &str); + if (ret == 0) { + ret = krb5_store_string(sp, str); + free(str); + } + } else + ret = krb5_store_string(sp, ""); + if (ret) { + *minor_status = ret; + major_status = GSS_S_FAILURE; + goto out; + } + + if (keytab_principal) { + ret = krb5_unparse_name(context, keytab_principal, &str); + if (ret == 0) { + ret = krb5_store_string(sp, str); + free(str); + } + } else + krb5_store_string(sp, ""); + if (ret) { + *minor_status = ret; + major_status = GSS_S_FAILURE; + goto out; + } + + + if (keytab) { + ret = krb5_kt_get_full_name(context, keytab, &str); + if (ret == 0) { + ret = krb5_store_string(sp, str); + free(str); + } + } else + krb5_store_string(sp, ""); + if (ret) { + *minor_status = ret; + major_status = GSS_S_FAILURE; + goto out; + } + + ret = krb5_storage_to_data(sp, &data); + if (ret) { + *minor_status = ret; + major_status = GSS_S_FAILURE; + goto out; + } + + buffer.value = data.data; + buffer.length = data.length; + + major_status = gss_set_cred_option(minor_status, + cred, + GSS_KRB5_IMPORT_CRED_X, + &buffer); + krb5_data_free(&data); +out: + if (sp) + krb5_storage_free(sp); + krb5_free_context(context); + return major_status; +} + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gsskrb5_register_acceptor_identity(const char *identity) +{ + gssapi_mech_interface m; + gss_buffer_desc buffer; + OM_uint32 junk; + + _gss_load_mech(); + + buffer.value = rk_UNCONST(identity); + buffer.length = strlen(identity); + + m = __gss_get_mechanism(GSS_KRB5_MECHANISM); + if (m == NULL || m->gm_set_sec_context_option == NULL) + return GSS_S_FAILURE; + + return m->gm_set_sec_context_option(&junk, NULL, + GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_X, &buffer); +} + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +krb5_gss_register_acceptor_identity(const char *identity) +{ + return gsskrb5_register_acceptor_identity(identity); +} + + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gsskrb5_set_dns_canonicalize(int flag) +{ + struct _gss_mech_switch *m; + gss_buffer_desc buffer; + OM_uint32 junk; + char b = (flag != 0); + + _gss_load_mech(); + + buffer.value = &b; + buffer.length = sizeof(b); + + HEIM_TAILQ_FOREACH(m, &_gss_mechs, gm_link) { + if (m->gm_mech.gm_set_sec_context_option == NULL) + continue; + m->gm_mech.gm_set_sec_context_option(&junk, NULL, + GSS_KRB5_SET_DNS_CANONICALIZE_X, &buffer); + } + + return (GSS_S_COMPLETE); +} + + + +static krb5_error_code +set_key(krb5_keyblock *keyblock, gss_krb5_lucid_key_t *key) +{ + key->type = keyblock->keytype; + key->length = keyblock->keyvalue.length; + key->data = malloc(key->length); + if (key->data == NULL && key->length != 0) + return ENOMEM; + memcpy(key->data, keyblock->keyvalue.data, key->length); + return 0; +} + +static void +free_key(gss_krb5_lucid_key_t *key) +{ + memset(key->data, 0, key->length); + free(key->data); + memset(key, 0, sizeof(*key)); +} + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_krb5_export_lucid_sec_context(OM_uint32 *minor_status, + gss_ctx_id_t *context_handle, + OM_uint32 version, + void **rctx) +{ + krb5_context context = NULL; + krb5_error_code ret; + gss_buffer_set_t data_set = GSS_C_NO_BUFFER_SET; + OM_uint32 major_status; + gss_krb5_lucid_context_v1_t *ctx = NULL; + krb5_storage *sp = NULL; + uint32_t num; + + if (context_handle == NULL + || *context_handle == GSS_C_NO_CONTEXT + || version != 1) + { + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + + major_status = + gss_inquire_sec_context_by_oid (minor_status, + *context_handle, + GSS_KRB5_EXPORT_LUCID_CONTEXT_V1_X, + &data_set); + if (major_status) + return major_status; + + if (data_set == GSS_C_NO_BUFFER_SET || data_set->count != 1) { + gss_release_buffer_set(minor_status, &data_set); + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + + ret = krb5_init_context(&context); + if (ret) + goto out; + + ctx = calloc(1, sizeof(*ctx)); + if (ctx == NULL) { + ret = ENOMEM; + goto out; + } + + sp = krb5_storage_from_mem(data_set->elements[0].value, + data_set->elements[0].length); + if (sp == NULL) { + ret = ENOMEM; + goto out; + } + + ret = krb5_ret_uint32(sp, &num); + if (ret) goto out; + if (num != 1) { + ret = EINVAL; + goto out; + } + ctx->version = 1; + /* initiator */ + ret = krb5_ret_uint32(sp, &ctx->initiate); + if (ret) goto out; + /* endtime */ + ret = krb5_ret_uint32(sp, &ctx->endtime); + if (ret) goto out; + /* send_seq */ + ret = krb5_ret_uint32(sp, &num); + if (ret) goto out; + ctx->send_seq = ((uint64_t)num) << 32; + ret = krb5_ret_uint32(sp, &num); + if (ret) goto out; + ctx->send_seq |= num; + /* recv_seq */ + ret = krb5_ret_uint32(sp, &num); + if (ret) goto out; + ctx->recv_seq = ((uint64_t)num) << 32; + ret = krb5_ret_uint32(sp, &num); + if (ret) goto out; + ctx->recv_seq |= num; + /* protocol */ + ret = krb5_ret_uint32(sp, &ctx->protocol); + if (ret) goto out; + if (ctx->protocol == 0) { + krb5_keyblock key; + + /* sign_alg */ + ret = krb5_ret_uint32(sp, &ctx->rfc1964_kd.sign_alg); + if (ret) goto out; + /* seal_alg */ + ret = krb5_ret_uint32(sp, &ctx->rfc1964_kd.seal_alg); + if (ret) goto out; + /* ctx_key */ + ret = krb5_ret_keyblock(sp, &key); + if (ret) goto out; + ret = set_key(&key, &ctx->rfc1964_kd.ctx_key); + krb5_free_keyblock_contents(context, &key); + if (ret) goto out; + } else if (ctx->protocol == 1) { + krb5_keyblock key; + + /* acceptor_subkey */ + ret = krb5_ret_uint32(sp, &ctx->cfx_kd.have_acceptor_subkey); + if (ret) goto out; + /* ctx_key */ + ret = krb5_ret_keyblock(sp, &key); + if (ret) goto out; + ret = set_key(&key, &ctx->cfx_kd.ctx_key); + krb5_free_keyblock_contents(context, &key); + if (ret) goto out; + /* acceptor_subkey */ + if (ctx->cfx_kd.have_acceptor_subkey) { + ret = krb5_ret_keyblock(sp, &key); + if (ret) goto out; + ret = set_key(&key, &ctx->cfx_kd.acceptor_subkey); + krb5_free_keyblock_contents(context, &key); + if (ret) goto out; + } + } else { + ret = EINVAL; + goto out; + } + + *rctx = ctx; + +out: + _gss_secure_release_buffer_set(minor_status, &data_set); + if (sp) + krb5_storage_free(sp); + if (context) + krb5_free_context(context); + + if (ret) { + OM_uint32 junk; + if (ctx) + gss_krb5_free_lucid_sec_context(&junk, ctx); + + *minor_status = ret; + return GSS_S_FAILURE; + } + *minor_status = 0; + return GSS_S_COMPLETE; +} + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_krb5_free_lucid_sec_context(OM_uint32 *minor_status, void *c) +{ + gss_krb5_lucid_context_v1_t *ctx = c; + + if (ctx->version != 1) { + if (minor_status) + *minor_status = 0; + return GSS_S_FAILURE; + } + + if (ctx->protocol == 0) { + free_key(&ctx->rfc1964_kd.ctx_key); + } else if (ctx->protocol == 1) { + free_key(&ctx->cfx_kd.ctx_key); + if (ctx->cfx_kd.have_acceptor_subkey) + free_key(&ctx->cfx_kd.acceptor_subkey); + } + free(ctx); + if (minor_status) + *minor_status = 0; + return GSS_S_COMPLETE; +} + +/* + * + */ + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_krb5_set_allowable_enctypes(OM_uint32 *minor_status, + gss_cred_id_t cred, + OM_uint32 num_enctypes, + int32_t *enctypes) +{ + krb5_error_code ret; + OM_uint32 maj_status; + gss_buffer_desc buffer; + krb5_storage *sp; + krb5_data data; + size_t i; + + sp = krb5_storage_emem(); + if (sp == NULL) { + *minor_status = ENOMEM; + maj_status = GSS_S_FAILURE; + goto out; + } + + for (i = 0; i < num_enctypes; i++) { + ret = krb5_store_int32(sp, enctypes[i]); + if (ret) { + *minor_status = ret; + maj_status = GSS_S_FAILURE; + goto out; + } + } + + ret = krb5_storage_to_data(sp, &data); + if (ret) { + *minor_status = ret; + maj_status = GSS_S_FAILURE; + goto out; + } + + buffer.value = data.data; + buffer.length = data.length; + + maj_status = gss_set_cred_option(minor_status, + &cred, + GSS_KRB5_SET_ALLOWABLE_ENCTYPES_X, + &buffer); + krb5_data_free(&data); +out: + if (sp) + krb5_storage_free(sp); + return maj_status; +} + +/* + * + */ + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gsskrb5_set_send_to_kdc(struct gsskrb5_send_to_kdc *c) +{ + struct _gss_mech_switch *m; + gss_buffer_desc buffer; + OM_uint32 junk; + + _gss_load_mech(); + + if (c) { + buffer.value = c; + buffer.length = sizeof(*c); + } else { + buffer.value = NULL; + buffer.length = 0; + } + + HEIM_TAILQ_FOREACH(m, &_gss_mechs, gm_link) { + if (m->gm_mech.gm_set_sec_context_option == NULL) + continue; + m->gm_mech.gm_set_sec_context_option(&junk, NULL, + GSS_KRB5_SEND_TO_KDC_X, &buffer); + } + + return (GSS_S_COMPLETE); +} + +/* + * + */ + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_krb5_ccache_name(OM_uint32 *minor_status, + const char *name, + const char **out_name) +{ + struct _gss_mech_switch *m; + gss_buffer_desc buffer = GSS_C_EMPTY_BUFFER; + OM_uint32 major_status; + struct gsskrb5_ccache_name_args args; + + _gss_load_mech(); + + *minor_status = 0; + + if (out_name) + *out_name = NULL; + + args.name = name; + args.out_name = NULL; + + buffer.value = &args; + buffer.length = sizeof(args); + + major_status = GSS_S_UNAVAILABLE; + + HEIM_TAILQ_FOREACH(m, &_gss_mechs, gm_link) { + OM_uint32 mech_major, mech_minor; + + if (m->gm_mech.gm_set_sec_context_option == NULL) + continue; + + mech_major = m->gm_mech.gm_set_sec_context_option(&mech_minor, + NULL, GSS_KRB5_CCACHE_NAME_X, &buffer); + if (mech_major != GSS_S_UNAVAILABLE) { + major_status = mech_major; + *minor_status = mech_minor; + break; + } + } + + if (out_name) + *out_name = args.out_name; + + return major_status; +} + + +/* + * + */ + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gsskrb5_extract_authtime_from_sec_context(OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + time_t *authtime) +{ + gss_buffer_set_t data_set = GSS_C_NO_BUFFER_SET; + OM_uint32 maj_stat; + + if (context_handle == GSS_C_NO_CONTEXT) { + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + + maj_stat = + gss_inquire_sec_context_by_oid (minor_status, + context_handle, + GSS_KRB5_GET_AUTHTIME_X, + &data_set); + if (maj_stat) + return maj_stat; + + if (data_set == GSS_C_NO_BUFFER_SET) { + gss_release_buffer_set(minor_status, &data_set); + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + + if (data_set->count != 1) { + gss_release_buffer_set(minor_status, &data_set); + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + + if (data_set->elements[0].length != 4) { + gss_release_buffer_set(minor_status, &data_set); + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + + { + unsigned char *buf = data_set->elements[0].value; + *authtime = ((unsigned long)buf[3] <<24) | (buf[2] << 16) | + (buf[1] << 8) | (buf[0] << 0); + } + + gss_release_buffer_set(minor_status, &data_set); + + *minor_status = 0; + return GSS_S_COMPLETE; +} + +/* + * + */ + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gsskrb5_extract_authz_data_from_sec_context(OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + int ad_type, + gss_buffer_t ad_data) +{ + gss_buffer_set_t data_set = GSS_C_NO_BUFFER_SET; + OM_uint32 maj_stat, tmp; + gss_OID_desc oid_flat; + heim_oid baseoid, oid; + size_t size; + + if (context_handle == GSS_C_NO_CONTEXT) { + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + + /* All this to append an integer to an oid... */ + + if (der_get_oid(GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_X->elements, + GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_X->length, + &baseoid, NULL) != 0) { + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + + oid.length = baseoid.length + 1; + oid.components = calloc(oid.length, sizeof(*oid.components)); + if (oid.components == NULL) { + der_free_oid(&baseoid); + + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + memcpy(oid.components, baseoid.components, + baseoid.length * sizeof(*baseoid.components)); + + der_free_oid(&baseoid); + + oid.components[oid.length - 1] = ad_type; + + oid_flat.length = (OM_uint32)der_length_oid(&oid); + oid_flat.elements = malloc(oid_flat.length); + if (oid_flat.elements == NULL) { + free(oid.components); + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + if (der_put_oid((unsigned char *)oid_flat.elements + oid_flat.length - 1, + oid_flat.length, &oid, &size) != 0) { + free(oid.components); + _gss_free_oid(&tmp, &oid_flat); + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + if (oid_flat.length != size) + abort(); + + free(oid.components); + + /* FINALLY, we have the OID */ + + maj_stat = gss_inquire_sec_context_by_oid (minor_status, + context_handle, + &oid_flat, + &data_set); + + _gss_free_oid(&tmp, &oid_flat); + + if (maj_stat) + return maj_stat; + + if (data_set == GSS_C_NO_BUFFER_SET || data_set->count != 1) { + gss_release_buffer_set(minor_status, &data_set); + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + + ad_data->value = malloc(data_set->elements[0].length); + if (ad_data->value == NULL) { + gss_release_buffer_set(minor_status, &data_set); + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + ad_data->length = data_set->elements[0].length; + memcpy(ad_data->value, data_set->elements[0].value, ad_data->length); + gss_release_buffer_set(minor_status, &data_set); + + *minor_status = 0; + return GSS_S_COMPLETE; +} + +/* + * + */ + +static OM_uint32 +gsskrb5_extract_key(OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + const gss_OID oid, + krb5_keyblock **keyblock) +{ + krb5_error_code ret; + gss_buffer_set_t data_set = GSS_C_NO_BUFFER_SET; + OM_uint32 major_status; + krb5_context context = NULL; + krb5_storage *sp = NULL; + + if (context_handle == GSS_C_NO_CONTEXT) { + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + + ret = krb5_init_context(&context); + if(ret) { + *minor_status = ret; + return GSS_S_FAILURE; + } + + major_status = + gss_inquire_sec_context_by_oid (minor_status, + context_handle, + oid, + &data_set); + if (major_status) + return major_status; + + if (data_set == GSS_C_NO_BUFFER_SET || data_set->count != 1) { + _gss_secure_release_buffer_set(minor_status, &data_set); + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + + sp = krb5_storage_from_mem(data_set->elements[0].value, + data_set->elements[0].length); + if (sp == NULL) { + ret = ENOMEM; + goto out; + } + + *keyblock = calloc(1, sizeof(**keyblock)); + if (*keyblock == NULL) { + ret = ENOMEM; + goto out; + } + + ret = krb5_ret_keyblock(sp, *keyblock); + +out: + _gss_secure_release_buffer_set(minor_status, &data_set); + if (sp) + krb5_storage_free(sp); + if (ret && keyblock) { + krb5_free_keyblock(context, *keyblock); + *keyblock = NULL; + } + if (context) + krb5_free_context(context); + + *minor_status = ret; + if (ret) + return GSS_S_FAILURE; + + return GSS_S_COMPLETE; +} + +/* + * + */ + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gsskrb5_extract_service_keyblock(OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + krb5_keyblock **keyblock) +{ + return gsskrb5_extract_key(minor_status, + context_handle, + GSS_KRB5_GET_SERVICE_KEYBLOCK_X, + keyblock); +} + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gsskrb5_get_initiator_subkey(OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + krb5_keyblock **keyblock) +{ + return gsskrb5_extract_key(minor_status, + context_handle, + GSS_KRB5_GET_INITIATOR_SUBKEY_X, + keyblock); +} + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gsskrb5_get_subkey(OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + krb5_keyblock **keyblock) +{ + return gsskrb5_extract_key(minor_status, + context_handle, + GSS_KRB5_GET_SUBKEY_X, + keyblock); +} + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gsskrb5_set_default_realm(const char *realm) +{ + struct _gss_mech_switch *m; + gss_buffer_desc buffer; + OM_uint32 junk; + + _gss_load_mech(); + + buffer.value = rk_UNCONST(realm); + buffer.length = strlen(realm); + + HEIM_TAILQ_FOREACH(m, &_gss_mechs, gm_link) { + if (m->gm_mech.gm_set_sec_context_option == NULL) + continue; + m->gm_mech.gm_set_sec_context_option(&junk, NULL, + GSS_KRB5_SET_DEFAULT_REALM_X, &buffer); + } + + return (GSS_S_COMPLETE); +} + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_krb5_get_tkt_flags(OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + OM_uint32 *tkt_flags) +{ + + OM_uint32 major_status; + gss_buffer_set_t data_set = GSS_C_NO_BUFFER_SET; + + if (context_handle == GSS_C_NO_CONTEXT) { + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + + major_status = + gss_inquire_sec_context_by_oid (minor_status, + context_handle, + GSS_KRB5_GET_TKT_FLAGS_X, + &data_set); + if (major_status) + return major_status; + + if (data_set == GSS_C_NO_BUFFER_SET || + data_set->count != 1 || + data_set->elements[0].length < 4) { + gss_release_buffer_set(minor_status, &data_set); + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + + { + const u_char *p = data_set->elements[0].value; + *tkt_flags = (p[0] << 0) | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); + } + + gss_release_buffer_set(minor_status, &data_set); + return GSS_S_COMPLETE; +} + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gsskrb5_set_time_offset(int offset) +{ + struct _gss_mech_switch *m; + gss_buffer_desc buffer; + OM_uint32 junk; + int32_t o = offset; + + _gss_load_mech(); + + buffer.value = &o; + buffer.length = sizeof(o); + + HEIM_TAILQ_FOREACH(m, &_gss_mechs, gm_link) { + if (m->gm_mech.gm_set_sec_context_option == NULL) + continue; + m->gm_mech.gm_set_sec_context_option(&junk, NULL, + GSS_KRB5_SET_TIME_OFFSET_X, &buffer); + } + + return (GSS_S_COMPLETE); +} + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gsskrb5_get_time_offset(int *offset) +{ + struct _gss_mech_switch *m; + gss_buffer_desc buffer; + OM_uint32 maj_stat, junk; + int32_t o; + + _gss_load_mech(); + + buffer.value = &o; + buffer.length = sizeof(o); + + HEIM_TAILQ_FOREACH(m, &_gss_mechs, gm_link) { + if (m->gm_mech.gm_set_sec_context_option == NULL) + continue; + maj_stat = m->gm_mech.gm_set_sec_context_option(&junk, NULL, + GSS_KRB5_GET_TIME_OFFSET_X, &buffer); + + if (maj_stat == GSS_S_COMPLETE) { + *offset = o; + return maj_stat; + } + } + + return (GSS_S_UNAVAILABLE); +} + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gsskrb5_plugin_register(struct gsskrb5_krb5_plugin *c) +{ + struct _gss_mech_switch *m; + gss_buffer_desc buffer; + OM_uint32 junk; + + _gss_load_mech(); + + buffer.value = c; + buffer.length = sizeof(*c); + + HEIM_TAILQ_FOREACH(m, &_gss_mechs, gm_link) { + if (m->gm_mech.gm_set_sec_context_option == NULL) + continue; + m->gm_mech.gm_set_sec_context_option(&junk, NULL, + GSS_KRB5_PLUGIN_REGISTER_X, &buffer); + } + + return (GSS_S_COMPLETE); +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_mech_switch.c b/third_party/heimdal/lib/gssapi/mech/gss_mech_switch.c new file mode 100644 index 0000000..372e72d --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_mech_switch.c @@ -0,0 +1,585 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_mech_switch.c,v 1.2 2006/02/04 09:40:21 dfr Exp $ + */ + +#include "mech_locl.h" +#include <heim_threads.h> + +#ifndef _PATH_GSS_MECH +#define _PATH_GSS_MECH "/etc/gss/mech" +#endif + +struct _gss_mech_switch_list _gss_mechs = { NULL, NULL } ; +gss_OID_set _gss_mech_oids; +static HEIMDAL_MUTEX _gss_mech_mutex = HEIMDAL_MUTEX_INITIALIZER; + +/* + * Convert a string containing an OID in 'dot' form + * (e.g. 1.2.840.113554.1.2.2) to a gss_OID. + */ +static int +_gss_string_to_oid(const char* s, gss_OID *oidp) +{ + int number_count, i, j; + size_t byte_count; + const char *p, *q; + char *res; + gss_OID_desc oid; + + *oidp = GSS_C_NO_OID; + + /* + * First figure out how many numbers in the oid, then + * calculate the compiled oid size. + */ + number_count = 0; + for (p = s; p; p = q) { + q = strchr(p, '.'); + if (q) q = q + 1; + number_count++; + } + + /* + * The first two numbers are in the first byte and each + * subsequent number is encoded in a variable byte sequence. + */ + if (number_count < 2) + return (EINVAL); + + /* + * We do this in two passes. The first pass, we just figure + * out the size. Second time around, we actually encode the + * number. + */ + res = 0; + for (i = 0; i < 2; i++) { + byte_count = 0; + for (p = s, j = 0; p; p = q, j++) { + unsigned int number = 0; + + /* + * Find the end of this number. + */ + q = strchr(p, '.'); + if (q) q = q + 1; + + /* + * Read the number of of the string. Don't + * bother with anything except base ten. + */ + while (*p && *p != '.') { + number = 10 * number + (*p - '0'); + p++; + } + + /* + * Encode the number. The first two numbers + * are packed into the first byte. Subsequent + * numbers are encoded in bytes seven bits at + * a time with the last byte having the high + * bit set. + */ + if (j == 0) { + if (res) + *res = number * 40; + } else if (j == 1) { + if (res) { + *res += number; + res++; + } + byte_count++; + } else if (j >= 2) { + /* + * The number is encoded in seven bit chunks. + */ + unsigned int t; + unsigned int bytes; + + bytes = 0; + for (t = number; t; t >>= 7) + bytes++; + if (bytes == 0) bytes = 1; + while (bytes) { + if (res) { + int bit = 7*(bytes-1); + + *res = (number >> bit) & 0x7f; + if (bytes != 1) + *res |= 0x80; + res++; + } + byte_count++; + bytes--; + } + } + } + if (byte_count == 0) + return EINVAL; + if (!res) { + res = malloc(byte_count); + if (!res) + return (ENOMEM); + oid.length = byte_count; + oid.elements = res; + } + } + + { + OM_uint32 minor_status, tmp; + + if (GSS_ERROR(_gss_intern_oid(&minor_status, &oid, oidp))) { + _gss_free_oid(&tmp, &oid); + return (minor_status); + } + + _gss_free_oid(&tmp, &oid); + } + + return (0); +} + +#define SYM(name) \ +do { \ + m->gm_mech.gm_ ## name = (_gss_##name##_t *)dlsym(so, "gss_" #name); \ + if (!m->gm_mech.gm_ ## name || \ + m->gm_mech.gm_ ##name == gss_ ## name) { \ + _gss_mg_log(1, "can't find symbol gss_" #name "\n"); \ + goto bad; \ + } \ +} while (0) + +#define OPTSYM(name) \ +do { \ + m->gm_mech.gm_ ## name = (_gss_##name##_t *)dlsym(so, "gss_" #name); \ + if (m->gm_mech.gm_ ## name == gss_ ## name) \ + m->gm_mech.gm_ ## name = NULL; \ +} while (0) + +/* mech exports gssspi_XXX, internally referred to as gss_XXX */ +#define OPTSPISYM(name) \ +do { \ + m->gm_mech.gm_ ## name = (_gss_##name##_t *)dlsym(so, "gssspi_" #name); \ +} while (0) + +/* mech exports gssspi_XXX, internally referred to as gssspi_XXX */ +#define OPTSPISPISYM(name) \ +do { \ + m->gm_mech.gm_ ## name = (_gss_##name##_t *)dlsym(so, "gssspi_" #name); \ + if (m->gm_mech.gm_ ## name == gssspi_ ## name) \ + m->gm_mech.gm_ ## name = NULL; \ +} while (0) + +#define COMPATSYM(name) \ +do { \ + m->gm_mech.gm_compat->gmc_ ## name = (_gss_##name##_t *)dlsym(so, "gss_" #name); \ + if (m->gm_mech.gm_compat->gmc_ ## name == gss_ ## name) \ + m->gm_mech.gm_compat->gmc_ ## name = NULL; \ +} while (0) + +#define COMPATSPISYM(name) \ +do { \ + m->gm_mech.gm_compat->gmc_ ## name = (_gss_##name##_t *)dlsym(so, "gssspi_" #name); \ + if (m->gm_mech.gm_compat->gmc_ ## name == gss_ ## name) \ + m->gm_mech.gm_compat->gmc_ ## name = NULL; \ +} while (0) + +/* + * + */ +static int +add_builtin(gssapi_mech_interface mech) +{ + struct _gss_mech_switch *m; + OM_uint32 minor_status; + + /* not registering any mech is ok */ + if (mech == NULL) + return 0; + + m = calloc(1, sizeof(*m)); + if (m == NULL) + return ENOMEM; + m->gm_so = NULL; + m->gm_mech = *mech; + _gss_intern_oid(&minor_status, &mech->gm_mech_oid, &m->gm_mech_oid); + if (minor_status) { + free(m); + return minor_status; + } + + if (gss_add_oid_set_member(&minor_status, &m->gm_mech.gm_mech_oid, + &_gss_mech_oids) != GSS_S_COMPLETE) { + free(m); + return ENOMEM; + } + + /* pick up the oid sets of names */ + + if (m->gm_mech.gm_inquire_names_for_mech) + (*m->gm_mech.gm_inquire_names_for_mech)(&minor_status, + &m->gm_mech.gm_mech_oid, &m->gm_name_types); + + if (m->gm_name_types == NULL && + gss_create_empty_oid_set(&minor_status, + &m->gm_name_types) != GSS_S_COMPLETE) { + free(m); + return ENOMEM; + } + + HEIM_TAILQ_INSERT_TAIL(&_gss_mechs, m, gm_link); + return 0; +} + +static void +init_mech_switch_list(void *p) +{ + struct _gss_mech_switch_list *mechs = p; + + HEIM_TAILQ_INIT(mechs); +} + +/* + * Load the mechanisms file (/etc/gss/mech). + */ +void +_gss_load_mech(void) +{ + OM_uint32 major_status, minor_status; + static heim_base_once_t once = HEIM_BASE_ONCE_INIT; +#ifdef HAVE_DLOPEN + FILE *fp; + char buf[256]; + char *p; + char *name, *oid, *lib, *kobj; + struct _gss_mech_switch *m; + void *so; + gss_OID mech_oid; + int found; + const char *conf = secure_getenv("GSS_MECH_CONFIG"); +#endif + + heim_base_once_f(&once, &_gss_mechs, init_mech_switch_list); + + HEIMDAL_MUTEX_lock(&_gss_mech_mutex); + + if (!HEIM_TAILQ_EMPTY(&_gss_mechs)) { + HEIMDAL_MUTEX_unlock(&_gss_mech_mutex); + return; + } + + major_status = gss_create_empty_oid_set(&minor_status, + &_gss_mech_oids); + if (major_status) { + HEIMDAL_MUTEX_unlock(&_gss_mech_mutex); + return; + } + + if (add_builtin(__gss_krb5_initialize())) + _gss_mg_log(1, "Out of memory while adding builtin Kerberos GSS " + "mechanism to the GSS mechanism switch"); + if (add_builtin(__gss_spnego_initialize())) + _gss_mg_log(1, "Out of memory while adding builtin SPNEGO " + "mechanism to the GSS mechanism switch"); + if (add_builtin(__gss_ntlm_initialize())) + _gss_mg_log(1, "Out of memory while adding builtin NTLM " + "mechanism to the GSS mechanism switch"); + +#ifdef HAVE_DLOPEN + fp = fopen(conf ? conf : _PATH_GSS_MECH, "r"); + if (!fp) + goto out; + rk_cloexec_file(fp); + + while (fgets(buf, sizeof(buf), fp)) { + _gss_mo_init *mi; + + if (*buf == '#') + continue; + p = buf; + name = strsep(&p, "\t\n "); + if (p) while (isspace((unsigned char)*p)) p++; + oid = strsep(&p, "\t\n "); + if (p) while (isspace((unsigned char)*p)) p++; + lib = strsep(&p, "\t\n "); + if (p) while (isspace((unsigned char)*p)) p++; + kobj = strsep(&p, "\t\n "); + if (!name || !oid || !lib || !kobj) + continue; + + if (_gss_string_to_oid(oid, &mech_oid)) + continue; + + /* + * Check for duplicates, already loaded mechs. + */ + found = 0; + HEIM_TAILQ_FOREACH(m, &_gss_mechs, gm_link) { + if (gss_oid_equal(&m->gm_mech.gm_mech_oid, mech_oid)) { + found = 1; + break; + } + } + if (found) + continue; + + so = dlopen(lib, RTLD_LAZY | RTLD_LOCAL | RTLD_GROUP); + if (so == NULL) { + _gss_mg_log(1, "dlopen: %s\n", dlerror()); + goto bad; + } + + m = calloc(1, sizeof(*m)); + if (m == NULL) + goto bad; + + m->gm_so = so; + m->gm_mech_oid = mech_oid; + m->gm_mech.gm_name = strdup(name); + m->gm_mech.gm_mech_oid = *mech_oid; + m->gm_mech.gm_flags = 0; + m->gm_mech.gm_compat = calloc(1, sizeof(struct gss_mech_compat_desc_struct)); + if (m->gm_mech.gm_compat == NULL) + goto bad; + + major_status = gss_add_oid_set_member(&minor_status, + &m->gm_mech.gm_mech_oid, &_gss_mech_oids); + if (GSS_ERROR(major_status)) + goto bad; + + SYM(acquire_cred); + SYM(release_cred); + SYM(init_sec_context); + SYM(accept_sec_context); + SYM(process_context_token); + SYM(delete_sec_context); + SYM(context_time); + SYM(get_mic); + SYM(verify_mic); + SYM(wrap); + SYM(unwrap); + OPTSYM(display_status); + OPTSYM(indicate_mechs); + SYM(compare_name); + SYM(display_name); + SYM(import_name); + SYM(export_name); + SYM(release_name); + OPTSYM(inquire_cred); + SYM(inquire_context); + SYM(wrap_size_limit); + OPTSYM(add_cred); + OPTSYM(inquire_cred_by_mech); + SYM(export_sec_context); + SYM(import_sec_context); + OPTSYM(inquire_names_for_mech); + OPTSYM(inquire_mechs_for_name); + SYM(canonicalize_name); + SYM(duplicate_name); + OPTSYM(inquire_cred_by_oid); + OPTSYM(inquire_sec_context_by_oid); + OPTSYM(set_sec_context_option); + OPTSPISYM(set_cred_option); + OPTSYM(pseudo_random); + OPTSYM(wrap_iov); + OPTSYM(unwrap_iov); + OPTSYM(wrap_iov_length); + OPTSYM(store_cred); + OPTSYM(export_cred); + OPTSYM(import_cred); + OPTSYM(acquire_cred_from); + OPTSYM(acquire_cred_impersonate_name); +#if 0 + OPTSYM(iter_creds); + OPTSYM(destroy_cred); + OPTSYM(cred_hold); + OPTSYM(cred_unhold); + OPTSYM(cred_label_get); + OPTSYM(cred_label_set); +#endif + OPTSYM(display_name_ext); + OPTSYM(inquire_name); + OPTSYM(get_name_attribute); + OPTSYM(set_name_attribute); + OPTSYM(delete_name_attribute); + OPTSYM(export_name_composite); + OPTSYM(localname); + OPTSYM(duplicate_cred); + OPTSYM(add_cred_from); + OPTSYM(store_cred_into); + OPTSPISYM(authorize_localname); + OPTSPISPISYM(query_mechanism_info); + OPTSPISPISYM(query_meta_data); + OPTSPISPISYM(exchange_meta_data); + + mi = (_gss_mo_init *)dlsym(so, "gss_mo_init"); + if (mi != NULL) { + major_status = mi(&minor_status, mech_oid, + &m->gm_mech.gm_mo, &m->gm_mech.gm_mo_num); + if (GSS_ERROR(major_status)) + goto bad; + } else { + /* API-as-SPI compatibility */ + COMPATSYM(inquire_saslname_for_mech); + COMPATSYM(inquire_mech_for_saslname); + COMPATSYM(inquire_attrs_for_mech); + COMPATSPISYM(acquire_cred_with_password); + } + + /* pick up the oid sets of names */ + + if (m->gm_mech.gm_inquire_names_for_mech) + (*m->gm_mech.gm_inquire_names_for_mech)(&minor_status, + &m->gm_mech.gm_mech_oid, &m->gm_name_types); + + if (m->gm_name_types == NULL) + gss_create_empty_oid_set(&minor_status, &m->gm_name_types); + + HEIM_TAILQ_INSERT_TAIL(&_gss_mechs, m, gm_link); + continue; + + bad: + if (m != NULL) { + free(m->gm_mech.gm_compat); + /* do not free OID, it has been interned */ + free((char *)m->gm_mech.gm_name); + free(m); + } + if (so != NULL) + dlclose(so); + continue; + } + fclose(fp); + +out: + +#endif + if (add_builtin(__gss_sanon_initialize())) + _gss_mg_log(1, "Out of memory while adding builtin SANON " + "mechanism to the GSS mechanism switch"); + HEIMDAL_MUTEX_unlock(&_gss_mech_mutex); +} + +gssapi_mech_interface +__gss_get_mechanism(gss_const_OID mech) +{ + struct _gss_mech_switch *m; + + _gss_load_mech(); + HEIM_TAILQ_FOREACH(m, &_gss_mechs, gm_link) { + if (gss_oid_equal(&m->gm_mech.gm_mech_oid, mech)) + return &m->gm_mech; + } + return NULL; +} + +gss_OID +_gss_mg_support_mechanism(gss_const_OID mech) +{ + struct _gss_mech_switch *m; + + _gss_load_mech(); + HEIM_TAILQ_FOREACH(m, &_gss_mechs, gm_link) { + if (gss_oid_equal(&m->gm_mech.gm_mech_oid, mech)) + return m->gm_mech_oid; + } + return NULL; +} + +enum mech_name_match { + MATCH_NONE = 0, + MATCH_COMPLETE, + MATCH_PARTIAL +}; + +static enum mech_name_match +match_mech_name(const char *gm_mech_name, + const char *name, + size_t namelen) +{ + if (gm_mech_name == NULL) + return MATCH_NONE; + else if (strcasecmp(gm_mech_name, name) == 0) + return MATCH_COMPLETE; + else if (strncasecmp(gm_mech_name, name, namelen) == 0) + return MATCH_PARTIAL; + else + return MATCH_NONE; +} + +/* + * Return an OID for a built-in or dynamically loaded mechanism. For + * API compatibility with previous versions, we treat "Kerberos 5" + * as an alias for "krb5". Unique partial matches are supported. + */ +GSSAPI_LIB_FUNCTION gss_OID GSSAPI_CALLCONV +gss_name_to_oid(const char *name) +{ + struct _gss_mech_switch *m, *partial = NULL; + gss_OID oid = GSS_C_NO_OID; + size_t namelen = strlen(name); + + if (isdigit(name[0]) && _gss_string_to_oid(name, &oid) == 0) + return oid; + + _gss_load_mech(); + HEIM_TAILQ_FOREACH(m, &_gss_mechs, gm_link) { + enum mech_name_match match; + + match = match_mech_name(m->gm_mech.gm_name, name, namelen); + if (match == MATCH_NONE && + gss_oid_equal(m->gm_mech_oid, GSS_KRB5_MECHANISM)) + match = match_mech_name("Kerberos 5", name, namelen); + + if (match == MATCH_COMPLETE) + return m->gm_mech_oid; + else if (match == MATCH_PARTIAL) { + if (partial) + return NULL; + else + partial = m; + } + } + + if (partial) + return partial->gm_mech_oid; + + return NULL; +} + +GSSAPI_LIB_FUNCTION const char * GSSAPI_LIB_CALL +gss_oid_to_name(gss_const_OID oid) +{ + struct _gss_mech_switch *m; + + _gss_load_mech(); + HEIM_TAILQ_FOREACH(m, &_gss_mechs, gm_link) { + if (gss_oid_equal(m->gm_mech_oid, oid)) + return m->gm_mech.gm_name; + } + + return NULL; +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_mo.c b/third_party/heimdal/lib/gssapi/mech/gss_mo.c new file mode 100644 index 0000000..b6ae282 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_mo.c @@ -0,0 +1,636 @@ +/* + * Copyright (c) 2010 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Portions Copyright (c) 2010 Apple Inc. All rights reserved. + * Portions Copyright (c) 2010 PADL Software Pty Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "mech_locl.h" + +#include <crypto-headers.h> + +static int +get_option_def(int def, gss_const_OID mech, gss_mo_desc *mo, gss_buffer_t value) +{ + return def; +} + +int +_gss_mo_get_option_1(gss_const_OID mech, gss_mo_desc *mo, gss_buffer_t value) +{ + return get_option_def(1, mech, mo, value); +} + +int +_gss_mo_get_option_0(gss_const_OID mech, gss_mo_desc *mo, gss_buffer_t value) +{ + return get_option_def(0, mech, mo, value); +} + +int +_gss_mo_get_ctx_as_string(gss_const_OID mech, gss_mo_desc *mo, gss_buffer_t value) +{ + if (value) { + value->value = strdup((char *)mo->ctx); + if (value->value == NULL) + return GSS_S_FAILURE; + value->length = strlen((char *)mo->ctx); + } + return GSS_S_COMPLETE; +} + +GSSAPI_LIB_FUNCTION int GSSAPI_LIB_CALL +gss_mo_set(gss_const_OID mech, gss_const_OID option, + int enable, gss_buffer_t value) +{ + gssapi_mech_interface m; + size_t n; + + if ((m = __gss_get_mechanism(mech)) == NULL) + return GSS_S_BAD_MECH; + + for (n = 0; n < m->gm_mo_num; n++) + if (gss_oid_equal(option, m->gm_mo[n].option) && m->gm_mo[n].set) + return m->gm_mo[n].set(mech, &m->gm_mo[n], enable, value); + + return GSS_S_UNAVAILABLE; +} + +GSSAPI_LIB_FUNCTION int GSSAPI_LIB_CALL +gss_mo_get(gss_const_OID mech, gss_const_OID option, gss_buffer_t value) +{ + gssapi_mech_interface m; + size_t n; + + _mg_buffer_zero(value); + + if ((m = __gss_get_mechanism(mech)) == NULL) + return GSS_S_BAD_MECH; + + for (n = 0; n < m->gm_mo_num; n++) + if (gss_oid_equal(option, m->gm_mo[n].option) && m->gm_mo[n].get) + return m->gm_mo[n].get(mech, &m->gm_mo[n], value); + + return GSS_S_UNAVAILABLE; +} + +static void +add_all_mo(gssapi_mech_interface m, gss_OID_set *options, OM_uint32 mask) +{ + OM_uint32 minor; + size_t n; + + for (n = 0; n < m->gm_mo_num; n++) + if ((m->gm_mo[n].flags & mask) == mask) + gss_add_oid_set_member(&minor, m->gm_mo[n].option, options); +} + +GSSAPI_LIB_FUNCTION void GSSAPI_LIB_CALL +gss_mo_list(gss_const_OID mech, gss_OID_set *options) +{ + gssapi_mech_interface m; + OM_uint32 major, minor; + + if (options == NULL) + return; + + *options = GSS_C_NO_OID_SET; + + if ((m = __gss_get_mechanism(mech)) == NULL) + return; + + major = gss_create_empty_oid_set(&minor, options); + if (major != GSS_S_COMPLETE) + return; + + add_all_mo(m, options, 0); +} + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_mo_name(gss_const_OID mech, gss_const_OID option, gss_buffer_t name) +{ + gssapi_mech_interface m; + size_t n; + + if (name == NULL) + return GSS_S_BAD_NAME; + + if ((m = __gss_get_mechanism(mech)) == NULL) + return GSS_S_BAD_MECH; + + for (n = 0; n < m->gm_mo_num; n++) { + if (gss_oid_equal(option, m->gm_mo[n].option)) { + /* + * If there is no name, its because its a GSS_C_MA and + * there is already a table for that. + */ + if (m->gm_mo[n].name) { + name->value = strdup(m->gm_mo[n].name); + if (name->value == NULL) + return GSS_S_BAD_NAME; + name->length = strlen(m->gm_mo[n].name); + return GSS_S_COMPLETE; + } else { + OM_uint32 junk; + return gss_display_mech_attr(&junk, option, + NULL, name, NULL); + } + } + } + return GSS_S_BAD_NAME; +} + +/* + * Helper function to allow NULL name + */ + +static OM_uint32 +mo_value(const gss_const_OID mech, gss_const_OID option, gss_buffer_t name) +{ + if (name == NULL) + return GSS_S_COMPLETE; + + return gss_mo_get(mech, option, name); +} + +/* code derived from draft-ietf-cat-sasl-gssapi-01 */ +static char basis_32[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; + +static OM_uint32 +make_sasl_name(OM_uint32 *minor, const gss_OID mech, char sasl_name[16]) +{ + EVP_MD_CTX *ctx; + char *p = sasl_name; + u_char hdr[2], hash[20], *h = hash; + + if (mech->length > 127) + return GSS_S_BAD_MECH; + + hdr[0] = 0x06; + hdr[1] = mech->length; + + ctx = EVP_MD_CTX_create(); + EVP_DigestInit_ex(ctx, EVP_sha1(), NULL); + EVP_DigestUpdate(ctx, hdr, 2); + EVP_DigestUpdate(ctx, mech->elements, mech->length); + EVP_DigestFinal_ex(ctx, hash, NULL); + EVP_MD_CTX_destroy(ctx); + + memcpy(p, "GS2-", 4); + p += 4; + + *p++ = basis_32[(h[0] >> 3)]; + *p++ = basis_32[((h[0] & 7) << 2) | (h[1] >> 6)]; + *p++ = basis_32[(h[1] & 0x3f) >> 1]; + *p++ = basis_32[((h[1] & 1) << 4) | (h[2] >> 4)]; + *p++ = basis_32[((h[2] & 0xf) << 1) | (h[3] >> 7)]; + *p++ = basis_32[(h[3] & 0x7f) >> 2]; + *p++ = basis_32[((h[3] & 3) << 3) | (h[4] >> 5)]; + *p++ = basis_32[(h[4] & 0x1f)]; + *p++ = basis_32[(h[5] >> 3)]; + *p++ = basis_32[((h[5] & 7) << 2) | (h[6] >> 6)]; + *p++ = basis_32[(h[6] & 0x3f) >> 1]; + + *p = '\0'; + + return GSS_S_COMPLETE; +} + +/* + * gss_inquire_saslname_for_mech() wrapper that uses MIT SPI + */ +static OM_uint32 +inquire_saslname_for_mech_compat(OM_uint32 *minor, + const gss_OID desired_mech, + gss_buffer_t sasl_mech_name, + gss_buffer_t mech_name, + gss_buffer_t mech_description) +{ + struct gss_mech_compat_desc_struct *gmc; + gssapi_mech_interface m; + OM_uint32 major; + + m = __gss_get_mechanism(desired_mech); + if (m == NULL) + return GSS_S_BAD_MECH; + + gmc = m->gm_compat; + + if (gmc != NULL && gmc->gmc_inquire_saslname_for_mech != NULL) { + major = gmc->gmc_inquire_saslname_for_mech(minor, + desired_mech, + sasl_mech_name, + mech_name, + mech_description); + } else { + major = GSS_S_UNAVAILABLE; + } + + return major; +} + +/** + * Returns different protocol names and description of the mechanism. + * + * @param minor_status minor status code + * @param desired_mech mech list query + * @param sasl_mech_name SASL GS2 protocol name + * @param mech_name gssapi protocol name + * @param mech_description description of gssapi mech + * + * @return returns GSS_S_COMPLETE or a error code. + * + * @ingroup gssapi + */ + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_inquire_saslname_for_mech(OM_uint32 *minor_status, + const gss_OID desired_mech, + gss_buffer_t sasl_mech_name, + gss_buffer_t mech_name, + gss_buffer_t mech_description) +{ + OM_uint32 major; + + _mg_buffer_zero(sasl_mech_name); + _mg_buffer_zero(mech_name); + _mg_buffer_zero(mech_description); + + if (minor_status) + *minor_status = 0; + + if (desired_mech == NULL) + return GSS_S_BAD_MECH; + + major = mo_value(desired_mech, GSS_C_MA_SASL_MECH_NAME, sasl_mech_name); + if (major == GSS_S_COMPLETE) { + /* Native SPI */ + major = mo_value(desired_mech, GSS_C_MA_MECH_NAME, mech_name); + if (GSS_ERROR(major)) + return major; + + major = mo_value(desired_mech, GSS_C_MA_MECH_DESCRIPTION, mech_description); + if (GSS_ERROR(major)) + return major; + } + + if (GSS_ERROR(major)) { + /* API-as-SPI compatibility */ + major = inquire_saslname_for_mech_compat(minor_status, + desired_mech, + sasl_mech_name, + mech_name, + mech_description); + } + + if (GSS_ERROR(major)) { + /* Algorithmically dervied SASL mechanism name */ + char buf[16]; + gss_buffer_desc tmp = { sizeof(buf) - 1, buf }; + + major = make_sasl_name(minor_status, desired_mech, buf); + if (GSS_ERROR(major)) + return major; + + major = _gss_copy_buffer(minor_status, &tmp, sasl_mech_name); + if (GSS_ERROR(major)) + return major; + } + + return major; +} + +/** + * Find a mech for a sasl name + * + * @param minor_status minor status code + * @param sasl_mech_name + * @param mech_type + * + * @return returns GSS_S_COMPLETE or an error code. + */ + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_inquire_mech_for_saslname(OM_uint32 *minor_status, + const gss_buffer_t sasl_mech_name, + gss_OID *mech_type) +{ + struct _gss_mech_switch *m; + gss_buffer_desc name; + OM_uint32 major, junk; + char buf[16]; + + _gss_load_mech(); + + *mech_type = NULL; + + HEIM_TAILQ_FOREACH(m, &_gss_mechs, gm_link) { + struct gss_mech_compat_desc_struct *gmc; + + /* Native SPI */ + major = mo_value(m->gm_mech_oid, GSS_C_MA_SASL_MECH_NAME, &name); + if (major == GSS_S_COMPLETE && + name.length == sasl_mech_name->length && + memcmp(name.value, sasl_mech_name->value, name.length) == 0) { + gss_release_buffer(&junk, &name); + *mech_type = m->gm_mech_oid; + return GSS_S_COMPLETE; + } + gss_release_buffer(&junk, &name); + + if (GSS_ERROR(major)) { + /* API-as-SPI compatibility */ + gmc = m->gm_mech.gm_compat; + if (gmc && gmc->gmc_inquire_mech_for_saslname) { + major = gmc->gmc_inquire_mech_for_saslname(minor_status, + sasl_mech_name, + mech_type); + if (major == GSS_S_COMPLETE) + return GSS_S_COMPLETE; + } + } + + if (GSS_ERROR(major)) { + /* Algorithmically dervied SASL mechanism name */ + if (sasl_mech_name->length == 16 && + make_sasl_name(minor_status, m->gm_mech_oid, buf) == GSS_S_COMPLETE && + memcmp(buf, sasl_mech_name->value, 16) == 0) { + *mech_type = m->gm_mech_oid; + return GSS_S_COMPLETE; + } + } + } + + return GSS_S_BAD_MECH; +} + +/* + * Test mechanism against indicated attributes using both Heimdal and + * MIT SPIs. + */ +static int +test_mech_attrs(gssapi_mech_interface mi, + gss_const_OID_set mech_attrs, + gss_const_OID_set against_attrs, + int except) +{ + size_t n, m; + int eq = 0; + + if (against_attrs == GSS_C_NO_OID_SET) + return 1; + + for (n = 0; n < against_attrs->count; n++) { + for (m = 0; m < mi->gm_mo_num; m++) { + eq = gss_oid_equal(mi->gm_mo[m].option, + &against_attrs->elements[n]); + if (eq) + break; + } + if (mech_attrs != GSS_C_NO_OID_SET) { + for (m = 0; m < mech_attrs->count; m++) { + eq = gss_oid_equal(&mech_attrs->elements[m], + &against_attrs->elements[n]); + if (eq) + break; + } + } + if (!eq ^ except) + return 0; + } + + return 1; +} + +/** + * Return set of mechanism that fullfill the criteria + * + * @param minor_status minor status code + * @param desired_mech_attrs + * @param except_mech_attrs + * @param critical_mech_attrs + * @param mechs returned mechs, free with gss_release_oid_set(). + * + * @return returns GSS_S_COMPLETE or an error code. + */ + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_indicate_mechs_by_attrs(OM_uint32 * minor_status, + gss_const_OID_set desired_mech_attrs, + gss_const_OID_set except_mech_attrs, + gss_const_OID_set critical_mech_attrs, + gss_OID_set *mechs) +{ + struct _gss_mech_switch *ms; + gss_OID_set mech_attrs = GSS_C_NO_OID_SET; + gss_OID_set known_mech_attrs = GSS_C_NO_OID_SET; + OM_uint32 major; + + major = gss_create_empty_oid_set(minor_status, mechs); + if (GSS_ERROR(major)) + return major; + + _gss_load_mech(); + + HEIM_TAILQ_FOREACH(ms, &_gss_mechs, gm_link) { + gssapi_mech_interface mi = &ms->gm_mech; + struct gss_mech_compat_desc_struct *gmc = mi->gm_compat; + OM_uint32 tmp; + + if (gmc && gmc->gmc_inquire_attrs_for_mech) { + major = gmc->gmc_inquire_attrs_for_mech(minor_status, + &mi->gm_mech_oid, + &mech_attrs, + &known_mech_attrs); + if (GSS_ERROR(major)) + continue; + } + + /* + * Test mechanism supports all of desired_mech_attrs; + * none of except_mech_attrs; + * and knows of all critical_mech_attrs. + */ + if (test_mech_attrs(mi, mech_attrs, desired_mech_attrs, 0) && + test_mech_attrs(mi, mech_attrs, except_mech_attrs, 1) && + test_mech_attrs(mi, known_mech_attrs, critical_mech_attrs, 0)) { + major = gss_add_oid_set_member(minor_status, &mi->gm_mech_oid, mechs); + } + + gss_release_oid_set(&tmp, &mech_attrs); + gss_release_oid_set(&tmp, &known_mech_attrs); + + if (GSS_ERROR(major)) + break; + } + + return major; +} + +/** + * List support attributes for a mech and/or all mechanisms. + * + * @param minor_status minor status code + * @param mech given together with mech_attr will return the list of + * attributes for mechanism, can optionally be GSS_C_NO_OID. + * @param mech_attr see mech parameter, can optionally be NULL, + * release with gss_release_oid_set(). + * @param known_mech_attrs all attributes for mechanisms supported, + * release with gss_release_oid_set(). + * + * @ingroup gssapi + */ + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_inquire_attrs_for_mech(OM_uint32 * minor_status, + gss_const_OID mech, + gss_OID_set *mech_attr, + gss_OID_set *known_mech_attrs) +{ + OM_uint32 major, junk; + + if (known_mech_attrs) + *known_mech_attrs = GSS_C_NO_OID_SET; + + if (mech_attr && mech) { + gssapi_mech_interface m; + struct gss_mech_compat_desc_struct *gmc; + + if ((m = __gss_get_mechanism(mech)) == NULL) { + *minor_status = 0; + return GSS_S_BAD_MECH; + } + + gmc = m->gm_compat; + + if (gmc && gmc->gmc_inquire_attrs_for_mech) { + major = gmc->gmc_inquire_attrs_for_mech(minor_status, + mech, + mech_attr, + known_mech_attrs); + } else { + major = gss_create_empty_oid_set(minor_status, mech_attr); + if (major == GSS_S_COMPLETE) + add_all_mo(m, mech_attr, GSS_MO_MA); + } + if (GSS_ERROR(major)) + return major; + } + + if (known_mech_attrs) { + struct _gss_mech_switch *m; + + if (*known_mech_attrs == GSS_C_NO_OID_SET) { + major = gss_create_empty_oid_set(minor_status, known_mech_attrs); + if (GSS_ERROR(major)) { + if (mech_attr) + gss_release_oid_set(&junk, mech_attr); + return major; + } + } + + _gss_load_mech(); + + HEIM_TAILQ_FOREACH(m, &_gss_mechs, gm_link) + add_all_mo(&m->gm_mech, known_mech_attrs, GSS_MO_MA); + } + + + return GSS_S_COMPLETE; +} + +/** + * Return names and descriptions of mech attributes + * + * @param minor_status minor status code + * @param mech_attr + * @param name + * @param short_desc + * @param long_desc + * + * @return returns GSS_S_COMPLETE or an error code. + */ + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_display_mech_attr(OM_uint32 * minor_status, + gss_const_OID mech_attr, + gss_buffer_t name, + gss_buffer_t short_desc, + gss_buffer_t long_desc) +{ + struct _gss_oid_name_table *ma = NULL; + OM_uint32 major; + size_t n; + + _mg_buffer_zero(name); + _mg_buffer_zero(short_desc); + _mg_buffer_zero(long_desc); + + if (minor_status) + *minor_status = 0; + + for (n = 0; ma == NULL && _gss_ont_ma[n].oid; n++) + if (gss_oid_equal(mech_attr, _gss_ont_ma[n].oid)) + ma = &_gss_ont_ma[n]; + + if (ma == NULL) + return GSS_S_BAD_MECH_ATTR; + + if (name) { + gss_buffer_desc bd; + bd.value = rk_UNCONST(ma->name); + bd.length = strlen(ma->name); + major = _gss_copy_buffer(minor_status, &bd, name); + if (major != GSS_S_COMPLETE) + return major; + } + + if (short_desc) { + gss_buffer_desc bd; + bd.value = rk_UNCONST(ma->short_desc); + bd.length = strlen(ma->short_desc); + major = _gss_copy_buffer(minor_status, &bd, short_desc); + if (major != GSS_S_COMPLETE) + return major; + } + + if (long_desc) { + gss_buffer_desc bd; + bd.value = rk_UNCONST(ma->long_desc); + bd.length = strlen(ma->long_desc); + major = _gss_copy_buffer(minor_status, &bd, long_desc); + if (major != GSS_S_COMPLETE) + return major; + } + + return GSS_S_COMPLETE; +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_names.c b/third_party/heimdal/lib/gssapi/mech/gss_names.c new file mode 100644 index 0000000..729e7f2 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_names.c @@ -0,0 +1,262 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Portions Copyright (c) 2009 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_names.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" + +gss_name_t +_gss_mg_get_underlying_mech_name(gss_name_t name, + gss_const_OID mech) +{ + struct _gss_name *n = (struct _gss_name *)name; + struct _gss_mechanism_name *mn; + + HEIM_TAILQ_FOREACH(mn, &n->gn_mn, gmn_link) { + if (gss_oid_equal(mech, mn->gmn_mech_oid)) + return mn->gmn_name; + } + return GSS_C_NO_NAME; +} + +OM_uint32 +_gss_find_mn(OM_uint32 *minor_status, + struct _gss_name *name, + gss_const_OID mech, + struct _gss_mechanism_name ** output_mn) +{ + OM_uint32 major_status; + gssapi_mech_interface m; + struct _gss_mechanism_name *mn; + + *output_mn = NULL; + + /* null names are ok, some mechs might not have names */ + if (name == NULL) + return GSS_S_COMPLETE; + + HEIM_TAILQ_FOREACH(mn, &name->gn_mn, gmn_link) { + if (gss_oid_equal(mech, mn->gmn_mech_oid)) + break; + } + + if (!mn) { + /* + * If this name is canonical (i.e. there is only an + * MN but it is from a different mech), give up now. + */ + if (!name->gn_value.value) + return GSS_S_BAD_NAME; + + m = __gss_get_mechanism(mech); + if (!m || !m->gm_import_name) + return (GSS_S_BAD_MECH); + + mn = malloc(sizeof(struct _gss_mechanism_name)); + if (!mn) + return GSS_S_FAILURE; + + major_status = m->gm_import_name(minor_status, + &name->gn_value, + name->gn_type, + &mn->gmn_name); + if (major_status != GSS_S_COMPLETE) { + _gss_mg_error(m, *minor_status); + free(mn); + return major_status; + } + + mn->gmn_mech = m; + mn->gmn_mech_oid = &m->gm_mech_oid; + HEIM_TAILQ_INSERT_TAIL(&name->gn_mn, mn, gmn_link); + } + *output_mn = mn; + return 0; +} + + +/* + * Make a name from an MN. + */ +struct _gss_name * +_gss_create_name(gss_name_t new_mn, + struct gssapi_mech_interface_desc *m) +{ + struct _gss_name *name; + struct _gss_mechanism_name *mn; + + name = calloc(1, sizeof(struct _gss_name)); + if (!name) + return (0); + + HEIM_TAILQ_INIT(&name->gn_mn); + + if (new_mn) { + mn = malloc(sizeof(struct _gss_mechanism_name)); + if (!mn) { + free(name); + return (0); + } + + mn->gmn_mech = m; + mn->gmn_mech_oid = &m->gm_mech_oid; + mn->gmn_name = new_mn; + HEIM_TAILQ_INSERT_TAIL(&name->gn_mn, mn, gmn_link); + } + + return (name); +} + +/* + * + */ + +void +_gss_mg_release_name(struct _gss_name *name) +{ + OM_uint32 junk; + struct _gss_mechanism_name *mn, *next; + + gss_release_oid(&junk, &name->gn_type); + + HEIM_TAILQ_FOREACH_SAFE(mn, &name->gn_mn, gmn_link, next) { + HEIM_TAILQ_REMOVE(&name->gn_mn, mn, gmn_link); + mn->gmn_mech->gm_release_name(&junk, &mn->gmn_name); + free(mn); + } + gss_release_buffer(&junk, &name->gn_value); + free(name); +} + +void +_gss_mg_check_name(gss_const_name_t name) +{ + if (name == NULL) return; +} + +/* + * + */ + +OM_uint32 +_gss_mech_import_name(OM_uint32 * minor_status, + gss_const_OID mech, + struct _gss_name_type *names, + const gss_buffer_t input_name_buffer, + gss_const_OID input_name_type, + gss_name_t *output_name) +{ + struct _gss_name_type *name; + gss_buffer_t name_buffer = input_name_buffer; + gss_buffer_desc export_name; + + *minor_status = 0; + + if (output_name == NULL) + return GSS_S_CALL_INACCESSIBLE_WRITE; + + *output_name = GSS_C_NO_NAME; + + /* + * If its a exported name, strip of the mech glue. + */ + + if (gss_oid_equal(input_name_type, GSS_C_NT_EXPORT_NAME)) { + unsigned char *p; + uint32_t length; + + if (name_buffer->length < 10 + mech->length) + return GSS_S_BAD_NAME; + + /* TOK, MECH_OID_LEN, DER(MECH_OID), NAME_LEN, NAME */ + + p = name_buffer->value; + + if (memcmp(&p[0], "\x04\x01\x00", 3) != 0 || + p[3] != mech->length + 2 || + p[4] != 0x06 || + p[5] != mech->length || + memcmp(&p[6], mech->elements, mech->length) != 0) + return GSS_S_BAD_NAME; + + p += 6 + mech->length; + + length = p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]; + p += 4; + + if (length > name_buffer->length - 10 - mech->length) + return GSS_S_BAD_NAME; + + /* + * Point this to the mech specific name part, don't modifity + * orignal input_name_buffer. + */ + + export_name.length = length; + export_name.value = p; + + name_buffer = &export_name; + } + + for (name = names; name->gnt_parse != NULL; name++) { + if (gss_oid_equal(input_name_type, name->gnt_name_type) + || (name->gnt_name_type == GSS_C_NO_OID && input_name_type == GSS_C_NO_OID)) + return name->gnt_parse(minor_status, mech, name_buffer, + input_name_type, output_name); + } + + return GSS_S_BAD_NAMETYPE; +} + +OM_uint32 +_gss_mech_inquire_names_for_mech(OM_uint32 * minor_status, + struct _gss_name_type *names, + gss_OID_set *name_types) +{ + struct _gss_name_type *name; + OM_uint32 ret, junk; + + ret = gss_create_empty_oid_set(minor_status, name_types); + if (ret != GSS_S_COMPLETE) + return ret; + + for (name = names; name->gnt_parse != NULL; name++) { + if (name->gnt_name_type == GSS_C_NO_OID) + continue; + ret = gss_add_oid_set_member(minor_status, + name->gnt_name_type, + name_types); + if (ret != GSS_S_COMPLETE) + break; + } + + if (ret != GSS_S_COMPLETE) + gss_release_oid_set(&junk, name_types); + + return GSS_S_COMPLETE; +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_oid.c b/third_party/heimdal/lib/gssapi/mech/gss_oid.c new file mode 100644 index 0000000..10ec22d --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_oid.c @@ -0,0 +1,370 @@ +/* Generated file */ +#include "mech_locl.h" + +/* GSS_KRB5_COPY_CCACHE_X - 1.2.752.43.13.1 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_copy_ccache_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x01") }; + +/* GSS_KRB5_GET_TKT_FLAGS_X - 1.2.752.43.13.2 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_get_tkt_flags_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x02") }; + +/* GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_X - 1.2.752.43.13.3 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_extract_authz_data_from_sec_context_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x03") }; + +/* GSS_KRB5_COMPAT_DES3_MIC_X - 1.2.752.43.13.4 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_compat_des3_mic_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x04") }; + +/* GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_X - 1.2.752.43.13.5 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_register_acceptor_identity_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x05") }; + +/* GSS_KRB5_EXPORT_LUCID_CONTEXT_X - 1.2.752.43.13.6 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_export_lucid_context_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x06") }; + +/* GSS_KRB5_EXPORT_LUCID_CONTEXT_V1_X - 1.2.752.43.13.6.1 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_export_lucid_context_v1_x_oid_desc = { 7, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x06\x01") }; + +/* GSS_KRB5_SET_DNS_CANONICALIZE_X - 1.2.752.43.13.7 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_set_dns_canonicalize_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x07") }; + +/* GSS_KRB5_GET_SUBKEY_X - 1.2.752.43.13.8 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_get_subkey_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x08") }; + +/* GSS_KRB5_GET_INITIATOR_SUBKEY_X - 1.2.752.43.13.9 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_get_initiator_subkey_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x09") }; + +/* GSS_KRB5_GET_ACCEPTOR_SUBKEY_X - 1.2.752.43.13.10 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_get_acceptor_subkey_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0a") }; + +/* GSS_KRB5_SEND_TO_KDC_X - 1.2.752.43.13.11 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_send_to_kdc_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0b") }; + +/* GSS_KRB5_GET_AUTHTIME_X - 1.2.752.43.13.12 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_get_authtime_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0c") }; + +/* GSS_KRB5_GET_SERVICE_KEYBLOCK_X - 1.2.752.43.13.13 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_get_service_keyblock_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0d") }; + +/* GSS_KRB5_SET_ALLOWABLE_ENCTYPES_X - 1.2.752.43.13.14 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_set_allowable_enctypes_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0e") }; + +/* GSS_KRB5_SET_DEFAULT_REALM_X - 1.2.752.43.13.15 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_set_default_realm_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0f") }; + +/* GSS_KRB5_CCACHE_NAME_X - 1.2.752.43.13.16 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_ccache_name_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x10") }; + +/* GSS_KRB5_SET_TIME_OFFSET_X - 1.2.752.43.13.17 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_set_time_offset_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x11") }; + +/* GSS_KRB5_GET_TIME_OFFSET_X - 1.2.752.43.13.18 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_get_time_offset_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x12") }; + +/* GSS_KRB5_PLUGIN_REGISTER_X - 1.2.752.43.13.19 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_plugin_register_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x13") }; + +/* GSS_NTLM_GET_SESSION_KEY_X - 1.2.752.43.13.20 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_ntlm_get_session_key_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x14") }; + +/* GSS_C_NT_NTLM - 1.2.752.43.13.21 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_nt_ntlm_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x15") }; + +/* GSS_C_NT_DN - 1.2.752.43.13.22 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_nt_dn_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x16") }; + +/* GSS_KRB5_NT_PRINCIPAL_NAME_REFERRAL - 1.2.752.43.13.23 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_nt_principal_name_referral_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x17") }; + +/* GSS_C_NTLM_AVGUEST - 1.2.752.43.13.24 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ntlm_avguest_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x18") }; + +/* GSS_C_NTLM_V1 - 1.2.752.43.13.25 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ntlm_v1_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x19") }; + +/* GSS_C_NTLM_V2 - 1.2.752.43.13.26 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ntlm_v2_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x1a") }; + +/* GSS_C_NTLM_SESSION_KEY - 1.2.752.43.13.27 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ntlm_session_key_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x1b") }; + +/* GSS_C_NTLM_FORCE_V1 - 1.2.752.43.13.28 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ntlm_force_v1_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x1c") }; + +/* GSS_KRB5_CRED_NO_CI_FLAGS_X - 1.2.752.43.13.29 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_cred_no_ci_flags_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x1d") }; + +/* GSS_KRB5_IMPORT_CRED_X - 1.2.752.43.13.30 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_import_cred_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x1e") }; + +/* GSS_KRB5_IMPORT_RFC4121_CONTEXT_X - 1.2.752.43.13.31 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_import_rfc4121_context_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x1f") }; + +/* GSS_C_MA_SASL_MECH_NAME - 1.2.752.43.13.100 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_sasl_mech_name_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x64") }; + +/* GSS_C_MA_MECH_NAME - 1.2.752.43.13.101 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_mech_name_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x65") }; + +/* GSS_C_MA_MECH_DESCRIPTION - 1.2.752.43.13.102 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_mech_description_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x66") }; + +/* GSS_SASL_DIGEST_MD5_MECHANISM - 1.2.752.43.14.1 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_sasl_digest_md5_mechanism_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0e\x01") }; + +/* GSS_NETLOGON_MECHANISM - 1.2.752.43.14.2 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_netlogon_mechanism_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0e\x02") }; + +/* GSS_NETLOGON_SET_SESSION_KEY_X - 1.2.752.43.14.3 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_netlogon_set_session_key_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0e\x03") }; + +/* GSS_NETLOGON_SET_SIGN_ALGORITHM_X - 1.2.752.43.14.4 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_netlogon_set_sign_algorithm_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0e\x04") }; + +/* GSS_NETLOGON_NT_NETBIOS_DNS_NAME - 1.2.752.43.14.5 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_netlogon_nt_netbios_dns_name_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0e\x05") }; + +/* GSS_C_INQ_WIN2K_PAC_X - 1.2.752.43.13.3.128 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_inq_win2k_pac_x_oid_desc = { 8, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x03\x81\x00") }; + +/* GSS_C_INQ_SSPI_SESSION_KEY - 1.2.840.113554.1.2.2.5.5 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_inq_sspi_session_key_oid_desc = { 11, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x05") }; + +/* GSS_C_INQ_NEGOEX_KEY - 1.2.840.113554.1.2.2.5.16 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_inq_negoex_key_oid_desc = { 11, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x10") }; + +/* GSS_C_INQ_NEGOEX_VERIFY_KEY - 1.2.840.113554.1.2.2.5.17 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_inq_negoex_verify_key_oid_desc = { 11, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x11") }; + +/* GSS_C_INQ_REQUIRE_MECHLIST_MIC - 1.3.6.1.4.1.7165.655.1.2 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_inq_require_mechlist_mic_oid_desc = { 11, rk_UNCONST("\x2b\x06\x01\x04\x01\xb7\x7d\x85\x0f\x01\x02") }; + +/* GSS_KRB5_MECHANISM - 1.2.840.113554.1.2.2 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_mechanism_oid_desc = { 9, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12\x01\x02\x02") }; + +/* GSS_NTLM_MECHANISM - 1.3.6.1.4.1.311.2.2.10 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_ntlm_mechanism_oid_desc = { 10, rk_UNCONST("\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x0a") }; + +/* GSS_SPNEGO_MECHANISM - 1.3.6.1.5.5.2 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_spnego_mechanism_oid_desc = { 6, rk_UNCONST("\x2b\x06\x01\x05\x05\x02") }; + +/* GSS_C_INQ_PEER_HAS_BUGGY_SPNEGO - 1.3.6.1.4.1.5322.19.6 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_inq_peer_has_buggy_spnego_oid_desc = { 9, rk_UNCONST("\x2b\x06\x01\x04\x01\xa9\x4a\x13\x06") }; + +/* GSS_C_NTLM_RESET_CRYPTO - 1.3.6.1.4.1.7165.655.1.3 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ntlm_reset_crypto_oid_desc = { 11, rk_UNCONST("\x2b\x06\x01\x04\x01\xb7\x7d\x85\x0f\x01\x03") }; + +/* GSS_NEGOEX_MECHANISM - 1.3.6.1.4.1.311.2.2.30 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_negoex_mechanism_oid_desc = { 10, rk_UNCONST("\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x1e") }; + +/* GSS_SANON_X25519_MECHANISM - 1.3.6.1.4.1.5322.26.1.110 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_sanon_x25519_mechanism_oid_desc = { 10, rk_UNCONST("\x2b\x06\x01\x04\x01\xa9\x4a\x1a\x01\x6e") }; + +/* GSS_C_MA_MECH_CONCRETE - 1.3.6.1.5.5.13.1 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_mech_concrete_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x01") }; + +/* GSS_C_MA_MECH_PSEUDO - 1.3.6.1.5.5.13.2 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_mech_pseudo_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x02") }; + +/* GSS_C_MA_MECH_COMPOSITE - 1.3.6.1.5.5.13.3 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_mech_composite_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x03") }; + +/* GSS_C_MA_MECH_NEGO - 1.3.6.1.5.5.13.4 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_mech_nego_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x04") }; + +/* GSS_C_MA_MECH_GLUE - 1.3.6.1.5.5.13.5 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_mech_glue_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x05") }; + +/* GSS_C_MA_NOT_MECH - 1.3.6.1.5.5.13.6 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_not_mech_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x06") }; + +/* GSS_C_MA_DEPRECATED - 1.3.6.1.5.5.13.7 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_deprecated_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x07") }; + +/* GSS_C_MA_NOT_DFLT_MECH - 1.3.6.1.5.5.13.8 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_not_dflt_mech_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x08") }; + +/* GSS_C_MA_ITOK_FRAMED - 1.3.6.1.5.5.13.9 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_itok_framed_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x09") }; + +/* GSS_C_MA_AUTH_INIT - 1.3.6.1.5.5.13.10 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_auth_init_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x0a") }; + +/* GSS_C_MA_AUTH_TARG - 1.3.6.1.5.5.13.11 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_auth_targ_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x0b") }; + +/* GSS_C_MA_AUTH_INIT_INIT - 1.3.6.1.5.5.13.12 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_auth_init_init_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x0c") }; + +/* GSS_C_MA_AUTH_TARG_INIT - 1.3.6.1.5.5.13.13 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_auth_targ_init_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x0d") }; + +/* GSS_C_MA_AUTH_INIT_ANON - 1.3.6.1.5.5.13.14 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_auth_init_anon_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x0e") }; + +/* GSS_C_MA_AUTH_TARG_ANON - 1.3.6.1.5.5.13.15 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_auth_targ_anon_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x0f") }; + +/* GSS_C_MA_DELEG_CRED - 1.3.6.1.5.5.13.16 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_deleg_cred_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x10") }; + +/* GSS_C_MA_INTEG_PROT - 1.3.6.1.5.5.13.17 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_integ_prot_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x11") }; + +/* GSS_C_MA_CONF_PROT - 1.3.6.1.5.5.13.18 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_conf_prot_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x12") }; + +/* GSS_C_MA_MIC - 1.3.6.1.5.5.13.19 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_mic_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x13") }; + +/* GSS_C_MA_WRAP - 1.3.6.1.5.5.13.20 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_wrap_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x14") }; + +/* GSS_C_MA_PROT_READY - 1.3.6.1.5.5.13.21 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_prot_ready_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x15") }; + +/* GSS_C_MA_REPLAY_DET - 1.3.6.1.5.5.13.22 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_replay_det_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x16") }; + +/* GSS_C_MA_OOS_DET - 1.3.6.1.5.5.13.23 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_oos_det_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x17") }; + +/* GSS_C_MA_CBINDINGS - 1.3.6.1.5.5.13.24 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_cbindings_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x18") }; + +/* GSS_C_MA_PFS - 1.3.6.1.5.5.13.25 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_pfs_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x19") }; + +/* GSS_C_MA_COMPRESS - 1.3.6.1.5.5.13.26 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_compress_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x1a") }; + +/* GSS_C_MA_CTX_TRANS - 1.3.6.1.5.5.13.27 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_ctx_trans_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x1b") }; + +/* GSS_C_MA_NEGOEX_AND_SPNEGO - 1.2.840.113554.1.2.2.5.18 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_negoex_and_spnego_oid_desc = { 11, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x12") }; + +struct _gss_oid_name_table _gss_ont_ma[] = { + { GSS_C_MA_AUTH_INIT, "GSS_C_MA_AUTH_INIT", "auth-init-princ", "" }, + { GSS_C_MA_AUTH_INIT_ANON, "GSS_C_MA_AUTH_INIT_ANON", "auth-init-princ-anon", "" }, + { GSS_C_MA_AUTH_INIT_INIT, "GSS_C_MA_AUTH_INIT_INIT", "auth-init-princ-initial", "" }, + { GSS_C_MA_AUTH_TARG, "GSS_C_MA_AUTH_TARG", "auth-targ-princ", "" }, + { GSS_C_MA_AUTH_TARG_ANON, "GSS_C_MA_AUTH_TARG_ANON", "auth-targ-princ-anon", "" }, + { GSS_C_MA_AUTH_TARG_INIT, "GSS_C_MA_AUTH_TARG_INIT", "auth-targ-princ-initial", "" }, + { GSS_C_MA_CBINDINGS, "GSS_C_MA_CBINDINGS", "channel-bindings", "" }, + { GSS_C_MA_COMPRESS, "GSS_C_MA_COMPRESS", "compress", "" }, + { GSS_C_MA_CONF_PROT, "GSS_C_MA_CONF_PROT", "conf-prot", "" }, + { GSS_C_MA_CTX_TRANS, "GSS_C_MA_CTX_TRANS", "context-transfer", "" }, + { GSS_C_MA_DELEG_CRED, "GSS_C_MA_DELEG_CRED", "deleg-cred", "" }, + { GSS_C_MA_DEPRECATED, "GSS_C_MA_DEPRECATED", "mech-deprecated", "" }, + { GSS_C_MA_INTEG_PROT, "GSS_C_MA_INTEG_PROT", "integ-prot", "" }, + { GSS_C_MA_ITOK_FRAMED, "GSS_C_MA_ITOK_FRAMED", "initial-is-framed", "" }, + { GSS_C_MA_MECH_COMPOSITE, "GSS_C_MA_MECH_COMPOSITE", "composite-mech", "" }, + { GSS_C_MA_MECH_CONCRETE, "GSS_C_MA_MECH_CONCRETE", "concrete-mech", "Indicates that a mech is neither a pseudo-mechanism nor a composite mechanism" }, + { GSS_C_MA_MECH_DESCRIPTION, "GSS_C_MA_MECH_DESCRIPTION", "Mech description", "The long description of the mechanism" }, + { GSS_C_MA_MECH_GLUE, "GSS_C_MA_MECH_GLUE", "mech-glue", "" }, + { GSS_C_MA_MECH_NAME, "GSS_C_MA_MECH_NAME", "GSS mech name", "The name of the GSS-API mechanism" }, + { GSS_C_MA_MECH_NEGO, "GSS_C_MA_MECH_NEGO", "mech-negotiation-mech", "" }, + { GSS_C_MA_MECH_PSEUDO, "GSS_C_MA_MECH_PSEUDO", "pseudo-mech", "" }, + { GSS_C_MA_MIC, "GSS_C_MA_MIC", "mic", "" }, + { GSS_C_MA_NEGOEX_AND_SPNEGO, "GSS_C_MA_NEGOEX_AND_SPNEGO", "negoex-and-spnego", "Indicates that a mechanism supports both NegoEx and SPNEGO" }, + { GSS_C_MA_NOT_DFLT_MECH, "GSS_C_MA_NOT_DFLT_MECH", "mech-not-default", "" }, + { GSS_C_MA_NOT_MECH, "GSS_C_MA_NOT_MECH", "not-mech", "" }, + { GSS_C_MA_OOS_DET, "GSS_C_MA_OOS_DET", "oos-detection", "" }, + { GSS_C_MA_PFS, "GSS_C_MA_PFS", "pfs", "" }, + { GSS_C_MA_PROT_READY, "GSS_C_MA_PROT_READY", "prot-ready", "" }, + { GSS_C_MA_REPLAY_DET, "GSS_C_MA_REPLAY_DET", "replay-detection", "" }, + { GSS_C_MA_SASL_MECH_NAME, "GSS_C_MA_SASL_MECH_NAME", "SASL mechanism name", "The name of the SASL mechanism" }, + { GSS_C_MA_WRAP, "GSS_C_MA_WRAP", "wrap", "" }, + { NULL, NULL, NULL, NULL } +}; + +struct _gss_oid_name_table _gss_ont_mech[] = { + { GSS_KRB5_MECHANISM, "GSS_KRB5_MECHANISM", "Kerberos 5", "Heimdal Kerberos 5 mechanism" }, + { GSS_NTLM_MECHANISM, "GSS_NTLM_MECHANISM", "NTLM", "Heimdal NTLM mechanism" }, + { GSS_SANON_X25519_MECHANISM, "GSS_SANON_X25519_MECHANISM", "SAnon-X25519", "Heimdal Simple Anonymous (X25519) mechanism" }, + { GSS_SPNEGO_MECHANISM, "GSS_SPNEGO_MECHANISM", "SPNEGO", "Heimdal SPNEGO mechanism" }, + { NULL, NULL, NULL, NULL } +}; + +gss_OID _gss_ot_internal[] = { + &__gss_krb5_copy_ccache_x_oid_desc, + &__gss_krb5_get_tkt_flags_x_oid_desc, + &__gss_krb5_extract_authz_data_from_sec_context_x_oid_desc, + &__gss_krb5_compat_des3_mic_x_oid_desc, + &__gss_krb5_register_acceptor_identity_x_oid_desc, + &__gss_krb5_export_lucid_context_x_oid_desc, + &__gss_krb5_export_lucid_context_v1_x_oid_desc, + &__gss_krb5_set_dns_canonicalize_x_oid_desc, + &__gss_krb5_get_subkey_x_oid_desc, + &__gss_krb5_get_initiator_subkey_x_oid_desc, + &__gss_krb5_get_acceptor_subkey_x_oid_desc, + &__gss_krb5_send_to_kdc_x_oid_desc, + &__gss_krb5_get_authtime_x_oid_desc, + &__gss_krb5_get_service_keyblock_x_oid_desc, + &__gss_krb5_set_allowable_enctypes_x_oid_desc, + &__gss_krb5_set_default_realm_x_oid_desc, + &__gss_krb5_ccache_name_x_oid_desc, + &__gss_krb5_set_time_offset_x_oid_desc, + &__gss_krb5_get_time_offset_x_oid_desc, + &__gss_krb5_plugin_register_x_oid_desc, + &__gss_ntlm_get_session_key_x_oid_desc, + &__gss_c_nt_ntlm_oid_desc, + &__gss_c_nt_dn_oid_desc, + &__gss_krb5_nt_principal_name_referral_oid_desc, + &__gss_c_ntlm_avguest_oid_desc, + &__gss_c_ntlm_v1_oid_desc, + &__gss_c_ntlm_v2_oid_desc, + &__gss_c_ntlm_session_key_oid_desc, + &__gss_c_ntlm_force_v1_oid_desc, + &__gss_krb5_cred_no_ci_flags_x_oid_desc, + &__gss_krb5_import_cred_x_oid_desc, + &__gss_krb5_import_rfc4121_context_x_oid_desc, + &__gss_c_ma_sasl_mech_name_oid_desc, + &__gss_c_ma_mech_name_oid_desc, + &__gss_c_ma_mech_description_oid_desc, + &__gss_sasl_digest_md5_mechanism_oid_desc, + &__gss_netlogon_mechanism_oid_desc, + &__gss_netlogon_set_session_key_x_oid_desc, + &__gss_netlogon_set_sign_algorithm_x_oid_desc, + &__gss_netlogon_nt_netbios_dns_name_oid_desc, + &__gss_c_inq_win2k_pac_x_oid_desc, + &__gss_c_inq_sspi_session_key_oid_desc, + &__gss_c_inq_negoex_key_oid_desc, + &__gss_c_inq_negoex_verify_key_oid_desc, + &__gss_c_inq_require_mechlist_mic_oid_desc, + &__gss_krb5_mechanism_oid_desc, + &__gss_ntlm_mechanism_oid_desc, + &__gss_spnego_mechanism_oid_desc, + &__gss_c_inq_peer_has_buggy_spnego_oid_desc, + &__gss_c_ntlm_reset_crypto_oid_desc, + &__gss_negoex_mechanism_oid_desc, + &__gss_sanon_x25519_mechanism_oid_desc, + &__gss_c_ma_mech_concrete_oid_desc, + &__gss_c_ma_mech_pseudo_oid_desc, + &__gss_c_ma_mech_composite_oid_desc, + &__gss_c_ma_mech_nego_oid_desc, + &__gss_c_ma_mech_glue_oid_desc, + &__gss_c_ma_not_mech_oid_desc, + &__gss_c_ma_deprecated_oid_desc, + &__gss_c_ma_not_dflt_mech_oid_desc, + &__gss_c_ma_itok_framed_oid_desc, + &__gss_c_ma_auth_init_oid_desc, + &__gss_c_ma_auth_targ_oid_desc, + &__gss_c_ma_auth_init_init_oid_desc, + &__gss_c_ma_auth_targ_init_oid_desc, + &__gss_c_ma_auth_init_anon_oid_desc, + &__gss_c_ma_auth_targ_anon_oid_desc, + &__gss_c_ma_deleg_cred_oid_desc, + &__gss_c_ma_integ_prot_oid_desc, + &__gss_c_ma_conf_prot_oid_desc, + &__gss_c_ma_mic_oid_desc, + &__gss_c_ma_wrap_oid_desc, + &__gss_c_ma_prot_ready_oid_desc, + &__gss_c_ma_replay_det_oid_desc, + &__gss_c_ma_oos_det_oid_desc, + &__gss_c_ma_cbindings_oid_desc, + &__gss_c_ma_pfs_oid_desc, + &__gss_c_ma_compress_oid_desc, + &__gss_c_ma_ctx_trans_oid_desc, + &__gss_c_ma_negoex_and_spnego_oid_desc, +}; + +size_t _gss_ot_internal_count = sizeof(_gss_ot_internal) / sizeof(_gss_ot_internal[0]); diff --git a/third_party/heimdal/lib/gssapi/mech/gss_oid_equal.c b/third_party/heimdal/lib/gssapi/mech/gss_oid_equal.c new file mode 100644 index 0000000..b125ede --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_oid_equal.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2006 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "mech_locl.h" + +/** + * Compare two GSS-API OIDs with each other. + * + * GSS_C_NO_OID matches nothing, not even it-self. + * + * @param a first oid to compare + * @param b second oid to compare + * + * @return non-zero when both oid are the same OID, zero when they are + * not the same. + * + * @ingroup gssapi + */ + +GSSAPI_LIB_FUNCTION int GSSAPI_LIB_CALL +gss_oid_equal(gss_const_OID a, gss_const_OID b) +{ + if (a == b && a != GSS_C_NO_OID) + return 1; + if (a == GSS_C_NO_OID || b == GSS_C_NO_OID || a->length != b->length) + return 0; + return memcmp(a->elements, b->elements, a->length) == 0; +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_oid_to_str.c b/third_party/heimdal/lib/gssapi/mech/gss_oid_to_str.c new file mode 100644 index 0000000..d8e188d --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_oid_to_str.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2006 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_oid_to_str(OM_uint32 *minor_status, gss_OID oid, gss_buffer_t oid_str) +{ + int ret; + size_t size; + heim_oid o; + char *p; + + _mg_buffer_zero(oid_str); + + if (oid == GSS_C_NULL_OID) + return GSS_S_FAILURE; + + ret = der_get_oid (oid->elements, oid->length, &o, &size); + if (ret) { + *minor_status = ret; + return GSS_S_FAILURE; + } + + ret = der_print_heim_oid(&o, ' ', &p); + der_free_oid(&o); + if (ret) { + *minor_status = ret; + return GSS_S_FAILURE; + } + + oid_str->value = p; + oid_str->length = strlen(p); + + *minor_status = 0; + return GSS_S_COMPLETE; +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_pname_to_uid.c b/third_party/heimdal/lib/gssapi/mech/gss_pname_to_uid.c new file mode 100644 index 0000000..5046fae --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_pname_to_uid.c @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2011, PADL Software Pty Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of PADL Software nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "mech_locl.h" + +static OM_uint32 +mech_localname(OM_uint32 *minor_status, + struct _gss_mechanism_name *mn, + gss_buffer_t localname) +{ + OM_uint32 major_status = GSS_S_UNAVAILABLE; + + *minor_status = 0; + + if (mn->gmn_mech->gm_localname == NULL) + return GSS_S_UNAVAILABLE; + + major_status = mn->gmn_mech->gm_localname(minor_status, + mn->gmn_name, + mn->gmn_mech_oid, + localname); + if (GSS_ERROR(major_status)) + _gss_mg_error(mn->gmn_mech, *minor_status); + + return major_status; +} + +static OM_uint32 +attr_localname(OM_uint32 *minor_status, + struct _gss_mechanism_name *mn, + gss_buffer_t localname) +{ + OM_uint32 major_status = GSS_S_UNAVAILABLE; + OM_uint32 tmpMinor; + gss_buffer_desc value = GSS_C_EMPTY_BUFFER; + gss_buffer_desc display_value = GSS_C_EMPTY_BUFFER; + int authenticated = 0, complete = 0; + int more = -1; + + *minor_status = 0; + + localname->length = 0; + localname->value = NULL; + + if (mn->gmn_mech->gm_get_name_attribute == NULL) + return GSS_S_UNAVAILABLE; + + major_status = mn->gmn_mech->gm_get_name_attribute(minor_status, + mn->gmn_name, + GSS_C_ATTR_LOCAL_LOGIN_USER, + &authenticated, + &complete, + &value, + &display_value, + &more); + if (GSS_ERROR(major_status)) { + _gss_mg_error(mn->gmn_mech, *minor_status); + return major_status; + } + + if (authenticated) { + *localname = value; + } else { + major_status = GSS_S_UNAVAILABLE; + gss_release_buffer(&tmpMinor, &value); + } + + gss_release_buffer(&tmpMinor, &display_value); + + return major_status; +} + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_localname(OM_uint32 *minor_status, + gss_const_name_t pname, + const gss_OID mech_type, + gss_buffer_t localname) +{ + OM_uint32 major_status = GSS_S_UNAVAILABLE; + struct _gss_name *name = (struct _gss_name *) pname; + struct _gss_mechanism_name *mn = NULL; + + *minor_status = 0; + + if (mech_type != GSS_C_NO_OID) { + major_status = _gss_find_mn(minor_status, name, mech_type, &mn); + if (GSS_ERROR(major_status)) + return major_status; + + major_status = mech_localname(minor_status, mn, localname); + if (major_status != GSS_S_COMPLETE) + major_status = attr_localname(minor_status, mn, localname); + } else { + HEIM_TAILQ_FOREACH(mn, &name->gn_mn, gmn_link) { + major_status = mech_localname(minor_status, mn, localname); + if (major_status != GSS_S_COMPLETE) + major_status = attr_localname(minor_status, mn, localname); + if (major_status != GSS_S_UNAVAILABLE) + break; + } + } + + if (major_status != GSS_S_COMPLETE && mn != NULL) + _gss_mg_error(mn->gmn_mech, *minor_status); + + return major_status; +} + + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_pname_to_uid(OM_uint32 *minor_status, + gss_const_name_t pname, + const gss_OID mech_type, + uid_t *uidp) +{ +#ifdef NO_LOCALNAME + return GSS_S_UNAVAILABLE; +#else + OM_uint32 major, tmpMinor; + gss_buffer_desc localname = GSS_C_EMPTY_BUFFER; + char *szLocalname; +#ifdef POSIX_GETPWNAM_R + char pwbuf[2048]; + struct passwd pw, *pwd; +#else + struct passwd *pwd; +#endif + + major = gss_localname(minor_status, pname, mech_type, &localname); + if (GSS_ERROR(major)) + return major; + if (localname.length == 0) { + *minor_status = KRB5_NO_LOCALNAME; + return GSS_S_FAILURE; + } + + szLocalname = malloc(localname.length + 1); + if (szLocalname == NULL) { + gss_release_buffer(&tmpMinor, &localname); + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + memcpy(szLocalname, localname.value, localname.length); + szLocalname[localname.length] = '\0'; + +#ifdef POSIX_GETPWNAM_R + if (getpwnam_r(szLocalname, &pw, pwbuf, sizeof(pwbuf), &pwd) != 0) + pwd = NULL; +#else + pwd = getpwnam(szLocalname); +#endif + + gss_release_buffer(&tmpMinor, &localname); + free(szLocalname); + + *minor_status = 0; + + if (pwd != NULL) { + *uidp = pwd->pw_uid; + major = GSS_S_COMPLETE; + } else { + major = GSS_S_UNAVAILABLE; + } + + return major; +#endif +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_process_context_token.c b/third_party/heimdal/lib/gssapi/mech/gss_process_context_token.c new file mode 100644 index 0000000..d10eb47 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_process_context_token.c @@ -0,0 +1,41 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_process_context_token.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_process_context_token(OM_uint32 *minor_status, + gss_const_ctx_id_t context_handle, + const gss_buffer_t token_buffer) +{ + struct _gss_context *ctx = (struct _gss_context *) context_handle; + gssapi_mech_interface m = ctx->gc_mech; + + return (m->gm_process_context_token(minor_status, ctx->gc_ctx, + token_buffer)); +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_pseudo_random.c b/third_party/heimdal/lib/gssapi/mech/gss_pseudo_random.c new file mode 100644 index 0000000..1b7eb7e --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_pseudo_random.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2007 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* $Id$ */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_pseudo_random(OM_uint32 *minor_status, + gss_ctx_id_t context, + int prf_key, + const gss_buffer_t prf_in, + ssize_t desired_output_len, + gss_buffer_t prf_out) +{ + struct _gss_context *ctx = (struct _gss_context *) context; + gssapi_mech_interface m; + OM_uint32 major_status; + + _mg_buffer_zero(prf_out); + *minor_status = 0; + + if (ctx == NULL) { + *minor_status = 0; + return GSS_S_NO_CONTEXT; + } + + m = ctx->gc_mech; + + if (m->gm_pseudo_random == NULL) + return GSS_S_UNAVAILABLE; + + major_status = (*m->gm_pseudo_random)(minor_status, ctx->gc_ctx, + prf_key, prf_in, desired_output_len, + prf_out); + if (major_status != GSS_S_COMPLETE) + _gss_mg_error(m, *minor_status); + + return major_status; +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_release_buffer.c b/third_party/heimdal/lib/gssapi/mech/gss_release_buffer.c new file mode 100644 index 0000000..c3dd457 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_release_buffer.c @@ -0,0 +1,42 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_release_buffer.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_release_buffer(OM_uint32 *minor_status, + gss_buffer_t buffer) +{ + + *minor_status = 0; + if (buffer->value) + free(buffer->value); + _mg_buffer_zero(buffer); + + return (GSS_S_COMPLETE); +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_release_cred.c b/third_party/heimdal/lib/gssapi/mech/gss_release_cred.c new file mode 100644 index 0000000..3a85de5 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_release_cred.c @@ -0,0 +1,66 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_release_cred.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" + +/** + * Release a credentials + * + * Its ok to release the GSS_C_NO_CREDENTIAL/NULL credential, it will + * return a GSS_S_COMPLETE error code. On return cred_handle is set ot + * GSS_C_NO_CREDENTIAL. + * + * Example: + * + * @code + * gss_cred_id_t cred = GSS_C_NO_CREDENTIAL; + * major = gss_release_cred(&minor, &cred); + * @endcode + * + * @param minor_status minor status return code, mech specific + * @param cred_handle a pointer to the credential too release + * + * @return an gssapi error code + * + * @ingroup gssapi + */ + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_release_cred(OM_uint32 *minor_status, gss_cred_id_t *cred_handle) +{ + struct _gss_cred *cred = (struct _gss_cred *) *cred_handle; + + if (cred == NULL) + return (GSS_S_COMPLETE); + + _gss_mg_release_cred(cred); + + *minor_status = 0; + *cred_handle = GSS_C_NO_CREDENTIAL; + return (GSS_S_COMPLETE); +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_release_name.c b/third_party/heimdal/lib/gssapi/mech/gss_release_name.c new file mode 100644 index 0000000..db1793e --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_release_name.c @@ -0,0 +1,63 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_release_name.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" + +/** + * Free a name + * + * import_name can point to NULL or be NULL, or a pointer to a + * gss_name_t structure. If it was a pointer to gss_name_t, the + * pointer will be set to NULL on success and failure. + * + * @param minor_status minor status code + * @param input_name name to free + * + * @returns a gss_error code, see gss_display_status() about printing + * the error code. + * + * @ingroup gssapi + */ +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_release_name(OM_uint32 *minor_status, + gss_name_t *input_name) +{ + struct _gss_name *name; + + *minor_status = 0; + + if (input_name == NULL || *input_name == NULL) + return GSS_S_COMPLETE; + + name = (struct _gss_name *) *input_name; + _gss_mg_release_name(name); + + *input_name = GSS_C_NO_NAME; + + return (GSS_S_COMPLETE); +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_release_oid.c b/third_party/heimdal/lib/gssapi/mech/gss_release_oid.c new file mode 100644 index 0000000..4f674b0 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_release_oid.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2006 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "mech_locl.h" + + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_release_oid(OM_uint32 *minor_status, gss_OID *oid) +{ + *oid = GSS_C_NO_OID; + + if (minor_status != NULL) + *minor_status = 0; + + return GSS_S_COMPLETE; +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_release_oid_set.c b/third_party/heimdal/lib/gssapi/mech/gss_release_oid_set.c new file mode 100644 index 0000000..183ddf8 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_release_oid_set.c @@ -0,0 +1,44 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_release_oid_set.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_release_oid_set(OM_uint32 *minor_status, + gss_OID_set *set) +{ + + *minor_status = 0; + if (set && *set) { + if ((*set)->elements) + free((*set)->elements); + free(*set); + *set = GSS_C_NO_OID_SET; + } + return (GSS_S_COMPLETE); +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_rfc4121.c b/third_party/heimdal/lib/gssapi/mech/gss_rfc4121.c new file mode 100644 index 0000000..97a0833 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_rfc4121.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2019-2020, AuriStor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "mech_locl.h" + +/* + * An internal API (for now) to return a mechglue context handle given + * a session key that can provide RFC 4121 compatible message protection + * and PRF services. Used by SAnon. The implementation of those services + * is currently provided by the krb5 GSS mechanism but that is opaque to + * the caller (minor status codes notwithstanding). + */ +OM_uint32 +_gss_mg_import_rfc4121_context(OM_uint32 *minor, + uint8_t initiator_flag, + OM_uint32 gss_flags, + int32_t rfc3961_enctype, + gss_const_buffer_t session_key, + gss_ctx_id_t *rfc4121_context_handle) +{ + OM_uint32 major = GSS_S_FAILURE, tmpMinor; + krb5_storage *sp; + krb5_error_code ret; + krb5_data d; + gss_buffer_desc rfc4121_args = GSS_C_EMPTY_BUFFER; + + krb5_data_zero(&d); + + *minor = 0; + *rfc4121_context_handle = GSS_C_NO_CONTEXT; + + sp = krb5_storage_emem(); + if (sp == NULL) { + ret = ENOMEM; + goto out; + } + + krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_HOST); + + /* + * The arguments GSS_KRB5_IMPORT_RFC4121_CONTEXT_X are the serialized + * form of initiator_flag || flags || keytype || session_key. The session + * key length is inferred from the keytype. + */ + ret = krb5_store_uint8(sp, initiator_flag); + if (ret != 0) + goto out; + + ret = krb5_store_uint32(sp, gss_flags); + if (ret != 0) + goto out; + + ret = krb5_store_int32(sp, rfc3961_enctype); + if (ret != 0) + goto out; + + if (krb5_storage_write(sp, session_key->value, session_key->length) + != session_key->length) { + ret = ENOMEM; + goto out; + } + + ret = krb5_storage_to_data(sp, &d); + if (ret != 0) + goto out; + + rfc4121_args.length = d.length; + rfc4121_args.value = d.data; + + major = gss_set_sec_context_option(minor, rfc4121_context_handle, + GSS_KRB5_IMPORT_RFC4121_CONTEXT_X, + &rfc4121_args); + +out: + _gss_secure_release_buffer(&tmpMinor, &rfc4121_args); + krb5_storage_free(sp); + + if (major == GSS_S_FAILURE && *minor == 0) + *minor = ret; + + return major; +} + diff --git a/third_party/heimdal/lib/gssapi/mech/gss_seal.c b/third_party/heimdal/lib/gssapi/mech/gss_seal.c new file mode 100644 index 0000000..26c65da --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_seal.c @@ -0,0 +1,45 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_seal.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_seal(OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + int conf_req_flag, + int qop_req, + gss_buffer_t input_message_buffer, + int *conf_state, + gss_buffer_t output_message_buffer) +{ + + return (gss_wrap(minor_status, + context_handle, conf_req_flag, qop_req, + input_message_buffer, conf_state, + output_message_buffer)); +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_set_cred_option.c b/third_party/heimdal/lib/gssapi/mech/gss_set_cred_option.c new file mode 100644 index 0000000..39b49e3 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_set_cred_option.c @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2004, PADL Software Pty Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of PADL Software nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_set_cred_option (OM_uint32 *minor_status, + gss_cred_id_t *cred_handle, + const gss_OID object, + const gss_buffer_t value) +{ + struct _gss_cred *cred = (struct _gss_cred *) *cred_handle; + OM_uint32 major_status = GSS_S_COMPLETE; + struct _gss_mechanism_cred *mc; + int one_ok = 0; + + *minor_status = 0; + + _gss_load_mech(); + + if (cred == NULL) { + struct _gss_mech_switch *m; + + cred = _gss_mg_alloc_cred(); + if (cred == NULL) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + HEIM_TAILQ_FOREACH(m, &_gss_mechs, gm_link) { + + if (m->gm_mech.gm_set_cred_option == NULL) + continue; + + mc = malloc(sizeof(*mc)); + if (mc == NULL) { + *cred_handle = (gss_cred_id_t)cred; + gss_release_cred(minor_status, cred_handle); + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + mc->gmc_mech = &m->gm_mech; + mc->gmc_mech_oid = m->gm_mech_oid; + mc->gmc_cred = GSS_C_NO_CREDENTIAL; + + major_status = m->gm_mech.gm_set_cred_option( + minor_status, &mc->gmc_cred, object, value); + + if (major_status) { + free(mc); + continue; + } + one_ok = 1; + HEIM_TAILQ_INSERT_TAIL(&cred->gc_mc, mc, gmc_link); + } + *cred_handle = (gss_cred_id_t)cred; + if (!one_ok) { + OM_uint32 junk; + gss_release_cred(&junk, cred_handle); + } + } else { + gssapi_mech_interface m; + + HEIM_TAILQ_FOREACH(mc, &cred->gc_mc, gmc_link) { + m = mc->gmc_mech; + + if (m == NULL) + return GSS_S_BAD_MECH; + + if (m->gm_set_cred_option == NULL) + continue; + + major_status = m->gm_set_cred_option(minor_status, + &mc->gmc_cred, object, value); + if (major_status == GSS_S_COMPLETE) + one_ok = 1; + else + _gss_mg_error(m, *minor_status); + + } + } + if (one_ok) { + *minor_status = 0; + return GSS_S_COMPLETE; + } + return major_status; +} + diff --git a/third_party/heimdal/lib/gssapi/mech/gss_set_name_attribute.c b/third_party/heimdal/lib/gssapi/mech/gss_set_name_attribute.c new file mode 100644 index 0000000..4e963f3 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_set_name_attribute.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2010, PADL Software Pty Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of PADL Software nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_set_name_attribute(OM_uint32 *minor_status, + gss_name_t input_name, + int complete, + gss_buffer_t attr, + gss_buffer_t value) +{ + OM_uint32 major_status = GSS_S_UNAVAILABLE; + struct _gss_name *name = (struct _gss_name *) input_name; + struct _gss_mechanism_name *mn; + + *minor_status = 0; + + if (input_name == GSS_C_NO_NAME) + return GSS_S_BAD_NAME; + + HEIM_TAILQ_FOREACH(mn, &name->gn_mn, gmn_link) { + gssapi_mech_interface m = mn->gmn_mech; + + if (!m->gm_set_name_attribute) + continue; + + major_status = m->gm_set_name_attribute(minor_status, + mn->gmn_name, + complete, + attr, + value); + if (GSS_ERROR(major_status)) + _gss_mg_error(m, *minor_status); + else + break; + } + + return major_status; +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_set_neg_mechs.c b/third_party/heimdal/lib/gssapi/mech/gss_set_neg_mechs.c new file mode 100644 index 0000000..7c527b2 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_set_neg_mechs.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2018, PADL Software Pty Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of PADL Software nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_set_neg_mechs(OM_uint32 *minor_status, + gss_cred_id_t cred_handle, + const gss_OID_set mechs) +{ + struct _gss_cred *cred = (struct _gss_cred *)cred_handle; + OM_uint32 major_status, junk; + gss_OID_set tmp_mechs; + + if (minor_status == NULL) + return GSS_S_CALL_INACCESSIBLE_WRITE; + + *minor_status = 0; + + if (cred_handle == GSS_C_NO_CREDENTIAL || mechs == GSS_C_NO_OID_SET) + return GSS_S_CALL_INACCESSIBLE_READ; + + major_status = gss_duplicate_oid_set(minor_status, mechs, &tmp_mechs); + if (major_status != GSS_S_COMPLETE) + return major_status; + + gss_release_oid_set(&junk, &cred->gc_neg_mechs); + cred->gc_neg_mechs = tmp_mechs; + + return GSS_S_COMPLETE; +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_set_sec_context_option.c b/third_party/heimdal/lib/gssapi/mech/gss_set_sec_context_option.c new file mode 100644 index 0000000..5b92ac4 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_set_sec_context_option.c @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2004, 2020, PADL Software Pty Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of PADL Software nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_set_sec_context_option (OM_uint32 *minor_status, + gss_ctx_id_t *context_handle, + const gss_OID object, + const gss_buffer_t value) +{ + struct _gss_context *ctx; + OM_uint32 major_status; + gssapi_mech_interface mi; + int allocated_ctx; + + *minor_status = 0; + + if (context_handle == NULL) + return GSS_S_CALL_INACCESSIBLE_READ; + + _gss_load_mech(); + + ctx = (struct _gss_context *) *context_handle; + if (ctx == NULL) { + ctx = calloc(1, sizeof(*ctx)); + if (ctx == NULL) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + allocated_ctx = 1; + } else { + allocated_ctx = 0; + } + + major_status = GSS_S_BAD_MECH; + + if (allocated_ctx) { + struct _gss_mech_switch *m; + + HEIM_TAILQ_FOREACH(m, &_gss_mechs, gm_link) { + mi = &m->gm_mech; + + if (mi->gm_set_sec_context_option == NULL) + continue; + major_status = mi->gm_set_sec_context_option(minor_status, + &ctx->gc_ctx, object, value); + if (major_status == GSS_S_COMPLETE) { + ctx->gc_mech = mi; + break; + } else { + _gss_mg_error(mi, *minor_status); + } + } + } else { + mi = ctx->gc_mech; + if (mi->gm_set_sec_context_option != NULL) { + major_status = mi->gm_set_sec_context_option(minor_status, + &ctx->gc_ctx, object, value); + if (major_status != GSS_S_COMPLETE) + _gss_mg_error(mi, *minor_status); + } + } + + if (allocated_ctx) { + if (major_status == GSS_S_COMPLETE) + *context_handle = (gss_ctx_id_t)ctx; + else + free(ctx); + } + + return major_status; +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_sign.c b/third_party/heimdal/lib/gssapi/mech/gss_sign.c new file mode 100644 index 0000000..4ef99c1 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_sign.c @@ -0,0 +1,41 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_sign.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_sign(OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + int qop_req, + gss_buffer_t message_buffer, + gss_buffer_t message_token) +{ + + return gss_get_mic(minor_status, + context_handle, qop_req, message_buffer, message_token); +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_store_cred.c b/third_party/heimdal/lib/gssapi/mech/gss_store_cred.c new file mode 100644 index 0000000..7a9344a --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_store_cred.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2009 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "mech_locl.h" + +/* See RFC5588 */ +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_store_cred(OM_uint32 *minor_status, + gss_cred_id_t input_cred_handle, + gss_cred_usage_t cred_usage, + const gss_OID desired_mech, + OM_uint32 overwrite_cred, + OM_uint32 default_cred, + gss_OID_set *elements_stored, + gss_cred_usage_t *cred_usage_stored) +{ + return gss_store_cred_into(minor_status, + input_cred_handle, + cred_usage, + desired_mech, + overwrite_cred, + default_cred, + GSS_C_NO_CRED_STORE, + elements_stored, + cred_usage_stored); +} + diff --git a/third_party/heimdal/lib/gssapi/mech/gss_store_cred_into.c b/third_party/heimdal/lib/gssapi/mech/gss_store_cred_into.c new file mode 100644 index 0000000..1c739b0 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_store_cred_into.c @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2009 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "mech_locl.h" + +static OM_uint32 +store_mech_cred(OM_uint32 *minor_status, + gssapi_mech_interface m, + const struct _gss_mechanism_cred *mc, + gss_cred_usage_t input_usage, + OM_uint32 store_cred_flags, + gss_const_key_value_set_t cred_store, + gss_cred_usage_t *usage_stored, + gss_buffer_set_t *env) +{ + OM_uint32 major_status; + OM_uint32 overwrite_cred = + !!(store_cred_flags & GSS_C_STORE_CRED_OVERWRITE); + OM_uint32 default_cred = !!(store_cred_flags & GSS_C_STORE_CRED_DEFAULT); + + if (m->gm_store_cred_into2) + major_status = m->gm_store_cred_into2(minor_status, mc->gmc_cred, + input_usage, &m->gm_mech_oid, + store_cred_flags, cred_store, + NULL, usage_stored, + env); + else if (m->gm_store_cred_into) + major_status = m->gm_store_cred_into(minor_status, mc->gmc_cred, + input_usage, &m->gm_mech_oid, + overwrite_cred, default_cred, + cred_store, NULL, usage_stored); + else if (cred_store == GSS_C_NO_CRED_STORE && m->gm_store_cred) + major_status = m->gm_store_cred(minor_status, mc->gmc_cred, + input_usage, &m->gm_mech_oid, + overwrite_cred, default_cred, + NULL, usage_stored); + else + major_status = GSS_S_UNAVAILABLE; + + return major_status; +} + +/* + * See RFC5588 for gss_store_cred(). This function is a variant that takes a + * const key/value hashmap-like thing that specifies a credential store in a + * mechanism- and implementation-specific way, though Heimdal and MIT agree on + * at least the following keys for the Kerberos mechanism: ccache, keytab, and + * client_keytab. A set of environment variables may be output as well + */ +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_store_cred_into2(OM_uint32 *minor_status, + gss_const_cred_id_t input_cred_handle, + gss_cred_usage_t input_usage, + const gss_OID desired_mech, + OM_uint32 store_cred_flags, + gss_const_key_value_set_t cred_store, + gss_OID_set *elements_stored, + gss_cred_usage_t *cred_usage_stored, + gss_buffer_set_t *env) +{ + struct _gss_cred *cred = (struct _gss_cred *)input_cred_handle; + struct _gss_mechanism_cred *mc; + OM_uint32 major_status; + OM_uint32 minor; + size_t successes; + + if (env != NULL) + *env = NULL; + + if (input_cred_handle == NULL) + return GSS_S_CALL_INACCESSIBLE_READ; + + if (minor_status == NULL) + return GSS_S_CALL_INACCESSIBLE_WRITE; + *minor_status = 0; + + if (cred_usage_stored) + *cred_usage_stored = 0; + + if (elements_stored) { + *elements_stored = GSS_C_NO_OID_SET; + + major_status = gss_create_empty_oid_set(minor_status, + elements_stored); + if (major_status != GSS_S_COMPLETE) + return major_status; + } + + major_status = GSS_S_NO_CRED; + successes = 0; + + HEIM_TAILQ_FOREACH(mc, &cred->gc_mc, gmc_link) { + gssapi_mech_interface m = mc->gmc_mech; + + if (m == NULL || (m->gm_flags & GM_USE_MG_CRED) != 0) + continue; + + if (desired_mech != GSS_C_NO_OID && + !gss_oid_equal(&m->gm_mech_oid, desired_mech)) + continue; + + major_status = store_mech_cred(minor_status, m, mc, input_usage, + store_cred_flags, cred_store, + cred_usage_stored, env); + if (major_status == GSS_S_COMPLETE) { + if (elements_stored && desired_mech != GSS_C_NO_OID) + gss_add_oid_set_member(&minor, desired_mech, elements_stored); + successes++; + } else if (desired_mech != GSS_C_NO_OID) { + _gss_mg_error(m, *minor_status); + gss_release_oid_set(&minor, elements_stored); + return major_status; + } + } + + if (successes > 0) { + *minor_status = 0; + major_status = GSS_S_COMPLETE; + } + + heim_assert(successes || major_status != GSS_S_COMPLETE, + "cred storage failed, but no error raised"); + + return major_status; +} + +/* + * See RFC5588 for gss_store_cred(). This function is a variant that takes a + * const key/value hashmap-like thing that specifies a credential store in a + * mechanism- and implementation-specific way, though Heimdal and MIT agree on + * at least the following keys for the Kerberos mechanism: ccache, keytab, and + * client_keytab. + */ +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_store_cred_into(OM_uint32 *minor_status, + gss_const_cred_id_t input_cred_handle, + gss_cred_usage_t input_usage, + const gss_OID desired_mech, + OM_uint32 overwrite_cred, + OM_uint32 default_cred, + gss_const_key_value_set_t cred_store, + gss_OID_set *elements_stored, + gss_cred_usage_t *cred_usage_stored) +{ + OM_uint32 store_cred_flags = + (overwrite_cred ? GSS_C_STORE_CRED_OVERWRITE : 0) | + (default_cred ? GSS_C_STORE_CRED_DEFAULT : 0); + return gss_store_cred_into2(minor_status, input_cred_handle, input_usage, + desired_mech, store_cred_flags, cred_store, + elements_stored, cred_usage_stored, NULL); +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_test_oid_set_member.c b/third_party/heimdal/lib/gssapi/mech/gss_test_oid_set_member.c new file mode 100644 index 0000000..715d34b --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_test_oid_set_member.c @@ -0,0 +1,46 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_test_oid_set_member.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_test_oid_set_member(OM_uint32 *minor_status, + const gss_OID member, + const gss_OID_set set, + int *present) +{ + size_t i; + + *present = 0; + for (i = 0; i < set->count; i++) + if (gss_oid_equal(member, &set->elements[i])) + *present = 1; + + *minor_status = 0; + return (GSS_S_COMPLETE); +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_unseal.c b/third_party/heimdal/lib/gssapi/mech/gss_unseal.c new file mode 100644 index 0000000..0add03d --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_unseal.c @@ -0,0 +1,43 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_unseal.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_unseal(OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + gss_buffer_t input_message_buffer, + gss_buffer_t output_message_buffer, + int *conf_state, + int *qop_state) +{ + + return (gss_unwrap(minor_status, + context_handle, input_message_buffer, + output_message_buffer, conf_state, (gss_qop_t *)qop_state)); +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_unwrap.c b/third_party/heimdal/lib/gssapi/mech/gss_unwrap.c new file mode 100644 index 0000000..dd6363b --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_unwrap.c @@ -0,0 +1,56 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_unwrap.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_unwrap(OM_uint32 *minor_status, + gss_const_ctx_id_t context_handle, + const gss_buffer_t input_message_buffer, + gss_buffer_t output_message_buffer, + int *conf_state, + gss_qop_t *qop_state) +{ + struct _gss_context *ctx = (struct _gss_context *) context_handle; + gssapi_mech_interface m; + + if (conf_state) + *conf_state = 0; + if (qop_state) + *qop_state = 0; + + if (ctx == NULL) { + *minor_status = 0; + return GSS_S_NO_CONTEXT; + } + m = ctx->gc_mech; + + return (m->gm_unwrap(minor_status, ctx->gc_ctx, + input_message_buffer, output_message_buffer, + conf_state, qop_state)); +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_utils.c b/third_party/heimdal/lib/gssapi/mech/gss_utils.c new file mode 100644 index 0000000..bb7e619 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_utils.c @@ -0,0 +1,324 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_utils.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" + +static OM_uint32 +_gss_copy_oid(OM_uint32 *minor_status, + gss_const_OID from_oid, + gss_OID to_oid) +{ + size_t len = from_oid->length; + + *minor_status = 0; + to_oid->elements = malloc(len); + if (!to_oid->elements) { + to_oid->length = 0; + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + to_oid->length = (OM_uint32)len; + memcpy(to_oid->elements, from_oid->elements, len); + return (GSS_S_COMPLETE); +} + +OM_uint32 +_gss_free_oid(OM_uint32 *minor_status, gss_OID oid) +{ + *minor_status = 0; + if (oid->elements) { + free(oid->elements); + oid->elements = NULL; + oid->length = 0; + } + return (GSS_S_COMPLETE); +} + +struct _gss_interned_oid { + HEIM_SLIST_ATOMIC_ENTRY(_gss_interned_oid) gio_link; + gss_OID_desc gio_oid; +}; + +static HEIM_SLIST_ATOMIC_HEAD(_gss_interned_oid_list, _gss_interned_oid) interned_oids = +HEIM_SLIST_HEAD_INITIALIZER(interned_oids); + +extern gss_OID _gss_ot_internal[]; +extern size_t _gss_ot_internal_count; + +static OM_uint32 +intern_oid_static(OM_uint32 *minor_status, + gss_const_OID from_oid, + gss_OID *to_oid) +{ + size_t i; + + /* statically allocated OIDs */ + for (i = 0; i < _gss_ot_internal_count; i++) { + if (gss_oid_equal(_gss_ot_internal[i], from_oid)) { + *minor_status = 0; + *to_oid = _gss_ot_internal[i]; + return GSS_S_COMPLETE; + } + } + + return GSS_S_CONTINUE_NEEDED; +} + +OM_uint32 +_gss_intern_oid(OM_uint32 *minor_status, + gss_const_OID from_oid, + gss_OID *to_oid) +{ + OM_uint32 major_status; + struct _gss_interned_oid *iop; + + major_status = intern_oid_static(minor_status, from_oid, to_oid); + if (major_status != GSS_S_CONTINUE_NEEDED) + return major_status; + + HEIM_SLIST_ATOMIC_FOREACH(iop, &interned_oids, gio_link) { + if (gss_oid_equal(&iop->gio_oid, from_oid)) { + *minor_status = 0; + *to_oid = &iop->gio_oid; + return GSS_S_COMPLETE; + } + } + + iop = malloc(sizeof(*iop)); + if (iop == NULL) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + major_status = _gss_copy_oid(minor_status, from_oid, &iop->gio_oid); + if (GSS_ERROR(major_status)) { + free(iop); + return major_status; + } + + HEIM_SLIST_ATOMIC_INSERT_HEAD(&interned_oids, iop, gio_link); + + *minor_status = 0; + *to_oid = &iop->gio_oid; + + return GSS_S_COMPLETE; +} + +OM_uint32 +_gss_copy_buffer(OM_uint32 *minor_status, + const gss_buffer_t from_buf, gss_buffer_t to_buf) +{ + size_t len = from_buf->length; + + *minor_status = 0; + to_buf->value = malloc(len); + if (!to_buf->value) { + *minor_status = ENOMEM; + to_buf->length = 0; + return GSS_S_FAILURE; + } + to_buf->length = len; + memcpy(to_buf->value, from_buf->value, len); + return (GSS_S_COMPLETE); +} + +OM_uint32 +_gss_secure_release_buffer(OM_uint32 *minor_status, + gss_buffer_t buffer) +{ + if (buffer->value) + memset_s(buffer->value, buffer->length, 0, buffer->length); + + return gss_release_buffer(minor_status, buffer); +} + +OM_uint32 +_gss_secure_release_buffer_set(OM_uint32 *minor_status, + gss_buffer_set_t *buffer_set) +{ + size_t i; + OM_uint32 minor; + + *minor_status = 0; + + if (*buffer_set == GSS_C_NO_BUFFER_SET) + return GSS_S_COMPLETE; + + for (i = 0; i < (*buffer_set)->count; i++) + _gss_secure_release_buffer(&minor, &((*buffer_set)->elements[i])); + + (*buffer_set)->count = 0; + + return gss_release_buffer_set(minor_status, buffer_set); +} + +void +_gss_mg_encode_le_uint32(uint32_t n, uint8_t *p) +{ + p[0] = (n >> 0 ) & 0xFF; + p[1] = (n >> 8 ) & 0xFF; + p[2] = (n >> 16) & 0xFF; + p[3] = (n >> 24) & 0xFF; +} + +void +_gss_mg_decode_le_uint32(const void *ptr, uint32_t *n) +{ + const uint8_t *p = ptr; + *n = (p[0] << 0) | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); +} + +void +_gss_mg_encode_be_uint32(uint32_t n, uint8_t *p) +{ + p[0] = (n >> 24) & 0xFF; + p[1] = (n >> 16) & 0xFF; + p[2] = (n >> 8 ) & 0xFF; + p[3] = (n >> 0 ) & 0xFF; +} + +void +_gss_mg_decode_be_uint32(const void *ptr, uint32_t *n) +{ + const uint8_t *p = ptr; + *n = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | (p[3] << 0); +} + +void +_gss_mg_encode_le_uint16(uint16_t n, uint8_t *p) +{ + p[0] = (n >> 0 ) & 0xFF; + p[1] = (n >> 8 ) & 0xFF; +} + +void +_gss_mg_decode_le_uint16(const void *ptr, uint16_t *n) +{ + const uint8_t *p = ptr; + *n = (p[0] << 0) | (p[1] << 8); +} + +void +_gss_mg_encode_be_uint16(uint16_t n, uint8_t *p) +{ + p[0] = (n >> 8) & 0xFF; + p[1] = (n >> 0) & 0xFF; +} + +void +_gss_mg_decode_be_uint16(const void *ptr, uint16_t *n) +{ + const uint8_t *p = ptr; + *n = (p[0] << 24) | (p[1] << 16); +} + +OM_uint32 +_gss_mg_ret_oid(OM_uint32 *minor, + krb5_storage *sp, + gss_OID *oidp) +{ + krb5_data data; + gss_OID_desc oid; + OM_uint32 major; + + *minor = 0; + *oidp = GSS_C_NO_OID; + + *minor = krb5_ret_data(sp, &data); + if (*minor) + return GSS_S_FAILURE; + + if (data.length) { + oid.length = data.length; + oid.elements = data.data; + + major = _gss_intern_oid(minor, &oid, oidp); + } else + major = GSS_S_COMPLETE; + + krb5_data_free(&data); + + return major; +} + +OM_uint32 +_gss_mg_store_oid(OM_uint32 *minor, + krb5_storage *sp, + gss_const_OID oid) +{ + krb5_data data; + + if (oid) { + data.length = oid->length; + data.data = oid->elements; + } else + krb5_data_zero(&data); + + *minor = krb5_store_data(sp, data); + + return *minor ? GSS_S_FAILURE : GSS_S_COMPLETE; +} + +OM_uint32 +_gss_mg_ret_buffer(OM_uint32 *minor, + krb5_storage *sp, + gss_buffer_t buffer) +{ + krb5_data data; + + _mg_buffer_zero(buffer); + + *minor = krb5_ret_data(sp, &data); + if (*minor == 0) { + if (data.length) { + buffer->length = data.length; + buffer->value = data.data; + } else + krb5_data_free(&data); + } + + return *minor ? GSS_S_FAILURE : GSS_S_COMPLETE; +} + +OM_uint32 +_gss_mg_store_buffer(OM_uint32 *minor, + krb5_storage *sp, + gss_const_buffer_t buffer) +{ + krb5_data data; + + if (buffer) { + data.length = buffer->length; + data.data = buffer->value; + } else + krb5_data_zero(&data); + + *minor = krb5_store_data(sp, data); + + return *minor ? GSS_S_FAILURE : GSS_S_COMPLETE; +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_verify.c b/third_party/heimdal/lib/gssapi/mech/gss_verify.c new file mode 100644 index 0000000..dd53ddb --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_verify.c @@ -0,0 +1,42 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_verify.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_verify(OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + gss_buffer_t message_buffer, + gss_buffer_t token_buffer, + int *qop_state) +{ + + return (gss_verify_mic(minor_status, + context_handle, message_buffer, token_buffer, + (gss_qop_t *)qop_state)); +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_verify_mic.c b/third_party/heimdal/lib/gssapi/mech/gss_verify_mic.c new file mode 100644 index 0000000..ae3b52f --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_verify_mic.c @@ -0,0 +1,52 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_verify_mic.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_verify_mic(OM_uint32 *minor_status, + gss_const_ctx_id_t context_handle, + const gss_buffer_t message_buffer, + const gss_buffer_t token_buffer, + gss_qop_t *qop_state) +{ + struct _gss_context *ctx = (struct _gss_context *) context_handle; + gssapi_mech_interface m; + + if (qop_state) + *qop_state = 0; + if (ctx == NULL) { + *minor_status = 0; + return GSS_S_NO_CONTEXT; + } + + m = ctx->gc_mech; + + return (m->gm_verify_mic(minor_status, ctx->gc_ctx, + message_buffer, token_buffer, qop_state)); +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_wrap.c b/third_party/heimdal/lib/gssapi/mech/gss_wrap.c new file mode 100644 index 0000000..82378d3 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_wrap.c @@ -0,0 +1,71 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_wrap.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" + +/** + * Wrap a message using either confidentiality (encryption + + * signature) or sealing (signature). + * + * @param minor_status minor status code. + * @param context_handle context handle. + * @param conf_req_flag if non zero, confidentiality is requestd. + * @param qop_req type of protection needed, in most cases it GSS_C_QOP_DEFAULT should be passed in. + * @param input_message_buffer messages to wrap + * @param conf_state returns non zero if confidentiality was honoured. + * @param output_message_buffer the resulting buffer, release with gss_release_buffer(). + * + * @ingroup gssapi + */ + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_wrap(OM_uint32 *minor_status, + gss_const_ctx_id_t context_handle, + int conf_req_flag, + gss_qop_t qop_req, + const gss_buffer_t input_message_buffer, + int *conf_state, + gss_buffer_t output_message_buffer) +{ + struct _gss_context *ctx = (struct _gss_context *) context_handle; + gssapi_mech_interface m; + + if (conf_state) + *conf_state = 0; + _mg_buffer_zero(output_message_buffer); + if (ctx == NULL) { + *minor_status = 0; + return GSS_S_NO_CONTEXT; + } + + m = ctx->gc_mech; + + return (m->gm_wrap(minor_status, ctx->gc_ctx, + conf_req_flag, qop_req, input_message_buffer, + conf_state, output_message_buffer)); +} diff --git a/third_party/heimdal/lib/gssapi/mech/gss_wrap_size_limit.c b/third_party/heimdal/lib/gssapi/mech/gss_wrap_size_limit.c new file mode 100644 index 0000000..3bcd9ec --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gss_wrap_size_limit.c @@ -0,0 +1,52 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_wrap_size_limit.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_wrap_size_limit(OM_uint32 *minor_status, + gss_const_ctx_id_t context_handle, + int conf_req_flag, + gss_qop_t qop_req, + OM_uint32 req_output_size, + OM_uint32 *max_input_size) +{ + struct _gss_context *ctx = (struct _gss_context *) context_handle; + gssapi_mech_interface m; + + *max_input_size = 0; + if (ctx == NULL) { + *minor_status = 0; + return GSS_S_NO_CONTEXT; + } + + m = ctx->gc_mech; + + return (m->gm_wrap_size_limit(minor_status, ctx->gc_ctx, + conf_req_flag, qop_req, req_output_size, max_input_size)); +} diff --git a/third_party/heimdal/lib/gssapi/mech/gssapi.asn1 b/third_party/heimdal/lib/gssapi/mech/gssapi.asn1 new file mode 100644 index 0000000..96ca6bd --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gssapi.asn1 @@ -0,0 +1,12 @@ +-- $Id$ + +GSS-API DEFINITIONS ::= BEGIN + +IMPORTS HEIM_ANY_SET FROM heim; + +GSSAPIContextToken ::= [APPLICATION 0] IMPLICIT SEQUENCE { + thisMech OBJECT IDENTIFIER, + innerContextToken HEIM_ANY_SET +} + +END diff --git a/third_party/heimdal/lib/gssapi/mech/gssspi_exchange_meta_data.c b/third_party/heimdal/lib/gssapi/mech/gssspi_exchange_meta_data.c new file mode 100644 index 0000000..fa98cbd --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gssspi_exchange_meta_data.c @@ -0,0 +1,115 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Portions Copyright (c) 2009 Apple Inc. All rights reserved. + * Portions Copyright (c) 2019 AuriStor, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gssspi_exchange_meta_data( + OM_uint32 *minor_status, + gss_const_OID input_mech_type, + gss_cred_id_t input_cred_handle, + gss_ctx_id_t *context_handle, + gss_const_name_t target_name, + OM_uint32 req_flags, + gss_const_buffer_t meta_data) +{ + OM_uint32 major_status, junk; + gssapi_mech_interface m; + struct _gss_name *name = (struct _gss_name *) target_name; + struct _gss_mechanism_name *mn; + struct _gss_context *ctx = (struct _gss_context *) *context_handle; + gss_cred_id_t cred_handle; + int allocated_ctx; + gss_const_OID mech_type = input_mech_type; + + *minor_status = 0; + + if (mech_type == GSS_C_NO_OID) + return GSS_S_BAD_MECH; + + if (ctx == NULL) { + ctx = calloc(1, sizeof(struct _gss_context)); + if (ctx == NULL) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + m = ctx->gc_mech = __gss_get_mechanism(mech_type); + if (m == NULL) { + free(ctx); + return GSS_S_BAD_MECH; + } + allocated_ctx = 1; + } else { + m = ctx->gc_mech; + mech_type = &m->gm_mech_oid; + allocated_ctx = 0; + } + + if (m->gm_exchange_meta_data == NULL) { + major_status = GSS_S_BAD_MECH; + goto cleanup; + } + + major_status = _gss_find_mn(minor_status, name, mech_type, &mn); + if (major_status != GSS_S_COMPLETE) + goto cleanup; + + if (m->gm_flags & GM_USE_MG_CRED) + cred_handle = input_cred_handle; + else + cred_handle = _gss_mg_find_mech_cred(input_cred_handle, mech_type); + + if (input_cred_handle != GSS_C_NO_CREDENTIAL && + cred_handle == NULL) { + major_status = GSS_S_NO_CRED; + goto cleanup; + } + + /* note: mechanism is not obligated to allocate a context on success */ + major_status = m->gm_exchange_meta_data(minor_status, + mech_type, + cred_handle, + &ctx->gc_ctx, + mn ? mn->gmn_name : GSS_C_NO_NAME, + req_flags, + meta_data); + if (major_status != GSS_S_COMPLETE) + _gss_mg_error(m, *minor_status); + +cleanup: + if (allocated_ctx && major_status != GSS_S_COMPLETE) + gss_delete_sec_context(&junk, (gss_ctx_id_t *)&ctx, GSS_C_NO_BUFFER); + + *context_handle = (gss_ctx_id_t) ctx; + + _gss_mg_log(10, "gss-emd: return %d/%d", (int)major_status, (int)*minor_status); + + return major_status; +} diff --git a/third_party/heimdal/lib/gssapi/mech/gssspi_query_mechanism_info.c b/third_party/heimdal/lib/gssapi/mech/gssspi_query_mechanism_info.c new file mode 100644 index 0000000..82fe9d9 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gssspi_query_mechanism_info.c @@ -0,0 +1,55 @@ +/*- + * Copyright (c) 2019 AuriStor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gssspi_query_mechanism_info( + OM_uint32 *minor_status, + gss_const_OID mech_type, + unsigned char auth_scheme[16]) +{ + OM_uint32 major_status; + gssapi_mech_interface m; + + *minor_status = 0; + + if (mech_type == GSS_C_NO_OID) + return GSS_S_BAD_MECH; + + m = __gss_get_mechanism(mech_type); + if (m == NULL || m->gm_query_mechanism_info == NULL) + return GSS_S_BAD_MECH; + + major_status = m->gm_query_mechanism_info(minor_status, + mech_type, + auth_scheme); + + if (major_status != GSS_S_COMPLETE) + _gss_mg_error(m, *minor_status); + + return major_status; +} diff --git a/third_party/heimdal/lib/gssapi/mech/gssspi_query_meta_data.c b/third_party/heimdal/lib/gssapi/mech/gssspi_query_meta_data.c new file mode 100644 index 0000000..490bbc9 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/gssspi_query_meta_data.c @@ -0,0 +1,117 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Portions Copyright (c) 2009 Apple Inc. All rights reserved. + * Portions Copyright (c) 2019 AuriStor, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gssspi_query_meta_data( + OM_uint32 *minor_status, + gss_const_OID input_mech_type, + gss_cred_id_t input_cred_handle, + gss_ctx_id_t *context_handle, + gss_const_name_t target_name, + OM_uint32 req_flags, + gss_buffer_t meta_data) +{ + OM_uint32 major_status, junk; + gssapi_mech_interface m; + struct _gss_name *name = (struct _gss_name *) target_name; + struct _gss_mechanism_name *mn; + struct _gss_context *ctx = (struct _gss_context *) *context_handle; + gss_cred_id_t cred_handle; + int allocated_ctx; + gss_const_OID mech_type = input_mech_type; + + *minor_status = 0; + + _mg_buffer_zero(meta_data); + + if (mech_type == GSS_C_NO_OID) + return GSS_S_BAD_MECH; + + if (ctx == NULL) { + ctx = calloc(1, sizeof(struct _gss_context)); + if (ctx == NULL) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + m = ctx->gc_mech = __gss_get_mechanism(mech_type); + if (m == NULL) { + free(ctx); + return GSS_S_BAD_MECH; + } + allocated_ctx = 1; + } else { + m = ctx->gc_mech; + mech_type = &m->gm_mech_oid; + allocated_ctx = 0; + } + + if (m->gm_query_meta_data == NULL) { + major_status = GSS_S_BAD_MECH; + goto cleanup; + } + + major_status = _gss_find_mn(minor_status, name, mech_type, &mn); + if (major_status != GSS_S_COMPLETE) + goto cleanup; + + if (m->gm_flags & GM_USE_MG_CRED) + cred_handle = input_cred_handle; + else + cred_handle = _gss_mg_find_mech_cred(input_cred_handle, mech_type); + + if (input_cred_handle != GSS_C_NO_CREDENTIAL && + cred_handle == NULL) { + major_status = GSS_S_NO_CRED; + goto cleanup; + } + + /* note: mechanism is not obligated to allocate a context on success */ + major_status = m->gm_query_meta_data(minor_status, + mech_type, + cred_handle, + &ctx->gc_ctx, + mn ? mn->gmn_name : GSS_C_NO_NAME, + req_flags, + meta_data); + if (major_status != GSS_S_COMPLETE) + _gss_mg_error(m, *minor_status); + +cleanup: + if (allocated_ctx && major_status != GSS_S_COMPLETE) + gss_delete_sec_context(&junk, (gss_ctx_id_t *)&ctx, GSS_C_NO_BUFFER); + + *context_handle = (gss_ctx_id_t) ctx; + + _gss_mg_log(10, "gss-qmd: return %d/%d", (int)major_status, (int)*minor_status); + + return major_status; +} diff --git a/third_party/heimdal/lib/gssapi/mech/mech.5 b/third_party/heimdal/lib/gssapi/mech/mech.5 new file mode 100644 index 0000000..56e916e --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/mech.5 @@ -0,0 +1,94 @@ +.\" Copyright (c) 2005 Doug Rabson +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD: src/lib/libgssapi/mech.5,v 1.1 2005/12/29 14:40:20 dfr Exp $ +.Dd November 14, 2005 +.Dt MECH 5 +.Os +.Sh NAME +.Nm mech , +.Nm qop +.Nd "GSS-API Mechanism and QOP files" +.Sh SYNOPSIS +.Pa "/etc/gss/mech" +.Pa "/etc/gss/qop" +.Sh DESCRIPTION +The +.Pa "/etc/gss/mech" +file contains a list of installed GSS-API security mechanisms. +Each line of the file either contains a comment if the first character +is '#' or it contains five fields with the following meanings: +.Bl -tag +.It Name +The name of this GSS-API mechanism. +.It Object identifier +The OID for this mechanism. +.It Library +A shared library containing the implementation of this mechanism. +.It Kernel module (optional) +A kernel module containing the implementation of this mechanism (not +yet supported in FreeBSD). +.It Library options (optional) +Optionsal parameters interpreted by the mechanism. Library options +must be enclosed in brackets ([ ]) to differentiate them from the +optional kernel module entry. +.El +.Pp +The +.Pa "/etc/gss/qop" +file contains a list of Quality of Protection values for use with +GSS-API. +Each line of the file either contains a comment if the first character +is '#' or it contains three fields with the following meanings: +.Bl -tag +.It QOP string +The name of this Quality of Protection algorithm. +.It QOP value +The numeric value used to select this algorithm for use with GSS-API +functions such as +.Xr gss_get_mic 3 . +.It Mechanism name +The GSS-API mechanism name that corresponds to this algorithm. +.El +.Sh EXAMPLES +This is a typical entry from +.Pa "/etc/gss/mech" : +.Bd -literal +kerberosv5 1.2.840.113554.1.2.2 /usr/lib/libgssapi_krb5.so.8 - +.Ed +.Pp +This is a typical entry from +.Pa "/etc/gss/qop" : +.Bd -literal +GSS_KRB5_CONF_C_QOP_DES 0x0100 kerberosv5 +.Ed +.Sh HISTORY +The +.Nm +manual page example first appeared in +.Fx 7.0 . +.Sh AUTHORS +This +manual page was written by +.An Doug Rabson Aq Mt dfr@FreeBSD.org . diff --git a/third_party/heimdal/lib/gssapi/mech/mech_locl.h b/third_party/heimdal/lib/gssapi/mech/mech_locl.h new file mode 100644 index 0000000..d451b87 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/mech_locl.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2006 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* $Id$ */ + +#include <config.h> + +#include <roken.h> + +#include <krb5-types.h> + +#include <ctype.h> + +#include <heimbase.h> + +#include <gssapi_asn1.h> +#include <der.h> + +#include <gssapi.h> +#include <gssapi_mech.h> +#include <gssapi_krb5.h> +#include <gssapi_spnego.h> + +#include <heimqueue.h> + +#include "context.h" +#include "cred.h" +#include "mech_switch.h" +#include "name.h" +#include "utils.h" +#include "compat.h" + +#define _mg_buffer_zero(buffer) \ + do { \ + if (buffer) { \ + (buffer)->value = NULL; \ + (buffer)->length = 0; \ + } \ + } while(0) + +#define _mg_oid_set_zero(oid_set) \ + do { \ + if (oid_set) { \ + (oid_set)->elements = NULL; \ + (oid_set)->count = 0; \ + } \ + } while(0) diff --git a/third_party/heimdal/lib/gssapi/mech/mech_switch.h b/third_party/heimdal/lib/gssapi/mech/mech_switch.h new file mode 100644 index 0000000..abc89ae --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/mech_switch.h @@ -0,0 +1,43 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/mech_switch.h,v 1.1 2005/12/29 14:40:20 dfr Exp $ + * $Id$ + */ + +#include <gssapi_mech.h> + +struct _gss_mech_switch { + HEIM_TAILQ_ENTRY(_gss_mech_switch) gm_link; + gss_OID gm_mech_oid; + gss_OID_set gm_name_types; + void *gm_so; + gssapi_mech_interface_desc gm_mech; +}; +HEIM_TAILQ_HEAD(_gss_mech_switch_list, _gss_mech_switch); +extern struct _gss_mech_switch_list _gss_mechs; +extern gss_OID_set _gss_mech_oids; + +void _gss_load_mech(void); diff --git a/third_party/heimdal/lib/gssapi/mech/name.h b/third_party/heimdal/lib/gssapi/mech/name.h new file mode 100644 index 0000000..4a03486 --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/name.h @@ -0,0 +1,77 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/name.h,v 1.1 2005/12/29 14:40:20 dfr Exp $ + * $Id$ + */ + +struct _gss_mechanism_name { + HEIM_TAILQ_ENTRY(_gss_mechanism_name) gmn_link; + gssapi_mech_interface gmn_mech; /* mechanism ops for MN */ + gss_OID gmn_mech_oid; /* mechanism oid for MN */ + gss_name_t gmn_name; /* underlying MN */ +}; +HEIM_TAILQ_HEAD(_gss_mechanism_name_list, _gss_mechanism_name); + +struct _gss_name { + gss_OID gn_type; /* type of name */ + gss_buffer_desc gn_value; /* value (as imported) */ + struct _gss_mechanism_name_list gn_mn; /* list of MNs */ +}; + +OM_uint32 + _gss_find_mn(OM_uint32 *, struct _gss_name *, gss_const_OID, + struct _gss_mechanism_name **); +struct _gss_name * + _gss_create_name(gss_name_t new_mn, gssapi_mech_interface m); +void _gss_mg_release_name(struct _gss_name *); + + +void _gss_mg_check_name(gss_const_name_t name); + +gss_name_t + _gss_mg_get_underlying_mech_name(gss_name_t name, gss_const_OID mech); + +OM_uint32 +_gss_mech_import_name(OM_uint32 * minor_status, + gss_const_OID mech, + struct _gss_name_type *names, + const gss_buffer_t input_name_buffer, + gss_const_OID input_name_type, + gss_name_t *output_name); + +OM_uint32 +gss_mg_export_name(OM_uint32 *minor_status, + const gss_const_OID mech, + const void *name, + size_t length, + gss_buffer_t exported_name); + +OM_uint32 +_gss_mech_inquire_names_for_mech(OM_uint32 * minor_status, + struct _gss_name_type *names, + gss_OID_set *name_types); + + diff --git a/third_party/heimdal/lib/gssapi/mech/utils.h b/third_party/heimdal/lib/gssapi/mech/utils.h new file mode 100644 index 0000000..208a59c --- /dev/null +++ b/third_party/heimdal/lib/gssapi/mech/utils.h @@ -0,0 +1,82 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/utils.h,v 1.1 2005/12/29 14:40:20 dfr Exp $ + * $Id$ + */ + +OM_uint32 _gss_free_oid(OM_uint32 *, gss_OID); +OM_uint32 _gss_intern_oid(OM_uint32 *, gss_const_OID, gss_OID *); +OM_uint32 _gss_copy_buffer(OM_uint32 *minor_status, + const gss_buffer_t from_buf, gss_buffer_t to_buf); +OM_uint32 _gss_secure_release_buffer(OM_uint32 *minor_status, + gss_buffer_t buffer); +OM_uint32 _gss_secure_release_buffer_set(OM_uint32 *minor_status, + gss_buffer_set_t *buffer_set); + +void _gss_mg_encode_le_uint32(uint32_t n, uint8_t *p); +void _gss_mg_decode_le_uint32(const void *ptr, uint32_t *n); +void _gss_mg_encode_be_uint32(uint32_t n, uint8_t *p); +void _gss_mg_decode_be_uint32(const void *ptr, uint32_t *n); + +void _gss_mg_encode_le_uint16(uint16_t n, uint8_t *p); +void _gss_mg_decode_le_uint16(const void *ptr, uint16_t *n); +void _gss_mg_encode_be_uint16(uint16_t n, uint8_t *p); +void _gss_mg_decode_be_uint16(const void *ptr, uint16_t *n); + +OM_uint32 +_gss_mg_import_rfc4121_context(OM_uint32 *minor, + uint8_t initiator_flag, + OM_uint32 gss_flags, + int32_t rfc3961_enctype, + gss_const_buffer_t session_key, + gss_ctx_id_t *rfc4121_context_handle); + +#include <krb5.h> + +/* + * Note: functions below support zero-length OIDs and buffers and will + * return NULL values. Callers should handle accordingly. + */ + +OM_uint32 +_gss_mg_ret_oid(OM_uint32 *minor, + krb5_storage *sp, + gss_OID *oidp); + +OM_uint32 +_gss_mg_store_oid(OM_uint32 *minor, + krb5_storage *sp, + gss_const_OID oid); + +OM_uint32 +_gss_mg_ret_buffer(OM_uint32 *minor, + krb5_storage *sp, + gss_buffer_t buffer); + +OM_uint32 +_gss_mg_store_buffer(OM_uint32 *minor, + krb5_storage *sp, + gss_const_buffer_t buffer); |