summaryrefslogtreecommitdiffstats
path: root/third_party/heimdal/lib/gssapi/mech
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/heimdal/lib/gssapi/mech')
-rw-r--r--third_party/heimdal/lib/gssapi/mech/compat.h94
-rw-r--r--third_party/heimdal/lib/gssapi/mech/context.c361
-rw-r--r--third_party/heimdal/lib/gssapi/mech/context.h51
-rw-r--r--third_party/heimdal/lib/gssapi/mech/cred.c81
-rw-r--r--third_party/heimdal/lib/gssapi/mech/cred.h65
-rw-r--r--third_party/heimdal/lib/gssapi/mech/doxygen.c133
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_accept_sec_context.c519
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_acquire_cred.c50
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_acquire_cred_from.c302
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_acquire_cred_impersonate_name.c51
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_acquire_cred_with_password.c85
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_add_cred.c58
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_add_cred_from.c292
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_add_cred_with_password.c88
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_add_oid_set_member.c87
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_aeap.c334
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_authorize_localname.c187
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_buffer_set.c124
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_canonicalize_name.c104
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_compare_name.c102
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_context_time.c40
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_create_empty_oid_set.c51
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_cred.c326
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_decapsulate_token.c72
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_delete_name_attribute.c65
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_delete_sec_context.c62
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_destroy_cred.c74
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_display_name.c82
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_display_name_ext.c68
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_display_status.c227
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_duplicate_cred.c153
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_duplicate_name.c93
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_duplicate_oid.c51
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_duplicate_oid_set.c57
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_encapsulate_token.c66
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_export_name.c113
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_export_name_composite.c66
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_export_sec_context.c147
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_get_mic.c51
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_get_name_attribute.c83
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_get_neg_mechs.c54
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_import_name.c323
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_import_sec_context.c147
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_indicate_mechs.c74
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_init_sec_context.c281
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_inquire_context.c120
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_inquire_cred.c218
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_inquire_cred_by_mech.c92
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_inquire_cred_by_oid.c90
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_inquire_mechs_for_name.c76
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_inquire_name.c79
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_inquire_names_for_mech.c73
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_inquire_sec_context_by_oid.c70
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_krb5.c927
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_mech_switch.c585
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_mo.c636
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_names.c262
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_oid.c370
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_oid_equal.c58
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_oid_to_str.c67
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_pname_to_uid.c197
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_process_context_token.c41
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_pseudo_random.c70
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_release_buffer.c42
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_release_cred.c66
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_release_name.c63
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_release_oid.c46
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_release_oid_set.c44
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_rfc4121.c111
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_seal.c45
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_set_cred_option.c118
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_set_name_attribute.c69
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_set_neg_mechs.c60
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_set_sec_context_option.c102
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_sign.c41
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_store_cred.c57
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_store_cred_into.c181
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_test_oid_set_member.c46
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_unseal.c43
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_unwrap.c56
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_utils.c324
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_verify.c42
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_verify_mic.c52
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_wrap.c71
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gss_wrap_size_limit.c52
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gssapi.asn112
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gssspi_exchange_meta_data.c115
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gssspi_query_mechanism_info.c55
-rw-r--r--third_party/heimdal/lib/gssapi/mech/gssspi_query_meta_data.c117
-rw-r--r--third_party/heimdal/lib/gssapi/mech/mech.594
-rw-r--r--third_party/heimdal/lib/gssapi/mech/mech_locl.h77
-rw-r--r--third_party/heimdal/lib/gssapi/mech/mech_switch.h43
-rw-r--r--third_party/heimdal/lib/gssapi/mech/name.h77
-rw-r--r--third_party/heimdal/lib/gssapi/mech/utils.h82
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, &copy_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);