summaryrefslogtreecommitdiff
path: root/source4/heimdal/lib/gssapi
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2006-11-07 06:59:56 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 14:25:03 -0500
commit3c1e780ec7e16dc6667402bbc65708bf9a5c062f (patch)
tree2102bb577ea9f00751b8c869b0a5c756fc2ae8e5 /source4/heimdal/lib/gssapi
parent8b91594e0936bbaedf5430406fcf8df3ea406c10 (diff)
downloadsamba-3c1e780ec7e16dc6667402bbc65708bf9a5c062f.tar.gz
samba-3c1e780ec7e16dc6667402bbc65708bf9a5c062f.tar.bz2
samba-3c1e780ec7e16dc6667402bbc65708bf9a5c062f.zip
r19604: This is a massive commit, and I appologise in advance for it's size.
This merges Samba4 with lorikeet-heimdal, which itself has been tracking Heimdal CVS for the past couple of weeks. This is such a big change because Heimdal reorganised it's internal structures, with the mechglue merge, and because many of our 'wishes' have been granted: we now have DCE_STYLE GSSAPI, send_to_kdc hooks and many other features merged into the mainline code. We have adapted to upstream's choice of API in these cases. In gensec_gssapi and gensec_krb5, we either expect a valid PAC, or NO PAC. This matches windows behavour. We also have an option to require the PAC to be present (which allows us to automate the testing of this code). This also includes a restructure of how the kerberos dependencies are handled, due to the fallout of the merge. Andrew Bartlett (This used to be commit 4826f1735197c2a471d771495e6d4c1051b4c471)
Diffstat (limited to 'source4/heimdal/lib/gssapi')
-rw-r--r--source4/heimdal/lib/gssapi/accept_sec_context.c1176
-rw-r--r--source4/heimdal/lib/gssapi/gssapi.h797
-rw-r--r--source4/heimdal/lib/gssapi/gssapi/gssapi.h837
-rw-r--r--source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h209
-rw-r--r--source4/heimdal/lib/gssapi/gssapi/gssapi_spnego.h58
-rw-r--r--source4/heimdal/lib/gssapi/gssapi_locl.h315
-rw-r--r--source4/heimdal/lib/gssapi/gssapi_mech.h348
-rw-r--r--source4/heimdal/lib/gssapi/init_sec_context.c1261
-rw-r--r--source4/heimdal/lib/gssapi/inquire_cred.c123
-rw-r--r--source4/heimdal/lib/gssapi/krb5/8003.c (renamed from source4/heimdal/lib/gssapi/8003.c)34
-rw-r--r--source4/heimdal/lib/gssapi/krb5/accept_sec_context.c774
-rw-r--r--source4/heimdal/lib/gssapi/krb5/acquire_cred.c (renamed from source4/heimdal/lib/gssapi/acquire_cred.c)174
-rw-r--r--source4/heimdal/lib/gssapi/krb5/add_cred.c249
-rw-r--r--source4/heimdal/lib/gssapi/krb5/add_oid_set_member.c (renamed from source4/heimdal/lib/gssapi/add_oid_set_member.c)9
-rw-r--r--source4/heimdal/lib/gssapi/krb5/address_to_krb5addr.c (renamed from source4/heimdal/lib/gssapi/address_to_krb5addr.c)14
-rw-r--r--source4/heimdal/lib/gssapi/krb5/arcfour.c (renamed from source4/heimdal/lib/gssapi/arcfour.c)263
-rw-r--r--source4/heimdal/lib/gssapi/krb5/canonicalize_name.c46
-rwxr-xr-xsource4/heimdal/lib/gssapi/krb5/cfx.c (renamed from source4/heimdal/lib/gssapi/cfx.c)286
-rwxr-xr-xsource4/heimdal/lib/gssapi/krb5/cfx.h (renamed from source4/heimdal/lib/gssapi/cfx.h)51
-rw-r--r--source4/heimdal/lib/gssapi/krb5/compare_name.c54
-rw-r--r--source4/heimdal/lib/gssapi/krb5/compat.c (renamed from source4/heimdal/lib/gssapi/compat.c)65
-rw-r--r--source4/heimdal/lib/gssapi/krb5/context_time.c (renamed from source4/heimdal/lib/gssapi/context_time.c)21
-rw-r--r--source4/heimdal/lib/gssapi/krb5/copy_ccache.c (renamed from source4/heimdal/lib/gssapi/copy_ccache.c)147
-rw-r--r--source4/heimdal/lib/gssapi/krb5/create_emtpy_oid_set.c (renamed from source4/heimdal/lib/gssapi/create_emtpy_oid_set.c)6
-rw-r--r--source4/heimdal/lib/gssapi/krb5/decapsulate.c (renamed from source4/heimdal/lib/gssapi/decapsulate.c)20
-rw-r--r--source4/heimdal/lib/gssapi/krb5/delete_sec_context.c (renamed from source4/heimdal/lib/gssapi/delete_sec_context.c)59
-rw-r--r--source4/heimdal/lib/gssapi/krb5/display_name.c (renamed from source4/heimdal/lib/gssapi/display_name.c)13
-rw-r--r--source4/heimdal/lib/gssapi/krb5/display_status.c (renamed from source4/heimdal/lib/gssapi/display_status.c)32
-rw-r--r--source4/heimdal/lib/gssapi/krb5/duplicate_name.c (renamed from source4/heimdal/lib/gssapi/duplicate_name.c)14
-rw-r--r--source4/heimdal/lib/gssapi/krb5/encapsulate.c (renamed from source4/heimdal/lib/gssapi/encapsulate.c)32
-rw-r--r--source4/heimdal/lib/gssapi/krb5/export_name.c93
-rw-r--r--source4/heimdal/lib/gssapi/krb5/export_sec_context.c239
-rw-r--r--source4/heimdal/lib/gssapi/krb5/external.c (renamed from source4/heimdal/lib/gssapi/external.c)171
-rw-r--r--source4/heimdal/lib/gssapi/krb5/get_mic.c (renamed from source4/heimdal/lib/gssapi/get_mic.c)87
-rw-r--r--source4/heimdal/lib/gssapi/krb5/gsskrb5-private.h705
-rw-r--r--source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h133
-rw-r--r--source4/heimdal/lib/gssapi/krb5/import_name.c (renamed from source4/heimdal/lib/gssapi/import_name.c)61
-rw-r--r--source4/heimdal/lib/gssapi/krb5/import_sec_context.c229
-rw-r--r--source4/heimdal/lib/gssapi/krb5/indicate_mechs.c58
-rw-r--r--source4/heimdal/lib/gssapi/krb5/init.c (renamed from source4/heimdal/lib/gssapi/init.c)70
-rw-r--r--source4/heimdal/lib/gssapi/krb5/init_sec_context.c789
-rw-r--r--source4/heimdal/lib/gssapi/krb5/inquire_context.c108
-rw-r--r--source4/heimdal/lib/gssapi/krb5/inquire_cred.c178
-rw-r--r--source4/heimdal/lib/gssapi/krb5/inquire_cred_by_mech.c (renamed from source4/heimdal/lib/gssapi/arcfour.h)86
-rw-r--r--source4/heimdal/lib/gssapi/krb5/inquire_cred_by_oid.c81
-rw-r--r--source4/heimdal/lib/gssapi/krb5/inquire_mechs_for_name.c57
-rw-r--r--source4/heimdal/lib/gssapi/krb5/inquire_names_for_mech.c80
-rw-r--r--source4/heimdal/lib/gssapi/krb5/inquire_sec_context_by_oid.c559
-rw-r--r--source4/heimdal/lib/gssapi/krb5/process_context_token.c66
-rw-r--r--source4/heimdal/lib/gssapi/krb5/release_buffer.c (renamed from source4/heimdal/lib/gssapi/release_buffer.c)6
-rw-r--r--source4/heimdal/lib/gssapi/krb5/release_cred.c (renamed from source4/heimdal/lib/gssapi/release_cred.c)45
-rw-r--r--source4/heimdal/lib/gssapi/krb5/release_name.c (renamed from source4/heimdal/lib/gssapi/release_name.c)15
-rw-r--r--source4/heimdal/lib/gssapi/krb5/release_oid_set.c (renamed from source4/heimdal/lib/gssapi/release_oid_set.c)6
-rwxr-xr-xsource4/heimdal/lib/gssapi/krb5/sequence.c (renamed from source4/heimdal/lib/gssapi/sequence.c)8
-rw-r--r--source4/heimdal/lib/gssapi/krb5/set_cred_option.c152
-rw-r--r--source4/heimdal/lib/gssapi/krb5/set_sec_context_option.c147
-rw-r--r--source4/heimdal/lib/gssapi/krb5/test_oid_set_member.c (renamed from source4/heimdal/lib/gssapi/test_oid_set_member.c)26
-rw-r--r--source4/heimdal/lib/gssapi/krb5/unwrap.c (renamed from source4/heimdal/lib/gssapi/unwrap.c)71
-rw-r--r--source4/heimdal/lib/gssapi/krb5/verify_mic.c (renamed from source4/heimdal/lib/gssapi/verify_mic.c)69
-rw-r--r--source4/heimdal/lib/gssapi/krb5/wrap.c (renamed from source4/heimdal/lib/gssapi/wrap.c)341
-rw-r--r--source4/heimdal/lib/gssapi/mech/context.h35
-rw-r--r--source4/heimdal/lib/gssapi/mech/cred.h42
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c223
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_acquire_cred.c164
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_add_cred.c175
-rw-r--r--[-rwxr-xr-x]source4/heimdal/lib/gssapi/mech/gss_add_oid_set_member.c (renamed from source4/heimdal/lib/gssapi/ccache_name.c)61
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_buffer_set.c125
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_canonicalize_name.c87
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_compare_name.c74
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_context_time.c41
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_create_empty_oid_set.c52
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_decapsulate_token.c74
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_delete_sec_context.c58
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_display_name.c74
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_display_status.c184
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_duplicate_name.c75
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_duplicate_oid.c67
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_encapsulate_token.c69
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_export_name.c56
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_export_sec_context.c73
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_get_mic.c44
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_import_name.c214
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_import_sec_context.c82
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_indicate_mechs.c65
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_init_sec_context.c133
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_inquire_context.c85
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_inquire_cred.c168
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_mech.c79
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_oid.c82
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_inquire_mechs_for_name.c77
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_inquire_names_for_mech.c73
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_inquire_sec_context_by_oid.c69
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_krb5.c710
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_mech_switch.c324
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_names.c105
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_oid_equal.c45
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_process_context_token.c42
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_release_buffer.c44
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_release_cred.c52
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_release_name.c55
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_release_oid.c59
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_release_oid_set.c45
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_seal.c46
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_set_cred_option.c115
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_set_sec_context_option.c69
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_sign.c42
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_test_oid_set_member.c47
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_unseal.c44
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_unwrap.c46
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_utils.c66
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_verify.c43
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_verify_mic.c44
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_wrap.c47
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_wrap_size_limit.c45
-rw-r--r--source4/heimdal/lib/gssapi/mech/gssapi.asn112
-rw-r--r--source4/heimdal/lib/gssapi/mech/mech_locl.h63
-rw-r--r--source4/heimdal/lib/gssapi/mech/mech_switch.h42
-rw-r--r--source4/heimdal/lib/gssapi/mech/mechqueue.h101
-rw-r--r--source4/heimdal/lib/gssapi/mech/name.h47
-rw-r--r--source4/heimdal/lib/gssapi/mech/utils.h32
-rwxr-xr-xsource4/heimdal/lib/gssapi/spnego.asn142
-rw-r--r--source4/heimdal/lib/gssapi/spnego/accept_sec_context.c873
-rw-r--r--source4/heimdal/lib/gssapi/spnego/compat.c285
-rw-r--r--source4/heimdal/lib/gssapi/spnego/context_stubs.c835
-rw-r--r--source4/heimdal/lib/gssapi/spnego/cred_stubs.c291
-rw-r--r--source4/heimdal/lib/gssapi/spnego/external.c89
-rw-r--r--source4/heimdal/lib/gssapi/spnego/init_sec_context.c578
-rw-r--r--source4/heimdal/lib/gssapi/spnego/spnego-private.h347
-rw-r--r--source4/heimdal/lib/gssapi/spnego/spnego.asn151
-rw-r--r--source4/heimdal/lib/gssapi/spnego/spnego_locl.h96
130 files changed, 16207 insertions, 4915 deletions
diff --git a/source4/heimdal/lib/gssapi/accept_sec_context.c b/source4/heimdal/lib/gssapi/accept_sec_context.c
deleted file mode 100644
index 41a54bdab1..0000000000
--- a/source4/heimdal/lib/gssapi/accept_sec_context.c
+++ /dev/null
@@ -1,1176 +0,0 @@
-/*
- * 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 "gssapi_locl.h"
-
-RCSID("$Id: accept_sec_context.c,v 1.55 2005/11/25 15:57:35 lha Exp $");
-
-HEIMDAL_MUTEX gssapi_keytab_mutex = HEIMDAL_MUTEX_INITIALIZER;
-krb5_keytab gssapi_krb5_keytab;
-
-OM_uint32
-gsskrb5_register_acceptor_identity (const char *identity)
-{
- krb5_error_code ret;
-
- ret = gssapi_krb5_init();
- if(ret)
- return GSS_S_FAILURE;
-
- HEIMDAL_MUTEX_lock(&gssapi_keytab_mutex);
-
- if(gssapi_krb5_keytab != NULL) {
- krb5_kt_close(gssapi_krb5_context, gssapi_krb5_keytab);
- gssapi_krb5_keytab = NULL;
- }
- if (identity == NULL) {
- ret = krb5_kt_default(gssapi_krb5_context, &gssapi_krb5_keytab);
- } else {
- char *p;
-
- asprintf(&p, "FILE:%s", identity);
- if(p == NULL) {
- HEIMDAL_MUTEX_unlock(&gssapi_keytab_mutex);
- return GSS_S_FAILURE;
- }
- ret = krb5_kt_resolve(gssapi_krb5_context, p, &gssapi_krb5_keytab);
- free(p);
- }
- HEIMDAL_MUTEX_unlock(&gssapi_keytab_mutex);
- if(ret)
- return GSS_S_FAILURE;
- return GSS_S_COMPLETE;
-}
-
-void
-gsskrb5_is_cfx(gss_ctx_id_t context_handle, int *is_cfx)
-{
- krb5_keyblock *key;
- int acceptor = (context_handle->more_flags & LOCAL) == 0;
- *is_cfx = 0;
-
- if (acceptor) {
- if (context_handle->auth_context->local_subkey)
- key = context_handle->auth_context->local_subkey;
- else
- key = context_handle->auth_context->remote_subkey;
- } else {
- if (context_handle->auth_context->remote_subkey)
- key = context_handle->auth_context->remote_subkey;
- else
- key = context_handle->auth_context->local_subkey;
- }
- if (key == NULL)
- key = context_handle->auth_context->keyblock;
-
- if (key == NULL)
- return;
-
- switch (key->keytype) {
- case ETYPE_DES_CBC_CRC:
- case ETYPE_DES_CBC_MD4:
- case ETYPE_DES_CBC_MD5:
- case ETYPE_DES3_CBC_MD5:
- case ETYPE_DES3_CBC_SHA1:
- case ETYPE_ARCFOUR_HMAC_MD5:
- case ETYPE_ARCFOUR_HMAC_MD5_56:
- break;
- default :
- *is_cfx = 1;
- if ((acceptor && context_handle->auth_context->local_subkey) ||
- (!acceptor && context_handle->auth_context->remote_subkey))
- context_handle->more_flags |= ACCEPTOR_SUBKEY;
- break;
- }
-}
-
-
-static OM_uint32
-gsskrb5_accept_delegated_token
- (OM_uint32 * minor_status,
- gss_ctx_id_t * context_handle,
- gss_cred_id_t * delegated_cred_handle)
-{
- krb5_data *fwd_data = &(*context_handle)->fwd_data;
- OM_uint32 *flags = &(*context_handle)->flags;
- krb5_principal principal = (*context_handle)->source;
- krb5_ccache ccache = NULL;
- krb5_error_code kret;
- int32_t ac_flags, ret = GSS_S_COMPLETE;
-
- *minor_status = 0;
-
- /* XXX Create a new delegated_cred_handle? */
- if (delegated_cred_handle == NULL)
- kret = krb5_cc_default (gssapi_krb5_context, &ccache);
- else
- kret = krb5_cc_gen_new (gssapi_krb5_context, &krb5_mcc_ops, &ccache);
- if (kret) {
- *flags &= ~GSS_C_DELEG_FLAG;
- goto out;
- }
-
- kret = krb5_cc_initialize(gssapi_krb5_context, ccache, principal);
- if (kret) {
- *flags &= ~GSS_C_DELEG_FLAG;
- goto out;
- }
-
- krb5_auth_con_removeflags(gssapi_krb5_context,
- (*context_handle)->auth_context,
- KRB5_AUTH_CONTEXT_DO_TIME,
- &ac_flags);
- kret = krb5_rd_cred2(gssapi_krb5_context,
- (*context_handle)->auth_context,
- ccache,
- fwd_data);
- if (kret)
- gssapi_krb5_set_error_string();
- krb5_auth_con_setflags(gssapi_krb5_context,
- (*context_handle)->auth_context,
- ac_flags);
- if (kret) {
- *flags &= ~GSS_C_DELEG_FLAG;
- ret = GSS_S_FAILURE;
- *minor_status = kret;
- goto out;
- }
-
- if (delegated_cred_handle) {
- ret = gss_krb5_import_cred(minor_status,
- ccache,
- NULL,
- NULL,
- delegated_cred_handle);
- if (ret != GSS_S_COMPLETE)
- goto out;
-
- (*delegated_cred_handle)->cred_flags |= GSS_CF_DESTROY_CRED_ON_RELEASE;
- ccache = NULL;
- }
-
-out:
- if (ccache) {
- if (delegated_cred_handle == NULL)
- krb5_cc_close(gssapi_krb5_context, ccache);
- else
- krb5_cc_destroy(gssapi_krb5_context, ccache);
- }
- return ret;
-}
-
-static OM_uint32
-gsskrb5_acceptor_ready(
- OM_uint32 * minor_status,
- gss_ctx_id_t * context_handle,
- gss_cred_id_t * delegated_cred_handle)
-{
- OM_uint32 ret;
- int32_t seq_number;
- int is_cfx = 0;
- OM_uint32 *flags = &(*context_handle)->flags;
-
- krb5_auth_getremoteseqnumber (gssapi_krb5_context,
- (*context_handle)->auth_context,
- &seq_number);
-
- gsskrb5_is_cfx(*context_handle, &is_cfx);
-
- ret = _gssapi_msg_order_create(minor_status,
- &(*context_handle)->order,
- _gssapi_msg_order_f(*flags),
- seq_number, 0, is_cfx);
- if (ret) return ret;
-
- if (!(*flags & GSS_C_MUTUAL_FLAG) && _gssapi_msg_order_f(*flags)) {
- krb5_auth_con_setlocalseqnumber(gssapi_krb5_context,
- (*context_handle)->auth_context,
- seq_number);
- }
-
- /*
- * We should handle the delegation ticket, in case it's there
- */
- if ((*context_handle)->fwd_data.length > 0 && (*flags & GSS_C_DELEG_FLAG)) {
- ret = gsskrb5_accept_delegated_token(minor_status,
- context_handle,
- delegated_cred_handle);
- if (ret) return ret;
- } else {
- /* Well, looks like it wasn't there after all */
- *flags &= ~GSS_C_DELEG_FLAG;
- }
-
- (*context_handle)->state = ACCEPTOR_READY;
- (*context_handle)->more_flags |= OPEN;
-
- return GSS_S_COMPLETE;
-}
-static OM_uint32
-gsskrb5_acceptor_start
- (OM_uint32 * minor_status,
- gss_ctx_id_t * context_handle,
- const gss_cred_id_t acceptor_cred_handle,
- const gss_buffer_t input_token_buffer,
- 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
- )
-{
- krb5_error_code kret;
- OM_uint32 ret = GSS_S_COMPLETE;
- krb5_data indata;
- krb5_flags ap_options;
- OM_uint32 flags;
- krb5_ticket *ticket = NULL;
- krb5_keytab keytab = NULL;
- krb5_keyblock *keyblock = NULL;
- int is_cfx = 0;
-
- krb5_data_zero (&(*context_handle)->fwd_data);
-
- /*
- * We may, or may not, have an escapsulation.
- */
- ret = gssapi_krb5_decapsulate (minor_status,
- input_token_buffer,
- &indata,
- "\x01\x00",
- GSS_KRB5_MECHANISM);
-
- if (ret) {
- /* No OID wrapping apparently available. */
- indata.length = input_token_buffer->length;
- indata.data = input_token_buffer->value;
- }
-
- /*
- * We need to get our keytab
- */
- if (acceptor_cred_handle == GSS_C_NO_CREDENTIAL) {
- if (gssapi_krb5_keytab != NULL) {
- keytab = gssapi_krb5_keytab;
- }
- } else if (acceptor_cred_handle->keytab != NULL) {
- keytab = acceptor_cred_handle->keytab;
- }
-
- /*
- * We need to check the ticket and create the AP-REP packet
- */
- kret = krb5_rd_req_return_keyblock(gssapi_krb5_context,
- &(*context_handle)->auth_context,
- &indata,
- (acceptor_cred_handle == GSS_C_NO_CREDENTIAL) ? NULL : acceptor_cred_handle->principal,
- keytab,
- &ap_options,
- &ticket,
- &keyblock);
- if (kret) {
- ret = GSS_S_FAILURE;
- *minor_status = kret;
- gssapi_krb5_set_error_string ();
- return ret;
- }
-
- /*
- * We need to remember some data on the context_handle
- */
- (*context_handle)->ticket = ticket;
- (*context_handle)->service_keyblock = keyblock;
- (*context_handle)->lifetime = ticket->ticket.endtime;
-
- /*
- * We need to copy the principal names to the context and the calling layer
- */
- kret = krb5_copy_principal(gssapi_krb5_context,
- ticket->client,
- &(*context_handle)->source);
- if (kret) {
- ret = GSS_S_FAILURE;
- *minor_status = kret;
- gssapi_krb5_set_error_string ();
- }
-
- kret = krb5_copy_principal (gssapi_krb5_context,
- ticket->server,
- &(*context_handle)->target);
- if (kret) {
- ret = GSS_S_FAILURE;
- *minor_status = kret;
- gssapi_krb5_set_error_string ();
- return ret;
- }
-
- /*
- * We need to setup some compat stuff, this assumes that context_handle->target is already set
- */
- ret = _gss_DES3_get_mic_compat(minor_status, *context_handle);
- if (ret) {
- return ret;
- }
-
- if (src_name != NULL) {
- kret = krb5_copy_principal (gssapi_krb5_context,
- ticket->client,
- src_name);
- if (kret) {
- ret = GSS_S_FAILURE;
- *minor_status = kret;
- gssapi_krb5_set_error_string ();
- return ret;
- }
- }
-
- /*
- * We need to get the flags out of the 8003 checksum
- */
- {
- krb5_authenticator authenticator;
-
- kret = krb5_auth_con_getauthenticator(gssapi_krb5_context,
- (*context_handle)->auth_context,
- &authenticator);
- if(kret) {
- ret = GSS_S_FAILURE;
- *minor_status = kret;
- gssapi_krb5_set_error_string ();
- return ret;
- }
-
- if (authenticator->cksum->cksumtype == CKSUMTYPE_GSSAPI) {
- ret = gssapi_krb5_verify_8003_checksum(minor_status,
- input_chan_bindings,
- authenticator->cksum,
- &flags,
- &(*context_handle)->fwd_data);
-
- krb5_free_authenticator(gssapi_krb5_context, &authenticator);
- if (ret) {
- return ret;
- }
- } else {
- krb5_crypto crypto;
-
- kret = krb5_crypto_init(gssapi_krb5_context,
- (*context_handle)->auth_context->keyblock,
- 0, &crypto);
- if(kret) {
- krb5_free_authenticator(gssapi_krb5_context, &authenticator);
-
- ret = GSS_S_FAILURE;
- *minor_status = kret;
- gssapi_krb5_set_error_string ();
- return ret;
- }
-
- /* Windows accepts Samba3's use of a kerberos,
- rather than GSSAPI checksum here */
- kret = krb5_verify_checksum(gssapi_krb5_context,
- crypto, KRB5_KU_AP_REQ_AUTH_CKSUM, NULL, 0,
- authenticator->cksum);
- krb5_free_authenticator(gssapi_krb5_context, &authenticator);
- krb5_crypto_destroy(gssapi_krb5_context, crypto);
-
- if(kret) {
- ret = GSS_S_BAD_SIG;
- *minor_status = kret;
- gssapi_krb5_set_error_string ();
- return ret;
- }
-
- flags = GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG;
- }
- }
-
- if(flags & GSS_C_MUTUAL_FLAG) {
- krb5_data outbuf;
-
- gsskrb5_is_cfx(*context_handle, &is_cfx);
-
- if (is_cfx != 0
- || (ap_options & AP_OPTS_USE_SUBKEY)) {
- kret = krb5_auth_con_addflags(gssapi_krb5_context,
- (*context_handle)->auth_context,
- KRB5_AUTH_CONTEXT_USE_SUBKEY,
- NULL);
- (*context_handle)->more_flags |= ACCEPTOR_SUBKEY;
- }
-
- kret = krb5_mk_rep(gssapi_krb5_context,
- (*context_handle)->auth_context,
- &outbuf);
- if (kret) {
- *minor_status = kret;
- gssapi_krb5_set_error_string ();
- return GSS_S_FAILURE;
- }
-
- if (!(flags & GSS_C_DCE_STYLE)) {
- ret = gssapi_krb5_encapsulate(minor_status,
- &outbuf,
- output_token,
- "\x02\x00",
- GSS_KRB5_MECHANISM);
- krb5_data_free (&outbuf);
- if (ret) {
- return ret;
- }
- } else {
- output_token->length = outbuf.length;
- output_token->value = outbuf.data;
- }
- }
-
- flags |= GSS_C_TRANS_FLAG;
-
- /* Remember the flags */
-
- (*context_handle)->lifetime = ticket->ticket.endtime;
- (*context_handle)->flags = flags;
- (*context_handle)->more_flags |= OPEN;
-
- if (mech_type)
- *mech_type = GSS_KRB5_MECHANISM;
-
- if (time_rec) {
- ret = gssapi_lifetime_left(minor_status,
- (*context_handle)->lifetime,
- time_rec);
- if (ret) {
- return ret;
- }
- }
-
- /*
- * When GSS_C_DCE_STYLE is in use, we need ask for a AP-REP from the client
- */
- if (flags & GSS_C_DCE_STYLE) {
- if (ret_flags) {
- /* Return flags to caller, but we haven't processed delgations yet */
- *ret_flags = flags & ~GSS_C_DELEG_FLAG;
- }
-
- (*context_handle)->state = ACCEPTOR_WAIT_FOR_DCESTYLE;
- return GSS_S_CONTINUE_NEEDED;
- }
-
- ret = gsskrb5_acceptor_ready(minor_status, context_handle, delegated_cred_handle);
-
- /*
- * We need to send the flags back to the caller
- */
-
- *ret_flags = (*context_handle)->flags;
- return ret;
-}
-
-static OM_uint32
-gsskrb5_acceptor_wait_for_dcestyle(
- OM_uint32 * minor_status,
- gss_ctx_id_t * context_handle,
- const gss_cred_id_t acceptor_cred_handle,
- const gss_buffer_t input_token_buffer,
- 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 ret;
- krb5_error_code kret;
- krb5_data inbuf;
- OM_uint32 r_seq_number;
- OM_uint32 l_seq_number;
-
- /* We know it's GSS_C_DCE_STYLE so we don't need to decapsulate the AP_REP */
- inbuf.length = input_token_buffer->length;
- inbuf.data = input_token_buffer->value;
-
- /*
- * We need to remeber the old remote seq_number, then check if the client has replied with our local seq_number,
- * and then reset the remote seq_number to the old value
- */
- {
- kret = krb5_auth_con_getlocalseqnumber(gssapi_krb5_context,
- (*context_handle)->auth_context,
- &l_seq_number);
- if (kret) {
- gssapi_krb5_set_error_string ();
- *minor_status = kret;
- return GSS_S_FAILURE;
- }
-
- kret = krb5_auth_getremoteseqnumber(gssapi_krb5_context,
- (*context_handle)->auth_context,
- &r_seq_number);
- if (kret) {
- gssapi_krb5_set_error_string ();
- *minor_status = kret;
- return GSS_S_FAILURE;
- }
-
- kret = krb5_auth_con_setremoteseqnumber(gssapi_krb5_context,
- (*context_handle)->auth_context,
- l_seq_number);
- if (kret) {
- gssapi_krb5_set_error_string ();
- *minor_status = kret;
- return GSS_S_FAILURE;
- }
- }
-
- /* We need to verify the AP_REP, but we need to flag that this
- is DCE_STYLE, so don't check the timestamps this time
- */
- {
- krb5_ap_rep_enc_part *repl;
- int32_t auth_flags;
-
- kret = krb5_auth_con_removeflags(gssapi_krb5_context,
- (*context_handle)->auth_context,
- KRB5_AUTH_CONTEXT_DO_TIME, &auth_flags);
- if (kret) { /* Can't happen */
- gssapi_krb5_set_error_string ();
- *minor_status = kret;
- return GSS_S_FAILURE;
- }
-
- kret = krb5_rd_rep(gssapi_krb5_context,
- (*context_handle)->auth_context,
- &inbuf,
- &repl);
- if (kret) {
- gssapi_krb5_set_error_string ();
- *minor_status = kret;
- return GSS_S_FAILURE;
- }
-
- /* Because the inbuf above is a final leg from client
- * to server, we don't have a use for a 'reply'
- * here */
- krb5_free_ap_rep_enc_part(gssapi_krb5_context, repl);
-
- /* Do no harm, put the flags back */
- kret = krb5_auth_con_setflags(gssapi_krb5_context,
- (*context_handle)->auth_context,
- auth_flags);
- if (kret) { /* Can't happen */
- gssapi_krb5_set_error_string ();
- *minor_status = kret;
- return GSS_S_FAILURE;
- }
- }
-
- /* We need to check the liftime */
- {
- OM_uint32 lifetime_rec;
-
- ret = gssapi_lifetime_left(minor_status,
- (*context_handle)->lifetime,
- &lifetime_rec);
- if (ret) {
- return ret;
- }
- if (lifetime_rec == 0) {
- return GSS_S_CONTEXT_EXPIRED;
- }
-
- if (time_rec) *time_rec = lifetime_rec;
- }
-
- /* We need to give the caller the flags which are in use */
- if (ret_flags) *ret_flags = (*context_handle)->flags;
-
- if (src_name) {
- kret = krb5_copy_principal(gssapi_krb5_context,
- (*context_handle)->source,
- src_name);
- if (kret) {
- *minor_status = kret;
- gssapi_krb5_set_error_string ();
- return GSS_S_FAILURE;
- }
- }
-
- /*
- * After the krb5_rd_rep() the remote and local seq_number should be the same,
- * because the client just replies the seq_number from our AP-REP in its AP-REP,
- * but then the client uses the seq_number from its AP-REQ for GSS_wrap()
- */
- {
- OM_uint32 tmp_r_seq_number;
- OM_uint32 tmp_l_seq_number;
-
- kret = krb5_auth_getremoteseqnumber(gssapi_krb5_context,
- (*context_handle)->auth_context,
- &tmp_r_seq_number);
- if (kret) {
- gssapi_krb5_set_error_string ();
- *minor_status = kret;
- return GSS_S_FAILURE;
- }
-
- kret = krb5_auth_con_getlocalseqnumber(gssapi_krb5_context,
- (*context_handle)->auth_context,
- &tmp_l_seq_number);
- if (kret) {
- gssapi_krb5_set_error_string ();
- *minor_status = kret;
- return GSS_S_FAILURE;
- }
-
- /*
- * Here we check if the client has responsed with our local seq_number,
- */
- if (tmp_r_seq_number != tmp_l_seq_number) {
- return GSS_S_UNSEQ_TOKEN;
- }
- }
-
- /*
- * We need to reset the remote seq_number, because the client will use,
- * the old one for the GSS_wrap() calls
- */
- {
- kret = krb5_auth_con_setremoteseqnumber(gssapi_krb5_context,
- (*context_handle)->auth_context,
- r_seq_number);
- if (kret) {
- gssapi_krb5_set_error_string ();
- *minor_status = kret;
- return GSS_S_FAILURE;
- }
- }
-
- return gsskrb5_acceptor_ready(minor_status, context_handle, delegated_cred_handle);
-}
-
-static OM_uint32
-gsskrb5_accept_sec_context
- (OM_uint32 * minor_status,
- gss_ctx_id_t * context_handle,
- const gss_cred_id_t acceptor_cred_handle,
- const gss_buffer_t input_token_buffer,
- 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 ret = GSS_S_COMPLETE;
- krb5_data fwd_data;
- gss_ctx_id_t local_context;
- OM_uint32 minor_status2;
- GSSAPI_KRB5_INIT();
-
- krb5_data_zero (&fwd_data);
- output_token->length = 0;
- output_token->value = NULL;
-
- if (src_name != NULL)
- *src_name = NULL;
- if (mech_type)
- *mech_type = GSS_KRB5_MECHANISM;
-
- if (*context_handle == GSS_C_NO_CONTEXT) {
- ret = _gsskrb5_create_ctx(minor_status,
- &local_context,
- input_chan_bindings,
- ACCEPTOR_START);
- if (ret) return ret;
- } else {
- local_context = *context_handle;
- }
-
- /*
- * TODO: check the channel_bindings
- * (above just sets them to krb5 layer)
- */
-
- HEIMDAL_MUTEX_lock(&(local_context)->ctx_id_mutex);
-
- switch ((local_context)->state) {
- case ACCEPTOR_START:
- ret = gsskrb5_acceptor_start(minor_status,
- &local_context,
- acceptor_cred_handle,
- input_token_buffer,
- input_chan_bindings,
- src_name,
- mech_type,
- output_token,
- ret_flags,
- time_rec,
- delegated_cred_handle);
- break;
- case ACCEPTOR_WAIT_FOR_DCESTYLE:
- ret = gsskrb5_acceptor_wait_for_dcestyle(minor_status,
- &local_context,
- acceptor_cred_handle,
- input_token_buffer,
- input_chan_bindings,
- src_name,
- mech_type,
- output_token,
- ret_flags,
- time_rec,
- delegated_cred_handle);
- break;
- case ACCEPTOR_READY:
- /* this function should not be called after it has returned GSS_S_COMPLETE */
- ret = GSS_S_BAD_STATUS;
- break;
- default:
- /* TODO: is this correct here? --metze */
- ret = GSS_S_BAD_STATUS;
- break;
- }
-
- HEIMDAL_MUTEX_unlock(&(local_context)->ctx_id_mutex);
-
- if (*context_handle == GSS_C_NO_CONTEXT) {
- if (ret == GSS_S_COMPLETE || ret == GSS_S_CONTINUE_NEEDED) {
- *context_handle = local_context;
- } else {
- gss_delete_sec_context(&minor_status2,
- &local_context,
- NULL);
- }
- }
-
- return ret;
-}
-
-static OM_uint32
-code_NegTokenArg(OM_uint32 *minor_status,
- const NegTokenTarg *targ,
- krb5_data *data,
- u_char **ret_buf)
-{
- OM_uint32 ret;
- u_char *buf;
- size_t buf_size, buf_len;
-
- buf_size = 1024;
- buf = malloc(buf_size);
- if (buf == NULL) {
- *minor_status = ENOMEM;
- return GSS_S_FAILURE;
- }
-
- do {
- ret = encode_NegTokenTarg(buf + buf_size - 1,
- buf_size,
- targ, &buf_len);
- if (ret == 0) {
- size_t tmp;
-
- ret = der_put_length_and_tag(buf + buf_size - buf_len - 1,
- buf_size - buf_len,
- buf_len,
- ASN1_C_CONTEXT,
- CONS,
- 1,
- &tmp);
- if (ret == 0)
- buf_len += tmp;
- }
- if (ret) {
- if (ret == ASN1_OVERFLOW) {
- u_char *tmp;
-
- buf_size *= 2;
- tmp = realloc (buf, buf_size);
- if (tmp == NULL) {
- *minor_status = ENOMEM;
- free(buf);
- return GSS_S_FAILURE;
- }
- buf = tmp;
- } else {
- *minor_status = ret;
- free(buf);
- return GSS_S_FAILURE;
- }
- }
- } while (ret == ASN1_OVERFLOW);
-
- data->data = buf + buf_size - buf_len;
- data->length = buf_len;
- *ret_buf = buf;
- return GSS_S_COMPLETE;
-}
-
-static OM_uint32
-send_reject (OM_uint32 *minor_status,
- gss_buffer_t output_token)
-{
- NegTokenTarg targ;
- krb5_data data;
- u_char *buf;
- OM_uint32 ret;
-
- ALLOC(targ.negResult, 1);
- if (targ.negResult == NULL) {
- *minor_status = ENOMEM;
- return GSS_S_FAILURE;
- }
- *(targ.negResult) = reject;
- targ.supportedMech = NULL;
- targ.responseToken = NULL;
- targ.mechListMIC = NULL;
-
- ret = code_NegTokenArg (minor_status, &targ, &data, &buf);
- free_NegTokenTarg(&targ);
- if (ret)
- return ret;
-
-#if 0
- ret = _gssapi_encapsulate(minor_status,
- &data,
- output_token,
- GSS_SPNEGO_MECHANISM);
-#else
- output_token->value = malloc(data.length);
- if (output_token->value == NULL) {
- *minor_status = ENOMEM;
- ret = GSS_S_FAILURE;
- } else {
- output_token->length = data.length;
- memcpy(output_token->value, data.data, output_token->length);
- }
-#endif
- free(buf);
- if (ret)
- return ret;
- return GSS_S_BAD_MECH;
-}
-
-static OM_uint32
-send_accept (OM_uint32 *minor_status,
- OM_uint32 major_status,
- gss_buffer_t output_token,
- gss_buffer_t mech_token,
- gss_ctx_id_t context_handle,
- const MechTypeList *mechtypelist)
-{
- NegTokenTarg targ;
- krb5_data data;
- u_char *buf;
- OM_uint32 ret;
- gss_buffer_desc mech_buf, mech_mic_buf;
- krb5_boolean require_mic;
-
- memset(&targ, 0, sizeof(targ));
- ALLOC(targ.negResult, 1);
- if (targ.negResult == NULL) {
- *minor_status = ENOMEM;
- return GSS_S_FAILURE;
- }
- *(targ.negResult) = accept_completed;
-
- ALLOC(targ.supportedMech, 1);
- if (targ.supportedMech == NULL) {
- free_NegTokenTarg(&targ);
- *minor_status = ENOMEM;
- return GSS_S_FAILURE;
- }
-
- ret = der_get_oid(GSS_KRB5_MECHANISM->elements,
- GSS_KRB5_MECHANISM->length,
- targ.supportedMech,
- NULL);
- if (ret) {
- free_NegTokenTarg(&targ);
- *minor_status = ENOMEM;
- return GSS_S_FAILURE;
- }
-
- if (mech_token != NULL && mech_token->length != 0) {
- ALLOC(targ.responseToken, 1);
- if (targ.responseToken == NULL) {
- free_NegTokenTarg(&targ);
- *minor_status = ENOMEM;
- return GSS_S_FAILURE;
- }
- targ.responseToken->length = mech_token->length;
- targ.responseToken->data = mech_token->value;
- mech_token->length = 0;
- mech_token->value = NULL;
- } else {
- targ.responseToken = NULL;
- }
-
- ret = _gss_spnego_require_mechlist_mic(minor_status, context_handle,
- &require_mic);
- if (ret) {
- free_NegTokenTarg(&targ);
- return ret;
- }
-
- if (major_status == GSS_S_COMPLETE && require_mic) {
- size_t buf_len;
-
- ALLOC(targ.mechListMIC, 1);
- if (targ.mechListMIC == NULL) {
- free_NegTokenTarg(&targ);
- *minor_status = ENOMEM;
- return GSS_S_FAILURE;
- }
-
- ASN1_MALLOC_ENCODE(MechTypeList, mech_buf.value, mech_buf.length,
- mechtypelist, &buf_len, ret);
- if (ret) {
- free_NegTokenTarg(&targ);
- return ret;
- }
- if (mech_buf.length != buf_len)
- abort();
-
- ret = gss_get_mic(minor_status, context_handle, 0, &mech_buf,
- &mech_mic_buf);
- free (mech_buf.value);
- if (ret) {
- free_NegTokenTarg(&targ);
- return ret;
- }
-
- targ.mechListMIC->length = mech_mic_buf.length;
- targ.mechListMIC->data = mech_mic_buf.value;
- } else
- targ.mechListMIC = NULL;
-
- ret = code_NegTokenArg (minor_status, &targ, &data, &buf);
- free_NegTokenTarg(&targ);
- if (ret)
- return ret;
-
-#if 0
- ret = _gssapi_encapsulate(minor_status,
- &data,
- output_token,
- GSS_SPNEGO_MECHANISM);
-#else
- output_token->value = malloc(data.length);
- if (output_token->value == NULL) {
- *minor_status = ENOMEM;
- ret = GSS_S_FAILURE;
- } else {
- output_token->length = data.length;
- memcpy(output_token->value, data.data, output_token->length);
- }
-#endif
- free(buf);
- if (ret)
- return ret;
- return GSS_S_COMPLETE;
-}
-
-static OM_uint32
-spnego_accept_sec_context
- (OM_uint32 * minor_status,
- gss_ctx_id_t * context_handle,
- const gss_cred_id_t acceptor_cred_handle,
- const gss_buffer_t input_token_buffer,
- 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 ret, ret2;
- NegTokenInit ni;
- size_t ni_len;
- int i;
- int found = 0;
- krb5_data data;
- size_t len, taglen;
-
- output_token->length = 0;
- output_token->value = NULL;
-
- ret = _gssapi_decapsulate (minor_status,
- input_token_buffer,
- &data,
- GSS_SPNEGO_MECHANISM);
- if (ret)
- return ret;
-
- ret = der_match_tag_and_length(data.data, data.length,
- ASN1_C_CONTEXT, CONS, 0, &len, &taglen);
- if (ret)
- return ret;
-
- if(len > data.length - taglen)
- return ASN1_OVERRUN;
-
- ret = decode_NegTokenInit((const unsigned char *)data.data + taglen, len,
- &ni, &ni_len);
- if (ret)
- return GSS_S_DEFECTIVE_TOKEN;
-
- if (ni.mechTypes == NULL) {
- free_NegTokenInit(&ni);
- return send_reject (minor_status, output_token);
- }
-
- for (i = 0; !found && i < ni.mechTypes->len; ++i) {
- unsigned char mechbuf[17];
- size_t mech_len;
-
- ret = der_put_oid (mechbuf + sizeof(mechbuf) - 1,
- sizeof(mechbuf),
- &ni.mechTypes->val[i],
- &mech_len);
- if (ret) {
- free_NegTokenInit(&ni);
- return GSS_S_DEFECTIVE_TOKEN;
- }
- if (mech_len == GSS_KRB5_MECHANISM->length
- && memcmp(GSS_KRB5_MECHANISM->elements,
- mechbuf + sizeof(mechbuf) - mech_len,
- mech_len) == 0)
- found = 1;
- }
- if (found) {
- gss_buffer_desc ibuf, obuf;
- gss_buffer_t ot = NULL;
- OM_uint32 minor;
-
- if (ni.mechToken != NULL) {
- ibuf.length = ni.mechToken->length;
- ibuf.value = ni.mechToken->data;
-
- ret = gsskrb5_accept_sec_context(&minor,
- context_handle,
- acceptor_cred_handle,
- &ibuf,
- input_chan_bindings,
- src_name,
- mech_type,
- &obuf,
- ret_flags,
- time_rec,
- delegated_cred_handle);
- if (ret == GSS_S_COMPLETE || ret == GSS_S_CONTINUE_NEEDED) {
- ot = &obuf;
- } else {
- free_NegTokenInit(&ni);
- send_reject (minor_status, output_token);
- return ret;
- }
- }
- ret2 = send_accept (minor_status, ret, output_token, ot,
- *context_handle, ni.mechTypes);
- if (ret2 != GSS_S_COMPLETE)
- ret = ret2;
- if (ot != NULL)
- gss_release_buffer(&minor, ot);
- free_NegTokenInit(&ni);
- return ret;
- } else {
- free_NegTokenInit(&ni);
- return send_reject (minor_status, output_token);
- }
-}
-
-OM_uint32
-gss_accept_sec_context
- (OM_uint32 * minor_status,
- gss_ctx_id_t * context_handle,
- const gss_cred_id_t acceptor_cred_handle,
- const gss_buffer_t input_token_buffer,
- 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 ret;
- ssize_t mech_len;
- const u_char *p;
-
- *minor_status = 0;
-
- mech_len = gssapi_krb5_get_mech (input_token_buffer->value,
- input_token_buffer->length,
- &p);
-
- /* This could be 'dce style' kerberos, where the OID is missing :-( */
- if ((mech_len < 0) || ((mech_len == GSS_KRB5_MECHANISM->length)
- && memcmp(p, GSS_KRB5_MECHANISM->elements, mech_len) == 0))
- ret = gsskrb5_accept_sec_context(minor_status,
- context_handle,
- acceptor_cred_handle,
- input_token_buffer,
- input_chan_bindings,
- src_name,
- mech_type,
- output_token,
- ret_flags,
- time_rec,
- delegated_cred_handle);
- else if (mech_len == GSS_SPNEGO_MECHANISM->length
- && memcmp(p, GSS_SPNEGO_MECHANISM->elements, mech_len) == 0)
- ret = spnego_accept_sec_context(minor_status,
- context_handle,
- acceptor_cred_handle,
- input_token_buffer,
- input_chan_bindings,
- src_name,
- mech_type,
- output_token,
- ret_flags,
- time_rec,
- delegated_cred_handle);
- else
- return GSS_S_BAD_MECH;
-
- return ret;
-}
diff --git a/source4/heimdal/lib/gssapi/gssapi.h b/source4/heimdal/lib/gssapi/gssapi.h
index eac2737f43..340b35377d 100644
--- a/source4/heimdal/lib/gssapi/gssapi.h
+++ b/source4/heimdal/lib/gssapi/gssapi.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997 - 2006 Kungliga Tekniska Högskolan
+ * Copyright (c) 2006 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -31,802 +31,11 @@
* SUCH DAMAGE.
*/
-/* $Id: gssapi.h,v 1.40 2006/05/05 11:08:29 lha Exp $ */
+/* $Id: gssapi.h,v 1.50 2006/10/07 20:57:15 lha Exp $ */
#ifndef GSSAPI_H_
#define GSSAPI_H_
-/*
- * First, include stddef.h to get size_t defined.
- */
-#include <stddef.h>
-
-#include <krb5-types.h>
-
-/*
- * Now define the three implementation-dependent types.
- */
-
-typedef uint32_t OM_uint32;
-
-typedef uint32_t gss_uint32;
-
-/*
- * This is to avoid having to include <krb5.h>
- */
-
-struct krb5_auth_context_data;
-
-struct Principal;
-
-/* typedef void *gss_name_t; */
-
-typedef struct Principal *gss_name_t;
-
-struct gss_ctx_id_t_desc_struct;
-typedef struct gss_ctx_id_t_desc_struct *gss_ctx_id_t;
-
-typedef struct gss_OID_desc_struct {
- OM_uint32 length;
- void *elements;
-} gss_OID_desc, *gss_OID;
-
-typedef struct gss_OID_set_desc_struct {
- size_t count;
- gss_OID elements;
-} gss_OID_set_desc, *gss_OID_set;
-
-struct krb5_keytab_data;
-
-struct krb5_ccache_data;
-
-typedef int gss_cred_usage_t;
-
-struct gss_cred_id_t_desc_struct;
-typedef struct gss_cred_id_t_desc_struct *gss_cred_id_t;
-
-typedef struct gss_buffer_desc_struct {
- size_t length;
- void *value;
-} gss_buffer_desc, *gss_buffer_t;
-
-typedef struct gss_channel_bindings_struct {
- OM_uint32 initiator_addrtype;
- gss_buffer_desc initiator_address;
- OM_uint32 acceptor_addrtype;
- gss_buffer_desc acceptor_address;
- gss_buffer_desc application_data;
-} *gss_channel_bindings_t;
-
-/*
- * For now, define a QOP-type as an OM_uint32
- */
-typedef OM_uint32 gss_qop_t;
-
-/*
- * Flag bits for context-level services.
- */
-#define GSS_C_DELEG_FLAG 1 /* 0x00000001 */
-#define GSS_C_MUTUAL_FLAG 2 /* 0x00000002 */
-#define GSS_C_REPLAY_FLAG 4 /* 0x00000004 */
-#define GSS_C_SEQUENCE_FLAG 8 /* 0x00000008 */
-#define GSS_C_CONF_FLAG 16 /* 0x00000010 */
-#define GSS_C_INTEG_FLAG 32 /* 0x00000020 */
-#define GSS_C_ANON_FLAG 64 /* 0x00000040 */
-#define GSS_C_PROT_READY_FLAG 128 /* 0x00000080 */
-#define GSS_C_TRANS_FLAG 256 /* 0x00000100 */
-
-/* these are from draft-brezak-win2k-krb-rc4-hmac-04.txt */
-#define GSS_C_DCE_STYLE 4096 /* 0x00001000 */
-#define GSS_C_IDENTIFY_FLAG 8192 /* 0x00002000 */
-#define GSS_C_EXTENDED_ERROR_FLAG 16384 /* 0x00004000 */
-
-/*
- * Credential usage options
- */
-#define GSS_C_BOTH 0
-#define GSS_C_INITIATE 1
-#define GSS_C_ACCEPT 2
-
-/*
- * Status code types for gss_display_status
- */
-#define GSS_C_GSS_CODE 1
-#define GSS_C_MECH_CODE 2
-
-/*
- * The constant definitions for channel-bindings address families
- */
-#define GSS_C_AF_UNSPEC 0
-#define GSS_C_AF_LOCAL 1
-#define GSS_C_AF_INET 2
-#define GSS_C_AF_IMPLINK 3
-#define GSS_C_AF_PUP 4
-#define GSS_C_AF_CHAOS 5
-#define GSS_C_AF_NS 6
-#define GSS_C_AF_NBS 7
-#define GSS_C_AF_ECMA 8
-#define GSS_C_AF_DATAKIT 9
-#define GSS_C_AF_CCITT 10
-#define GSS_C_AF_SNA 11
-#define GSS_C_AF_DECnet 12
-#define GSS_C_AF_DLI 13
-#define GSS_C_AF_LAT 14
-#define GSS_C_AF_HYLINK 15
-#define GSS_C_AF_APPLETALK 16
-#define GSS_C_AF_BSC 17
-#define GSS_C_AF_DSS 18
-#define GSS_C_AF_OSI 19
-#define GSS_C_AF_X25 21
-#define GSS_C_AF_INET6 24
-
-#define GSS_C_AF_NULLADDR 255
-
-/*
- * Various Null values
- */
-#define GSS_C_NO_NAME ((gss_name_t) 0)
-#define GSS_C_NO_BUFFER ((gss_buffer_t) 0)
-#define GSS_C_NO_OID ((gss_OID) 0)
-#define GSS_C_NO_OID_SET ((gss_OID_set) 0)
-#define GSS_C_NO_CONTEXT ((gss_ctx_id_t) 0)
-#define GSS_C_NO_CREDENTIAL ((gss_cred_id_t) 0)
-#define GSS_C_NO_CHANNEL_BINDINGS ((gss_channel_bindings_t) 0)
-#define GSS_C_EMPTY_BUFFER {0, NULL}
-
-/*
- * Some alternate names for a couple of the above
- * values. These are defined for V1 compatibility.
- */
-#define GSS_C_NULL_OID GSS_C_NO_OID
-#define GSS_C_NULL_OID_SET GSS_C_NO_OID_SET
-
-/*
- * Define the default Quality of Protection for per-message
- * services. Note that an implementation that offers multiple
- * levels of QOP may define GSS_C_QOP_DEFAULT to be either zero
- * (as done here) to mean "default protection", or to a specific
- * explicit QOP value. However, a value of 0 should always be
- * interpreted by a GSSAPI implementation as a request for the
- * default protection level.
- */
-#define GSS_C_QOP_DEFAULT 0
-
-#define GSS_KRB5_CONF_C_QOP_DES 0x0100
-#define GSS_KRB5_CONF_C_QOP_DES3_KD 0x0200
-
-/*
- * Expiration time of 2^32-1 seconds means infinite lifetime for a
- * credential or security context
- */
-#define GSS_C_INDEFINITE 0xfffffffful
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * The implementation must reserve static storage for a
- * gss_OID_desc object containing the value
- * {10, (void *)"\x2a\x86\x48\x86\xf7\x12"
- * "\x01\x02\x01\x01"},
- * corresponding to an object-identifier value of
- * {iso(1) member-body(2) United States(840) mit(113554)
- * infosys(1) gssapi(2) generic(1) user_name(1)}. The constant
- * GSS_C_NT_USER_NAME should be initialized to point
- * to that gss_OID_desc.
- */
-extern gss_OID GSS_C_NT_USER_NAME;
-
-/*
- * The implementation must reserve static storage for a
- * gss_OID_desc object containing the value
- * {10, (void *)"\x2a\x86\x48\x86\xf7\x12"
- * "\x01\x02\x01\x02"},
- * corresponding to an object-identifier value of
- * {iso(1) member-body(2) United States(840) mit(113554)
- * infosys(1) gssapi(2) generic(1) machine_uid_name(2)}.
- * The constant GSS_C_NT_MACHINE_UID_NAME should be
- * initialized to point to that gss_OID_desc.
- */
-extern gss_OID GSS_C_NT_MACHINE_UID_NAME;
-
-/*
- * The implementation must reserve static storage for a
- * gss_OID_desc object containing the value
- * {10, (void *)"\x2a\x86\x48\x86\xf7\x12"
- * "\x01\x02\x01\x03"},
- * corresponding to an object-identifier value of
- * {iso(1) member-body(2) United States(840) mit(113554)
- * infosys(1) gssapi(2) generic(1) string_uid_name(3)}.
- * The constant GSS_C_NT_STRING_UID_NAME should be
- * initialized to point to that gss_OID_desc.
- */
-extern gss_OID GSS_C_NT_STRING_UID_NAME;
-
-/*
- * The implementation must reserve static storage for a
- * gss_OID_desc object containing the value
- * {6, (void *)"\x2b\x06\x01\x05\x06\x02"},
- * corresponding to an object-identifier value of
- * {iso(1) org(3) dod(6) internet(1) security(5)
- * nametypes(6) gss-host-based-services(2)). The constant
- * GSS_C_NT_HOSTBASED_SERVICE_X should be initialized to point
- * to that gss_OID_desc. This is a deprecated OID value, and
- * implementations wishing to support hostbased-service names
- * should instead use the GSS_C_NT_HOSTBASED_SERVICE OID,
- * defined below, to identify such names;
- * GSS_C_NT_HOSTBASED_SERVICE_X should be accepted a synonym
- * for GSS_C_NT_HOSTBASED_SERVICE when presented as an input
- * parameter, but should not be emitted by GSS-API
- * implementations
- */
-extern gss_OID GSS_C_NT_HOSTBASED_SERVICE_X;
-
-/*
- * The implementation must reserve static storage for a
- * gss_OID_desc object containing the value
- * {10, (void *)"\x2a\x86\x48\x86\xf7\x12"
- * "\x01\x02\x01\x04"}, corresponding to an
- * object-identifier value of {iso(1) member-body(2)
- * Unites States(840) mit(113554) infosys(1) gssapi(2)
- * generic(1) service_name(4)}. The constant
- * GSS_C_NT_HOSTBASED_SERVICE should be initialized
- * to point to that gss_OID_desc.
- */
-extern gss_OID GSS_C_NT_HOSTBASED_SERVICE;
-
-/*
- * The implementation must reserve static storage for a
- * gss_OID_desc object containing the value
- * {6, (void *)"\x2b\x06\01\x05\x06\x03"},
- * corresponding to an object identifier value of
- * {1(iso), 3(org), 6(dod), 1(internet), 5(security),
- * 6(nametypes), 3(gss-anonymous-name)}. The constant
- * and GSS_C_NT_ANONYMOUS should be initialized to point
- * to that gss_OID_desc.
- */
-extern gss_OID GSS_C_NT_ANONYMOUS;
-
-/*
- * The implementation must reserve static storage for a
- * gss_OID_desc object containing the value
- * {6, (void *)"\x2b\x06\x01\x05\x06\x04"},
- * corresponding to an object-identifier value of
- * {1(iso), 3(org), 6(dod), 1(internet), 5(security),
- * 6(nametypes), 4(gss-api-exported-name)}. The constant
- * GSS_C_NT_EXPORT_NAME should be initialized to point
- * to that gss_OID_desc.
- */
-extern gss_OID GSS_C_NT_EXPORT_NAME;
-
-/*
- * RFC2478, SPNEGO:
- * The security mechanism of the initial
- * negotiation token is identified by the Object Identifier
- * iso.org.dod.internet.security.mechanism.snego (1.3.6.1.5.5.2).
- */
-extern gss_OID GSS_SPNEGO_MECHANISM;
-
-/*
- * This if for kerberos5 names.
- */
-
-extern gss_OID GSS_KRB5_NT_PRINCIPAL_NAME;
-extern gss_OID GSS_KRB5_NT_USER_NAME;
-extern gss_OID GSS_KRB5_NT_MACHINE_UID_NAME;
-extern gss_OID GSS_KRB5_NT_STRING_UID_NAME;
-
-extern gss_OID GSS_KRB5_MECHANISM;
-
-/* for compatibility with MIT api */
-
-#define gss_mech_krb5 GSS_KRB5_MECHANISM
-#define gss_krb5_nt_general_name GSS_KRB5_NT_PRINCIPAL_NAME
+#include <gssapi/gssapi.h>
-/* Major status codes */
-
-#define GSS_S_COMPLETE 0
-
-/*
- * Some "helper" definitions to make the status code macros obvious.
- */
-#define GSS_C_CALLING_ERROR_OFFSET 24
-#define GSS_C_ROUTINE_ERROR_OFFSET 16
-#define GSS_C_SUPPLEMENTARY_OFFSET 0
-#define GSS_C_CALLING_ERROR_MASK 0377ul
-#define GSS_C_ROUTINE_ERROR_MASK 0377ul
-#define GSS_C_SUPPLEMENTARY_MASK 0177777ul
-
-/*
- * The macros that test status codes for error conditions.
- * Note that the GSS_ERROR() macro has changed slightly from
- * the V1 GSSAPI so that it now evaluates its argument
- * only once.
- */
-#define GSS_CALLING_ERROR(x) \
- (x & (GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET))
-#define GSS_ROUTINE_ERROR(x) \
- (x & (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET))
-#define GSS_SUPPLEMENTARY_INFO(x) \
- (x & (GSS_C_SUPPLEMENTARY_MASK << GSS_C_SUPPLEMENTARY_OFFSET))
-#define GSS_ERROR(x) \
- (x & ((GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET) | \
- (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET)))
-
-/*
- * Now the actual status code definitions
- */
-
-/*
- * Calling errors:
- */
-#define GSS_S_CALL_INACCESSIBLE_READ \
- (1ul << GSS_C_CALLING_ERROR_OFFSET)
-#define GSS_S_CALL_INACCESSIBLE_WRITE \
- (2ul << GSS_C_CALLING_ERROR_OFFSET)
-#define GSS_S_CALL_BAD_STRUCTURE \
- (3ul << GSS_C_CALLING_ERROR_OFFSET)
-
-/*
- * Routine errors:
- */
-#define GSS_S_BAD_MECH (1ul << GSS_C_ROUTINE_ERROR_OFFSET)
-#define GSS_S_BAD_NAME (2ul << GSS_C_ROUTINE_ERROR_OFFSET)
-#define GSS_S_BAD_NAMETYPE (3ul << GSS_C_ROUTINE_ERROR_OFFSET)
-
-#define GSS_S_BAD_BINDINGS (4ul << GSS_C_ROUTINE_ERROR_OFFSET)
-#define GSS_S_BAD_STATUS (5ul << GSS_C_ROUTINE_ERROR_OFFSET)
-#define GSS_S_BAD_SIG (6ul << GSS_C_ROUTINE_ERROR_OFFSET)
-#define GSS_S_BAD_MIC GSS_S_BAD_SIG
-#define GSS_S_NO_CRED (7ul << GSS_C_ROUTINE_ERROR_OFFSET)
-#define GSS_S_NO_CONTEXT (8ul << GSS_C_ROUTINE_ERROR_OFFSET)
-#define GSS_S_DEFECTIVE_TOKEN (9ul << GSS_C_ROUTINE_ERROR_OFFSET)
-#define GSS_S_DEFECTIVE_CREDENTIAL (10ul << GSS_C_ROUTINE_ERROR_OFFSET)
-#define GSS_S_CREDENTIALS_EXPIRED (11ul << GSS_C_ROUTINE_ERROR_OFFSET)
-#define GSS_S_CONTEXT_EXPIRED (12ul << GSS_C_ROUTINE_ERROR_OFFSET)
-#define GSS_S_FAILURE (13ul << GSS_C_ROUTINE_ERROR_OFFSET)
-#define GSS_S_BAD_QOP (14ul << GSS_C_ROUTINE_ERROR_OFFSET)
-#define GSS_S_UNAUTHORIZED (15ul << GSS_C_ROUTINE_ERROR_OFFSET)
-#define GSS_S_UNAVAILABLE (16ul << GSS_C_ROUTINE_ERROR_OFFSET)
-#define GSS_S_DUPLICATE_ELEMENT (17ul << GSS_C_ROUTINE_ERROR_OFFSET)
-#define GSS_S_NAME_NOT_MN (18ul << GSS_C_ROUTINE_ERROR_OFFSET)
-
-/*
- * Supplementary info bits:
- */
-#define GSS_S_CONTINUE_NEEDED (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 0))
-#define GSS_S_DUPLICATE_TOKEN (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 1))
-#define GSS_S_OLD_TOKEN (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 2))
-#define GSS_S_UNSEQ_TOKEN (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 3))
-#define GSS_S_GAP_TOKEN (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 4))
-
-/*
- * From RFC1964:
- *
- * 4.1.1. Non-Kerberos-specific codes
- */
-
-#define GSS_KRB5_S_G_BAD_SERVICE_NAME 1
- /* "No @ in SERVICE-NAME name string" */
-#define GSS_KRB5_S_G_BAD_STRING_UID 2
- /* "STRING-UID-NAME contains nondigits" */
-#define GSS_KRB5_S_G_NOUSER 3
- /* "UID does not resolve to username" */
-#define GSS_KRB5_S_G_VALIDATE_FAILED 4
- /* "Validation error" */
-#define GSS_KRB5_S_G_BUFFER_ALLOC 5
- /* "Couldn't allocate gss_buffer_t data" */
-#define GSS_KRB5_S_G_BAD_MSG_CTX 6
- /* "Message context invalid" */
-#define GSS_KRB5_S_G_WRONG_SIZE 7
- /* "Buffer is the wrong size" */
-#define GSS_KRB5_S_G_BAD_USAGE 8
- /* "Credential usage type is unknown" */
-#define GSS_KRB5_S_G_UNKNOWN_QOP 9
- /* "Unknown quality of protection specified" */
-
- /*
- * 4.1.2. Kerberos-specific-codes
- */
-
-#define GSS_KRB5_S_KG_CCACHE_NOMATCH 10
- /* "Principal in credential cache does not match desired name" */
-#define GSS_KRB5_S_KG_KEYTAB_NOMATCH 11
- /* "No principal in keytab matches desired name" */
-#define GSS_KRB5_S_KG_TGT_MISSING 12
- /* "Credential cache has no TGT" */
-#define GSS_KRB5_S_KG_NO_SUBKEY 13
- /* "Authenticator has no subkey" */
-#define GSS_KRB5_S_KG_CONTEXT_ESTABLISHED 14
- /* "Context is already fully established" */
-#define GSS_KRB5_S_KG_BAD_SIGN_TYPE 15
- /* "Unknown signature type in token" */
-#define GSS_KRB5_S_KG_BAD_LENGTH 16
- /* "Invalid field length in token" */
-#define GSS_KRB5_S_KG_CTX_INCOMPLETE 17
- /* "Attempt to use incomplete security context" */
-
-/*
- * Finally, function prototypes for the GSS-API routines.
- */
-
-
-OM_uint32 gss_acquire_cred
- (OM_uint32 * /*minor_status*/,
- const gss_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*/
- );
-
-OM_uint32 gss_release_cred
- (OM_uint32 * /*minor_status*/,
- gss_cred_id_t * /*cred_handle*/
- );
-
-OM_uint32 gss_init_sec_context
- (OM_uint32 * /*minor_status*/,
- const gss_cred_id_t /*initiator_cred_handle*/,
- gss_ctx_id_t * /*context_handle*/,
- const gss_name_t /*target_name*/,
- const gss_OID /*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 gss_accept_sec_context
- (OM_uint32 * /*minor_status*/,
- gss_ctx_id_t * /*context_handle*/,
- const gss_cred_id_t /*acceptor_cred_handle*/,
- const gss_buffer_t /*input_token_buffer*/,
- 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 gss_process_context_token
- (OM_uint32 * /*minor_status*/,
- const gss_ctx_id_t /*context_handle*/,
- const gss_buffer_t /*token_buffer*/
- );
-
-OM_uint32 gss_delete_sec_context
- (OM_uint32 * /*minor_status*/,
- gss_ctx_id_t * /*context_handle*/,
- gss_buffer_t /*output_token*/
- );
-
-OM_uint32 gss_context_time
- (OM_uint32 * /*minor_status*/,
- const gss_ctx_id_t /*context_handle*/,
- OM_uint32 * /*time_rec*/
- );
-
-OM_uint32 gss_get_mic
- (OM_uint32 * /*minor_status*/,
- const gss_ctx_id_t /*context_handle*/,
- gss_qop_t /*qop_req*/,
- const gss_buffer_t /*message_buffer*/,
- gss_buffer_t /*message_token*/
- );
-
-OM_uint32 gss_verify_mic
- (OM_uint32 * /*minor_status*/,
- const gss_ctx_id_t /*context_handle*/,
- const gss_buffer_t /*message_buffer*/,
- const gss_buffer_t /*token_buffer*/,
- gss_qop_t * /*qop_state*/
- );
-
-OM_uint32 gss_wrap
- (OM_uint32 * /*minor_status*/,
- const gss_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*/
- );
-
-OM_uint32 gss_unwrap
- (OM_uint32 * /*minor_status*/,
- const gss_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*/
- );
-
-OM_uint32 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 gss_indicate_mechs
- (OM_uint32 * /*minor_status*/,
- gss_OID_set * /*mech_set*/
- );
-
-OM_uint32 gss_compare_name
- (OM_uint32 * /*minor_status*/,
- const gss_name_t /*name1*/,
- const gss_name_t /*name2*/,
- int * /*name_equal*/
- );
-
-OM_uint32 gss_display_name
- (OM_uint32 * /*minor_status*/,
- const gss_name_t /*input_name*/,
- gss_buffer_t /*output_name_buffer*/,
- gss_OID * /*output_name_type*/
- );
-
-OM_uint32 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*/
- );
-
-OM_uint32 gss_export_name
- (OM_uint32 * /*minor_status*/,
- const gss_name_t /*input_name*/,
- gss_buffer_t /*exported_name*/
- );
-
-OM_uint32 gss_release_name
- (OM_uint32 * /*minor_status*/,
- gss_name_t * /*input_name*/
- );
-
-OM_uint32 gss_release_buffer
- (OM_uint32 * /*minor_status*/,
- gss_buffer_t /*buffer*/
- );
-
-OM_uint32 gss_release_oid_set
- (OM_uint32 * /*minor_status*/,
- gss_OID_set * /*set*/
- );
-
-OM_uint32 gss_inquire_cred
- (OM_uint32 * /*minor_status*/,
- const gss_cred_id_t /*cred_handle*/,
- gss_name_t * /*name*/,
- OM_uint32 * /*lifetime*/,
- gss_cred_usage_t * /*cred_usage*/,
- gss_OID_set * /*mechanisms*/
- );
-
-OM_uint32 gss_inquire_context (
- OM_uint32 * /*minor_status*/,
- const gss_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 * /*open_context*/
- );
-
-OM_uint32 gsskrb5_wrap_size (
- OM_uint32 * /*minor_status*/,
- const gss_ctx_id_t /*context_handle*/,
- int /*conf_req_flag*/,
- gss_qop_t /*qop_req*/,
- OM_uint32 /*req_input_size*/,
- OM_uint32 * /*output_size*/
- );
-
-OM_uint32 gss_wrap_size_limit (
- OM_uint32 * /*minor_status*/,
- const gss_ctx_id_t /*context_handle*/,
- int /*conf_req_flag*/,
- gss_qop_t /*qop_req*/,
- OM_uint32 /*req_output_size*/,
- OM_uint32 * /*max_input_size*/
- );
-
-OM_uint32 gss_add_cred (
- OM_uint32 * /*minor_status*/,
- const gss_cred_id_t /*input_cred_handle*/,
- const gss_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*/
- );
-
-OM_uint32 gss_inquire_cred_by_mech (
- OM_uint32 * /*minor_status*/,
- const gss_cred_id_t /*cred_handle*/,
- const gss_OID /*mech_type*/,
- gss_name_t * /*name*/,
- OM_uint32 * /*initiator_lifetime*/,
- OM_uint32 * /*acceptor_lifetime*/,
- gss_cred_usage_t * /*cred_usage*/
- );
-
-OM_uint32 gss_export_sec_context (
- OM_uint32 * /*minor_status*/,
- gss_ctx_id_t * /*context_handle*/,
- gss_buffer_t /*interprocess_token*/
- );
-
-OM_uint32 gss_import_sec_context (
- OM_uint32 * /*minor_status*/,
- const gss_buffer_t /*interprocess_token*/,
- gss_ctx_id_t * /*context_handle*/
- );
-
-OM_uint32 gss_create_empty_oid_set (
- OM_uint32 * /*minor_status*/,
- gss_OID_set * /*oid_set*/
- );
-
-OM_uint32 gss_add_oid_set_member (
- OM_uint32 * /*minor_status*/,
- const gss_OID /*member_oid*/,
- gss_OID_set * /*oid_set*/
- );
-
-OM_uint32 gss_test_oid_set_member (
- OM_uint32 * /*minor_status*/,
- const gss_OID /*member*/,
- const gss_OID_set /*set*/,
- int * /*present*/
- );
-
-OM_uint32 gss_inquire_names_for_mech (
- OM_uint32 * /*minor_status*/,
- const gss_OID /*mechanism*/,
- gss_OID_set * /*name_types*/
- );
-
-OM_uint32 gss_inquire_mechs_for_name (
- OM_uint32 * /*minor_status*/,
- const gss_name_t /*input_name*/,
- gss_OID_set * /*mech_types*/
- );
-
-OM_uint32 gss_canonicalize_name (
- OM_uint32 * /*minor_status*/,
- const gss_name_t /*input_name*/,
- const gss_OID /*mech_type*/,
- gss_name_t * /*output_name*/
- );
-
-OM_uint32 gss_duplicate_name (
- OM_uint32 * /*minor_status*/,
- const gss_name_t /*src_name*/,
- gss_name_t * /*dest_name*/
- );
-
-/*
- * The following routines are obsolete variants of gss_get_mic,
- * gss_verify_mic, gss_wrap and gss_unwrap. They should be
- * provided by GSSAPI V2 implementations for backwards
- * compatibility with V1 applications. Distinct entrypoints
- * (as opposed to #defines) should be provided, both to allow
- * GSSAPI V1 applications to link against GSSAPI V2 implementations,
- * and to retain the slight parameter type differences between the
- * obsolete versions of these routines and their current forms.
- */
-
-OM_uint32 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*/
- );
-
-OM_uint32 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*/
- );
-
-OM_uint32 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*/
- );
-
-OM_uint32 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*/
- );
-
-/*
- * kerberos mechanism specific functions
- */
-
-OM_uint32
-gss_krb5_ccache_name(OM_uint32 * /*minor_status*/,
- const char * /*name */,
- const char ** /*out_name */);
-
-OM_uint32 gsskrb5_register_acceptor_identity
- (const char */*identity*/);
-
-OM_uint32 gss_krb5_copy_ccache
- (OM_uint32 */*minor*/,
- gss_cred_id_t /*cred*/,
- struct krb5_ccache_data */*out*/);
-
-OM_uint32 gss_krb5_copy_service_keyblock
- (OM_uint32 *minor_status,
- gss_ctx_id_t context_handle,
- struct EncryptionKey **out);
-
-OM_uint32 gss_krb5_import_cred(OM_uint32 *minor_status,
- struct krb5_ccache_data * /* id */,
- struct Principal * /* keytab_principal */,
- struct krb5_keytab_data * /* keytab */,
- gss_cred_id_t */* cred */);
-
-OM_uint32 gss_krb5_get_tkt_flags
- (OM_uint32 */*minor*/,
- gss_ctx_id_t /*context_handle*/,
- OM_uint32 */*tkt_flags*/);
-
-OM_uint32
-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*/);
-OM_uint32
-gsskrb5_extract_authtime_from_sec_context(OM_uint32 *minor_status,
- gss_ctx_id_t context_handle,
- time_t *authtime);
-OM_uint32
-gsskrb5_get_initiator_subkey
- (OM_uint32 * /*minor_status*/,
- const gss_ctx_id_t context_handle,
- gss_buffer_t /* subkey */);
-
-#define GSS_C_KRB5_COMPAT_DES3_MIC 1
-
-OM_uint32
-gss_krb5_compat_des3_mic(OM_uint32 *, gss_ctx_id_t, int);
-
-#ifdef __cplusplus
-}
#endif
-
-#endif /* GSSAPI_H_ */
diff --git a/source4/heimdal/lib/gssapi/gssapi/gssapi.h b/source4/heimdal/lib/gssapi/gssapi/gssapi.h
new file mode 100644
index 0000000000..238907653e
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/gssapi/gssapi.h
@@ -0,0 +1,837 @@
+/*
+ * Copyright (c) 1997 - 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: gssapi.h,v 1.5 2006/10/19 07:11:14 lha Exp $ */
+
+#ifndef GSSAPI_GSSAPI_H_
+#define GSSAPI_GSSAPI_H_
+
+/*
+ * First, include stddef.h to get size_t defined.
+ */
+#include <stddef.h>
+
+#include <krb5-types.h>
+
+/*
+ * Now define the three implementation-dependent types.
+ */
+
+typedef uint32_t OM_uint32;
+typedef uint64_t OM_uint64;
+
+typedef uint32_t gss_uint32;
+
+struct gss_name_t_desc_struct;
+typedef struct gss_name_t_desc_struct *gss_name_t;
+
+struct gss_ctx_id_t_desc_struct;
+typedef struct gss_ctx_id_t_desc_struct *gss_ctx_id_t;
+
+typedef struct gss_OID_desc_struct {
+ OM_uint32 length;
+ void *elements;
+} gss_OID_desc, *gss_OID;
+
+typedef struct gss_OID_set_desc_struct {
+ size_t count;
+ gss_OID elements;
+} gss_OID_set_desc, *gss_OID_set;
+
+typedef int gss_cred_usage_t;
+
+struct gss_cred_id_t_desc_struct;
+typedef struct gss_cred_id_t_desc_struct *gss_cred_id_t;
+
+typedef struct gss_buffer_desc_struct {
+ size_t length;
+ void *value;
+} gss_buffer_desc, *gss_buffer_t;
+
+typedef struct gss_channel_bindings_struct {
+ OM_uint32 initiator_addrtype;
+ gss_buffer_desc initiator_address;
+ OM_uint32 acceptor_addrtype;
+ gss_buffer_desc acceptor_address;
+ gss_buffer_desc application_data;
+} *gss_channel_bindings_t;
+
+/* GGF extension data types */
+typedef struct gss_buffer_set_desc_struct {
+ size_t count;
+ gss_buffer_desc *elements;
+} gss_buffer_set_desc, *gss_buffer_set_t;
+
+/*
+ * For now, define a QOP-type as an OM_uint32
+ */
+typedef OM_uint32 gss_qop_t;
+
+/*
+ * Flag bits for context-level services.
+ */
+#define GSS_C_DELEG_FLAG 1
+#define GSS_C_MUTUAL_FLAG 2
+#define GSS_C_REPLAY_FLAG 4
+#define GSS_C_SEQUENCE_FLAG 8
+#define GSS_C_CONF_FLAG 16
+#define GSS_C_INTEG_FLAG 32
+#define GSS_C_ANON_FLAG 64
+#define GSS_C_PROT_READY_FLAG 128
+#define GSS_C_TRANS_FLAG 256
+
+#define GSS_C_DCE_STYLE 4096
+#define GSS_C_IDENTIFY_FLAG 8192
+#define GSS_C_EXTENDED_ERROR_FLAG 16384
+
+/*
+ * Credential usage options
+ */
+#define GSS_C_BOTH 0
+#define GSS_C_INITIATE 1
+#define GSS_C_ACCEPT 2
+
+/*
+ * Status code types for gss_display_status
+ */
+#define GSS_C_GSS_CODE 1
+#define GSS_C_MECH_CODE 2
+
+/*
+ * The constant definitions for channel-bindings address families
+ */
+#define GSS_C_AF_UNSPEC 0
+#define GSS_C_AF_LOCAL 1
+#define GSS_C_AF_INET 2
+#define GSS_C_AF_IMPLINK 3
+#define GSS_C_AF_PUP 4
+#define GSS_C_AF_CHAOS 5
+#define GSS_C_AF_NS 6
+#define GSS_C_AF_NBS 7
+#define GSS_C_AF_ECMA 8
+#define GSS_C_AF_DATAKIT 9
+#define GSS_C_AF_CCITT 10
+#define GSS_C_AF_SNA 11
+#define GSS_C_AF_DECnet 12
+#define GSS_C_AF_DLI 13
+#define GSS_C_AF_LAT 14
+#define GSS_C_AF_HYLINK 15
+#define GSS_C_AF_APPLETALK 16
+#define GSS_C_AF_BSC 17
+#define GSS_C_AF_DSS 18
+#define GSS_C_AF_OSI 19
+#define GSS_C_AF_X25 21
+#define GSS_C_AF_INET6 24
+
+#define GSS_C_AF_NULLADDR 255
+
+/*
+ * Various Null values
+ */
+#define GSS_C_NO_NAME ((gss_name_t) 0)
+#define GSS_C_NO_BUFFER ((gss_buffer_t) 0)
+#define GSS_C_NO_BUFFER_SET ((gss_buffer_set_t) 0)
+#define GSS_C_NO_OID ((gss_OID) 0)
+#define GSS_C_NO_OID_SET ((gss_OID_set) 0)
+#define GSS_C_NO_CONTEXT ((gss_ctx_id_t) 0)
+#define GSS_C_NO_CREDENTIAL ((gss_cred_id_t) 0)
+#define GSS_C_NO_CHANNEL_BINDINGS ((gss_channel_bindings_t) 0)
+#define GSS_C_EMPTY_BUFFER {0, NULL}
+
+/*
+ * Some alternate names for a couple of the above
+ * values. These are defined for V1 compatibility.
+ */
+#define GSS_C_NULL_OID GSS_C_NO_OID
+#define GSS_C_NULL_OID_SET GSS_C_NO_OID_SET
+
+/*
+ * Define the default Quality of Protection for per-message
+ * services. Note that an implementation that offers multiple
+ * levels of QOP may define GSS_C_QOP_DEFAULT to be either zero
+ * (as done here) to mean "default protection", or to a specific
+ * explicit QOP value. However, a value of 0 should always be
+ * interpreted by a GSSAPI implementation as a request for the
+ * default protection level.
+ */
+#define GSS_C_QOP_DEFAULT 0
+
+#define GSS_KRB5_CONF_C_QOP_DES 0x0100
+#define GSS_KRB5_CONF_C_QOP_DES3_KD 0x0200
+
+/*
+ * Expiration time of 2^32-1 seconds means infinite lifetime for a
+ * credential or security context
+ */
+#define GSS_C_INDEFINITE 0xfffffffful
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {10, (void *)"\x2a\x86\x48\x86\xf7\x12"
+ * "\x01\x02\x01\x01"},
+ * corresponding to an object-identifier value of
+ * {iso(1) member-body(2) United States(840) mit(113554)
+ * infosys(1) gssapi(2) generic(1) user_name(1)}. The constant
+ * GSS_C_NT_USER_NAME should be initialized to point
+ * to that gss_OID_desc.
+ */
+extern gss_OID GSS_C_NT_USER_NAME;
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {10, (void *)"\x2a\x86\x48\x86\xf7\x12"
+ * "\x01\x02\x01\x02"},
+ * corresponding to an object-identifier value of
+ * {iso(1) member-body(2) United States(840) mit(113554)
+ * infosys(1) gssapi(2) generic(1) machine_uid_name(2)}.
+ * The constant GSS_C_NT_MACHINE_UID_NAME should be
+ * initialized to point to that gss_OID_desc.
+ */
+extern gss_OID GSS_C_NT_MACHINE_UID_NAME;
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {10, (void *)"\x2a\x86\x48\x86\xf7\x12"
+ * "\x01\x02\x01\x03"},
+ * corresponding to an object-identifier value of
+ * {iso(1) member-body(2) United States(840) mit(113554)
+ * infosys(1) gssapi(2) generic(1) string_uid_name(3)}.
+ * The constant GSS_C_NT_STRING_UID_NAME should be
+ * initialized to point to that gss_OID_desc.
+ */
+extern gss_OID GSS_C_NT_STRING_UID_NAME;
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {6, (void *)"\x2b\x06\x01\x05\x06\x02"},
+ * corresponding to an object-identifier value of
+ * {iso(1) org(3) dod(6) internet(1) security(5)
+ * nametypes(6) gss-host-based-services(2)). The constant
+ * GSS_C_NT_HOSTBASED_SERVICE_X should be initialized to point
+ * to that gss_OID_desc. This is a deprecated OID value, and
+ * implementations wishing to support hostbased-service names
+ * should instead use the GSS_C_NT_HOSTBASED_SERVICE OID,
+ * defined below, to identify such names;
+ * GSS_C_NT_HOSTBASED_SERVICE_X should be accepted a synonym
+ * for GSS_C_NT_HOSTBASED_SERVICE when presented as an input
+ * parameter, but should not be emitted by GSS-API
+ * implementations
+ */
+extern gss_OID GSS_C_NT_HOSTBASED_SERVICE_X;
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {10, (void *)"\x2a\x86\x48\x86\xf7\x12"
+ * "\x01\x02\x01\x04"}, corresponding to an
+ * object-identifier value of {iso(1) member-body(2)
+ * Unites States(840) mit(113554) infosys(1) gssapi(2)
+ * generic(1) service_name(4)}. The constant
+ * GSS_C_NT_HOSTBASED_SERVICE should be initialized
+ * to point to that gss_OID_desc.
+ */
+extern gss_OID GSS_C_NT_HOSTBASED_SERVICE;
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {6, (void *)"\x2b\x06\01\x05\x06\x03"},
+ * corresponding to an object identifier value of
+ * {1(iso), 3(org), 6(dod), 1(internet), 5(security),
+ * 6(nametypes), 3(gss-anonymous-name)}. The constant
+ * and GSS_C_NT_ANONYMOUS should be initialized to point
+ * to that gss_OID_desc.
+ */
+extern gss_OID GSS_C_NT_ANONYMOUS;
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {6, (void *)"\x2b\x06\x01\x05\x06\x04"},
+ * corresponding to an object-identifier value of
+ * {1(iso), 3(org), 6(dod), 1(internet), 5(security),
+ * 6(nametypes), 4(gss-api-exported-name)}. The constant
+ * GSS_C_NT_EXPORT_NAME should be initialized to point
+ * to that gss_OID_desc.
+ */
+extern gss_OID GSS_C_NT_EXPORT_NAME;
+
+/*
+ * Digest mechanism
+ */
+
+extern gss_OID GSS_SASL_DIGEST_MD5_MECHANISM;
+
+/* Major status codes */
+
+#define GSS_S_COMPLETE 0
+
+/*
+ * Some "helper" definitions to make the status code macros obvious.
+ */
+#define GSS_C_CALLING_ERROR_OFFSET 24
+#define GSS_C_ROUTINE_ERROR_OFFSET 16
+#define GSS_C_SUPPLEMENTARY_OFFSET 0
+#define GSS_C_CALLING_ERROR_MASK 0377ul
+#define GSS_C_ROUTINE_ERROR_MASK 0377ul
+#define GSS_C_SUPPLEMENTARY_MASK 0177777ul
+
+/*
+ * The macros that test status codes for error conditions.
+ * Note that the GSS_ERROR() macro has changed slightly from
+ * the V1 GSSAPI so that it now evaluates its argument
+ * only once.
+ */
+#define GSS_CALLING_ERROR(x) \
+ (x & (GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET))
+#define GSS_ROUTINE_ERROR(x) \
+ (x & (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET))
+#define GSS_SUPPLEMENTARY_INFO(x) \
+ (x & (GSS_C_SUPPLEMENTARY_MASK << GSS_C_SUPPLEMENTARY_OFFSET))
+#define GSS_ERROR(x) \
+ (x & ((GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET) | \
+ (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET)))
+
+/*
+ * Now the actual status code definitions
+ */
+
+/*
+ * Calling errors:
+ */
+#define GSS_S_CALL_INACCESSIBLE_READ \
+ (1ul << GSS_C_CALLING_ERROR_OFFSET)
+#define GSS_S_CALL_INACCESSIBLE_WRITE \
+ (2ul << GSS_C_CALLING_ERROR_OFFSET)
+#define GSS_S_CALL_BAD_STRUCTURE \
+ (3ul << GSS_C_CALLING_ERROR_OFFSET)
+
+/*
+ * Routine errors:
+ */
+#define GSS_S_BAD_MECH (1ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_NAME (2ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_NAMETYPE (3ul << GSS_C_ROUTINE_ERROR_OFFSET)
+
+#define GSS_S_BAD_BINDINGS (4ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_STATUS (5ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_SIG (6ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_MIC GSS_S_BAD_SIG
+#define GSS_S_NO_CRED (7ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_NO_CONTEXT (8ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_DEFECTIVE_TOKEN (9ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_DEFECTIVE_CREDENTIAL (10ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_CREDENTIALS_EXPIRED (11ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_CONTEXT_EXPIRED (12ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_FAILURE (13ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_QOP (14ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_UNAUTHORIZED (15ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_UNAVAILABLE (16ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_DUPLICATE_ELEMENT (17ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_NAME_NOT_MN (18ul << GSS_C_ROUTINE_ERROR_OFFSET)
+
+/*
+ * Supplementary info bits:
+ */
+#define GSS_S_CONTINUE_NEEDED (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 0))
+#define GSS_S_DUPLICATE_TOKEN (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 1))
+#define GSS_S_OLD_TOKEN (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 2))
+#define GSS_S_UNSEQ_TOKEN (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 3))
+#define GSS_S_GAP_TOKEN (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 4))
+
+/*
+ * From RFC1964:
+ *
+ * 4.1.1. Non-Kerberos-specific codes
+ */
+
+#define GSS_KRB5_S_G_BAD_SERVICE_NAME 1
+ /* "No @ in SERVICE-NAME name string" */
+#define GSS_KRB5_S_G_BAD_STRING_UID 2
+ /* "STRING-UID-NAME contains nondigits" */
+#define GSS_KRB5_S_G_NOUSER 3
+ /* "UID does not resolve to username" */
+#define GSS_KRB5_S_G_VALIDATE_FAILED 4
+ /* "Validation error" */
+#define GSS_KRB5_S_G_BUFFER_ALLOC 5
+ /* "Couldn't allocate gss_buffer_t data" */
+#define GSS_KRB5_S_G_BAD_MSG_CTX 6
+ /* "Message context invalid" */
+#define GSS_KRB5_S_G_WRONG_SIZE 7
+ /* "Buffer is the wrong size" */
+#define GSS_KRB5_S_G_BAD_USAGE 8
+ /* "Credential usage type is unknown" */
+#define GSS_KRB5_S_G_UNKNOWN_QOP 9
+ /* "Unknown quality of protection specified" */
+
+ /*
+ * 4.1.2. Kerberos-specific-codes
+ */
+
+#define GSS_KRB5_S_KG_CCACHE_NOMATCH 10
+ /* "Principal in credential cache does not match desired name" */
+#define GSS_KRB5_S_KG_KEYTAB_NOMATCH 11
+ /* "No principal in keytab matches desired name" */
+#define GSS_KRB5_S_KG_TGT_MISSING 12
+ /* "Credential cache has no TGT" */
+#define GSS_KRB5_S_KG_NO_SUBKEY 13
+ /* "Authenticator has no subkey" */
+#define GSS_KRB5_S_KG_CONTEXT_ESTABLISHED 14
+ /* "Context is already fully established" */
+#define GSS_KRB5_S_KG_BAD_SIGN_TYPE 15
+ /* "Unknown signature type in token" */
+#define GSS_KRB5_S_KG_BAD_LENGTH 16
+ /* "Invalid field length in token" */
+#define GSS_KRB5_S_KG_CTX_INCOMPLETE 17
+ /* "Attempt to use incomplete security context" */
+
+/*
+ * This is used to make sure mechs that don't want to have external
+ * references don't get any prototypes, and thus can get warnings.
+ */
+
+/*
+ * Finally, function prototypes for the GSS-API routines.
+ */
+
+OM_uint32 gss_acquire_cred
+ (OM_uint32 * /*minor_status*/,
+ const gss_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*/
+ );
+
+OM_uint32 gss_release_cred
+ (OM_uint32 * /*minor_status*/,
+ gss_cred_id_t * /*cred_handle*/
+ );
+
+OM_uint32 gss_init_sec_context
+ (OM_uint32 * /*minor_status*/,
+ const gss_cred_id_t /*initiator_cred_handle*/,
+ gss_ctx_id_t * /*context_handle*/,
+ const gss_name_t /*target_name*/,
+ const gss_OID /*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 gss_accept_sec_context
+ (OM_uint32 * /*minor_status*/,
+ gss_ctx_id_t * /*context_handle*/,
+ const gss_cred_id_t /*acceptor_cred_handle*/,
+ const gss_buffer_t /*input_token_buffer*/,
+ 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 gss_process_context_token
+ (OM_uint32 * /*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ const gss_buffer_t /*token_buffer*/
+ );
+
+OM_uint32 gss_delete_sec_context
+ (OM_uint32 * /*minor_status*/,
+ gss_ctx_id_t * /*context_handle*/,
+ gss_buffer_t /*output_token*/
+ );
+
+OM_uint32 gss_context_time
+ (OM_uint32 * /*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ OM_uint32 * /*time_rec*/
+ );
+
+OM_uint32 gss_get_mic
+ (OM_uint32 * /*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ gss_qop_t /*qop_req*/,
+ const gss_buffer_t /*message_buffer*/,
+ gss_buffer_t /*message_token*/
+ );
+
+OM_uint32 gss_verify_mic
+ (OM_uint32 * /*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ const gss_buffer_t /*message_buffer*/,
+ const gss_buffer_t /*token_buffer*/,
+ gss_qop_t * /*qop_state*/
+ );
+
+OM_uint32 gss_wrap
+ (OM_uint32 * /*minor_status*/,
+ const gss_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*/
+ );
+
+OM_uint32 gss_unwrap
+ (OM_uint32 * /*minor_status*/,
+ const gss_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*/
+ );
+
+OM_uint32 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 gss_indicate_mechs
+ (OM_uint32 * /*minor_status*/,
+ gss_OID_set * /*mech_set*/
+ );
+
+OM_uint32 gss_compare_name
+ (OM_uint32 * /*minor_status*/,
+ const gss_name_t /*name1*/,
+ const gss_name_t /*name2*/,
+ int * /*name_equal*/
+ );
+
+OM_uint32 gss_display_name
+ (OM_uint32 * /*minor_status*/,
+ const gss_name_t /*input_name*/,
+ gss_buffer_t /*output_name_buffer*/,
+ gss_OID * /*output_name_type*/
+ );
+
+OM_uint32 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*/
+ );
+
+OM_uint32 gss_export_name
+ (OM_uint32 * /*minor_status*/,
+ const gss_name_t /*input_name*/,
+ gss_buffer_t /*exported_name*/
+ );
+
+OM_uint32 gss_release_name
+ (OM_uint32 * /*minor_status*/,
+ gss_name_t * /*input_name*/
+ );
+
+OM_uint32 gss_release_buffer
+ (OM_uint32 * /*minor_status*/,
+ gss_buffer_t /*buffer*/
+ );
+
+OM_uint32 gss_release_oid_set
+ (OM_uint32 * /*minor_status*/,
+ gss_OID_set * /*set*/
+ );
+
+OM_uint32 gss_inquire_cred
+ (OM_uint32 * /*minor_status*/,
+ const gss_cred_id_t /*cred_handle*/,
+ gss_name_t * /*name*/,
+ OM_uint32 * /*lifetime*/,
+ gss_cred_usage_t * /*cred_usage*/,
+ gss_OID_set * /*mechanisms*/
+ );
+
+OM_uint32 gss_inquire_context (
+ OM_uint32 * /*minor_status*/,
+ const gss_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 * /*open_context*/
+ );
+
+OM_uint32 gss_wrap_size_limit (
+ OM_uint32 * /*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ int /*conf_req_flag*/,
+ gss_qop_t /*qop_req*/,
+ OM_uint32 /*req_output_size*/,
+ OM_uint32 * /*max_input_size*/
+ );
+
+OM_uint32 gss_add_cred (
+ OM_uint32 * /*minor_status*/,
+ const gss_cred_id_t /*input_cred_handle*/,
+ const gss_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*/
+ );
+
+OM_uint32 gss_inquire_cred_by_mech (
+ OM_uint32 * /*minor_status*/,
+ const gss_cred_id_t /*cred_handle*/,
+ const gss_OID /*mech_type*/,
+ gss_name_t * /*name*/,
+ OM_uint32 * /*initiator_lifetime*/,
+ OM_uint32 * /*acceptor_lifetime*/,
+ gss_cred_usage_t * /*cred_usage*/
+ );
+
+OM_uint32 gss_export_sec_context (
+ OM_uint32 * /*minor_status*/,
+ gss_ctx_id_t * /*context_handle*/,
+ gss_buffer_t /*interprocess_token*/
+ );
+
+OM_uint32 gss_import_sec_context (
+ OM_uint32 * /*minor_status*/,
+ const gss_buffer_t /*interprocess_token*/,
+ gss_ctx_id_t * /*context_handle*/
+ );
+
+OM_uint32 gss_create_empty_oid_set (
+ OM_uint32 * /*minor_status*/,
+ gss_OID_set * /*oid_set*/
+ );
+
+OM_uint32 gss_add_oid_set_member (
+ OM_uint32 * /*minor_status*/,
+ const gss_OID /*member_oid*/,
+ gss_OID_set * /*oid_set*/
+ );
+
+OM_uint32 gss_test_oid_set_member (
+ OM_uint32 * /*minor_status*/,
+ const gss_OID /*member*/,
+ const gss_OID_set /*set*/,
+ int * /*present*/
+ );
+
+OM_uint32 gss_inquire_names_for_mech (
+ OM_uint32 * /*minor_status*/,
+ const gss_OID /*mechanism*/,
+ gss_OID_set * /*name_types*/
+ );
+
+OM_uint32 gss_inquire_mechs_for_name (
+ OM_uint32 * /*minor_status*/,
+ const gss_name_t /*input_name*/,
+ gss_OID_set * /*mech_types*/
+ );
+
+OM_uint32 gss_canonicalize_name (
+ OM_uint32 * /*minor_status*/,
+ const gss_name_t /*input_name*/,
+ const gss_OID /*mech_type*/,
+ gss_name_t * /*output_name*/
+ );
+
+OM_uint32 gss_duplicate_name (
+ OM_uint32 * /*minor_status*/,
+ const gss_name_t /*src_name*/,
+ gss_name_t * /*dest_name*/
+ );
+
+OM_uint32 gss_duplicate_oid (
+ OM_uint32 * /* minor_status */,
+ gss_OID /* src_oid */,
+ gss_OID * /* dest_oid */
+ );
+OM_uint32
+gss_release_oid
+ (OM_uint32 * /*minor_status*/,
+ gss_OID * /* oid */
+ );
+
+OM_uint32
+gss_oid_to_str(
+ OM_uint32 * /*minor_status*/,
+ gss_OID /* oid */,
+ gss_buffer_t /* str */
+ );
+
+OM_uint32
+gss_inquire_sec_context_by_oid(
+ OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ const gss_OID desired_object,
+ gss_buffer_set_t *data_set
+ );
+
+OM_uint32
+gss_set_sec_context_option (OM_uint32 *minor_status,
+ gss_ctx_id_t *context_handle,
+ const gss_OID desired_object,
+ const gss_buffer_t value);
+
+OM_uint32
+gss_set_cred_option (OM_uint32 *minor_status,
+ gss_cred_id_t *cred_handle,
+ const gss_OID object,
+ const gss_buffer_t value);
+
+int
+gss_oid_equal(const gss_OID a, const gss_OID b);
+
+OM_uint32
+gss_create_empty_buffer_set
+ (OM_uint32 * minor_status,
+ gss_buffer_set_t *buffer_set);
+
+OM_uint32
+gss_add_buffer_set_member
+ (OM_uint32 * minor_status,
+ const gss_buffer_t member_buffer,
+ gss_buffer_set_t *buffer_set);
+
+OM_uint32
+gss_release_buffer_set
+ (OM_uint32 * minor_status,
+ gss_buffer_set_t *buffer_set);
+
+OM_uint32
+gss_inquire_cred_by_oid(OM_uint32 *minor_status,
+ const gss_cred_id_t cred_handle,
+ const gss_OID desired_object,
+ gss_buffer_set_t *data_set);
+
+/*
+ * The following routines are obsolete variants of gss_get_mic,
+ * gss_verify_mic, gss_wrap and gss_unwrap. They should be
+ * provided by GSSAPI V2 implementations for backwards
+ * compatibility with V1 applications. Distinct entrypoints
+ * (as opposed to #defines) should be provided, both to allow
+ * GSSAPI V1 applications to link against GSSAPI V2 implementations,
+ * and to retain the slight parameter type differences between the
+ * obsolete versions of these routines and their current forms.
+ */
+
+OM_uint32 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*/
+ );
+
+OM_uint32 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*/
+ );
+
+OM_uint32 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*/
+ );
+
+OM_uint32 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*/
+ );
+
+/*
+ *
+ */
+
+OM_uint32
+gss_inquire_sec_context_by_oid (OM_uint32 *minor_status,
+ const gss_ctx_id_t context_handle,
+ const gss_OID desired_object,
+ gss_buffer_set_t *data_set);
+
+OM_uint32
+gss_encapsulate_token(gss_buffer_t /* input_token */,
+ gss_OID /* oid */,
+ gss_buffer_t /* output_token */);
+
+OM_uint32
+gss_decapsulate_token(gss_buffer_t /* input_token */,
+ gss_OID /* oid */,
+ gss_buffer_t /* output_token */);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#include <gssapi/gssapi_krb5.h>
+#include <gssapi/gssapi_spnego.h>
+
+#endif /* GSSAPI_GSSAPI_H_ */
diff --git a/source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h b/source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h
new file mode 100644
index 0000000000..8c025c8366
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 1997 - 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: gssapi_krb5.h,v 1.10 2006/10/20 22:04:03 lha Exp $ */
+
+#ifndef GSSAPI_KRB5_H_
+#define GSSAPI_KRB5_H_
+
+#include <gssapi/gssapi.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * This is for kerberos5 names.
+ */
+
+extern gss_OID GSS_KRB5_NT_PRINCIPAL_NAME;
+extern gss_OID GSS_KRB5_NT_USER_NAME;
+extern gss_OID GSS_KRB5_NT_MACHINE_UID_NAME;
+extern gss_OID GSS_KRB5_NT_STRING_UID_NAME;
+
+extern gss_OID GSS_KRB5_MECHANISM;
+
+/* for compatibility with MIT api */
+
+#define gss_mech_krb5 GSS_KRB5_MECHANISM
+#define gss_krb5_nt_general_name GSS_KRB5_NT_PRINCIPAL_NAME
+
+/* Extensions set contexts options */
+extern gss_OID GSS_KRB5_COPY_CCACHE_X;
+extern gss_OID GSS_KRB5_COMPAT_DES3_MIC_X;
+extern gss_OID GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_X;
+extern gss_OID GSS_KRB5_SET_DNS_CANONICALIZE_X;
+extern gss_OID GSS_KRB5_SEND_TO_KDC_X;
+/* Extensions inquire context */
+extern gss_OID GSS_KRB5_GET_TKT_FLAGS_X;
+extern gss_OID GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_X;
+extern gss_OID GSS_C_PEER_HAS_UPDATED_SPNEGO;
+extern gss_OID GSS_KRB5_EXPORT_LUCID_CONTEXT_X;
+extern gss_OID GSS_KRB5_EXPORT_LUCID_CONTEXT_V1_X;
+extern gss_OID GSS_KRB5_GET_SUBKEY_X;
+extern gss_OID GSS_KRB5_GET_INITIATOR_SUBKEY_X;
+extern gss_OID GSS_KRB5_GET_ACCEPTOR_SUBKEY_X;
+extern gss_OID GSS_KRB5_GET_AUTHTIME_X;
+extern gss_OID GSS_KRB5_GET_SERVICE_KEYBLOCK_X;
+/* Extensions creds */
+extern gss_OID GSS_KRB5_IMPORT_CRED_X;
+
+/*
+ * kerberos mechanism specific functions
+ */
+
+struct krb5_keytab_data;
+struct krb5_ccache_data;
+struct Principal;
+
+OM_uint32
+gss_krb5_ccache_name(OM_uint32 * /*minor_status*/,
+ const char * /*name */,
+ const char ** /*out_name */);
+
+OM_uint32 gsskrb5_register_acceptor_identity
+ (const char */*identity*/);
+
+OM_uint32 gss_krb5_copy_ccache
+ (OM_uint32 */*minor*/,
+ gss_cred_id_t /*cred*/,
+ struct krb5_ccache_data */*out*/);
+
+OM_uint32
+gss_krb5_import_cred(OM_uint32 */*minor*/,
+ struct krb5_ccache_data * /*in*/,
+ struct Principal * /*keytab_principal*/,
+ struct krb5_keytab_data * /*keytab*/,
+ gss_cred_id_t */*out*/);
+
+OM_uint32 gss_krb5_get_tkt_flags
+ (OM_uint32 */*minor*/,
+ gss_ctx_id_t /*context_handle*/,
+ OM_uint32 */*tkt_flags*/);
+
+OM_uint32
+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*/);
+
+OM_uint32
+gsskrb5_set_dns_canonicalize(int);
+
+struct gsskrb5_send_to_kdc {
+ void *func;
+ void *ptr;
+};
+
+OM_uint32
+gsskrb5_set_send_to_kdc(struct gsskrb5_send_to_kdc *);
+
+OM_uint32
+gsskrb5_extract_authtime_from_sec_context(OM_uint32 *, gss_ctx_id_t, time_t *);
+
+struct EncryptionKey;
+
+OM_uint32
+gsskrb5_extract_service_keyblock(OM_uint32 *minor_status,
+ gss_ctx_id_t context_handle,
+ struct EncryptionKey **out);
+OM_uint32
+gsskrb5_get_initiator_subkey(OM_uint32 *minor_status,
+ gss_ctx_id_t context_handle,
+ struct EncryptionKey **out);
+OM_uint32
+gsskrb5_get_subkey(OM_uint32 *minor_status,
+ gss_ctx_id_t context_handle,
+ struct EncryptionKey **out);
+
+/*
+ * Lucid - NFSv4 interface to GSS-API KRB5 to expose key material to
+ * do GSS content token handling in-kernel.
+ */
+
+typedef struct gss_krb5_lucid_key {
+ OM_uint32 type;
+ OM_uint32 length;
+ void * data;
+} gss_krb5_lucid_key_t;
+
+typedef struct gss_krb5_rfc1964_keydata {
+ OM_uint32 sign_alg;
+ OM_uint32 seal_alg;
+ gss_krb5_lucid_key_t ctx_key;
+} gss_krb5_rfc1964_keydata_t;
+
+typedef struct gss_krb5_cfx_keydata {
+ OM_uint32 have_acceptor_subkey;
+ gss_krb5_lucid_key_t ctx_key;
+ gss_krb5_lucid_key_t acceptor_subkey;
+} gss_krb5_cfx_keydata_t;
+
+typedef struct gss_krb5_lucid_context_v1 {
+ OM_uint32 version;
+ OM_uint32 initiate;
+ OM_uint32 endtime;
+ OM_uint64 send_seq;
+ OM_uint64 recv_seq;
+ OM_uint32 protocol;
+ gss_krb5_rfc1964_keydata_t rfc1964_kd;
+ gss_krb5_cfx_keydata_t cfx_kd;
+} gss_krb5_lucid_context_v1_t;
+
+typedef struct gss_krb5_lucid_context_version {
+ OM_uint32 version; /* Structure version number */
+} gss_krb5_lucid_context_version_t;
+
+/*
+ * Function declarations
+ */
+
+OM_uint32
+gss_krb5_export_lucid_sec_context(OM_uint32 *minor_status,
+ gss_ctx_id_t *context_handle,
+ OM_uint32 version,
+ void **kctx);
+
+
+OM_uint32
+gss_krb5_free_lucid_sec_context(OM_uint32 *minor_status,
+ void *kctx);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GSSAPI_SPNEGO_H_ */
diff --git a/source4/heimdal/lib/gssapi/gssapi/gssapi_spnego.h b/source4/heimdal/lib/gssapi/gssapi/gssapi_spnego.h
new file mode 100644
index 0000000000..0a856e39aa
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/gssapi/gssapi_spnego.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1997 - 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: gssapi_spnego.h,v 1.1 2006/10/07 22:26:21 lha Exp $ */
+
+#ifndef GSSAPI_SPNEGO_H_
+#define GSSAPI_SPNEGO_H_
+
+#include <gssapi.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * RFC2478, SPNEGO:
+ * The security mechanism of the initial
+ * negotiation token is identified by the Object Identifier
+ * iso.org.dod.internet.security.mechanism.snego (1.3.6.1.5.5.2).
+ */
+extern gss_OID GSS_SPNEGO_MECHANISM;
+#define gss_mech_spnego GSS_SPNEGO_MECHANISM
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GSSAPI_SPNEGO_H_ */
diff --git a/source4/heimdal/lib/gssapi/gssapi_locl.h b/source4/heimdal/lib/gssapi/gssapi_locl.h
deleted file mode 100644
index 81169a8500..0000000000
--- a/source4/heimdal/lib/gssapi/gssapi_locl.h
+++ /dev/null
@@ -1,315 +0,0 @@
-/*
- * Copyright (c) 1997 - 2004 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: gssapi_locl.h,v 1.45 2006/05/04 11:56:14 lha Exp $ */
-
-#ifndef GSSAPI_LOCL_H
-#define GSSAPI_LOCL_H
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <krb5_locl.h>
-#include <gssapi.h>
-#include <assert.h>
-
-#include "cfx.h"
-#include "arcfour.h"
-
-#include "spnego_asn1.h"
-
-/*
- *
- */
-
-struct gss_msg_order;
-
-typedef struct gss_ctx_id_t_desc_struct {
- struct krb5_auth_context_data *auth_context;
- gss_name_t source, target;
- enum gss_ctx_id_t_state {
- INITIATOR_START = 1, INITIATOR_WAIT_FOR_MUTAL = 2, INITIATOR_READY= 3,
- ACCEPTOR_START = 11, ACCEPTOR_WAIT_FOR_DCESTYLE = 12, ACCEPTOR_READY = 13
- } state;
- OM_uint32 flags;
- enum {LOCAL = 1,
- OPEN = 2,
- COMPAT_OLD_DES3 = 4,
- COMPAT_OLD_DES3_SELECTED = 8,
- ACCEPTOR_SUBKEY = 16
- } more_flags;
- struct krb5_ticket *ticket;
- krb5_keyblock *service_keyblock;
- krb5_data fwd_data;
- OM_uint32 lifetime;
- HEIMDAL_MUTEX ctx_id_mutex;
- struct gss_msg_order *order;
-} gss_ctx_id_t_desc;
-
-typedef struct gss_cred_id_t_desc_struct {
- gss_name_t principal;
- int cred_flags;
-#define GSS_CF_DESTROY_CRED_ON_RELEASE 1
- struct krb5_keytab_data *keytab;
- OM_uint32 lifetime;
- gss_cred_usage_t usage;
- gss_OID_set mechanisms;
- struct krb5_ccache_data *ccache;
- HEIMDAL_MUTEX cred_id_mutex;
-} gss_cred_id_t_desc;
-
-/*
- *
- */
-
-extern krb5_context gssapi_krb5_context;
-
-extern krb5_keytab gssapi_krb5_keytab;
-extern HEIMDAL_MUTEX gssapi_keytab_mutex;
-
-struct gssapi_thr_context {
- HEIMDAL_MUTEX mutex;
- char *error_string;
-};
-
-/*
- * Prototypes
- */
-
-krb5_error_code gssapi_krb5_init (void);
-
-krb5_error_code gssapi_krb5_init_ev (void *);
-
-#define GSSAPI_KRB5_INIT() do { \
- krb5_error_code kret_gss_init; \
- if((kret_gss_init = gssapi_krb5_init ()) != 0) { \
- *minor_status = kret_gss_init; \
- return GSS_S_FAILURE; \
- } \
-} while (0)
-
-struct gssapi_thr_context *
-gssapi_get_thread_context(int);
-
-OM_uint32
-_gsskrb5_create_ctx(
- OM_uint32 * minor_status,
- gss_ctx_id_t * context_handle,
- const gss_channel_bindings_t input_chan_bindings,
- enum gss_ctx_id_t_state state);
-
-void
-gsskrb5_is_cfx(gss_ctx_id_t, int *);
-
-OM_uint32
-gssapi_krb5_create_8003_checksum (
- OM_uint32 *minor_status,
- const gss_channel_bindings_t input_chan_bindings,
- OM_uint32 flags,
- const krb5_data *fwd_data,
- Checksum *result);
-
-OM_uint32
-gssapi_krb5_verify_8003_checksum (
- OM_uint32 *minor_status,
- const gss_channel_bindings_t input_chan_bindings,
- const Checksum *cksum,
- OM_uint32 *flags,
- krb5_data *fwd_data);
-
-void
-_gssapi_encap_length (size_t data_len,
- size_t *len,
- size_t *total_len,
- const gss_OID mech);
-
-void
-gssapi_krb5_encap_length (size_t data_len,
- size_t *len,
- size_t *total_len,
- const gss_OID mech);
-
-
-
-OM_uint32
-_gssapi_encapsulate(OM_uint32 *minor_status,
- const krb5_data *in_data,
- gss_buffer_t output_token,
- const gss_OID mech);
-
-
-OM_uint32
-gssapi_krb5_encapsulate(OM_uint32 *minor_status,
- const krb5_data *in_data,
- gss_buffer_t output_token,
- const u_char *type,
- const gss_OID mech);
-
-OM_uint32
-gssapi_krb5_decapsulate(OM_uint32 *minor_status,
- gss_buffer_t input_token_buffer,
- krb5_data *out_data,
- const char *type,
- gss_OID oid);
-
-u_char *
-gssapi_krb5_make_header (u_char *p,
- size_t len,
- const u_char *type,
- const gss_OID mech);
-
-u_char *
-_gssapi_make_mech_header(u_char *p,
- size_t len,
- const gss_OID mech);
-
-OM_uint32
-_gssapi_verify_mech_header(u_char **str,
- size_t total_len,
- gss_OID oid);
-
-OM_uint32
-gssapi_krb5_verify_header(u_char **str,
- size_t total_len,
- const u_char *type,
- gss_OID oid);
-
-OM_uint32
-_gssapi_decapsulate(OM_uint32 *minor_status,
- gss_buffer_t input_token_buffer,
- krb5_data *out_data,
- const gss_OID mech);
-
-
-ssize_t
-gssapi_krb5_get_mech (const u_char *, size_t, const u_char **);
-
-OM_uint32
-_gssapi_verify_pad(gss_buffer_t, size_t, size_t *);
-
-OM_uint32
-gss_verify_mic_internal(OM_uint32 * minor_status,
- const gss_ctx_id_t context_handle,
- const gss_buffer_t message_buffer,
- const gss_buffer_t token_buffer,
- gss_qop_t * qop_state,
- char * type);
-
-OM_uint32
-gss_krb5_get_subkey(const gss_ctx_id_t context_handle,
- krb5_keyblock **key);
-
-krb5_error_code
-gss_address_to_krb5addr(OM_uint32 gss_addr_type,
- gss_buffer_desc *gss_addr,
- int16_t port,
- krb5_address *address);
-
-/* sec_context flags */
-
-#define SC_LOCAL_ADDRESS 0x01
-#define SC_REMOTE_ADDRESS 0x02
-#define SC_KEYBLOCK 0x04
-#define SC_LOCAL_SUBKEY 0x08
-#define SC_REMOTE_SUBKEY 0x10
-
-int
-gss_oid_equal(const gss_OID a, const gss_OID b);
-
-void
-gssapi_krb5_clear_status (void);
-
-void
-gssapi_krb5_set_status (const char *fmt, ...);
-
-void
-gssapi_krb5_set_error_string (void);
-
-char *
-gssapi_krb5_get_error_string (void);
-
-OM_uint32
-_gss_DES3_get_mic_compat(OM_uint32 *, gss_ctx_id_t);
-
-OM_uint32
-_gss_spnego_require_mechlist_mic(OM_uint32 *, gss_ctx_id_t, krb5_boolean *);
-
-krb5_error_code
-_gss_check_compat(OM_uint32 *, gss_name_t, const char *,
- krb5_boolean *, krb5_boolean);
-
-OM_uint32
-gssapi_lifetime_left(OM_uint32 *, OM_uint32, OM_uint32 *);
-
-OM_uint32
-_gssapi_krb5_ccache_lifetime(OM_uint32 *, krb5_ccache,
- krb5_principal, OM_uint32 *);
-
-/* sequence */
-
-OM_uint32
-_gssapi_msg_order_create(OM_uint32 *, struct gss_msg_order **,
- OM_uint32, OM_uint32, OM_uint32, int);
-OM_uint32
-_gssapi_msg_order_destroy(struct gss_msg_order **);
-
-OM_uint32
-_gssapi_msg_order_check(struct gss_msg_order *, OM_uint32);
-
-OM_uint32
-_gssapi_msg_order_f(OM_uint32);
-
-OM_uint32
-_gssapi_msg_order_import(OM_uint32 *, krb5_storage *,
- struct gss_msg_order **);
-
-krb5_error_code
-_gssapi_msg_order_export(krb5_storage *, struct gss_msg_order *);
-
-
-/* 8003 */
-
-krb5_error_code
-gssapi_encode_om_uint32(OM_uint32, u_char *);
-
-krb5_error_code
-gssapi_encode_be_om_uint32(OM_uint32, u_char *);
-
-krb5_error_code
-gssapi_decode_om_uint32(const void *, OM_uint32 *);
-
-krb5_error_code
-gssapi_decode_be_om_uint32(const void *, OM_uint32 *);
-
-#endif
diff --git a/source4/heimdal/lib/gssapi/gssapi_mech.h b/source4/heimdal/lib/gssapi/gssapi_mech.h
new file mode 100644
index 0000000000..a05919b510
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/gssapi_mech.h
@@ -0,0 +1,348 @@
+/*-
+ * 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 $
+ */
+
+#ifndef GSSAPI_MECH_H
+#define GSSAPI_MECH_H 1
+
+#include <gssapi.h>
+
+typedef OM_uint32 _gss_acquire_cred_t
+ (OM_uint32 *, /* minor_status */
+ const gss_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 */
+ );
+
+typedef OM_uint32 _gss_release_cred_t
+ (OM_uint32 *, /* minor_status */
+ gss_cred_id_t * /* cred_handle */
+ );
+
+typedef OM_uint32 _gss_init_sec_context_t
+ (OM_uint32 *, /* minor_status */
+ const gss_cred_id_t, /* initiator_cred_handle */
+ gss_ctx_id_t *, /* context_handle */
+ const gss_name_t, /* target_name */
+ const gss_OID, /* 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 */
+ );
+
+typedef OM_uint32 _gss_accept_sec_context_t
+ (OM_uint32 *, /* minor_status */
+ gss_ctx_id_t *, /* context_handle */
+ const gss_cred_id_t, /* acceptor_cred_handle */
+ const gss_buffer_t, /* input_token_buffer */
+ 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 */
+ );
+
+typedef OM_uint32 _gss_process_context_token_t
+ (OM_uint32 *, /* minor_status */
+ const gss_ctx_id_t, /* context_handle */
+ const gss_buffer_t /* token_buffer */
+ );
+
+typedef OM_uint32 _gss_delete_sec_context_t
+ (OM_uint32 *, /* minor_status */
+ gss_ctx_id_t *, /* context_handle */
+ gss_buffer_t /* output_token */
+ );
+
+typedef OM_uint32 _gss_context_time_t
+ (OM_uint32 *, /* minor_status */
+ const gss_ctx_id_t, /* context_handle */
+ OM_uint32 * /* time_rec */
+ );
+
+typedef OM_uint32 _gss_get_mic_t
+ (OM_uint32 *, /* minor_status */
+ const gss_ctx_id_t, /* context_handle */
+ gss_qop_t, /* qop_req */
+ const gss_buffer_t, /* message_buffer */
+ gss_buffer_t /* message_token */
+ );
+
+typedef OM_uint32 _gss_verify_mic_t
+ (OM_uint32 *, /* minor_status */
+ const gss_ctx_id_t, /* context_handle */
+ const gss_buffer_t, /* message_buffer */
+ const gss_buffer_t, /* token_buffer */
+ gss_qop_t * /* qop_state */
+ );
+
+typedef OM_uint32 _gss_wrap_t
+ (OM_uint32 *, /* minor_status */
+ const gss_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 */
+ );
+
+typedef OM_uint32 _gss_unwrap_t
+ (OM_uint32 *, /* minor_status */
+ const gss_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 */
+ );
+
+typedef OM_uint32 _gss_display_status_t
+ (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 */
+ );
+
+typedef OM_uint32 _gss_indicate_mechs_t
+ (OM_uint32 *, /* minor_status */
+ gss_OID_set * /* mech_set */
+ );
+
+typedef OM_uint32 _gss_compare_name_t
+ (OM_uint32 *, /* minor_status */
+ const gss_name_t, /* name1 */
+ const gss_name_t, /* name2 */
+ int * /* name_equal */
+ );
+
+typedef OM_uint32 _gss_display_name_t
+ (OM_uint32 *, /* minor_status */
+ const gss_name_t, /* input_name */
+ gss_buffer_t, /* output_name_buffer */
+ gss_OID * /* output_name_type */
+ );
+
+typedef OM_uint32 _gss_import_name_t
+ (OM_uint32 *, /* minor_status */
+ const gss_buffer_t, /* input_name_buffer */
+ const gss_OID, /* input_name_type */
+ gss_name_t * /* output_name */
+ );
+
+typedef OM_uint32 _gss_export_name_t
+ (OM_uint32 *, /* minor_status */
+ const gss_name_t, /* input_name */
+ gss_buffer_t /* exported_name */
+ );
+
+typedef OM_uint32 _gss_release_name_t
+ (OM_uint32 *, /* minor_status */
+ gss_name_t * /* input_name */
+ );
+
+typedef OM_uint32 _gss_inquire_cred_t
+ (OM_uint32 *, /* minor_status */
+ const gss_cred_id_t, /* cred_handle */
+ gss_name_t *, /* name */
+ OM_uint32 *, /* lifetime */
+ gss_cred_usage_t *, /* cred_usage */
+ gss_OID_set * /* mechanisms */
+ );
+
+typedef OM_uint32 _gss_inquire_context_t
+ (OM_uint32 *, /* minor_status */
+ const gss_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 * /* open */
+ );
+
+typedef OM_uint32 _gss_wrap_size_limit_t
+ (OM_uint32 *, /* minor_status */
+ const gss_ctx_id_t, /* context_handle */
+ int, /* conf_req_flag */
+ gss_qop_t, /* qop_req */
+ OM_uint32, /* req_output_size */
+ OM_uint32 * /* max_input_size */
+ );
+
+typedef OM_uint32 _gss_add_cred_t (
+ OM_uint32 *, /* minor_status */
+ const gss_cred_id_t, /* input_cred_handle */
+ const gss_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 */
+ );
+
+typedef OM_uint32 _gss_inquire_cred_by_mech_t (
+ OM_uint32 *, /* minor_status */
+ const gss_cred_id_t, /* cred_handle */
+ const gss_OID, /* mech_type */
+ gss_name_t *, /* name */
+ OM_uint32 *, /* initiator_lifetime */
+ OM_uint32 *, /* acceptor_lifetime */
+ gss_cred_usage_t * /* cred_usage */
+ );
+
+typedef OM_uint32 _gss_export_sec_context_t (
+ OM_uint32 *, /* minor_status */
+ gss_ctx_id_t *, /* context_handle */
+ gss_buffer_t /* interprocess_token */
+ );
+
+typedef OM_uint32 _gss_import_sec_context_t (
+ OM_uint32 *, /* minor_status */
+ const gss_buffer_t, /* interprocess_token */
+ gss_ctx_id_t * /* context_handle */
+ );
+
+typedef OM_uint32 _gss_inquire_names_for_mech_t (
+ OM_uint32 *, /* minor_status */
+ const gss_OID, /* mechanism */
+ gss_OID_set * /* name_types */
+ );
+
+typedef OM_uint32 _gss_inquire_mechs_for_name_t (
+ OM_uint32 *, /* minor_status */
+ const gss_name_t, /* input_name */
+ gss_OID_set * /* mech_types */
+ );
+
+typedef OM_uint32 _gss_canonicalize_name_t (
+ OM_uint32 *, /* minor_status */
+ const gss_name_t, /* input_name */
+ const gss_OID, /* mech_type */
+ gss_name_t * /* output_name */
+ );
+
+typedef OM_uint32 _gss_duplicate_name_t (
+ OM_uint32 *, /* minor_status */
+ const gss_name_t, /* src_name */
+ gss_name_t * /* dest_name */
+ );
+
+typedef OM_uint32 _gss_inquire_sec_context_by_oid (
+ OM_uint32 *minor_status,
+ const gss_ctx_id_t context_handle,
+ const gss_OID desired_object,
+ gss_buffer_set_t *data_set
+ );
+
+typedef OM_uint32 _gss_inquire_cred_by_oid (
+ OM_uint32 *minor_status,
+ const gss_cred_id_t cred,
+ const gss_OID desired_object,
+ gss_buffer_set_t *data_set
+ );
+
+typedef OM_uint32 _gss_set_sec_context_option (
+ OM_uint32 *minor_status,
+ gss_ctx_id_t *cred_handle,
+ const gss_OID desired_object,
+ const gss_buffer_t value
+ );
+
+typedef OM_uint32 _gss_set_cred_option (
+ OM_uint32 *minor_status,
+ gss_cred_id_t *cred_handle,
+ const gss_OID desired_object,
+ const gss_buffer_t value
+ );
+
+
+#define GMI_VERSION 1
+
+typedef struct gssapi_mech_interface_desc {
+ unsigned gm_version;
+ const char *gm_name;
+ gss_OID_desc gm_mech_oid;
+ _gss_acquire_cred_t *gm_acquire_cred;
+ _gss_release_cred_t *gm_release_cred;
+ _gss_init_sec_context_t *gm_init_sec_context;
+ _gss_accept_sec_context_t *gm_accept_sec_context;
+ _gss_process_context_token_t *gm_process_context_token;
+ _gss_delete_sec_context_t *gm_delete_sec_context;
+ _gss_context_time_t *gm_context_time;
+ _gss_get_mic_t *gm_get_mic;
+ _gss_verify_mic_t *gm_verify_mic;
+ _gss_wrap_t *gm_wrap;
+ _gss_unwrap_t *gm_unwrap;
+ _gss_display_status_t *gm_display_status;
+ _gss_indicate_mechs_t *gm_indicate_mechs;
+ _gss_compare_name_t *gm_compare_name;
+ _gss_display_name_t *gm_display_name;
+ _gss_import_name_t *gm_import_name;
+ _gss_export_name_t *gm_export_name;
+ _gss_release_name_t *gm_release_name;
+ _gss_inquire_cred_t *gm_inquire_cred;
+ _gss_inquire_context_t *gm_inquire_context;
+ _gss_wrap_size_limit_t *gm_wrap_size_limit;
+ _gss_add_cred_t *gm_add_cred;
+ _gss_inquire_cred_by_mech_t *gm_inquire_cred_by_mech;
+ _gss_export_sec_context_t *gm_export_sec_context;
+ _gss_import_sec_context_t *gm_import_sec_context;
+ _gss_inquire_names_for_mech_t *gm_inquire_names_for_mech;
+ _gss_inquire_mechs_for_name_t *gm_inquire_mechs_for_name;
+ _gss_canonicalize_name_t *gm_canonicalize_name;
+ _gss_duplicate_name_t *gm_duplicate_name;
+ _gss_inquire_sec_context_by_oid *gm_inquire_sec_context_by_oid;
+ _gss_inquire_cred_by_oid *gm_inquire_cred_by_oid;
+ _gss_set_sec_context_option *gm_set_sec_context_option;
+ _gss_set_cred_option *gm_set_cred_option;
+} gssapi_mech_interface_desc, *gssapi_mech_interface;
+
+gssapi_mech_interface
+__gss_get_mechanism(gss_OID /* oid */);
+
+gssapi_mech_interface __gss_spnego_initialize(void);
+gssapi_mech_interface __gss_krb5_initialize(void);
+
+#endif /* GSSAPI_MECH_H */
diff --git a/source4/heimdal/lib/gssapi/init_sec_context.c b/source4/heimdal/lib/gssapi/init_sec_context.c
deleted file mode 100644
index 4f0d237241..0000000000
--- a/source4/heimdal/lib/gssapi/init_sec_context.c
+++ /dev/null
@@ -1,1261 +0,0 @@
-/*
- * 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 "gssapi_locl.h"
-
-RCSID("$Id: init_sec_context.c,v 1.63 2006/05/05 10:27:13 lha Exp $");
-
-/*
- * copy the addresses from `input_chan_bindings' (if any) to
- * the auth context `ac'
- */
-
-static OM_uint32
-set_addresses (krb5_auth_context ac,
- const gss_channel_bindings_t input_chan_bindings)
-{
- /* Port numbers are expected to be in application_data.value,
- * initator's port first */
-
- krb5_address initiator_addr, acceptor_addr;
- krb5_error_code kret;
-
- if (input_chan_bindings == GSS_C_NO_CHANNEL_BINDINGS
- || input_chan_bindings->application_data.length !=
- 2 * sizeof(ac->local_port))
- return 0;
-
- memset(&initiator_addr, 0, sizeof(initiator_addr));
- memset(&acceptor_addr, 0, sizeof(acceptor_addr));
-
- ac->local_port =
- *(int16_t *) input_chan_bindings->application_data.value;
-
- ac->remote_port =
- *((int16_t *) input_chan_bindings->application_data.value + 1);
-
- kret = gss_address_to_krb5addr(input_chan_bindings->acceptor_addrtype,
- &input_chan_bindings->acceptor_address,
- ac->remote_port,
- &acceptor_addr);
- if (kret)
- return kret;
-
- kret = gss_address_to_krb5addr(input_chan_bindings->initiator_addrtype,
- &input_chan_bindings->initiator_address,
- ac->local_port,
- &initiator_addr);
- if (kret) {
- krb5_free_address (gssapi_krb5_context, &acceptor_addr);
- return kret;
- }
-
- kret = krb5_auth_con_setaddrs(gssapi_krb5_context,
- ac,
- &initiator_addr, /* local address */
- &acceptor_addr); /* remote address */
-
- krb5_free_address (gssapi_krb5_context, &initiator_addr);
- krb5_free_address (gssapi_krb5_context, &acceptor_addr);
-
-#if 0
- free(input_chan_bindings->application_data.value);
- input_chan_bindings->application_data.value = NULL;
- input_chan_bindings->application_data.length = 0;
-#endif
-
- return kret;
-}
-
-OM_uint32
-_gsskrb5_create_ctx(
- OM_uint32 * minor_status,
- gss_ctx_id_t * context_handle,
- const gss_channel_bindings_t input_chan_bindings,
- enum gss_ctx_id_t_state state)
-{
- krb5_error_code kret;
-
- *context_handle = malloc(sizeof(**context_handle));
- if (*context_handle == NULL) {
- *minor_status = ENOMEM;
- return GSS_S_FAILURE;
- }
- (*context_handle)->auth_context = NULL;
- (*context_handle)->source = NULL;
- (*context_handle)->target = NULL;
- (*context_handle)->state = state;
- (*context_handle)->flags = 0;
- (*context_handle)->more_flags = 0;
- (*context_handle)->service_keyblock = NULL;
- (*context_handle)->ticket = NULL;
- krb5_data_zero(&(*context_handle)->fwd_data);
- (*context_handle)->lifetime = GSS_C_INDEFINITE;
- (*context_handle)->order = NULL;
- HEIMDAL_MUTEX_init(&(*context_handle)->ctx_id_mutex);
-
- kret = krb5_auth_con_init (gssapi_krb5_context,
- &(*context_handle)->auth_context);
- if (kret) {
- *minor_status = kret;
- gssapi_krb5_set_error_string ();
-
- HEIMDAL_MUTEX_destroy(&(*context_handle)->ctx_id_mutex);
-
- return GSS_S_FAILURE;
- }
-
- kret = set_addresses((*context_handle)->auth_context,
- input_chan_bindings);
- if (kret) {
- *minor_status = kret;
-
- HEIMDAL_MUTEX_destroy(&(*context_handle)->ctx_id_mutex);
-
- krb5_auth_con_free(gssapi_krb5_context, (*context_handle)->auth_context);
-
- return GSS_S_BAD_BINDINGS;
- }
-
- /*
- * We need a sequence number
- */
-
- krb5_auth_con_addflags(gssapi_krb5_context,
- (*context_handle)->auth_context,
- KRB5_AUTH_CONTEXT_DO_SEQUENCE,
- NULL);
-
- return GSS_S_COMPLETE;
-}
-
-static OM_uint32
-gsskrb5_get_creds(
- OM_uint32 * minor_status,
- krb5_ccache ccache,
- gss_ctx_id_t * context_handle,
- const gss_name_t target_name,
- OM_uint32 time_req,
- OM_uint32 * time_rec,
- krb5_creds ** cred)
-{
- OM_uint32 ret;
- krb5_error_code kret;
- krb5_creds this_cred;
- OM_uint32 lifetime_rec;
-
- *cred = NULL;
-
- kret = krb5_cc_get_principal(gssapi_krb5_context,
- ccache,
- &(*context_handle)->source);
- if (kret) {
- gssapi_krb5_set_error_string ();
- *minor_status = kret;
- return GSS_S_FAILURE;
- }
-
- kret = krb5_copy_principal(gssapi_krb5_context,
- target_name,
- &(*context_handle)->target);
- if (kret) {
- gssapi_krb5_set_error_string ();
- *minor_status = kret;
- return GSS_S_FAILURE;
- }
-
- memset(&this_cred, 0, sizeof(this_cred));
- this_cred.client = (*context_handle)->source;
- this_cred.server = (*context_handle)->target;
-
- if (time_req && time_req != GSS_C_INDEFINITE) {
- krb5_timestamp ts;
-
- krb5_timeofday (gssapi_krb5_context, &ts);
- this_cred.times.endtime = ts + time_req;
- } else {
- this_cred.times.endtime = 0;
- }
-
- this_cred.session.keytype = KEYTYPE_NULL;
-
- kret = krb5_get_credentials(gssapi_krb5_context,
- 0,
- ccache,
- &this_cred,
- cred);
- if (kret) {
- gssapi_krb5_set_error_string ();
- *minor_status = kret;
- return GSS_S_FAILURE;
- }
-
- (*context_handle)->lifetime = (*cred)->times.endtime;
-
- ret = gssapi_lifetime_left(minor_status,
- (*context_handle)->lifetime,
- &lifetime_rec);
- if (ret) return ret;
-
- if (lifetime_rec == 0) {
- *minor_status = 0;
- return GSS_S_CONTEXT_EXPIRED;
- }
-
- if (time_rec) *time_rec = lifetime_rec;
-
- return GSS_S_COMPLETE;
-}
-
-static OM_uint32
-gsskrb5_initiator_ready(
- OM_uint32 * minor_status,
- gss_ctx_id_t * context_handle)
-{
- OM_uint32 ret;
- int32_t seq_number;
- int is_cfx = 0;
- OM_uint32 flags = (*context_handle)->flags;
-
- krb5_auth_getremoteseqnumber (gssapi_krb5_context,
- (*context_handle)->auth_context,
- &seq_number);
-
- gsskrb5_is_cfx(*context_handle, &is_cfx);
-
- ret = _gssapi_msg_order_create(minor_status,
- &(*context_handle)->order,
- _gssapi_msg_order_f(flags),
- seq_number, 0, is_cfx);
- if (ret) return ret;
-
- (*context_handle)->state = INITIATOR_READY;
- (*context_handle)->more_flags |= OPEN;
-
- return GSS_S_COMPLETE;
-}
-
-/*
- * handle delegated creds in init-sec-context
- */
-
-static void
-do_delegation (krb5_auth_context ac,
- krb5_ccache ccache,
- krb5_creds *cred,
- const gss_name_t target_name,
- krb5_data *fwd_data,
- OM_uint32 *flags)
-{
- krb5_creds creds;
- krb5_kdc_flags fwd_flags;
- krb5_error_code kret;
-
- memset (&creds, 0, sizeof(creds));
- krb5_data_zero (fwd_data);
-
- kret = krb5_cc_get_principal(gssapi_krb5_context, ccache, &creds.client);
- if (kret)
- goto out;
-
- kret = krb5_build_principal(gssapi_krb5_context,
- &creds.server,
- strlen(creds.client->realm),
- creds.client->realm,
- KRB5_TGS_NAME,
- creds.client->realm,
- NULL);
- if (kret)
- goto out;
-
- creds.times.endtime = 0;
-
- fwd_flags.i = 0;
- fwd_flags.b.forwarded = 1;
- fwd_flags.b.forwardable = 1;
-
- if ( /*target_name->name.name_type != KRB5_NT_SRV_HST ||*/
- target_name->name.name_string.len < 2)
- goto out;
-
- kret = krb5_get_forwarded_creds(gssapi_krb5_context,
- ac,
- ccache,
- fwd_flags.i,
- target_name->name.name_string.val[1],
- &creds,
- fwd_data);
-
- out:
- if (kret)
- *flags &= ~GSS_C_DELEG_FLAG;
- else
- *flags |= GSS_C_DELEG_FLAG;
-
- if (creds.client)
- krb5_free_principal(gssapi_krb5_context, creds.client);
- if (creds.server)
- krb5_free_principal(gssapi_krb5_context, creds.server);
-}
-
-/*
- * first stage of init-sec-context
- */
-
-static OM_uint32
-gsskrb5_initiator_start
-(OM_uint32 * minor_status,
- krb5_ccache ccache,
- gss_ctx_id_t * context_handle,
- const gss_name_t target_name,
- const gss_OID 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_buffer_t output_token,
- OM_uint32 * ret_flags,
- OM_uint32 * time_rec
- )
-{
- OM_uint32 ret = GSS_S_FAILURE;
- krb5_error_code kret;
- krb5_flags ap_options;
- krb5_creds *cred = NULL;
- krb5_data outbuf;
- OM_uint32 flags;
- krb5_data authenticator;
- Checksum cksum;
- krb5_enctype enctype;
- krb5_data fwd_data;
- int is_cfx;
-
- krb5_data_zero(&outbuf);
- krb5_data_zero(&fwd_data);
-
- (*context_handle)->more_flags |= LOCAL;
-
- /* We need to get the credentials for the requested target */
- ret = gsskrb5_get_creds(minor_status,
- ccache,
- context_handle,
- target_name,
- time_req,
- time_rec,
- &cred);
- if (ret) return ret;
-
- /*
- * We need to setup some compat stuff, this assumes that context_handle->target is already set
- */
- ret = _gss_DES3_get_mic_compat(minor_status, *context_handle);
- if (ret) return ret;
-
- /* We need the key and a random local subkey */
- {
- kret = krb5_auth_con_setkey(gssapi_krb5_context,
- (*context_handle)->auth_context,
- &cred->session);
- if (kret) {
- gssapi_krb5_set_error_string ();
- *minor_status = kret;
- return GSS_S_FAILURE;
- }
-
- kret = krb5_auth_con_generatelocalsubkey(gssapi_krb5_context,
- (*context_handle)->auth_context,
- &cred->session);
- if (kret) {
- gssapi_krb5_set_error_string ();
- *minor_status = kret;
- return GSS_S_FAILURE;
- }
- }
-
- /* We need to prepare the flags used for this context */
- {
- flags = 0;
- ap_options = 0;
-
- /*
- * The KDC may have issued us a service ticket marked NOT
- * ok-as-delegate. We may still wish to force the matter, and to
- * allow this we check a per-realm gssapi [appdefaults] config
- * option. If ok-as-delegate in the config file is set to TRUE
- * (default FALSE) and our caller has so requested, we will still
- * attempt to forward the ticket.
- *
- * Otherwise, strip the GSS_C_DELEG_FLAG (so we don't attempt a
- * delegation)
- */
- if (!cred->flags.b.ok_as_delegate) {
- krb5_boolean delegate;
-
- krb5_appdefault_boolean(gssapi_krb5_context,
- "gssapi", target_name->realm,
- "ok-as-delegate", FALSE, &delegate);
- if (!delegate)
- req_flags &= ~GSS_C_DELEG_FLAG;
- }
-
- if (req_flags & GSS_C_DELEG_FLAG) {
- do_delegation((*context_handle)->auth_context,
- ccache, cred, target_name, &fwd_data, &flags);
- }
-
- if (req_flags & GSS_C_MUTUAL_FLAG) {
- flags |= GSS_C_MUTUAL_FLAG;
- ap_options |= AP_OPTS_MUTUAL_REQUIRED;
- }
-
- if (req_flags & GSS_C_REPLAY_FLAG) {
- flags |= GSS_C_REPLAY_FLAG;
- }
-
- if (req_flags & GSS_C_SEQUENCE_FLAG) {
- flags |= GSS_C_SEQUENCE_FLAG;
- }
-
- if (req_flags & GSS_C_ANON_FLAG) {
- ;/* XXX */
- }
-
- if (req_flags & GSS_C_DCE_STYLE) {
- flags |= GSS_C_DCE_STYLE;
- /* GSS_C_DCE_STYLE implies GSS_C_MUTUAL_FLAG */
- flags |= GSS_C_MUTUAL_FLAG;
- ap_options |= AP_OPTS_MUTUAL_REQUIRED;
- }
-
- if (req_flags & GSS_C_IDENTIFY_FLAG) {
- flags |= GSS_C_IDENTIFY_FLAG;
- }
-
- if (req_flags & GSS_C_EXTENDED_ERROR_FLAG) {
- flags |= GSS_C_EXTENDED_ERROR_FLAG;
- }
-
- /* TODO: why are this always there? --metze */
- flags |= GSS_C_CONF_FLAG;
- flags |= GSS_C_INTEG_FLAG;
- flags |= GSS_C_TRANS_FLAG;
-
- if (ret_flags) *ret_flags = flags;
- (*context_handle)->flags = flags;
- }
-
- /* We need to generate the 8003 checksum */
- {
- ret = gssapi_krb5_create_8003_checksum(minor_status,
- input_chan_bindings,
- flags,
- &fwd_data,
- &cksum);
- krb5_data_free (&fwd_data);
- if (ret) return ret;
- }
-
- enctype = (*context_handle)->auth_context->keyblock->keytype;
-
- gsskrb5_is_cfx(*context_handle, &is_cfx);
-
- if (is_cfx != 0) {
- kret = krb5_auth_con_addflags(gssapi_krb5_context,
- (*context_handle)->auth_context,
- KRB5_AUTH_CONTEXT_USE_SUBKEY,
- NULL);
- (*context_handle)->more_flags |= ACCEPTOR_SUBKEY;
- }
-
- /* We need to create an Authenticator */
- {
- kret = krb5_build_authenticator (gssapi_krb5_context,
- (*context_handle)->auth_context,
- enctype,
- cred,
- &cksum,
- NULL,
- &authenticator,
- KRB5_KU_AP_REQ_AUTH);
- free_Checksum(&cksum);
- if (kret) {
- gssapi_krb5_set_error_string ();
- *minor_status = kret;
- return GSS_S_FAILURE;
- }
- }
-
- /* We need to create the AP_REQ */
- {
- kret = krb5_build_ap_req(gssapi_krb5_context,
- enctype,
- cred,
- ap_options,
- authenticator,
- &outbuf);
- if (kret) {
- gssapi_krb5_set_error_string ();
- *minor_status = kret;
- return GSS_S_FAILURE;
- }
- }
-
- /* We need to encapsulate the AP_REQ if GSS_C_DCE_STYLE isn't in use */
- {
- if (!(flags & GSS_C_DCE_STYLE)) {
- ret = gssapi_krb5_encapsulate(minor_status, &outbuf, output_token,
- "\x01\x00", GSS_KRB5_MECHANISM);
- krb5_data_free (&outbuf);
- if (ret) return ret;
- } else {
- output_token->length = outbuf.length;
- output_token->value = outbuf.data;
- }
- }
-
- /* We no longer need the creds */
- krb5_free_creds(gssapi_krb5_context, cred);
-
- /* We are done if GSS_C_MUTUAL_FLAG is in use */
- if (flags & GSS_C_MUTUAL_FLAG) {
- (*context_handle)->state = INITIATOR_WAIT_FOR_MUTAL;
- return GSS_S_CONTINUE_NEEDED;
- }
-
- return gsskrb5_initiator_ready(minor_status, context_handle);
-}
-
-static OM_uint32
-gsskrb5_initiator_wait_for_mutual(
- OM_uint32 * minor_status,
- krb5_ccache ccache,
- gss_ctx_id_t * context_handle,
- const gss_name_t target_name,
- const gss_OID 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_buffer_t output_token,
- OM_uint32 * ret_flags,
- OM_uint32 * time_rec)
-{
- OM_uint32 ret;
- krb5_error_code kret;
- krb5_data inbuf;
- OM_uint32 flags = (*context_handle)->flags;
- int32_t l_seq_number;
- int32_t r_seq_number;
-
- /* We need to decapsulate the AP_REP if GSS_C_DCE_STYLE isn't in use */
- {
- if (!(flags & GSS_C_DCE_STYLE)) {
- ret = gssapi_krb5_decapsulate(minor_status, input_token, &inbuf,
- "\x02\x00", GSS_KRB5_MECHANISM);
- if (ret) return ret;
- } else {
- inbuf.length = input_token->length;
- inbuf.data = input_token->value;
- }
- }
-
- /* We need to verify the AP_REP */
- {
- krb5_ap_rep_enc_part *repl;
-
- kret = krb5_rd_rep(gssapi_krb5_context,
- (*context_handle)->auth_context,
- &inbuf,
- &repl);
- if (kret) {
- gssapi_krb5_set_error_string ();
- *minor_status = kret;
- return GSS_S_FAILURE;
- }
- krb5_free_ap_rep_enc_part(gssapi_krb5_context, repl);
- }
-
- /* We need to check the liftime */
- {
- OM_uint32 lifetime_rec;
-
- ret = gssapi_lifetime_left(minor_status,
- (*context_handle)->lifetime,
- &lifetime_rec);
- if (ret) return ret;
-
- if (lifetime_rec == 0) {
- return GSS_S_CONTEXT_EXPIRED;
- }
-
- if (time_rec) *time_rec = lifetime_rec;
- }
-
- /* We need to give the caller the flags which are in use */
- if (ret_flags) *ret_flags = (*context_handle)->flags;
-
- /* We are done here if GSS_C_DCE_STYLE isn't in use */
- if (!(flags & GSS_C_DCE_STYLE)) {
- return gsskrb5_initiator_ready(minor_status, context_handle);
- }
-
- /*
- * We need to set the local seq_number to the remote one just for the krb5_mk_rep(),
- * and then we need to use the old local seq_number again for the GSS_Wrap() messages
- */
- {
- kret = krb5_auth_getremoteseqnumber(gssapi_krb5_context,
- (*context_handle)->auth_context,
- &r_seq_number);
- if (kret) {
- gssapi_krb5_set_error_string ();
- *minor_status = kret;
- return GSS_S_FAILURE;
- }
-
- kret = krb5_auth_con_getlocalseqnumber(gssapi_krb5_context,
- (*context_handle)->auth_context,
- &l_seq_number);
- if (kret) {
- gssapi_krb5_set_error_string ();
- *minor_status = kret;
- return GSS_S_FAILURE;
- }
-
- kret = krb5_auth_con_setlocalseqnumber(gssapi_krb5_context,
- (*context_handle)->auth_context,
- r_seq_number);
- if (kret) {
- gssapi_krb5_set_error_string ();
- *minor_status = kret;
- return GSS_S_FAILURE;
- }
- }
-
- /* We need to create an AP_REP */
- {
- krb5_data outbuf;
-
- kret = krb5_mk_rep(gssapi_krb5_context,
- (*context_handle)->auth_context,
- &outbuf);
- if (kret) {
- gssapi_krb5_set_error_string ();
- *minor_status = kret;
- return GSS_S_FAILURE;
- }
-
- output_token->length = outbuf.length;
- output_token->value = outbuf.data;
- }
-
- /* We need to reset the local seq_number */
- {
- kret = krb5_auth_con_setlocalseqnumber(gssapi_krb5_context,
- (*context_handle)->auth_context,
- l_seq_number);
- if (kret) {
- gssapi_krb5_set_error_string ();
- *minor_status = kret;
- return GSS_S_FAILURE;
- }
- }
-
- return gsskrb5_initiator_ready(minor_status, context_handle);
-}
-
-static OM_uint32
-gsskrb5_init_sec_context
- (OM_uint32 * minor_status,
- const gss_cred_id_t initiator_cred_handle,
- gss_ctx_id_t * context_handle,
- const gss_name_t target_name,
- const gss_OID 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 ret;
- krb5_error_code kret;
- krb5_ccache ccache = NULL;
-
- if (*context_handle == GSS_C_NO_CONTEXT) {
- ret = _gsskrb5_create_ctx(minor_status,
- context_handle,
- input_chan_bindings,
- INITIATOR_START);
- if (ret) return ret;
- }
-
- if (actual_mech_type) *actual_mech_type = GSS_KRB5_MECHANISM;
-
- if (initiator_cred_handle == GSS_C_NO_CREDENTIAL) {
- kret = krb5_cc_default (gssapi_krb5_context, &ccache);
- if (kret) {
- gssapi_krb5_set_error_string ();
- *minor_status = kret;
- return GSS_S_FAILURE;
- }
- } else {
- ccache = initiator_cred_handle->ccache;
- }
-
- HEIMDAL_MUTEX_lock(&(*context_handle)->ctx_id_mutex);
-
- switch ((*context_handle)->state) {
- case INITIATOR_START:
- ret = gsskrb5_initiator_start(minor_status,
- ccache,
- context_handle,
- target_name,
- mech_type,
- req_flags,
- time_req,
- input_chan_bindings,
- input_token,
- output_token,
- ret_flags,
- time_rec);
- break;
- case INITIATOR_WAIT_FOR_MUTAL:
- ret = gsskrb5_initiator_wait_for_mutual(minor_status,
- ccache,
- context_handle,
- target_name,
- mech_type,
- req_flags,
- time_req,
- input_chan_bindings,
- input_token,
- output_token,
- ret_flags,
- time_rec);
- break;
- case INITIATOR_READY:
- /* should this be GSS_S_BAD_STATUS ? --metze */
-
- /* We need to check the liftime */
- {
- OM_uint32 lifetime_rec;
-
- ret = gssapi_lifetime_left(minor_status,
- (*context_handle)->lifetime,
- &lifetime_rec);
- if (ret) break;
-
- if (lifetime_rec == 0) {
- *minor_status = 0;
- ret = GSS_S_CONTEXT_EXPIRED;
- break;
- }
-
- if (time_rec) *time_rec = lifetime_rec;
- }
-
- /* We need to give the caller the flags which are in use */
- if (ret_flags) *ret_flags = (*context_handle)->flags;
-
- ret = GSS_S_COMPLETE;
- break;
- default:
- /* TODO: is this correct here? --metze */
- ret = GSS_S_BAD_STATUS;
- break;
- }
-
- if (initiator_cred_handle == GSS_C_NO_CREDENTIAL) {
- krb5_cc_close(gssapi_krb5_context, ccache);
- }
-
- HEIMDAL_MUTEX_unlock(&(*context_handle)->ctx_id_mutex);
-
- return ret;
-}
-
-static OM_uint32
-spnego_reply
- (OM_uint32 * minor_status,
- const gss_cred_id_t initiator_cred_handle,
- gss_ctx_id_t * context_handle,
- const gss_name_t target_name,
- const gss_OID 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 ret;
- krb5_data indata;
- NegTokenTarg targ;
- u_char oidbuf[17];
- size_t oidlen;
- gss_buffer_desc sub_token;
- ssize_t mech_len;
- const u_char *p;
- size_t len, taglen;
- krb5_boolean require_mic;
-
- output_token->length = 0;
- output_token->value = NULL;
-
- /*
- * SPNEGO doesn't include gss wrapping on SubsequentContextToken
- * like the Kerberos 5 mech does. But lets check for it anyway.
- */
-
- mech_len = gssapi_krb5_get_mech (input_token->value,
- input_token->length,
- &p);
-
- if (mech_len < 0) {
- indata.data = input_token->value;
- indata.length = input_token->length;
- } else if (mech_len == GSS_KRB5_MECHANISM->length
- && memcmp(GSS_KRB5_MECHANISM->elements, p, mech_len) == 0)
- return gsskrb5_init_sec_context (minor_status,
- initiator_cred_handle,
- context_handle,
- target_name,
- GSS_KRB5_MECHANISM,
- req_flags,
- time_req,
- input_chan_bindings,
- input_token,
- actual_mech_type,
- output_token,
- ret_flags,
- time_rec);
- else if (mech_len == GSS_SPNEGO_MECHANISM->length
- && memcmp(GSS_SPNEGO_MECHANISM->elements, p, mech_len) == 0){
- ret = _gssapi_decapsulate (minor_status,
- input_token,
- &indata,
- GSS_SPNEGO_MECHANISM);
- if (ret)
- return ret;
- } else
- return GSS_S_BAD_MECH;
-
- ret = der_match_tag_and_length((const char *)indata.data,
- indata.length,
- ASN1_C_CONTEXT, CONS, 1, &len, &taglen);
- if (ret) {
- gssapi_krb5_set_status("Failed to decode NegToken choice");
- *minor_status = ret;
- return GSS_S_FAILURE;
- }
-
- if(len > indata.length - taglen) {
- gssapi_krb5_set_status("Buffer overrun in NegToken choice");
- *minor_status = ASN1_OVERRUN;
- return GSS_S_FAILURE;
- }
-
- ret = decode_NegTokenTarg((const char *)indata.data + taglen,
- len, &targ, NULL);
- if (ret) {
- gssapi_krb5_set_status("Failed to decode NegTokenTarg");
- *minor_status = ret;
- return GSS_S_FAILURE;
- }
-
- if (targ.negResult == NULL
- || *(targ.negResult) == reject
- || targ.supportedMech == NULL) {
- free_NegTokenTarg(&targ);
- return GSS_S_BAD_MECH;
- }
-
- ret = der_put_oid(oidbuf + sizeof(oidbuf) - 1,
- sizeof(oidbuf),
- targ.supportedMech,
- &oidlen);
- if (ret || oidlen != GSS_KRB5_MECHANISM->length
- || memcmp(oidbuf + sizeof(oidbuf) - oidlen,
- GSS_KRB5_MECHANISM->elements,
- oidlen) != 0) {
- free_NegTokenTarg(&targ);
- return GSS_S_BAD_MECH;
- }
-
- if (targ.responseToken != NULL) {
- sub_token.length = targ.responseToken->length;
- sub_token.value = targ.responseToken->data;
- } else {
- sub_token.length = 0;
- sub_token.value = NULL;
- }
-
- ret = gsskrb5_init_sec_context(minor_status,
- initiator_cred_handle,
- context_handle,
- target_name,
- GSS_KRB5_MECHANISM,
- req_flags,
- time_req,
- input_chan_bindings,
- &sub_token,
- actual_mech_type,
- output_token,
- ret_flags,
- time_rec);
- if (ret) {
- free_NegTokenTarg(&targ);
- return ret;
- }
-
- /*
- * Verify the mechListMIC if CFX was used; or if local policy
- * dictated so.
- */
- ret = _gss_spnego_require_mechlist_mic(minor_status, *context_handle,
- &require_mic);
- if (ret) {
- free_NegTokenTarg(&targ);
- return ret;
- }
-
- if (require_mic) {
- MechTypeList mechlist;
- MechType m0;
- size_t buf_len;
- gss_buffer_desc mic_buf, mech_buf;
-
- if (targ.mechListMIC == NULL) {
- free_NegTokenTarg(&targ);
- *minor_status = 0;
- return GSS_S_BAD_MIC;
- }
-
- mechlist.len = 1;
- mechlist.val = &m0;
-
- ret = der_get_oid(GSS_KRB5_MECHANISM->elements,
- GSS_KRB5_MECHANISM->length,
- &m0,
- NULL);
- if (ret) {
- free_NegTokenTarg(&targ);
- *minor_status = ENOMEM;
- return GSS_S_FAILURE;
- }
-
- ASN1_MALLOC_ENCODE(MechTypeList, mech_buf.value, mech_buf.length,
- &mechlist, &buf_len, ret);
- if (ret) {
- free_NegTokenTarg(&targ);
- free_oid(&m0);
- *minor_status = ENOMEM;
- return GSS_S_FAILURE;
- }
- if (mech_buf.length != buf_len)
- abort();
-
- mic_buf.length = targ.mechListMIC->length;
- mic_buf.value = targ.mechListMIC->data;
-
- ret = gss_verify_mic(minor_status, *context_handle,
- &mech_buf, &mic_buf, NULL);
- free(mech_buf.value);
- free_oid(&m0);
- }
- free_NegTokenTarg(&targ);
- return ret;
-}
-
-static OM_uint32
-spnego_initial
- (OM_uint32 * minor_status,
- const gss_cred_id_t initiator_cred_handle,
- gss_ctx_id_t * context_handle,
- const gss_name_t target_name,
- const gss_OID 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
- )
-{
- NegTokenInit ni;
- int ret;
- OM_uint32 sub, minor;
- gss_buffer_desc mech_token;
- u_char *buf;
- size_t buf_size, buf_len;
- krb5_data data;
-
- memset (&ni, 0, sizeof(ni));
-
- ALLOC(ni.mechTypes, 1);
- if (ni.mechTypes == NULL) {
- *minor_status = ENOMEM;
- return GSS_S_FAILURE;
- }
- ALLOC_SEQ(ni.mechTypes, 1);
- if (ni.mechTypes->val == NULL) {
- free_NegTokenInit(&ni);
- *minor_status = ENOMEM;
- return GSS_S_FAILURE;
- }
- ret = der_get_oid(GSS_KRB5_MECHANISM->elements,
- GSS_KRB5_MECHANISM->length,
- &ni.mechTypes->val[0],
- NULL);
- if (ret) {
- free_NegTokenInit(&ni);
- *minor_status = ENOMEM;
- return GSS_S_FAILURE;
- }
-
-#if 0
- ALLOC(ni.reqFlags, 1);
- if (ni.reqFlags == NULL) {
- free_NegTokenInit(&ni);
- *minor_status = ENOMEM;
- return GSS_S_FAILURE;
- }
- ni.reqFlags->delegFlag = req_flags & GSS_C_DELEG_FLAG;
- ni.reqFlags->mutualFlag = req_flags & GSS_C_MUTUAL_FLAG;
- ni.reqFlags->replayFlag = req_flags & GSS_C_REPLAY_FLAG;
- ni.reqFlags->sequenceFlag = req_flags & GSS_C_SEQUENCE_FLAG;
- ni.reqFlags->anonFlag = req_flags & GSS_C_ANON_FLAG;
- ni.reqFlags->confFlag = req_flags & GSS_C_CONF_FLAG;
- ni.reqFlags->integFlag = req_flags & GSS_C_INTEG_FLAG;
-#else
- ni.reqFlags = NULL;
-#endif
-
- sub = gsskrb5_init_sec_context(&minor,
- initiator_cred_handle,
- context_handle,
- target_name,
- GSS_KRB5_MECHANISM,
- req_flags,
- time_req,
- input_chan_bindings,
- GSS_C_NO_BUFFER,
- actual_mech_type,
- &mech_token,
- ret_flags,
- time_rec);
- if (GSS_ERROR(sub)) {
- free_NegTokenInit(&ni);
- return sub;
- }
- if (mech_token.length != 0) {
- ALLOC(ni.mechToken, 1);
- if (ni.mechToken == NULL) {
- free_NegTokenInit(&ni);
- gss_release_buffer(&minor, &mech_token);
- *minor_status = ENOMEM;
- return GSS_S_FAILURE;
- }
- ni.mechToken->length = mech_token.length;
- ni.mechToken->data = malloc(mech_token.length);
- if (ni.mechToken->data == NULL && mech_token.length != 0) {
- free_NegTokenInit(&ni);
- gss_release_buffer(&minor, &mech_token);
- *minor_status = ENOMEM;
- return GSS_S_FAILURE;
- }
- memcpy(ni.mechToken->data, mech_token.value, mech_token.length);
- gss_release_buffer(&minor, &mech_token);
- } else
- ni.mechToken = NULL;
-
- /* XXX ignore mech list mic for now */
- ni.mechListMIC = NULL;
-
-
- {
- NegotiationToken nt;
-
- nt.element = choice_NegotiationToken_negTokenInit;
- nt.u.negTokenInit = ni;
-
- ASN1_MALLOC_ENCODE(NegotiationToken, buf, buf_size,
- &nt, &buf_len, ret);
- if (ret == 0 && buf_size != buf_len)
- abort();
- }
-
- data.data = buf;
- data.length = buf_size;
-
- free_NegTokenInit(&ni);
- if (ret)
- return ret;
-
- sub = _gssapi_encapsulate(minor_status,
- &data,
- output_token,
- GSS_SPNEGO_MECHANISM);
- free (buf);
-
- if (sub)
- return sub;
-
- return GSS_S_CONTINUE_NEEDED;
-}
-
-static OM_uint32
-spnego_init_sec_context
- (OM_uint32 * minor_status,
- const gss_cred_id_t initiator_cred_handle,
- gss_ctx_id_t * context_handle,
- const gss_name_t target_name,
- const gss_OID 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
- )
-{
- if (input_token == GSS_C_NO_BUFFER || input_token->length == 0)
- return spnego_initial (minor_status,
- initiator_cred_handle,
- context_handle,
- target_name,
- mech_type,
- req_flags,
- time_req,
- input_chan_bindings,
- input_token,
- actual_mech_type,
- output_token,
- ret_flags,
- time_rec);
- else
- return spnego_reply (minor_status,
- initiator_cred_handle,
- context_handle,
- target_name,
- mech_type,
- req_flags,
- time_req,
- input_chan_bindings,
- input_token,
- actual_mech_type,
- output_token,
- ret_flags,
- time_rec);
-}
-
-/*
- * gss_init_sec_context
- */
-
-OM_uint32 gss_init_sec_context
- (OM_uint32 * minor_status,
- const gss_cred_id_t initiator_cred_handle,
- gss_ctx_id_t * context_handle,
- const gss_name_t target_name,
- const gss_OID 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
- )
-{
- GSSAPI_KRB5_INIT ();
-
- output_token->length = 0;
- output_token->value = NULL;
-
- if (ret_flags)
- *ret_flags = 0;
- if (time_rec)
- *time_rec = 0;
-
- if (target_name == GSS_C_NO_NAME) {
- if (actual_mech_type)
- *actual_mech_type = GSS_C_NO_OID;
- *minor_status = 0;
- return GSS_S_BAD_NAME;
- }
-
- if (mech_type == GSS_C_NO_OID ||
- gss_oid_equal(mech_type, GSS_KRB5_MECHANISM))
- return gsskrb5_init_sec_context(minor_status,
- initiator_cred_handle,
- context_handle,
- target_name,
- mech_type,
- req_flags,
- time_req,
- input_chan_bindings,
- input_token,
- actual_mech_type,
- output_token,
- ret_flags,
- time_rec);
- else if (gss_oid_equal(mech_type, GSS_SPNEGO_MECHANISM))
- return spnego_init_sec_context (minor_status,
- initiator_cred_handle,
- context_handle,
- target_name,
- mech_type,
- req_flags,
- time_req,
- input_chan_bindings,
- input_token,
- actual_mech_type,
- output_token,
- ret_flags,
- time_rec);
- else
- return GSS_S_BAD_MECH;
-}
diff --git a/source4/heimdal/lib/gssapi/inquire_cred.c b/source4/heimdal/lib/gssapi/inquire_cred.c
deleted file mode 100644
index 9ed1ff4cc4..0000000000
--- a/source4/heimdal/lib/gssapi/inquire_cred.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * 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 "gssapi_locl.h"
-
-RCSID("$Id: inquire_cred.c,v 1.7 2004/11/30 19:27:11 lha Exp $");
-
-OM_uint32 gss_inquire_cred
- (OM_uint32 * minor_status,
- const gss_cred_id_t cred_handle,
- gss_name_t * name,
- OM_uint32 * lifetime,
- gss_cred_usage_t * cred_usage,
- gss_OID_set * mechanisms
- )
-{
- gss_cred_id_t cred;
- OM_uint32 ret;
-
- *minor_status = 0;
-
- if (name)
- *name = NULL;
- if (mechanisms)
- *mechanisms = GSS_C_NO_OID_SET;
-
- if (cred_handle == GSS_C_NO_CREDENTIAL) {
- ret = gss_acquire_cred(minor_status,
- GSS_C_NO_NAME,
- GSS_C_INDEFINITE,
- GSS_C_NO_OID_SET,
- GSS_C_BOTH,
- &cred,
- NULL,
- NULL);
- if (ret)
- return ret;
- } else
- cred = (gss_cred_id_t)cred_handle;
-
- HEIMDAL_MUTEX_lock(&cred->cred_id_mutex);
-
- if (name != NULL) {
- if (cred->principal != NULL) {
- ret = gss_duplicate_name(minor_status, cred->principal,
- name);
- if (ret)
- goto out;
- } else if (cred->usage == GSS_C_ACCEPT) {
- *minor_status = krb5_sname_to_principal(gssapi_krb5_context, NULL,
- NULL, KRB5_NT_SRV_HST, name);
- if (*minor_status) {
- ret = GSS_S_FAILURE;
- goto out;
- }
- } else {
- *minor_status = krb5_get_default_principal(gssapi_krb5_context,
- name);
- if (*minor_status) {
- ret = GSS_S_FAILURE;
- goto out;
- }
- }
- }
- if (lifetime != NULL) {
- ret = gssapi_lifetime_left(minor_status,
- cred->lifetime,
- lifetime);
- if (ret)
- goto out;
- }
- if (cred_usage != NULL)
- *cred_usage = cred->usage;
-
- if (mechanisms != NULL) {
- ret = gss_create_empty_oid_set(minor_status, mechanisms);
- if (ret)
- goto out;
- ret = gss_add_oid_set_member(minor_status,
- &cred->mechanisms->elements[0],
- mechanisms);
- if (ret)
- goto out;
- }
- ret = GSS_S_COMPLETE;
- out:
- HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
-
- if (cred_handle == GSS_C_NO_CREDENTIAL)
- ret = gss_release_cred(minor_status, &cred);
-
- return ret;
-}
diff --git a/source4/heimdal/lib/gssapi/8003.c b/source4/heimdal/lib/gssapi/krb5/8003.c
index 359bb6e715..0123f67e09 100644
--- a/source4/heimdal/lib/gssapi/8003.c
+++ b/source4/heimdal/lib/gssapi/krb5/8003.c
@@ -31,12 +31,12 @@
* SUCH DAMAGE.
*/
-#include "gssapi_locl.h"
+#include "krb5/gsskrb5_locl.h"
-RCSID("$Id: 8003.c,v 1.18 2006/05/04 11:55:40 lha Exp $");
+RCSID("$Id: 8003.c,v 1.20 2006/10/07 22:13:51 lha Exp $");
krb5_error_code
-gssapi_encode_om_uint32(OM_uint32 n, u_char *p)
+_gsskrb5_encode_om_uint32(OM_uint32 n, u_char *p)
{
p[0] = (n >> 0) & 0xFF;
p[1] = (n >> 8) & 0xFF;
@@ -46,7 +46,7 @@ gssapi_encode_om_uint32(OM_uint32 n, u_char *p)
}
krb5_error_code
-gssapi_encode_be_om_uint32(OM_uint32 n, u_char *p)
+_gsskrb5_encode_be_om_uint32(OM_uint32 n, u_char *p)
{
p[0] = (n >> 24) & 0xFF;
p[1] = (n >> 16) & 0xFF;
@@ -56,7 +56,7 @@ gssapi_encode_be_om_uint32(OM_uint32 n, u_char *p)
}
krb5_error_code
-gssapi_decode_om_uint32(const void *ptr, OM_uint32 *n)
+_gsskrb5_decode_om_uint32(const void *ptr, OM_uint32 *n)
{
const u_char *p = ptr;
*n = (p[0] << 0) | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
@@ -64,7 +64,7 @@ gssapi_decode_om_uint32(const void *ptr, OM_uint32 *n)
}
krb5_error_code
-gssapi_decode_be_om_uint32(const void *ptr, OM_uint32 *n)
+_gsskrb5_decode_be_om_uint32(const void *ptr, OM_uint32 *n)
{
const u_char *p = ptr;
*n = (p[0] <<24) | (p[1] << 16) | (p[2] << 8) | (p[3] << 0);
@@ -79,23 +79,23 @@ hash_input_chan_bindings (const gss_channel_bindings_t b,
MD5_CTX md5;
MD5_Init(&md5);
- gssapi_encode_om_uint32 (b->initiator_addrtype, num);
+ _gsskrb5_encode_om_uint32 (b->initiator_addrtype, num);
MD5_Update (&md5, num, sizeof(num));
- gssapi_encode_om_uint32 (b->initiator_address.length, num);
+ _gsskrb5_encode_om_uint32 (b->initiator_address.length, num);
MD5_Update (&md5, num, sizeof(num));
if (b->initiator_address.length)
MD5_Update (&md5,
b->initiator_address.value,
b->initiator_address.length);
- gssapi_encode_om_uint32 (b->acceptor_addrtype, num);
+ _gsskrb5_encode_om_uint32 (b->acceptor_addrtype, num);
MD5_Update (&md5, num, sizeof(num));
- gssapi_encode_om_uint32 (b->acceptor_address.length, num);
+ _gsskrb5_encode_om_uint32 (b->acceptor_address.length, num);
MD5_Update (&md5, num, sizeof(num));
if (b->acceptor_address.length)
MD5_Update (&md5,
b->acceptor_address.value,
b->acceptor_address.length);
- gssapi_encode_om_uint32 (b->application_data.length, num);
+ _gsskrb5_encode_om_uint32 (b->application_data.length, num);
MD5_Update (&md5, num, sizeof(num));
if (b->application_data.length)
MD5_Update (&md5,
@@ -112,7 +112,7 @@ hash_input_chan_bindings (const gss_channel_bindings_t b,
*/
OM_uint32
-gssapi_krb5_create_8003_checksum (
+_gsskrb5_create_8003_checksum (
OM_uint32 *minor_status,
const gss_channel_bindings_t input_chan_bindings,
OM_uint32 flags,
@@ -136,7 +136,7 @@ gssapi_krb5_create_8003_checksum (
}
p = result->checksum.data;
- gssapi_encode_om_uint32 (16, p);
+ _gsskrb5_encode_om_uint32 (16, p);
p += 4;
if (input_chan_bindings == GSS_C_NO_CHANNEL_BINDINGS) {
memset (p, 0, 16);
@@ -144,7 +144,7 @@ gssapi_krb5_create_8003_checksum (
hash_input_chan_bindings (input_chan_bindings, p);
}
p += 16;
- gssapi_encode_om_uint32 (flags, p);
+ _gsskrb5_encode_om_uint32 (flags, p);
p += 4;
if (fwd_data->length > 0 && (flags & GSS_C_DELEG_FLAG)) {
@@ -167,7 +167,7 @@ gssapi_krb5_create_8003_checksum (
*/
OM_uint32
-gssapi_krb5_verify_8003_checksum(
+_gsskrb5_verify_8003_checksum(
OM_uint32 *minor_status,
const gss_channel_bindings_t input_chan_bindings,
const Checksum *cksum,
@@ -192,7 +192,7 @@ gssapi_krb5_verify_8003_checksum(
}
p = cksum->checksum.data;
- gssapi_decode_om_uint32(p, &length);
+ _gsskrb5_decode_om_uint32(p, &length);
if(length != sizeof(hash)) {
*minor_status = 0;
return GSS_S_BAD_BINDINGS;
@@ -214,7 +214,7 @@ gssapi_krb5_verify_8003_checksum(
p += sizeof(hash);
- gssapi_decode_om_uint32(p, flags);
+ _gsskrb5_decode_om_uint32(p, flags);
p += 4;
if (cksum->checksum.length > 24 && (*flags & GSS_C_DELEG_FLAG)) {
diff --git a/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c b/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c
new file mode 100644
index 0000000000..e42bb11b85
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c
@@ -0,0 +1,774 @@
+/*
+ * Copyright (c) 1997 - 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 "krb5/gsskrb5_locl.h"
+
+RCSID("$Id: accept_sec_context.c,v 1.64 2006/10/25 04:19:45 lha Exp $");
+
+HEIMDAL_MUTEX gssapi_keytab_mutex = HEIMDAL_MUTEX_INITIALIZER;
+krb5_keytab _gsskrb5_keytab;
+
+OM_uint32
+_gsskrb5_register_acceptor_identity (const char *identity)
+{
+ krb5_error_code ret;
+
+ ret = _gsskrb5_init();
+ if(ret)
+ return GSS_S_FAILURE;
+
+ HEIMDAL_MUTEX_lock(&gssapi_keytab_mutex);
+
+ if(_gsskrb5_keytab != NULL) {
+ krb5_kt_close(_gsskrb5_context, _gsskrb5_keytab);
+ _gsskrb5_keytab = NULL;
+ }
+ if (identity == NULL) {
+ ret = krb5_kt_default(_gsskrb5_context, &_gsskrb5_keytab);
+ } else {
+ char *p;
+
+ asprintf(&p, "FILE:%s", identity);
+ if(p == NULL) {
+ HEIMDAL_MUTEX_unlock(&gssapi_keytab_mutex);
+ return GSS_S_FAILURE;
+ }
+ ret = krb5_kt_resolve(_gsskrb5_context, p, &_gsskrb5_keytab);
+ free(p);
+ }
+ HEIMDAL_MUTEX_unlock(&gssapi_keytab_mutex);
+ if(ret)
+ return GSS_S_FAILURE;
+ return GSS_S_COMPLETE;
+}
+
+void
+_gsskrb5i_is_cfx(gsskrb5_ctx ctx, int *is_cfx)
+{
+ krb5_keyblock *key;
+ int acceptor = (ctx->more_flags & LOCAL) == 0;
+
+ *is_cfx = 0;
+
+ if (acceptor) {
+ if (ctx->auth_context->local_subkey)
+ key = ctx->auth_context->local_subkey;
+ else
+ key = ctx->auth_context->remote_subkey;
+ } else {
+ if (ctx->auth_context->remote_subkey)
+ key = ctx->auth_context->remote_subkey;
+ else
+ key = ctx->auth_context->local_subkey;
+ }
+ if (key == NULL)
+ key = ctx->auth_context->keyblock;
+
+ if (key == NULL)
+ return;
+
+ switch (key->keytype) {
+ case ETYPE_DES_CBC_CRC:
+ case ETYPE_DES_CBC_MD4:
+ case ETYPE_DES_CBC_MD5:
+ case ETYPE_DES3_CBC_MD5:
+ case ETYPE_DES3_CBC_SHA1:
+ case ETYPE_ARCFOUR_HMAC_MD5:
+ case ETYPE_ARCFOUR_HMAC_MD5_56:
+ break;
+ default :
+ *is_cfx = 1;
+ if ((acceptor && ctx->auth_context->local_subkey) ||
+ (!acceptor && ctx->auth_context->remote_subkey))
+ ctx->more_flags |= ACCEPTOR_SUBKEY;
+ break;
+ }
+}
+
+
+static OM_uint32
+gsskrb5_accept_delegated_token
+(OM_uint32 * minor_status,
+ gsskrb5_ctx ctx,
+ gss_cred_id_t * delegated_cred_handle
+ )
+{
+ krb5_ccache ccache = NULL;
+ krb5_error_code kret;
+ int32_t ac_flags, ret = GSS_S_COMPLETE;
+
+ *minor_status = 0;
+
+ /* XXX Create a new delegated_cred_handle? */
+ if (delegated_cred_handle == NULL) {
+ kret = krb5_cc_default (_gsskrb5_context, &ccache);
+ } else {
+ *delegated_cred_handle = NULL;
+ kret = krb5_cc_gen_new (_gsskrb5_context, &krb5_mcc_ops, &ccache);
+ }
+ if (kret) {
+ ctx->flags &= ~GSS_C_DELEG_FLAG;
+ goto out;
+ }
+
+ kret = krb5_cc_initialize(_gsskrb5_context, ccache, ctx->source);
+ if (kret) {
+ ctx->flags &= ~GSS_C_DELEG_FLAG;
+ goto out;
+ }
+
+ krb5_auth_con_removeflags(_gsskrb5_context,
+ ctx->auth_context,
+ KRB5_AUTH_CONTEXT_DO_TIME,
+ &ac_flags);
+ kret = krb5_rd_cred2(_gsskrb5_context,
+ ctx->auth_context,
+ ccache,
+ &ctx->fwd_data);
+ if (kret)
+ _gsskrb5_set_error_string();
+ krb5_auth_con_setflags(_gsskrb5_context,
+ ctx->auth_context,
+ ac_flags);
+ if (kret) {
+ ctx->flags &= ~GSS_C_DELEG_FLAG;
+ ret = GSS_S_FAILURE;
+ *minor_status = kret;
+ goto out;
+ }
+
+ if (delegated_cred_handle) {
+ gsskrb5_cred handle;
+
+ ret = _gsskrb5_import_cred(minor_status,
+ ccache,
+ NULL,
+ NULL,
+ delegated_cred_handle);
+ if (ret != GSS_S_COMPLETE)
+ goto out;
+
+ handle = (gsskrb5_cred) *delegated_cred_handle;
+
+ handle->cred_flags |= GSS_CF_DESTROY_CRED_ON_RELEASE;
+ krb5_cc_close(_gsskrb5_context, ccache);
+ ccache = NULL;
+ }
+
+out:
+ if (ccache) {
+ if (delegated_cred_handle == NULL)
+ krb5_cc_close(_gsskrb5_context, ccache);
+ else
+ krb5_cc_destroy(_gsskrb5_context, ccache);
+ }
+ return ret;
+}
+
+static OM_uint32
+gsskrb5_acceptor_ready(OM_uint32 * minor_status,
+ gsskrb5_ctx ctx,
+ gss_cred_id_t *delegated_cred_handle)
+{
+ OM_uint32 ret;
+ int32_t seq_number;
+ int is_cfx = 0;
+
+ krb5_auth_getremoteseqnumber (_gsskrb5_context,
+ ctx->auth_context,
+ &seq_number);
+
+ _gsskrb5i_is_cfx(ctx, &is_cfx);
+
+ ret = _gssapi_msg_order_create(minor_status,
+ &ctx->order,
+ _gssapi_msg_order_f(ctx->flags),
+ seq_number, 0, is_cfx);
+ if (ret)
+ return ret;
+
+ /*
+ * If requested, set local sequence num to remote sequence if this
+ * isn't a mutual authentication context
+ */
+ if (!(ctx->flags & GSS_C_MUTUAL_FLAG) && _gssapi_msg_order_f(ctx->flags)) {
+ krb5_auth_con_setlocalseqnumber(_gsskrb5_context,
+ ctx->auth_context,
+ seq_number);
+ }
+
+ /*
+ * We should handle the delegation ticket, in case it's there
+ */
+ if (ctx->fwd_data.length > 0 && (ctx->flags & GSS_C_DELEG_FLAG)) {
+ ret = gsskrb5_accept_delegated_token(minor_status,
+ ctx,
+ delegated_cred_handle);
+ if (ret)
+ return ret;
+ } else {
+ /* Well, looks like it wasn't there after all */
+ ctx->flags &= ~GSS_C_DELEG_FLAG;
+ }
+
+ ctx->state = ACCEPTOR_READY;
+ ctx->more_flags |= OPEN;
+
+ return GSS_S_COMPLETE;
+}
+
+static OM_uint32
+gsskrb5_acceptor_start(OM_uint32 * minor_status,
+ gsskrb5_ctx ctx,
+ const gss_cred_id_t acceptor_cred_handle,
+ const gss_buffer_t input_token_buffer,
+ 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)
+{
+ krb5_error_code kret;
+ OM_uint32 ret = GSS_S_COMPLETE;
+ krb5_data indata;
+ krb5_flags ap_options;
+ krb5_ticket *ticket = NULL;
+ krb5_keytab keytab = NULL;
+ krb5_keyblock *keyblock = NULL;
+ int is_cfx = 0;
+ const gsskrb5_cred acceptor_cred = (gsskrb5_cred)acceptor_cred_handle;
+
+ /*
+ * We may, or may not, have an escapsulation.
+ */
+ ret = _gsskrb5_decapsulate (minor_status,
+ input_token_buffer,
+ &indata,
+ "\x01\x00",
+ GSS_KRB5_MECHANISM);
+
+ if (ret) {
+ /* Assume that there is no OID wrapping. */
+ indata.length = input_token_buffer->length;
+ indata.data = input_token_buffer->value;
+ }
+
+ /*
+ * We need to get our keytab
+ */
+ if (acceptor_cred == NULL) {
+ if (_gsskrb5_keytab != NULL)
+ keytab = _gsskrb5_keytab;
+ } else if (acceptor_cred->keytab != NULL) {
+ keytab = acceptor_cred->keytab;
+ }
+
+ /*
+ * We need to check the ticket and create the AP-REP packet
+ */
+ kret = krb5_rd_req_return_keyblock(_gsskrb5_context,
+ &ctx->auth_context,
+ &indata,
+ (acceptor_cred == NULL) ? NULL : acceptor_cred->principal,
+ keytab,
+ &ap_options,
+ &ticket,
+ &keyblock);
+ if (kret) {
+ ret = GSS_S_FAILURE;
+ *minor_status = kret;
+ _gsskrb5_set_error_string ();
+ return ret;
+ }
+
+ /*
+ * We need to remember some data on the context_handle.
+ */
+ ctx->ticket = ticket;
+ ctx->service_keyblock = keyblock;
+ ctx->lifetime = ticket->ticket.endtime;
+
+ /*
+ * We need to copy the principal names to the context and the
+ * calling layer.
+ */
+ kret = krb5_copy_principal(_gsskrb5_context,
+ ticket->client,
+ &ctx->source);
+ if (kret) {
+ ret = GSS_S_FAILURE;
+ *minor_status = kret;
+ _gsskrb5_set_error_string ();
+ }
+
+ kret = krb5_copy_principal(_gsskrb5_context, ticket->server, &ctx->target);
+ if (kret) {
+ ret = GSS_S_FAILURE;
+ *minor_status = kret;
+ _gsskrb5_set_error_string ();
+ return ret;
+ }
+
+ /*
+ * We need to setup some compat stuff, this assumes that
+ * context_handle->target is already set.
+ */
+ ret = _gss_DES3_get_mic_compat(minor_status, ctx);
+ if (ret)
+ return ret;
+
+ if (src_name != NULL) {
+ kret = krb5_copy_principal (_gsskrb5_context,
+ ticket->client,
+ (gsskrb5_name*)src_name);
+ if (kret) {
+ ret = GSS_S_FAILURE;
+ *minor_status = kret;
+ _gsskrb5_set_error_string ();
+ return ret;
+ }
+ }
+
+ /*
+ * We need to get the flags out of the 8003 checksum.
+ */
+ {
+ krb5_authenticator authenticator;
+
+ kret = krb5_auth_con_getauthenticator(_gsskrb5_context,
+ ctx->auth_context,
+ &authenticator);
+ if(kret) {
+ ret = GSS_S_FAILURE;
+ *minor_status = kret;
+ _gsskrb5_set_error_string ();
+ return ret;
+ }
+
+ if (authenticator->cksum->cksumtype == CKSUMTYPE_GSSAPI) {
+ ret = _gsskrb5_verify_8003_checksum(minor_status,
+ input_chan_bindings,
+ authenticator->cksum,
+ &ctx->flags,
+ &ctx->fwd_data);
+
+ krb5_free_authenticator(_gsskrb5_context, &authenticator);
+ if (ret) {
+ return ret;
+ }
+ } else {
+ krb5_crypto crypto;
+
+ kret = krb5_crypto_init(_gsskrb5_context,
+ ctx->auth_context->keyblock,
+ 0, &crypto);
+ if(kret) {
+ krb5_free_authenticator(_gsskrb5_context, &authenticator);
+
+ ret = GSS_S_FAILURE;
+ *minor_status = kret;
+ _gsskrb5_set_error_string ();
+ return ret;
+ }
+
+ /*
+ * Windows accepts Samba3's use of a kerberos, rather than
+ * GSSAPI checksum here
+ */
+
+ kret = krb5_verify_checksum(_gsskrb5_context,
+ crypto, KRB5_KU_AP_REQ_AUTH_CKSUM, NULL, 0,
+ authenticator->cksum);
+ krb5_free_authenticator(_gsskrb5_context, &authenticator);
+ krb5_crypto_destroy(_gsskrb5_context, crypto);
+
+ if(kret) {
+ ret = GSS_S_BAD_SIG;
+ *minor_status = kret;
+ _gsskrb5_set_error_string ();
+ return ret;
+ }
+
+ /*
+ * Samba style get some flags (but not DCE-STYLE)
+ */
+ ctx->flags =
+ GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG;
+ }
+ }
+
+ if(ctx->flags & GSS_C_MUTUAL_FLAG) {
+ krb5_data outbuf;
+
+ _gsskrb5i_is_cfx(ctx, &is_cfx);
+
+ if (is_cfx != 0
+ || (ap_options & AP_OPTS_USE_SUBKEY)) {
+ kret = krb5_auth_con_addflags(_gsskrb5_context,
+ ctx->auth_context,
+ KRB5_AUTH_CONTEXT_USE_SUBKEY,
+ NULL);
+ ctx->more_flags |= ACCEPTOR_SUBKEY;
+ }
+
+ kret = krb5_mk_rep(_gsskrb5_context,
+ ctx->auth_context,
+ &outbuf);
+ if (kret) {
+ *minor_status = kret;
+ _gsskrb5_set_error_string ();
+ return GSS_S_FAILURE;
+ }
+
+ if (ctx->flags & GSS_C_DCE_STYLE) {
+ output_token->length = outbuf.length;
+ output_token->value = outbuf.data;
+ } else {
+ ret = _gsskrb5_encapsulate(minor_status,
+ &outbuf,
+ output_token,
+ "\x02\x00",
+ GSS_KRB5_MECHANISM);
+ krb5_data_free (&outbuf);
+ if (ret)
+ return ret;
+ }
+ }
+
+ ctx->flags |= GSS_C_TRANS_FLAG;
+
+ /* Remember the flags */
+
+ ctx->lifetime = ticket->ticket.endtime;
+ ctx->more_flags |= OPEN;
+
+ if (mech_type)
+ *mech_type = GSS_KRB5_MECHANISM;
+
+ if (time_rec) {
+ ret = _gsskrb5_lifetime_left(minor_status,
+ ctx->lifetime,
+ time_rec);
+ if (ret) {
+ return ret;
+ }
+ }
+
+ /*
+ * When GSS_C_DCE_STYLE is in use, we need ask for a AP-REP from
+ * the client.
+ */
+ if (ctx->flags & GSS_C_DCE_STYLE) {
+ /*
+ * Return flags to caller, but we haven't processed
+ * delgations yet
+ */
+ if (ret_flags)
+ *ret_flags = (ctx->flags & ~GSS_C_DELEG_FLAG);
+
+ ctx->state = ACCEPTOR_WAIT_FOR_DCESTYLE;
+ return GSS_S_CONTINUE_NEEDED;
+ }
+
+ ret = gsskrb5_acceptor_ready(minor_status, ctx, delegated_cred_handle);
+
+ if (ret_flags)
+ *ret_flags = ctx->flags;
+
+ return ret;
+}
+
+static OM_uint32
+acceptor_wait_for_dcestyle(OM_uint32 * minor_status,
+ gsskrb5_ctx ctx,
+ const gss_cred_id_t acceptor_cred_handle,
+ const gss_buffer_t input_token_buffer,
+ 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 ret;
+ krb5_error_code kret;
+ krb5_data inbuf;
+ int32_t r_seq_number, l_seq_number;
+
+ /*
+ * We know it's GSS_C_DCE_STYLE so we don't need to decapsulate the AP_REP
+ */
+
+ inbuf.length = input_token_buffer->length;
+ inbuf.data = input_token_buffer->value;
+
+ /*
+ * We need to remeber the old remote seq_number, then check if the
+ * client has replied with our local seq_number, and then reset
+ * the remote seq_number to the old value
+ */
+ {
+ kret = krb5_auth_con_getlocalseqnumber(_gsskrb5_context,
+ ctx->auth_context,
+ &l_seq_number);
+ if (kret) {
+ _gsskrb5_set_error_string ();
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+
+ kret = krb5_auth_getremoteseqnumber(_gsskrb5_context,
+ ctx->auth_context,
+ &r_seq_number);
+ if (kret) {
+ _gsskrb5_set_error_string ();
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+
+ kret = krb5_auth_con_setremoteseqnumber(_gsskrb5_context,
+ ctx->auth_context,
+ l_seq_number);
+ if (kret) {
+ _gsskrb5_set_error_string ();
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+ }
+
+ /*
+ * We need to verify the AP_REP, but we need to flag that this is
+ * DCE_STYLE, so don't check the timestamps this time, but put the
+ * flag DO_TIME back afterward.
+ */
+ {
+ krb5_ap_rep_enc_part *repl;
+ int32_t auth_flags;
+
+ krb5_auth_con_removeflags(_gsskrb5_context,
+ ctx->auth_context,
+ KRB5_AUTH_CONTEXT_DO_TIME,
+ &auth_flags);
+
+ kret = krb5_rd_rep(_gsskrb5_context, ctx->auth_context, &inbuf, &repl);
+ if (kret) {
+ _gsskrb5_set_error_string ();
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+ krb5_free_ap_rep_enc_part(_gsskrb5_context, repl);
+ krb5_auth_con_setflags(_gsskrb5_context, ctx->auth_context, auth_flags);
+ }
+
+ /* We need to check the liftime */
+ {
+ OM_uint32 lifetime_rec;
+
+ ret = _gsskrb5_lifetime_left(minor_status,
+ ctx->lifetime,
+ &lifetime_rec);
+ if (ret) {
+ return ret;
+ }
+ if (lifetime_rec == 0) {
+ return GSS_S_CONTEXT_EXPIRED;
+ }
+
+ if (time_rec) *time_rec = lifetime_rec;
+ }
+
+ /* We need to give the caller the flags which are in use */
+ if (ret_flags) *ret_flags = ctx->flags;
+
+ if (src_name) {
+ kret = krb5_copy_principal(_gsskrb5_context,
+ ctx->source,
+ (gsskrb5_name*)src_name);
+ if (kret) {
+ *minor_status = kret;
+ _gsskrb5_set_error_string ();
+ return GSS_S_FAILURE;
+ }
+ }
+
+ /*
+ * After the krb5_rd_rep() the remote and local seq_number should
+ * be the same, because the client just replies the seq_number
+ * from our AP-REP in its AP-REP, but then the client uses the
+ * seq_number from its AP-REQ for GSS_wrap()
+ */
+ {
+ int32_t tmp_r_seq_number, tmp_l_seq_number;
+
+ kret = krb5_auth_getremoteseqnumber(_gsskrb5_context,
+ ctx->auth_context,
+ &tmp_r_seq_number);
+ if (kret) {
+ _gsskrb5_set_error_string ();
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+
+ kret = krb5_auth_con_getlocalseqnumber(_gsskrb5_context,
+ ctx->auth_context,
+ &tmp_l_seq_number);
+ if (kret) {
+ _gsskrb5_set_error_string ();
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+
+ /*
+ * Here we check if the client has responsed with our local seq_number,
+ */
+ if (tmp_r_seq_number != tmp_l_seq_number) {
+ return GSS_S_UNSEQ_TOKEN;
+ }
+ }
+
+ /*
+ * We need to reset the remote seq_number, because the client will use,
+ * the old one for the GSS_wrap() calls
+ */
+ {
+ kret = krb5_auth_con_setremoteseqnumber(_gsskrb5_context,
+ ctx->auth_context,
+ r_seq_number);
+ if (kret) {
+ _gsskrb5_set_error_string ();
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+ }
+
+ return gsskrb5_acceptor_ready(minor_status, ctx, delegated_cred_handle);
+}
+
+
+OM_uint32
+_gsskrb5_accept_sec_context(OM_uint32 * minor_status,
+ gss_ctx_id_t * context_handle,
+ const gss_cred_id_t acceptor_cred_handle,
+ const gss_buffer_t input_token_buffer,
+ 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 ret;
+ gsskrb5_ctx ctx;
+
+ GSSAPI_KRB5_INIT();
+
+ output_token->length = 0;
+ output_token->value = NULL;
+
+ if (src_name != NULL)
+ *src_name = NULL;
+ if (mech_type)
+ *mech_type = GSS_KRB5_MECHANISM;
+
+ if (*context_handle == GSS_C_NO_CONTEXT) {
+ ret = _gsskrb5_create_ctx(minor_status,
+ context_handle,
+ input_chan_bindings,
+ ACCEPTOR_START);
+ if (ret)
+ return ret;
+ }
+
+ ctx = (gsskrb5_ctx)*context_handle;
+
+
+ /*
+ * TODO: check the channel_bindings
+ * (above just sets them to krb5 layer)
+ */
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+
+ switch (ctx->state) {
+ case ACCEPTOR_START:
+ ret = gsskrb5_acceptor_start(minor_status,
+ ctx,
+ acceptor_cred_handle,
+ input_token_buffer,
+ input_chan_bindings,
+ src_name,
+ mech_type,
+ output_token,
+ ret_flags,
+ time_rec,
+ delegated_cred_handle);
+ break;
+ case ACCEPTOR_WAIT_FOR_DCESTYLE:
+ ret = acceptor_wait_for_dcestyle(minor_status,
+ ctx,
+ acceptor_cred_handle,
+ input_token_buffer,
+ input_chan_bindings,
+ src_name,
+ mech_type,
+ output_token,
+ ret_flags,
+ time_rec,
+ delegated_cred_handle);
+ break;
+ case ACCEPTOR_READY:
+ /*
+ * If we get there, the caller have called
+ * gss_accept_sec_context() one time too many.
+ */
+ ret = GSS_S_BAD_STATUS;
+ break;
+ default:
+ /* TODO: is this correct here? --metze */
+ ret = GSS_S_BAD_STATUS;
+ break;
+ }
+
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+
+ if (GSS_ERROR(ret)) {
+ OM_uint32 min2;
+ _gsskrb5_delete_sec_context(&min2, context_handle, GSS_C_NO_BUFFER);
+ }
+
+ return ret;
+}
diff --git a/source4/heimdal/lib/gssapi/acquire_cred.c b/source4/heimdal/lib/gssapi/krb5/acquire_cred.c
index fa5d709a30..df6e137402 100644
--- a/source4/heimdal/lib/gssapi/acquire_cred.c
+++ b/source4/heimdal/lib/gssapi/krb5/acquire_cred.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997 - 2004 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -31,12 +31,12 @@
* SUCH DAMAGE.
*/
-#include "gssapi_locl.h"
+#include "krb5/gsskrb5_locl.h"
-RCSID("$Id: acquire_cred.c,v 1.27 2005/12/01 16:26:02 lha Exp $");
+RCSID("$Id: acquire_cred.c,v 1.31 2006/10/07 22:13:55 lha Exp $");
OM_uint32
-_gssapi_krb5_ccache_lifetime(OM_uint32 *minor_status,
+__gsskrb5_ccache_lifetime(OM_uint32 *minor_status,
krb5_ccache id,
krb5_principal principal,
OM_uint32 *lifetime)
@@ -48,32 +48,32 @@ _gssapi_krb5_ccache_lifetime(OM_uint32 *minor_status,
memset(&in_cred, 0, sizeof(in_cred));
in_cred.client = principal;
- realm = krb5_principal_get_realm(gssapi_krb5_context, principal);
+ realm = krb5_principal_get_realm(_gsskrb5_context, principal);
if (realm == NULL) {
- gssapi_krb5_clear_status ();
+ _gsskrb5_clear_status ();
*minor_status = KRB5_PRINC_NOMATCH; /* XXX */
return GSS_S_FAILURE;
}
- kret = krb5_make_principal(gssapi_krb5_context, &in_cred.server,
+ kret = krb5_make_principal(_gsskrb5_context, &in_cred.server,
realm, KRB5_TGS_NAME, realm, NULL);
if (kret) {
- gssapi_krb5_set_error_string();
+ _gsskrb5_set_error_string();
*minor_status = kret;
return GSS_S_FAILURE;
}
- kret = krb5_get_credentials(gssapi_krb5_context, 0,
+ kret = krb5_get_credentials(_gsskrb5_context, 0,
id, &in_cred, &out_cred);
- krb5_free_principal(gssapi_krb5_context, in_cred.server);
+ krb5_free_principal(_gsskrb5_context, in_cred.server);
if (kret) {
- gssapi_krb5_set_error_string();
+ _gsskrb5_set_error_string();
*minor_status = kret;
return GSS_S_FAILURE;
}
*lifetime = out_cred->times.endtime;
- krb5_free_creds(gssapi_krb5_context, out_cred);
+ krb5_free_creds(_gsskrb5_context, out_cred);
return GSS_S_COMPLETE;
}
@@ -82,21 +82,21 @@ _gssapi_krb5_ccache_lifetime(OM_uint32 *minor_status,
static krb5_error_code
-get_keytab(krb5_context context, krb5_keytab *keytab)
+get_keytab(krb5_keytab *keytab)
{
char kt_name[256];
krb5_error_code kret;
HEIMDAL_MUTEX_lock(&gssapi_keytab_mutex);
- if (gssapi_krb5_keytab != NULL) {
- kret = krb5_kt_get_name(context,
- gssapi_krb5_keytab,
+ if (_gsskrb5_keytab != NULL) {
+ kret = krb5_kt_get_name(_gsskrb5_context,
+ _gsskrb5_keytab,
kt_name, sizeof(kt_name));
if (kret == 0)
- kret = krb5_kt_resolve(context, kt_name, keytab);
+ kret = krb5_kt_resolve(_gsskrb5_context, kt_name, keytab);
} else
- kret = krb5_kt_default(context, keytab);
+ kret = krb5_kt_default(_gsskrb5_context, keytab);
HEIMDAL_MUTEX_unlock(&gssapi_keytab_mutex);
@@ -105,12 +105,11 @@ get_keytab(krb5_context context, krb5_keytab *keytab)
static OM_uint32 acquire_initiator_cred
(OM_uint32 * minor_status,
- krb5_context context,
const gss_name_t desired_name,
OM_uint32 time_req,
const gss_OID_set desired_mechs,
gss_cred_usage_t cred_usage,
- gss_cred_id_t handle,
+ gsskrb5_cred handle,
gss_OID_set * actual_mechs,
OM_uint32 * time_rec
)
@@ -120,9 +119,10 @@ static OM_uint32 acquire_initiator_cred
krb5_principal def_princ;
krb5_get_init_creds_opt *opt;
krb5_ccache ccache;
- krb5_error_code kret;
krb5_keytab keytab;
+ krb5_error_code kret;
+ keytab = NULL;
ccache = NULL;
def_princ = NULL;
ret = GSS_S_FAILURE;
@@ -132,33 +132,33 @@ static OM_uint32 acquire_initiator_cred
* caches, otherwise, fall back to default cache. Ignore
* errors. */
if (handle->principal)
- kret = krb5_cc_cache_match (gssapi_krb5_context,
+ kret = krb5_cc_cache_match (_gsskrb5_context,
handle->principal,
NULL,
&ccache);
if (ccache == NULL) {
- kret = krb5_cc_default(gssapi_krb5_context, &ccache);
+ kret = krb5_cc_default(_gsskrb5_context, &ccache);
if (kret)
goto end;
}
- kret = krb5_cc_get_principal(context, ccache,
+ kret = krb5_cc_get_principal(_gsskrb5_context, ccache,
&def_princ);
if (kret != 0) {
/* we'll try to use a keytab below */
- krb5_cc_destroy(context, ccache);
+ krb5_cc_destroy(_gsskrb5_context, ccache);
ccache = NULL;
kret = 0;
} else if (handle->principal == NULL) {
- kret = krb5_copy_principal(context, def_princ,
+ kret = krb5_copy_principal(_gsskrb5_context, def_princ,
&handle->principal);
if (kret)
goto end;
} else if (handle->principal != NULL &&
- krb5_principal_compare(context, handle->principal,
+ krb5_principal_compare(_gsskrb5_context, handle->principal,
def_princ) == FALSE) {
/* Before failing, lets check the keytab */
- krb5_free_principal(context, def_princ);
+ krb5_free_principal(_gsskrb5_context, def_princ);
def_princ = NULL;
}
if (def_princ == NULL) {
@@ -166,37 +166,37 @@ static OM_uint32 acquire_initiator_cred
* so attempt to get a TGT using a keytab.
*/
if (handle->principal == NULL) {
- kret = krb5_get_default_principal(context,
+ kret = krb5_get_default_principal(_gsskrb5_context,
&handle->principal);
if (kret)
goto end;
}
- kret = get_keytab(context, &keytab);
+ kret = get_keytab(&keytab);
if (kret)
goto end;
- kret = krb5_get_init_creds_opt_alloc(gssapi_krb5_context, &opt);
+ kret = krb5_get_init_creds_opt_alloc(_gsskrb5_context, &opt);
if (kret)
goto end;
- kret = krb5_get_init_creds_keytab(gssapi_krb5_context, &cred,
+ kret = krb5_get_init_creds_keytab(_gsskrb5_context, &cred,
handle->principal, keytab, 0, NULL, opt);
krb5_get_init_creds_opt_free(opt);
if (kret)
goto end;
- kret = krb5_cc_gen_new(gssapi_krb5_context, &krb5_mcc_ops,
+ kret = krb5_cc_gen_new(_gsskrb5_context, &krb5_mcc_ops,
&ccache);
if (kret)
goto end;
- kret = krb5_cc_initialize(gssapi_krb5_context, ccache, cred.client);
+ kret = krb5_cc_initialize(_gsskrb5_context, ccache, cred.client);
if (kret)
goto end;
- kret = krb5_cc_store_cred(gssapi_krb5_context, ccache, &cred);
+ kret = krb5_cc_store_cred(_gsskrb5_context, ccache, &cred);
if (kret)
goto end;
handle->lifetime = cred.times.endtime;
handle->cred_flags |= GSS_CF_DESTROY_CRED_ON_RELEASE;
} else {
- ret = _gssapi_krb5_ccache_lifetime(minor_status,
+ ret = __gsskrb5_ccache_lifetime(minor_status,
ccache,
handle->principal,
&handle->lifetime);
@@ -210,17 +210,17 @@ static OM_uint32 acquire_initiator_cred
end:
if (cred.client != NULL)
- krb5_free_cred_contents(context, &cred);
+ krb5_free_cred_contents(_gsskrb5_context, &cred);
if (def_princ != NULL)
- krb5_free_principal(context, def_princ);
+ krb5_free_principal(_gsskrb5_context, def_princ);
if (keytab != NULL)
- krb5_kt_close(context, keytab);
+ krb5_kt_close(_gsskrb5_context, keytab);
if (ret != GSS_S_COMPLETE) {
if (ccache != NULL)
- krb5_cc_close(gssapi_krb5_context, ccache);
+ krb5_cc_close(_gsskrb5_context, ccache);
if (kret != 0) {
*minor_status = kret;
- gssapi_krb5_set_error_string ();
+ _gsskrb5_set_error_string ();
}
}
return (ret);
@@ -228,11 +228,11 @@ end:
static OM_uint32 acquire_acceptor_cred
(OM_uint32 * minor_status,
- krb5_context context,
+ const gss_name_t desired_name,
OM_uint32 time_req,
const gss_OID_set desired_mechs,
gss_cred_usage_t cred_usage,
- gss_cred_id_t handle,
+ gsskrb5_cred handle,
gss_OID_set * actual_mechs,
OM_uint32 * time_rec
)
@@ -242,7 +242,7 @@ static OM_uint32 acquire_acceptor_cred
kret = 0;
ret = GSS_S_FAILURE;
- kret = get_keytab(context, &handle->keytab);
+ kret = get_keytab(&handle->keytab);
if (kret)
goto end;
@@ -250,37 +250,38 @@ static OM_uint32 acquire_acceptor_cred
if (handle->principal) {
krb5_keytab_entry entry;
- kret = krb5_kt_get_entry(gssapi_krb5_context, handle->keytab,
+ kret = krb5_kt_get_entry(_gsskrb5_context, handle->keytab,
handle->principal, 0, 0, &entry);
if (kret)
goto end;
- krb5_kt_free_entry(gssapi_krb5_context, &entry);
+ krb5_kt_free_entry(_gsskrb5_context, &entry);
}
ret = GSS_S_COMPLETE;
end:
if (ret != GSS_S_COMPLETE) {
- krb5_kt_close(context, handle->keytab);
+ if (handle->keytab != NULL)
+ krb5_kt_close(_gsskrb5_context, handle->keytab);
if (kret != 0) {
*minor_status = kret;
- gssapi_krb5_set_error_string ();
+ _gsskrb5_set_error_string ();
}
}
return (ret);
}
-OM_uint32 gss_acquire_cred
- (OM_uint32 * minor_status,
- const gss_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
- )
+OM_uint32 _gsskrb5_acquire_cred
+(OM_uint32 * minor_status,
+ const gss_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
+ )
{
- gss_cred_id_t handle;
+ gsskrb5_cred handle;
OM_uint32 ret;
if (cred_usage != GSS_C_ACCEPT && cred_usage != GSS_C_INITIATE && cred_usage != GSS_C_BOTH) {
@@ -299,8 +300,8 @@ OM_uint32 gss_acquire_cred
if (desired_mechs) {
int present = 0;
- ret = gss_test_oid_set_member(minor_status, GSS_KRB5_MECHANISM,
- desired_mechs, &present);
+ ret = _gsskrb5_test_oid_set_member(minor_status, GSS_KRB5_MECHANISM,
+ desired_mechs, &present);
if (ret)
return ret;
if (!present) {
@@ -309,66 +310,63 @@ OM_uint32 gss_acquire_cred
}
}
- handle = (gss_cred_id_t)malloc(sizeof(*handle));
- if (handle == GSS_C_NO_CREDENTIAL) {
+ handle = calloc(1, sizeof(*handle));
+ if (handle == NULL) {
*minor_status = ENOMEM;
return (GSS_S_FAILURE);
}
- memset(handle, 0, sizeof (*handle));
HEIMDAL_MUTEX_init(&handle->cred_id_mutex);
if (desired_name != GSS_C_NO_NAME) {
- ret = gss_duplicate_name(minor_status, desired_name,
- &handle->principal);
- if (ret != GSS_S_COMPLETE) {
+ krb5_principal name = (krb5_principal)desired_name;
+ ret = krb5_copy_principal(_gsskrb5_context, name, &handle->principal);
+ if (ret) {
HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
+ _gsskrb5_set_error_string();
+ *minor_status = ret;
free(handle);
- return (ret);
+ return GSS_S_FAILURE;
}
}
if (cred_usage == GSS_C_INITIATE || cred_usage == GSS_C_BOTH) {
- ret = acquire_initiator_cred(minor_status, gssapi_krb5_context,
- desired_name, time_req,
- desired_mechs, cred_usage,
- handle, actual_mechs, time_rec);
+ ret = acquire_initiator_cred(minor_status, desired_name, time_req,
+ desired_mechs, cred_usage, handle, actual_mechs, time_rec);
if (ret != GSS_S_COMPLETE) {
HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
- krb5_free_principal(gssapi_krb5_context, handle->principal);
+ krb5_free_principal(_gsskrb5_context, handle->principal);
free(handle);
return (ret);
}
}
if (cred_usage == GSS_C_ACCEPT || cred_usage == GSS_C_BOTH) {
- ret = acquire_acceptor_cred(minor_status, gssapi_krb5_context,
- time_req,
- desired_mechs, cred_usage,
- handle, actual_mechs, time_rec);
+ ret = acquire_acceptor_cred(minor_status, desired_name, time_req,
+ desired_mechs, cred_usage, handle, actual_mechs, time_rec);
if (ret != GSS_S_COMPLETE) {
HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
- krb5_free_principal(gssapi_krb5_context, handle->principal);
+ krb5_free_principal(_gsskrb5_context, handle->principal);
free(handle);
return (ret);
}
}
- ret = gss_create_empty_oid_set(minor_status, &handle->mechanisms);
+ ret = _gsskrb5_create_empty_oid_set(minor_status, &handle->mechanisms);
if (ret == GSS_S_COMPLETE)
- ret = gss_add_oid_set_member(minor_status, GSS_KRB5_MECHANISM,
- &handle->mechanisms);
+ ret = _gsskrb5_add_oid_set_member(minor_status, GSS_KRB5_MECHANISM,
+ &handle->mechanisms);
if (ret == GSS_S_COMPLETE)
- ret = gss_inquire_cred(minor_status, handle, NULL, time_rec, NULL,
- actual_mechs);
+ ret = _gsskrb5_inquire_cred(minor_status, (gss_cred_id_t)handle,
+ NULL, time_rec, NULL, actual_mechs);
if (ret != GSS_S_COMPLETE) {
if (handle->mechanisms != NULL)
- gss_release_oid_set(NULL, &handle->mechanisms);
+ _gsskrb5_release_oid_set(NULL, &handle->mechanisms);
HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
- krb5_free_principal(gssapi_krb5_context, handle->principal);
+ krb5_free_principal(_gsskrb5_context, handle->principal);
free(handle);
return (ret);
}
*minor_status = 0;
if (time_rec) {
- ret = gssapi_lifetime_left(minor_status,
+ ret = _gsskrb5_lifetime_left(minor_status,
handle->lifetime,
time_rec);
@@ -376,8 +374,6 @@ OM_uint32 gss_acquire_cred
return ret;
}
handle->usage = cred_usage;
-
- *output_cred_handle = handle;
+ *output_cred_handle = (gss_cred_id_t)handle;
return (GSS_S_COMPLETE);
}
-
diff --git a/source4/heimdal/lib/gssapi/krb5/add_cred.c b/source4/heimdal/lib/gssapi/krb5/add_cred.c
new file mode 100644
index 0000000000..4892e84798
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/krb5/add_cred.c
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 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 "krb5/gsskrb5_locl.h"
+
+RCSID("$Id: add_cred.c,v 1.9 2006/10/07 22:13:58 lha Exp $");
+
+OM_uint32 _gsskrb5_add_cred (
+ OM_uint32 *minor_status,
+ const gss_cred_id_t input_cred_handle,
+ const gss_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)
+{
+ OM_uint32 ret, lifetime;
+ gsskrb5_cred cred, handle;
+ krb5_const_principal dname;
+
+ handle = NULL;
+ cred = (gsskrb5_cred)input_cred_handle;
+ dname = (krb5_const_principal)desired_name;
+
+ if (gss_oid_equal(desired_mech, GSS_KRB5_MECHANISM) == 0) {
+ *minor_status = 0;
+ return GSS_S_BAD_MECH;
+ }
+
+ if (cred == NULL && output_cred_handle == NULL) {
+ *minor_status = 0;
+ return GSS_S_NO_CRED;
+ }
+
+ if (cred == NULL) { /* XXX standard conformance failure */
+ *minor_status = 0;
+ return GSS_S_NO_CRED;
+ }
+
+ /* check if requested output usage is compatible with output usage */
+ if (output_cred_handle != NULL) {
+ HEIMDAL_MUTEX_lock(&cred->cred_id_mutex);
+ if (cred->usage != cred_usage && cred->usage != GSS_C_BOTH) {
+ HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
+ *minor_status = GSS_KRB5_S_G_BAD_USAGE;
+ return(GSS_S_FAILURE);
+ }
+ }
+
+ /* check that we have the same name */
+ if (dname != NULL &&
+ krb5_principal_compare(_gsskrb5_context, dname,
+ cred->principal) != FALSE) {
+ if (output_cred_handle)
+ HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
+ *minor_status = 0;
+ return GSS_S_BAD_NAME;
+ }
+
+ /* make a copy */
+ if (output_cred_handle) {
+ krb5_error_code kret;
+
+ handle = calloc(1, sizeof(*handle));
+ if (handle == NULL) {
+ HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
+ *minor_status = ENOMEM;
+ return (GSS_S_FAILURE);
+ }
+
+ handle->usage = cred_usage;
+ handle->lifetime = cred->lifetime;
+ handle->principal = NULL;
+ handle->keytab = NULL;
+ handle->ccache = NULL;
+ handle->mechanisms = NULL;
+ HEIMDAL_MUTEX_init(&handle->cred_id_mutex);
+
+ ret = GSS_S_FAILURE;
+
+ kret = krb5_copy_principal(_gsskrb5_context, cred->principal,
+ &handle->principal);
+ if (kret) {
+ HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
+ free(handle);
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+
+ if (cred->keytab) {
+ char name[KRB5_KT_PREFIX_MAX_LEN + MAXPATHLEN];
+ int len;
+
+ ret = GSS_S_FAILURE;
+
+ kret = krb5_kt_get_type(_gsskrb5_context, cred->keytab,
+ name, KRB5_KT_PREFIX_MAX_LEN);
+ if (kret) {
+ *minor_status = kret;
+ goto failure;
+ }
+ len = strlen(name);
+ name[len++] = ':';
+
+ kret = krb5_kt_get_name(_gsskrb5_context, cred->keytab,
+ name + len,
+ sizeof(name) - len);
+ if (kret) {
+ *minor_status = kret;
+ goto failure;
+ }
+
+ kret = krb5_kt_resolve(_gsskrb5_context, name,
+ &handle->keytab);
+ if (kret){
+ *minor_status = kret;
+ goto failure;
+ }
+ }
+
+ if (cred->ccache) {
+ const char *type, *name;
+ char *type_name;
+
+ ret = GSS_S_FAILURE;
+
+ type = krb5_cc_get_type(_gsskrb5_context, cred->ccache);
+ if (type == NULL){
+ *minor_status = ENOMEM;
+ goto failure;
+ }
+
+ if (strcmp(type, "MEMORY") == 0) {
+ ret = krb5_cc_gen_new(_gsskrb5_context, &krb5_mcc_ops,
+ &handle->ccache);
+ if (ret) {
+ *minor_status = ret;
+ goto failure;
+ }
+
+ ret = krb5_cc_copy_cache(_gsskrb5_context, cred->ccache,
+ handle->ccache);
+ if (ret) {
+ *minor_status = ret;
+ goto failure;
+ }
+
+ } else {
+ name = krb5_cc_get_name(_gsskrb5_context, cred->ccache);
+ if (name == NULL) {
+ *minor_status = ENOMEM;
+ goto failure;
+ }
+
+ asprintf(&type_name, "%s:%s", type, name);
+ if (type_name == NULL) {
+ *minor_status = ENOMEM;
+ goto failure;
+ }
+
+ kret = krb5_cc_resolve(_gsskrb5_context, type_name,
+ &handle->ccache);
+ free(type_name);
+ if (kret) {
+ *minor_status = kret;
+ goto failure;
+ }
+ }
+ }
+ ret = _gsskrb5_create_empty_oid_set(minor_status, &handle->mechanisms);
+ if (ret)
+ goto failure;
+
+ ret = _gsskrb5_add_oid_set_member(minor_status, GSS_KRB5_MECHANISM,
+ &handle->mechanisms);
+ if (ret)
+ goto failure;
+ }
+
+ HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
+
+ ret = _gsskrb5_inquire_cred(minor_status, (gss_cred_id_t)cred,
+ NULL, &lifetime, NULL, actual_mechs);
+ if (ret)
+ goto failure;
+
+ if (initiator_time_rec)
+ *initiator_time_rec = lifetime;
+ if (acceptor_time_rec)
+ *acceptor_time_rec = lifetime;
+
+ if (output_cred_handle) {
+ *output_cred_handle = (gss_cred_id_t)handle;
+ }
+
+ *minor_status = 0;
+ return ret;
+
+ failure:
+
+ if (handle) {
+ if (handle->principal)
+ krb5_free_principal(_gsskrb5_context, handle->principal);
+ if (handle->keytab)
+ krb5_kt_close(_gsskrb5_context, handle->keytab);
+ if (handle->ccache)
+ krb5_cc_destroy(_gsskrb5_context, handle->ccache);
+ if (handle->mechanisms)
+ _gsskrb5_release_oid_set(NULL, &handle->mechanisms);
+ free(handle);
+ }
+ if (output_cred_handle)
+ HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
+ return ret;
+}
diff --git a/source4/heimdal/lib/gssapi/add_oid_set_member.c b/source4/heimdal/lib/gssapi/krb5/add_oid_set_member.c
index ed654fc8c5..b0ec2c60d8 100644
--- a/source4/heimdal/lib/gssapi/add_oid_set_member.c
+++ b/source4/heimdal/lib/gssapi/krb5/add_oid_set_member.c
@@ -31,11 +31,11 @@
* SUCH DAMAGE.
*/
-#include "gssapi_locl.h"
+#include "krb5/gsskrb5_locl.h"
-RCSID("$Id: add_oid_set_member.c,v 1.8 2003/03/16 17:50:49 lha Exp $");
+RCSID("$Id: add_oid_set_member.c,v 1.10 2006/10/07 22:14:00 lha Exp $");
-OM_uint32 gss_add_oid_set_member (
+OM_uint32 _gsskrb5_add_oid_set_member (
OM_uint32 * minor_status,
const gss_OID member_oid,
gss_OID_set * oid_set
@@ -46,7 +46,8 @@ OM_uint32 gss_add_oid_set_member (
OM_uint32 res;
int present;
- res = gss_test_oid_set_member(minor_status, member_oid, *oid_set, &present);
+ res = _gsskrb5_test_oid_set_member(minor_status, member_oid,
+ *oid_set, &present);
if (res != GSS_S_COMPLETE)
return res;
diff --git a/source4/heimdal/lib/gssapi/address_to_krb5addr.c b/source4/heimdal/lib/gssapi/krb5/address_to_krb5addr.c
index 13a6825f55..9aec53faaa 100644
--- a/source4/heimdal/lib/gssapi/address_to_krb5addr.c
+++ b/source4/heimdal/lib/gssapi/krb5/address_to_krb5addr.c
@@ -31,15 +31,15 @@
* SUCH DAMAGE.
*/
-#include "gssapi_locl.h"
+#include "krb5/gsskrb5_locl.h"
#include <roken.h>
krb5_error_code
-gss_address_to_krb5addr(OM_uint32 gss_addr_type,
- gss_buffer_desc *gss_addr,
- int16_t port,
- krb5_address *address)
+_gsskrb5i_address_to_krb5addr(OM_uint32 gss_addr_type,
+ gss_buffer_desc *gss_addr,
+ int16_t port,
+ krb5_address *address)
{
int addr_type;
struct sockaddr sa;
@@ -61,7 +61,7 @@ gss_address_to_krb5addr(OM_uint32 gss_addr_type,
return GSS_S_FAILURE;
}
- problem = krb5_h_addr2sockaddr (gssapi_krb5_context,
+ problem = krb5_h_addr2sockaddr (_gsskrb5_context,
addr_type,
gss_addr->value,
&sa,
@@ -70,7 +70,7 @@ gss_address_to_krb5addr(OM_uint32 gss_addr_type,
if (problem)
return GSS_S_FAILURE;
- problem = krb5_sockaddr2address (gssapi_krb5_context, &sa, address);
+ problem = krb5_sockaddr2address (_gsskrb5_context, &sa, address);
return problem;
}
diff --git a/source4/heimdal/lib/gssapi/arcfour.c b/source4/heimdal/lib/gssapi/krb5/arcfour.c
index 936a20d403..82851f5a78 100644
--- a/source4/heimdal/lib/gssapi/arcfour.c
+++ b/source4/heimdal/lib/gssapi/krb5/arcfour.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003 - 2005 Kungliga Tekniska Högskolan
+ * Copyright (c) 2003 - 2006 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -31,9 +31,9 @@
* SUCH DAMAGE.
*/
-#include "gssapi_locl.h"
+#include "krb5/gsskrb5_locl.h"
-RCSID("$Id: arcfour.c,v 1.19 2006/05/04 11:56:50 lha Exp $");
+RCSID("$Id: arcfour.c,v 1.29 2006/10/07 22:14:05 lha Exp $");
/*
* Implements draft-brezak-win2k-krb-rc4-hmac-04.txt
@@ -57,6 +57,17 @@ RCSID("$Id: arcfour.c,v 1.19 2006/05/04 11:56:50 lha Exp $");
* Confounder[8]
*/
+/*
+ * WRAP in DCE-style have a fixed size header, the oid and length over
+ * the WRAP header is a total of
+ * GSS_ARCFOUR_WRAP_TOKEN_DCE_DER_HEADER_SIZE +
+ * GSS_ARCFOUR_WRAP_TOKEN_SIZE byte (ie total of 45 bytes overhead,
+ * remember the 2 bytes from APPL [0] SEQ).
+ */
+
+#define GSS_ARCFOUR_WRAP_TOKEN_SIZE 32
+#define GSS_ARCFOUR_WRAP_TOKEN_DCE_DER_HEADER_SIZE 13
+
static krb5_error_code
arcfour_mic_key(krb5_context context, krb5_keyblock *key,
@@ -127,13 +138,13 @@ arcfour_mic_cksum(krb5_keyblock *key, unsigned usage,
memcpy(ptr + l1, v2, l2);
memcpy(ptr + l1 + l2, v3, l3);
- ret = krb5_crypto_init(gssapi_krb5_context, key, 0, &crypto);
+ ret = krb5_crypto_init(_gsskrb5_context, key, 0, &crypto);
if (ret) {
free(ptr);
return ret;
}
- ret = krb5_create_checksum(gssapi_krb5_context,
+ ret = krb5_create_checksum(_gsskrb5_context,
crypto,
usage,
0,
@@ -144,7 +155,7 @@ arcfour_mic_cksum(krb5_keyblock *key, unsigned usage,
memcpy(sgn_cksum, CKSUM.checksum.data, sgn_cksum_sz);
free_Checksum(&CKSUM);
}
- krb5_crypto_destroy(gssapi_krb5_context, crypto);
+ krb5_crypto_destroy(_gsskrb5_context, crypto);
return ret;
}
@@ -152,7 +163,7 @@ arcfour_mic_cksum(krb5_keyblock *key, unsigned usage,
OM_uint32
_gssapi_get_mic_arcfour(OM_uint32 * minor_status,
- const gss_ctx_id_t context_handle,
+ const gsskrb5_ctx context_handle,
gss_qop_t qop_req,
const gss_buffer_t message_buffer,
gss_buffer_t message_token,
@@ -164,7 +175,7 @@ _gssapi_get_mic_arcfour(OM_uint32 * minor_status,
u_char k6_data[16], *p0, *p;
RC4_KEY rc4_key;
- gssapi_krb5_encap_length (22, &len, &total_len, GSS_KRB5_MECHANISM);
+ _gsskrb5_encap_length (22, &len, &total_len, GSS_KRB5_MECHANISM);
message_token->length = total_len;
message_token->value = malloc (total_len);
@@ -195,28 +206,28 @@ _gssapi_get_mic_arcfour(OM_uint32 * minor_status,
message_buffer->value, message_buffer->length,
NULL, 0);
if (ret) {
- gss_release_buffer(minor_status, message_token);
+ _gsskrb5_release_buffer(minor_status, message_token);
*minor_status = ret;
return GSS_S_FAILURE;
}
- ret = arcfour_mic_key(gssapi_krb5_context, key,
+ ret = arcfour_mic_key(_gsskrb5_context, key,
p0 + 16, 8, /* SGN_CKSUM */
k6_data, sizeof(k6_data));
if (ret) {
- gss_release_buffer(minor_status, message_token);
+ _gsskrb5_release_buffer(minor_status, message_token);
*minor_status = ret;
return GSS_S_FAILURE;
}
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
- krb5_auth_con_getlocalseqnumber (gssapi_krb5_context,
+ krb5_auth_con_getlocalseqnumber (_gsskrb5_context,
context_handle->auth_context,
&seq_number);
p = p0 + 8; /* SND_SEQ */
- gssapi_encode_be_om_uint32(seq_number, p);
+ _gsskrb5_encode_be_om_uint32(seq_number, p);
- krb5_auth_con_setlocalseqnumber (gssapi_krb5_context,
+ krb5_auth_con_setlocalseqnumber (_gsskrb5_context,
context_handle->auth_context,
++seq_number);
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
@@ -236,7 +247,7 @@ _gssapi_get_mic_arcfour(OM_uint32 * minor_status,
OM_uint32
_gssapi_verify_mic_arcfour(OM_uint32 * minor_status,
- const gss_ctx_id_t context_handle,
+ const gsskrb5_ctx context_handle,
const gss_buffer_t message_buffer,
const gss_buffer_t token_buffer,
gss_qop_t * qop_state,
@@ -244,7 +255,7 @@ _gssapi_verify_mic_arcfour(OM_uint32 * minor_status,
char *type)
{
krb5_error_code ret;
- int32_t seq_number;
+ uint32_t seq_number;
OM_uint32 omret;
u_char SND_SEQ[8], cksum_data[8], *p;
char k6_data[16];
@@ -254,7 +265,7 @@ _gssapi_verify_mic_arcfour(OM_uint32 * minor_status,
*qop_state = 0;
p = token_buffer->value;
- omret = gssapi_krb5_verify_header (&p,
+ omret = _gsskrb5_verify_header (&p,
token_buffer->length,
(u_char *)type,
GSS_KRB5_MECHANISM);
@@ -278,7 +289,7 @@ _gssapi_verify_mic_arcfour(OM_uint32 * minor_status,
return GSS_S_FAILURE;
}
- ret = arcfour_mic_key(gssapi_krb5_context, key,
+ ret = arcfour_mic_key(_gsskrb5_context, key,
cksum_data, sizeof(cksum_data),
k6_data, sizeof(k6_data));
if (ret) {
@@ -302,7 +313,7 @@ _gssapi_verify_mic_arcfour(OM_uint32 * minor_status,
memset(k6_data, 0, sizeof(k6_data));
}
- gssapi_decode_be_om_uint32(SND_SEQ, &seq_number);
+ _gsskrb5_decode_be_om_uint32(SND_SEQ, &seq_number);
if (context_handle->more_flags & LOCAL)
cmp = memcmp(&SND_SEQ[4], "\xff\xff\xff\xff", 4);
@@ -326,39 +337,8 @@ _gssapi_verify_mic_arcfour(OM_uint32 * minor_status,
}
OM_uint32
-_gssapi_wrap_size_arcfour(OM_uint32 * minor_status,
- const gss_ctx_id_t context_handle,
- int conf_req_flag,
- gss_qop_t qop_req,
- OM_uint32 req_input_size,
- OM_uint32 * output_size,
- OM_uint32 * padlen,
- krb5_keyblock *key)
-{
- size_t len, total_len, datalen;
- *padlen = 0;
- datalen = req_input_size;
- len = GSS_ARCFOUR_WRAP_TOKEN_SIZE;
- /* if GSS_C_DCE_STYLE is in use:
- * - we only need to encapsulate the WRAP token
- * - we should not add padding
- */
- if (!(context_handle->flags & GSS_C_DCE_STYLE)) {
- datalen += 1 /* padding */;
- len += datalen;
- }
- _gssapi_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM);
- if (context_handle->flags & GSS_C_DCE_STYLE) {
- total_len += datalen;
- }
-
- *output_size = total_len;
- return GSS_S_COMPLETE;
-}
-
-OM_uint32
_gssapi_wrap_arcfour(OM_uint32 * minor_status,
- const gss_ctx_id_t context_handle,
+ const gsskrb5_ctx context_handle,
int conf_req_flag,
gss_qop_t qop_req,
const gss_buffer_t input_message_buffer,
@@ -375,19 +355,17 @@ _gssapi_wrap_arcfour(OM_uint32 * minor_status,
if (conf_state)
*conf_state = 0;
- datalen = input_message_buffer->length;
- len = GSS_ARCFOUR_WRAP_TOKEN_SIZE;
- /* if GSS_C_DCE_STYLE is in use:
- * - we only need to encapsulate the WRAP token
- * - we should not add padding
- */
- if (!(context_handle->flags & GSS_C_DCE_STYLE)) {
- datalen += 1 /* padding */;
- len += datalen;
- }
- _gssapi_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM);
- if (context_handle->flags & GSS_C_DCE_STYLE) {
- total_len += datalen;
+ if ((context_handle->flags & GSS_C_DCE_STYLE) == 0) {
+ datalen = input_message_buffer->length + 1 /* padding */;
+
+ len = datalen + GSS_ARCFOUR_WRAP_TOKEN_SIZE;
+ _gssapi_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM);
+ } else {
+ datalen = input_message_buffer->length;
+
+ len = GSS_ARCFOUR_WRAP_TOKEN_SIZE;
+ _gssapi_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM);
+ total_len += datalen;
}
output_message_buffer->length = total_len;
@@ -419,13 +397,13 @@ _gssapi_wrap_arcfour(OM_uint32 * minor_status,
p = NULL;
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
- krb5_auth_con_getlocalseqnumber (gssapi_krb5_context,
+ krb5_auth_con_getlocalseqnumber (_gsskrb5_context,
context_handle->auth_context,
&seq_number);
- gssapi_encode_be_om_uint32(seq_number, p0 + 8);
+ _gsskrb5_encode_be_om_uint32(seq_number, p0 + 8);
- krb5_auth_con_setlocalseqnumber (gssapi_krb5_context,
+ krb5_auth_con_setlocalseqnumber (_gsskrb5_context,
context_handle->auth_context,
++seq_number);
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
@@ -439,9 +417,9 @@ _gssapi_wrap_arcfour(OM_uint32 * minor_status,
/* p points to data */
p = p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE;
memcpy(p, input_message_buffer->value, input_message_buffer->length);
- /* only add padding when GSS_C_DCE_STYLE is not in use */
- if (!(context_handle->flags & GSS_C_DCE_STYLE)) {
- p[input_message_buffer->length] = 1; /* PADDING */
+
+ if ((context_handle->flags & GSS_C_DCE_STYLE) == 0) {
+ p[input_message_buffer->length] = 1; /* PADDING */
}
ret = arcfour_mic_cksum(key, KRB5_KU_USAGE_SEAL,
@@ -452,7 +430,7 @@ _gssapi_wrap_arcfour(OM_uint32 * minor_status,
datalen);
if (ret) {
*minor_status = ret;
- gss_release_buffer(minor_status, output_message_buffer);
+ _gsskrb5_release_buffer(minor_status, output_message_buffer);
return GSS_S_FAILURE;
}
@@ -466,12 +444,12 @@ _gssapi_wrap_arcfour(OM_uint32 * minor_status,
for (i = 0; i < 16; i++)
Klocaldata[i] = ((u_char *)key->keyvalue.data)[i] ^ 0xF0;
}
- ret = arcfour_mic_key(gssapi_krb5_context, &Klocal,
+ ret = arcfour_mic_key(_gsskrb5_context, &Klocal,
p0 + 8, 4, /* SND_SEQ */
k6_data, sizeof(k6_data));
memset(Klocaldata, 0, sizeof(Klocaldata));
if (ret) {
- gss_release_buffer(minor_status, output_message_buffer);
+ _gsskrb5_release_buffer(minor_status, output_message_buffer);
*minor_status = ret;
return GSS_S_FAILURE;
}
@@ -487,11 +465,11 @@ _gssapi_wrap_arcfour(OM_uint32 * minor_status,
}
memset(k6_data, 0, sizeof(k6_data));
- ret = arcfour_mic_key(gssapi_krb5_context, key,
+ ret = arcfour_mic_key(_gsskrb5_context, key,
p0 + 16, 8, /* SGN_CKSUM */
k6_data, sizeof(k6_data));
if (ret) {
- gss_release_buffer(minor_status, output_message_buffer);
+ _gsskrb5_release_buffer(minor_status, output_message_buffer);
*minor_status = ret;
return GSS_S_FAILURE;
}
@@ -513,7 +491,7 @@ _gssapi_wrap_arcfour(OM_uint32 * minor_status,
}
OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status,
- const gss_ctx_id_t context_handle,
+ const gsskrb5_ctx context_handle,
const gss_buffer_t input_message_buffer,
gss_buffer_t output_message_buffer,
int *conf_state,
@@ -523,15 +501,15 @@ OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status,
u_char Klocaldata[16];
krb5_keyblock Klocal;
krb5_error_code ret;
- int32_t seq_number;
- size_t len, datalen;
+ uint32_t seq_number;
+ size_t datalen;
OM_uint32 omret;
u_char k6_data[16], SND_SEQ[8], Confounder[8];
u_char cksum_data[8];
u_char *p, *p0;
int cmp;
int conf_flag;
- size_t padlen = 0;
+ size_t padlen = 0, len;
if (conf_state)
*conf_state = 0;
@@ -539,25 +517,34 @@ OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status,
*qop_state = 0;
p0 = input_message_buffer->value;
- len = input_message_buffer->length;
- /* if we have GSS_C_DCE_STYLE in use, we only need to decapsulate the WRAP token */
- if (context_handle->flags & GSS_C_DCE_STYLE) {
- if (input_message_buffer->length < (GSS_ARCFOUR_WRAP_TOKEN_OFFSET+GSS_ARCFOUR_WRAP_TOKEN_SIZE)) {
- return GSS_S_BAD_MECH;
- }
- len = GSS_ARCFOUR_WRAP_TOKEN_OFFSET+GSS_ARCFOUR_WRAP_TOKEN_SIZE;
+
+ if ((context_handle->flags & GSS_C_DCE_STYLE) == 0) {
+ len = input_message_buffer->length;
+ } else {
+ len = GSS_ARCFOUR_WRAP_TOKEN_SIZE +
+ GSS_ARCFOUR_WRAP_TOKEN_DCE_DER_HEADER_SIZE;
+ if (input_message_buffer->length < len)
+ return GSS_S_BAD_MECH;
}
+
omret = _gssapi_verify_mech_header(&p0,
len,
GSS_KRB5_MECHANISM);
if (omret)
return omret;
- p = p0;
- datalen = input_message_buffer->length -
- (p - ((u_char *)input_message_buffer->value)) -
+ /* length of mech header */
+ len = (p0 - (u_char *)input_message_buffer->value) +
GSS_ARCFOUR_WRAP_TOKEN_SIZE;
+ if (len > input_message_buffer->length)
+ return GSS_S_BAD_MECH;
+
+ /* length of data */
+ datalen = input_message_buffer->length - len;
+
+ p = p0;
+
if (memcmp(p, "\x02\x01", 2) != 0)
return GSS_S_BAD_SIG;
p += 2;
@@ -577,7 +564,7 @@ OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status,
return GSS_S_BAD_MIC;
p = NULL;
- ret = arcfour_mic_key(gssapi_krb5_context, key,
+ ret = arcfour_mic_key(_gsskrb5_context, key,
p0 + 16, 8, /* SGN_CKSUM */
k6_data, sizeof(k6_data));
if (ret) {
@@ -594,7 +581,7 @@ OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status,
memset(k6_data, 0, sizeof(k6_data));
}
- gssapi_decode_be_om_uint32(SND_SEQ, &seq_number);
+ _gsskrb5_decode_be_om_uint32(SND_SEQ, &seq_number);
if (context_handle->more_flags & LOCAL)
cmp = memcmp(&SND_SEQ[4], "\xff\xff\xff\xff", 4);
@@ -616,7 +603,7 @@ OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status,
for (i = 0; i < 16; i++)
Klocaldata[i] = ((u_char *)key->keyvalue.data)[i] ^ 0xF0;
}
- ret = arcfour_mic_key(gssapi_krb5_context, &Klocal,
+ ret = arcfour_mic_key(_gsskrb5_context, &Klocal,
SND_SEQ, 4,
k6_data, sizeof(k6_data));
memset(Klocaldata, 0, sizeof(Klocaldata));
@@ -648,14 +635,14 @@ OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status,
}
memset(k6_data, 0, sizeof(k6_data));
- if (!(context_handle->flags & GSS_C_DCE_STYLE)) {
- ret = _gssapi_verify_pad(output_message_buffer, datalen, &padlen);
- if (ret) {
- gss_release_buffer(minor_status, output_message_buffer);
+ if ((context_handle->flags & GSS_C_DCE_STYLE) == 0) {
+ ret = _gssapi_verify_pad(output_message_buffer, datalen, &padlen);
+ if (ret) {
+ _gsskrb5_release_buffer(minor_status, output_message_buffer);
*minor_status = 0;
return ret;
- }
- output_message_buffer->length -= padlen;
+ }
+ output_message_buffer->length -= padlen;
}
ret = arcfour_mic_cksum(key, KRB5_KU_USAGE_SEAL,
@@ -665,14 +652,14 @@ OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status,
output_message_buffer->value,
output_message_buffer->length + padlen);
if (ret) {
- gss_release_buffer(minor_status, output_message_buffer);
+ _gsskrb5_release_buffer(minor_status, output_message_buffer);
*minor_status = ret;
return GSS_S_FAILURE;
}
cmp = memcmp(cksum_data, p0 + 16, 8); /* SGN_CKSUM */
if (cmp) {
- gss_release_buffer(minor_status, output_message_buffer);
+ _gsskrb5_release_buffer(minor_status, output_message_buffer);
*minor_status = 0;
return GSS_S_BAD_MIC;
}
@@ -689,3 +676,79 @@ OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status,
*minor_status = 0;
return GSS_S_COMPLETE;
}
+
+static OM_uint32
+max_wrap_length_arcfour(const gsskrb5_ctx ctx,
+ krb5_crypto crypto,
+ size_t input_length,
+ OM_uint32 *max_input_size)
+{
+ /*
+ * if GSS_C_DCE_STYLE is in use:
+ * - we only need to encapsulate the WRAP token
+ * However, since this is a fixed since, we just
+ */
+ if (ctx->flags & GSS_C_DCE_STYLE) {
+ size_t len, total_len;
+
+ len = GSS_ARCFOUR_WRAP_TOKEN_SIZE;
+ _gssapi_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM);
+
+ if (input_length < len)
+ *max_input_size = 0;
+ else
+ *max_input_size = input_length - len;
+
+ } else {
+ size_t extrasize = GSS_ARCFOUR_WRAP_TOKEN_SIZE;
+ size_t blocksize = 8;
+ size_t len, total_len;
+
+ len = 8 + input_length + blocksize + extrasize;
+
+ _gsskrb5_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM);
+
+ total_len -= input_length; /* token length */
+ if (total_len < input_length) {
+ *max_input_size = (input_length - total_len);
+ (*max_input_size) &= (~(OM_uint32)(blocksize - 1));
+ } else {
+ *max_input_size = 0;
+ }
+ }
+
+ return GSS_S_COMPLETE;
+}
+
+OM_uint32
+_gssapi_wrap_size_arcfour(OM_uint32 *minor_status,
+ const gsskrb5_ctx ctx,
+ int conf_req_flag,
+ gss_qop_t qop_req,
+ OM_uint32 req_output_size,
+ OM_uint32 *max_input_size,
+ krb5_keyblock *key)
+{
+ krb5_error_code ret;
+ krb5_crypto crypto;
+
+ ret = krb5_crypto_init(_gsskrb5_context, key, 0, &crypto);
+ if (ret != 0) {
+ _gsskrb5_set_error_string();
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ ret = max_wrap_length_arcfour(ctx, crypto,
+ req_output_size, max_input_size);
+ if (ret != 0) {
+ _gsskrb5_set_error_string();
+ *minor_status = ret;
+ krb5_crypto_destroy(_gsskrb5_context, crypto);
+ return GSS_S_FAILURE;
+ }
+
+ krb5_crypto_destroy(_gsskrb5_context, crypto);
+
+ return GSS_S_COMPLETE;
+}
diff --git a/source4/heimdal/lib/gssapi/krb5/canonicalize_name.c b/source4/heimdal/lib/gssapi/krb5/canonicalize_name.c
new file mode 100644
index 0000000000..f69300b590
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/krb5/canonicalize_name.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 1997 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 "krb5/gsskrb5_locl.h"
+
+RCSID("$Id: canonicalize_name.c,v 1.4 2006/10/07 22:14:08 lha Exp $");
+
+OM_uint32 _gsskrb5_canonicalize_name (
+ OM_uint32 * minor_status,
+ const gss_name_t input_name,
+ const gss_OID mech_type,
+ gss_name_t * output_name
+ )
+{
+ return _gsskrb5_duplicate_name (minor_status, input_name, output_name);
+}
diff --git a/source4/heimdal/lib/gssapi/cfx.c b/source4/heimdal/lib/gssapi/krb5/cfx.c
index ef7907c0de..cb3f9ee5d3 100755
--- a/source4/heimdal/lib/gssapi/cfx.c
+++ b/source4/heimdal/lib/gssapi/krb5/cfx.c
@@ -30,9 +30,9 @@
* SUCH DAMAGE.
*/
-#include "gssapi_locl.h"
+#include "krb5/gsskrb5_locl.h"
-RCSID("$Id: cfx.c,v 1.19 2006/05/05 10:26:43 lha Exp $");
+RCSID("$Id: cfx.c,v 1.24 2006/10/24 21:13:22 lha Exp $");
/*
* Implementation of draft-ietf-krb-wg-gssapi-cfx-06.txt
@@ -42,14 +42,13 @@ RCSID("$Id: cfx.c,v 1.19 2006/05/05 10:26:43 lha Exp $");
#define CFXSealed (1 << 1)
#define CFXAcceptorSubkey (1 << 2)
-static krb5_error_code
-wrap_length_cfx(krb5_crypto crypto,
- int conf_req_flag,
- size_t input_length,
- size_t *output_length,
- size_t *cksumsize,
- uint16_t *padlength,
- size_t *padsize)
+krb5_error_code
+_gsskrb5cfx_wrap_length_cfx(krb5_crypto crypto,
+ int conf_req_flag,
+ size_t input_length,
+ size_t *output_length,
+ size_t *cksumsize,
+ uint16_t *padlength)
{
krb5_error_code ret;
krb5_cksumtype type;
@@ -58,39 +57,37 @@ wrap_length_cfx(krb5_crypto crypto,
*output_length = sizeof(gss_cfx_wrap_token_desc);
*padlength = 0;
- ret = krb5_crypto_get_checksum_type(gssapi_krb5_context, crypto, &type);
- if (ret) {
+ ret = krb5_crypto_get_checksum_type(_gsskrb5_context, crypto, &type);
+ if (ret)
return ret;
- }
- ret = krb5_checksumsize(gssapi_krb5_context, type, cksumsize);
- if (ret) {
+ ret = krb5_checksumsize(_gsskrb5_context, type, cksumsize);
+ if (ret)
return ret;
- }
if (conf_req_flag) {
+ size_t padsize;
/* Header is concatenated with data before encryption */
input_length += sizeof(gss_cfx_wrap_token_desc);
- ret = krb5_crypto_getpadsize(gssapi_krb5_context, crypto, padsize);
+ ret = krb5_crypto_getpadsize(_gsskrb5_context, crypto, &padsize);
if (ret) {
return ret;
}
- if (*padsize > 1) {
+ if (padsize > 1) {
/* XXX check this */
- *padlength = *padsize - (input_length % *padsize);
- }
+ *padlength = padsize - (input_length % padsize);
- /* We add the pad ourselves (noted here for completeness only) */
- input_length += *padlength;
+ /* We add the pad ourselves (noted here for completeness only) */
+ input_length += *padlength;
+ }
- *output_length += krb5_get_wrapped_length(gssapi_krb5_context,
+ *output_length += krb5_get_wrapped_length(_gsskrb5_context,
crypto, input_length);
} else {
/* Checksum is concatenated with data */
*output_length += input_length + *cksumsize;
- *padsize = 0;
}
assert(*output_length > input_length);
@@ -98,42 +95,94 @@ wrap_length_cfx(krb5_crypto crypto,
return 0;
}
+krb5_error_code
+_gsskrb5cfx_max_wrap_length_cfx(krb5_crypto crypto,
+ int conf_req_flag,
+ size_t input_length,
+ OM_uint32 *output_length)
+{
+ krb5_error_code ret;
+
+ *output_length = 0;
+
+ /* 16-byte header is always first */
+ if (input_length < 16)
+ return 0;
+ input_length -= 16;
+
+ if (conf_req_flag) {
+ size_t wrapped_size, sz;
+
+ wrapped_size = input_length + 1;
+ do {
+ wrapped_size--;
+ sz = krb5_get_wrapped_length(_gsskrb5_context,
+ crypto, wrapped_size);
+ } while (wrapped_size && sz > input_length);
+ if (wrapped_size == 0) {
+ *output_length = 0;
+ return 0;
+ }
+
+ /* inner header */
+ if (wrapped_size < 16) {
+ *output_length = 0;
+ return 0;
+ }
+ wrapped_size -= 16;
+
+ *output_length = wrapped_size;
+ } else {
+ krb5_cksumtype type;
+ size_t cksumsize;
+
+ ret = krb5_crypto_get_checksum_type(_gsskrb5_context, crypto, &type);
+ if (ret)
+ return ret;
+
+ ret = krb5_checksumsize(_gsskrb5_context, type, &cksumsize);
+ if (ret)
+ return ret;
+
+ if (input_length < cksumsize)
+ return 0;
+
+ /* Checksum is concatenated with data */
+ *output_length = input_length - cksumsize;
+ }
+
+ return 0;
+}
+
+
OM_uint32 _gssapi_wrap_size_cfx(OM_uint32 *minor_status,
- const gss_ctx_id_t context_handle,
+ const gsskrb5_ctx context_handle,
int conf_req_flag,
gss_qop_t qop_req,
- OM_uint32 req_input_size,
- OM_uint32 *output_len,
- OM_uint32 *padsize,
+ OM_uint32 req_output_size,
+ OM_uint32 *max_input_size,
krb5_keyblock *key)
{
krb5_error_code ret;
krb5_crypto crypto;
- uint16_t pad_length;
- size_t pad_size;
- size_t output_length, cksumsize;
- ret = krb5_crypto_init(gssapi_krb5_context, key, 0, &crypto);
+ ret = krb5_crypto_init(_gsskrb5_context, key, 0, &crypto);
if (ret != 0) {
- gssapi_krb5_set_error_string();
+ _gsskrb5_set_error_string();
*minor_status = ret;
return GSS_S_FAILURE;
}
- ret = wrap_length_cfx(crypto, conf_req_flag,
- req_input_size,
- &output_length, &cksumsize, &pad_length, &pad_size);
+ ret = _gsskrb5cfx_max_wrap_length_cfx(crypto, conf_req_flag,
+ req_output_size, max_input_size);
if (ret != 0) {
- gssapi_krb5_set_error_string();
+ _gsskrb5_set_error_string();
*minor_status = ret;
- krb5_crypto_destroy(gssapi_krb5_context, crypto);
+ krb5_crypto_destroy(_gsskrb5_context, crypto);
return GSS_S_FAILURE;
}
- *output_len = output_length;
- *padsize = pad_size;
-
- krb5_crypto_destroy(gssapi_krb5_context, crypto);
+ krb5_crypto_destroy(_gsskrb5_context, crypto);
return GSS_S_COMPLETE;
}
@@ -183,7 +232,7 @@ rrc_rotate(void *data, size_t len, uint16_t rrc, krb5_boolean unrotate)
}
OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
- const gss_ctx_id_t context_handle,
+ const gsskrb5_ctx context_handle,
int conf_req_flag,
gss_qop_t qop_req,
const gss_buffer_t input_message_buffer,
@@ -199,23 +248,22 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
size_t wrapped_len, cksumsize;
uint16_t padlength, rrc = 0;
int32_t seq_number;
- size_t padsize;
u_char *p;
- ret = krb5_crypto_init(gssapi_krb5_context, key, 0, &crypto);
+ ret = krb5_crypto_init(_gsskrb5_context, key, 0, &crypto);
if (ret != 0) {
- gssapi_krb5_set_error_string();
+ _gsskrb5_set_error_string();
*minor_status = ret;
return GSS_S_FAILURE;
}
- ret = wrap_length_cfx(crypto, conf_req_flag,
- input_message_buffer->length,
- &wrapped_len, &cksumsize, &padlength, &padsize);
+ ret = _gsskrb5cfx_wrap_length_cfx(crypto, conf_req_flag,
+ input_message_buffer->length,
+ &wrapped_len, &cksumsize, &padlength);
if (ret != 0) {
- gssapi_krb5_set_error_string();
+ _gsskrb5_set_error_string();
*minor_status = ret;
- krb5_crypto_destroy(gssapi_krb5_context, crypto);
+ krb5_crypto_destroy(_gsskrb5_context, crypto);
return GSS_S_FAILURE;
}
@@ -226,7 +274,7 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
output_message_buffer->value = malloc(output_message_buffer->length);
if (output_message_buffer->value == NULL) {
*minor_status = ENOMEM;
- krb5_crypto_destroy(gssapi_krb5_context, crypto);
+ krb5_crypto_destroy(_gsskrb5_context, crypto);
return GSS_S_FAILURE;
}
@@ -276,12 +324,12 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
token->RRC[1] = 0;
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
- krb5_auth_con_getlocalseqnumber(gssapi_krb5_context,
+ krb5_auth_con_getlocalseqnumber(_gsskrb5_context,
context_handle->auth_context,
&seq_number);
- gssapi_encode_be_om_uint32(0, &token->SND_SEQ[0]);
- gssapi_encode_be_om_uint32(seq_number, &token->SND_SEQ[4]);
- krb5_auth_con_setlocalseqnumber(gssapi_krb5_context,
+ _gsskrb5_encode_be_om_uint32(0, &token->SND_SEQ[0]);
+ _gsskrb5_encode_be_om_uint32(seq_number, &token->SND_SEQ[4]);
+ krb5_auth_con_setlocalseqnumber(_gsskrb5_context,
context_handle->auth_context,
++seq_number);
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
@@ -316,16 +364,16 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
memcpy(p + input_message_buffer->length + padlength,
token, sizeof(*token));
- ret = krb5_encrypt(gssapi_krb5_context, crypto,
+ ret = krb5_encrypt(_gsskrb5_context, crypto,
usage, p,
input_message_buffer->length + padlength +
sizeof(*token),
&cipher);
if (ret != 0) {
- gssapi_krb5_set_error_string();
+ _gsskrb5_set_error_string();
*minor_status = ret;
- krb5_crypto_destroy(gssapi_krb5_context, crypto);
- gss_release_buffer(minor_status, output_message_buffer);
+ krb5_crypto_destroy(_gsskrb5_context, crypto);
+ _gsskrb5_release_buffer(minor_status, output_message_buffer);
return GSS_S_FAILURE;
}
assert(sizeof(*token) + cipher.length == wrapped_len);
@@ -334,10 +382,10 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
ret = rrc_rotate(cipher.data, cipher.length, rrc, FALSE);
if (ret != 0) {
- gssapi_krb5_set_error_string();
+ _gsskrb5_set_error_string();
*minor_status = ret;
- krb5_crypto_destroy(gssapi_krb5_context, crypto);
- gss_release_buffer(minor_status, output_message_buffer);
+ krb5_crypto_destroy(_gsskrb5_context, crypto);
+ _gsskrb5_release_buffer(minor_status, output_message_buffer);
return GSS_S_FAILURE;
}
memcpy(p, cipher.data, cipher.length);
@@ -349,23 +397,23 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
buf = malloc(input_message_buffer->length + sizeof(*token));
if (buf == NULL) {
*minor_status = ENOMEM;
- krb5_crypto_destroy(gssapi_krb5_context, crypto);
- gss_release_buffer(minor_status, output_message_buffer);
+ krb5_crypto_destroy(_gsskrb5_context, crypto);
+ _gsskrb5_release_buffer(minor_status, output_message_buffer);
return GSS_S_FAILURE;
}
memcpy(buf, input_message_buffer->value, input_message_buffer->length);
memcpy(buf + input_message_buffer->length, token, sizeof(*token));
- ret = krb5_create_checksum(gssapi_krb5_context, crypto,
+ ret = krb5_create_checksum(_gsskrb5_context, crypto,
usage, 0, buf,
input_message_buffer->length +
sizeof(*token),
&cksum);
if (ret != 0) {
- gssapi_krb5_set_error_string();
+ _gsskrb5_set_error_string();
*minor_status = ret;
- krb5_crypto_destroy(gssapi_krb5_context, crypto);
- gss_release_buffer(minor_status, output_message_buffer);
+ krb5_crypto_destroy(_gsskrb5_context, crypto);
+ _gsskrb5_release_buffer(minor_status, output_message_buffer);
free(buf);
return GSS_S_FAILURE;
}
@@ -386,17 +434,17 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
ret = rrc_rotate(p,
input_message_buffer->length + cksum.checksum.length, rrc, FALSE);
if (ret != 0) {
- gssapi_krb5_set_error_string();
+ _gsskrb5_set_error_string();
*minor_status = ret;
- krb5_crypto_destroy(gssapi_krb5_context, crypto);
- gss_release_buffer(minor_status, output_message_buffer);
+ krb5_crypto_destroy(_gsskrb5_context, crypto);
+ _gsskrb5_release_buffer(minor_status, output_message_buffer);
free_Checksum(&cksum);
return GSS_S_FAILURE;
}
free_Checksum(&cksum);
}
- krb5_crypto_destroy(gssapi_krb5_context, crypto);
+ krb5_crypto_destroy(_gsskrb5_context, crypto);
if (conf_state != NULL) {
*conf_state = conf_req_flag;
@@ -407,7 +455,7 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
}
OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status,
- const gss_ctx_id_t context_handle,
+ const gsskrb5_ctx context_handle,
const gss_buffer_t input_message_buffer,
gss_buffer_t output_message_buffer,
int *conf_state,
@@ -470,8 +518,8 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status,
/*
* Check sequence number
*/
- gssapi_decode_be_om_uint32(&token->SND_SEQ[0], &seq_number_hi);
- gssapi_decode_be_om_uint32(&token->SND_SEQ[4], &seq_number_lo);
+ _gsskrb5_decode_be_om_uint32(&token->SND_SEQ[0], &seq_number_hi);
+ _gsskrb5_decode_be_om_uint32(&token->SND_SEQ[4], &seq_number_lo);
if (seq_number_hi) {
/* no support for 64-bit sequence numbers */
*minor_status = ERANGE;
@@ -483,7 +531,7 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status,
if (ret != 0) {
*minor_status = 0;
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
- gss_release_buffer(minor_status, output_message_buffer);
+ _gsskrb5_release_buffer(minor_status, output_message_buffer);
return ret;
}
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
@@ -491,9 +539,9 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status,
/*
* Decrypt and/or verify checksum
*/
- ret = krb5_crypto_init(gssapi_krb5_context, key, 0, &crypto);
+ ret = krb5_crypto_init(_gsskrb5_context, key, 0, &crypto);
if (ret != 0) {
- gssapi_krb5_set_error_string();
+ _gsskrb5_set_error_string();
*minor_status = ret;
return GSS_S_FAILURE;
}
@@ -511,23 +559,23 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status,
/* Rotate by RRC; bogus to do this in-place XXX */
*minor_status = rrc_rotate(p, len, rrc, TRUE);
if (*minor_status != 0) {
- krb5_crypto_destroy(gssapi_krb5_context, crypto);
+ krb5_crypto_destroy(_gsskrb5_context, crypto);
return GSS_S_FAILURE;
}
if (token_flags & CFXSealed) {
- ret = krb5_decrypt(gssapi_krb5_context, crypto, usage,
+ ret = krb5_decrypt(_gsskrb5_context, crypto, usage,
p, len, &data);
if (ret != 0) {
- gssapi_krb5_set_error_string();
+ _gsskrb5_set_error_string();
*minor_status = ret;
- krb5_crypto_destroy(gssapi_krb5_context, crypto);
+ krb5_crypto_destroy(_gsskrb5_context, crypto);
return GSS_S_BAD_MIC;
}
/* Check that there is room for the pad and token header */
if (data.length < ec + sizeof(*token)) {
- krb5_crypto_destroy(gssapi_krb5_context, crypto);
+ krb5_crypto_destroy(_gsskrb5_context, crypto);
krb5_data_free(&data);
return GSS_S_DEFECTIVE_TOKEN;
}
@@ -540,7 +588,7 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status,
/* Check the integrity of the header */
if (memcmp(p, token, sizeof(*token)) != 0) {
- krb5_crypto_destroy(gssapi_krb5_context, crypto);
+ krb5_crypto_destroy(_gsskrb5_context, crypto);
krb5_data_free(&data);
return GSS_S_BAD_MIC;
}
@@ -551,12 +599,12 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status,
Checksum cksum;
/* Determine checksum type */
- ret = krb5_crypto_get_checksum_type(gssapi_krb5_context,
+ ret = krb5_crypto_get_checksum_type(_gsskrb5_context,
crypto, &cksum.cksumtype);
if (ret != 0) {
- gssapi_krb5_set_error_string();
+ _gsskrb5_set_error_string();
*minor_status = ret;
- krb5_crypto_destroy(gssapi_krb5_context, crypto);
+ krb5_crypto_destroy(_gsskrb5_context, crypto);
return GSS_S_FAILURE;
}
@@ -565,7 +613,7 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status,
/* Check we have at least as much data as the checksum */
if (len < cksum.checksum.length) {
*minor_status = ERANGE;
- krb5_crypto_destroy(gssapi_krb5_context, crypto);
+ krb5_crypto_destroy(_gsskrb5_context, crypto);
return GSS_S_BAD_MIC;
}
@@ -577,7 +625,7 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status,
output_message_buffer->value = malloc(len + sizeof(*token));
if (output_message_buffer->value == NULL) {
*minor_status = ENOMEM;
- krb5_crypto_destroy(gssapi_krb5_context, crypto);
+ krb5_crypto_destroy(_gsskrb5_context, crypto);
return GSS_S_FAILURE;
}
@@ -594,21 +642,21 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status,
token->RRC[0] = 0;
token->RRC[1] = 0;
- ret = krb5_verify_checksum(gssapi_krb5_context, crypto,
+ ret = krb5_verify_checksum(_gsskrb5_context, crypto,
usage,
output_message_buffer->value,
len + sizeof(*token),
&cksum);
if (ret != 0) {
- gssapi_krb5_set_error_string();
+ _gsskrb5_set_error_string();
*minor_status = ret;
- krb5_crypto_destroy(gssapi_krb5_context, crypto);
- gss_release_buffer(minor_status, output_message_buffer);
+ krb5_crypto_destroy(_gsskrb5_context, crypto);
+ _gsskrb5_release_buffer(minor_status, output_message_buffer);
return GSS_S_BAD_MIC;
}
}
- krb5_crypto_destroy(gssapi_krb5_context, crypto);
+ krb5_crypto_destroy(_gsskrb5_context, crypto);
if (qop_state != NULL) {
*qop_state = GSS_C_QOP_DEFAULT;
@@ -619,7 +667,7 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status,
}
OM_uint32 _gssapi_mic_cfx(OM_uint32 *minor_status,
- const gss_ctx_id_t context_handle,
+ const gsskrb5_ctx context_handle,
gss_qop_t qop_req,
const gss_buffer_t message_buffer,
gss_buffer_t message_token,
@@ -634,9 +682,9 @@ OM_uint32 _gssapi_mic_cfx(OM_uint32 *minor_status,
size_t len;
int32_t seq_number;
- ret = krb5_crypto_init(gssapi_krb5_context, key, 0, &crypto);
+ ret = krb5_crypto_init(_gsskrb5_context, key, 0, &crypto);
if (ret != 0) {
- gssapi_krb5_set_error_string();
+ _gsskrb5_set_error_string();
*minor_status = ret;
return GSS_S_FAILURE;
}
@@ -645,7 +693,7 @@ OM_uint32 _gssapi_mic_cfx(OM_uint32 *minor_status,
buf = malloc(len);
if (buf == NULL) {
*minor_status = ENOMEM;
- krb5_crypto_destroy(gssapi_krb5_context, crypto);
+ krb5_crypto_destroy(_gsskrb5_context, crypto);
return GSS_S_FAILURE;
}
@@ -662,12 +710,12 @@ OM_uint32 _gssapi_mic_cfx(OM_uint32 *minor_status,
memset(token->Filler, 0xFF, 5);
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
- krb5_auth_con_getlocalseqnumber(gssapi_krb5_context,
+ krb5_auth_con_getlocalseqnumber(_gsskrb5_context,
context_handle->auth_context,
&seq_number);
- gssapi_encode_be_om_uint32(0, &token->SND_SEQ[0]);
- gssapi_encode_be_om_uint32(seq_number, &token->SND_SEQ[4]);
- krb5_auth_con_setlocalseqnumber(gssapi_krb5_context,
+ _gsskrb5_encode_be_om_uint32(0, &token->SND_SEQ[0]);
+ _gsskrb5_encode_be_om_uint32(seq_number, &token->SND_SEQ[4]);
+ krb5_auth_con_setlocalseqnumber(_gsskrb5_context,
context_handle->auth_context,
++seq_number);
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
@@ -678,16 +726,16 @@ OM_uint32 _gssapi_mic_cfx(OM_uint32 *minor_status,
usage = KRB5_KU_USAGE_ACCEPTOR_SIGN;
}
- ret = krb5_create_checksum(gssapi_krb5_context, crypto,
+ ret = krb5_create_checksum(_gsskrb5_context, crypto,
usage, 0, buf, len, &cksum);
if (ret != 0) {
- gssapi_krb5_set_error_string();
+ _gsskrb5_set_error_string();
*minor_status = ret;
- krb5_crypto_destroy(gssapi_krb5_context, crypto);
+ krb5_crypto_destroy(_gsskrb5_context, crypto);
free(buf);
return GSS_S_FAILURE;
}
- krb5_crypto_destroy(gssapi_krb5_context, crypto);
+ krb5_crypto_destroy(_gsskrb5_context, crypto);
/* Determine MIC length */
message_token->length = sizeof(*token) + cksum.checksum.length;
@@ -712,7 +760,7 @@ OM_uint32 _gssapi_mic_cfx(OM_uint32 *minor_status,
}
OM_uint32 _gssapi_verify_mic_cfx(OM_uint32 *minor_status,
- const gss_ctx_id_t context_handle,
+ const gsskrb5_ctx context_handle,
const gss_buffer_t message_buffer,
const gss_buffer_t token_buffer,
gss_qop_t *qop_state,
@@ -763,8 +811,8 @@ OM_uint32 _gssapi_verify_mic_cfx(OM_uint32 *minor_status,
/*
* Check sequence number
*/
- gssapi_decode_be_om_uint32(&token->SND_SEQ[0], &seq_number_hi);
- gssapi_decode_be_om_uint32(&token->SND_SEQ[4], &seq_number_lo);
+ _gsskrb5_decode_be_om_uint32(&token->SND_SEQ[0], &seq_number_hi);
+ _gsskrb5_decode_be_om_uint32(&token->SND_SEQ[4], &seq_number_lo);
if (seq_number_hi) {
*minor_status = ERANGE;
return GSS_S_UNSEQ_TOKEN;
@@ -782,19 +830,19 @@ OM_uint32 _gssapi_verify_mic_cfx(OM_uint32 *minor_status,
/*
* Verify checksum
*/
- ret = krb5_crypto_init(gssapi_krb5_context, key, 0, &crypto);
+ ret = krb5_crypto_init(_gsskrb5_context, key, 0, &crypto);
if (ret != 0) {
- gssapi_krb5_set_error_string();
+ _gsskrb5_set_error_string();
*minor_status = ret;
return GSS_S_FAILURE;
}
- ret = krb5_crypto_get_checksum_type(gssapi_krb5_context, crypto,
+ ret = krb5_crypto_get_checksum_type(_gsskrb5_context, crypto,
&cksum.cksumtype);
if (ret != 0) {
- gssapi_krb5_set_error_string();
+ _gsskrb5_set_error_string();
*minor_status = ret;
- krb5_crypto_destroy(gssapi_krb5_context, crypto);
+ krb5_crypto_destroy(_gsskrb5_context, crypto);
return GSS_S_FAILURE;
}
@@ -810,21 +858,21 @@ OM_uint32 _gssapi_verify_mic_cfx(OM_uint32 *minor_status,
buf = malloc(message_buffer->length + sizeof(*token));
if (buf == NULL) {
*minor_status = ENOMEM;
- krb5_crypto_destroy(gssapi_krb5_context, crypto);
+ krb5_crypto_destroy(_gsskrb5_context, crypto);
return GSS_S_FAILURE;
}
memcpy(buf, message_buffer->value, message_buffer->length);
memcpy(buf + message_buffer->length, token, sizeof(*token));
- ret = krb5_verify_checksum(gssapi_krb5_context, crypto,
+ ret = krb5_verify_checksum(_gsskrb5_context, crypto,
usage,
buf,
sizeof(*token) + message_buffer->length,
&cksum);
+ krb5_crypto_destroy(_gsskrb5_context, crypto);
if (ret != 0) {
- gssapi_krb5_set_error_string();
+ _gsskrb5_set_error_string();
*minor_status = ret;
- krb5_crypto_destroy(gssapi_krb5_context, crypto);
free(buf);
return GSS_S_BAD_MIC;
}
diff --git a/source4/heimdal/lib/gssapi/cfx.h b/source4/heimdal/lib/gssapi/krb5/cfx.h
index d9bdd9da19..1120544fbe 100755
--- a/source4/heimdal/lib/gssapi/cfx.h
+++ b/source4/heimdal/lib/gssapi/krb5/cfx.h
@@ -30,7 +30,7 @@
* SUCH DAMAGE.
*/
-/* $Id: cfx.h,v 1.5 2003/09/22 21:48:35 lha Exp $ */
+/* $Id: cfx.h,v 1.7 2006/07/19 14:16:33 lha Exp $ */
#ifndef GSSAPI_CFX_H_
#define GSSAPI_CFX_H_ 1
@@ -62,44 +62,19 @@ typedef struct gss_cfx_delete_token_desc_struct {
u_char SND_SEQ[8];
} gss_cfx_delete_token_desc, *gss_cfx_delete_token;
-OM_uint32 _gssapi_wrap_size_cfx(OM_uint32 *minor_status,
- const gss_ctx_id_t context_handle,
- int conf_req_flag,
- gss_qop_t qop_req,
- OM_uint32 req_input_size,
- OM_uint32 *output_len,
- OM_uint32 *padlen,
- krb5_keyblock *key);
-
-OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
- const gss_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,
- krb5_keyblock *key);
+krb5_error_code
+_gsskrb5cfx_wrap_length_cfx(krb5_crypto crypto,
+ int conf_req_flag,
+ size_t input_length,
+ size_t *output_length,
+ size_t *cksumsize,
+ uint16_t *padlength);
-OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status,
- const gss_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,
- krb5_keyblock *key);
-
-OM_uint32 _gssapi_mic_cfx(OM_uint32 *minor_status,
- const gss_ctx_id_t context_handle,
- gss_qop_t qop_req,
- const gss_buffer_t message_buffer,
- gss_buffer_t message_token,
- krb5_keyblock *key);
+krb5_error_code
+_gsskrb5cfx_max_wrap_length_cfx(krb5_crypto crypto,
+ int conf_req_flag,
+ size_t input_length,
+ OM_uint32 *output_length);
-OM_uint32 _gssapi_verify_mic_cfx(OM_uint32 *minor_status,
- const gss_ctx_id_t context_handle,
- const gss_buffer_t message_buffer,
- const gss_buffer_t token_buffer,
- gss_qop_t *qop_state,
- krb5_keyblock *key);
#endif /* GSSAPI_CFX_H_ */
diff --git a/source4/heimdal/lib/gssapi/krb5/compare_name.c b/source4/heimdal/lib/gssapi/krb5/compare_name.c
new file mode 100644
index 0000000000..3e0f7edfee
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/krb5/compare_name.c
@@ -0,0 +1,54 @@
+/*
+ * 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 "krb5/gsskrb5_locl.h"
+
+RCSID("$Id: compare_name.c,v 1.7 2006/10/07 22:14:15 lha Exp $");
+
+OM_uint32 _gsskrb5_compare_name
+ (OM_uint32 * minor_status,
+ const gss_name_t name1,
+ const gss_name_t name2,
+ int * name_equal
+ )
+{
+ krb5_const_principal princ1 = (krb5_const_principal)name1;
+ krb5_const_principal princ2 = (krb5_const_principal)name2;
+
+ GSSAPI_KRB5_INIT();
+
+ *name_equal = krb5_principal_compare (_gsskrb5_context,
+ princ1, princ2);
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
diff --git a/source4/heimdal/lib/gssapi/compat.c b/source4/heimdal/lib/gssapi/krb5/compat.c
index 5605c48023..0ea2fce0e8 100644
--- a/source4/heimdal/lib/gssapi/compat.c
+++ b/source4/heimdal/lib/gssapi/krb5/compat.c
@@ -31,42 +31,42 @@
* SUCH DAMAGE.
*/
-#include "gssapi_locl.h"
+#include "krb5/gsskrb5_locl.h"
-RCSID("$Id: compat.c,v 1.10 2005/05/30 20:51:51 lha Exp $");
+RCSID("$Id: compat.c,v 1.13 2006/10/07 22:14:17 lha Exp $");
-krb5_error_code
-_gss_check_compat(OM_uint32 *minor_status, gss_name_t name,
- const char *option, krb5_boolean *compat,
- krb5_boolean match_val)
+static krb5_error_code
+check_compat(OM_uint32 *minor_status, krb5_const_principal name,
+ const char *option, krb5_boolean *compat,
+ krb5_boolean match_val)
{
krb5_error_code ret = 0;
char **p, **q;
krb5_principal match;
- p = krb5_config_get_strings(gssapi_krb5_context, NULL, "gssapi",
+ p = krb5_config_get_strings(_gsskrb5_context, NULL, "gssapi",
option, NULL);
if(p == NULL)
return 0;
match = NULL;
for(q = p; *q; q++) {
- ret = krb5_parse_name(gssapi_krb5_context, *q, &match);
+ ret = krb5_parse_name(_gsskrb5_context, *q, &match);
if (ret)
break;
- if (krb5_principal_match(gssapi_krb5_context, name, match)) {
+ if (krb5_principal_match(_gsskrb5_context, name, match)) {
*compat = match_val;
break;
}
- krb5_free_principal(gssapi_krb5_context, match);
+ krb5_free_principal(_gsskrb5_context, match);
match = NULL;
}
if (match)
- krb5_free_principal(gssapi_krb5_context, match);
+ krb5_free_principal(_gsskrb5_context, match);
krb5_config_free_strings(p);
if (ret) {
@@ -83,18 +83,18 @@ _gss_check_compat(OM_uint32 *minor_status, gss_name_t name,
*/
OM_uint32
-_gss_DES3_get_mic_compat(OM_uint32 *minor_status, gss_ctx_id_t ctx)
+_gss_DES3_get_mic_compat(OM_uint32 *minor_status, gsskrb5_ctx ctx)
{
krb5_boolean use_compat = FALSE;
OM_uint32 ret;
if ((ctx->more_flags & COMPAT_OLD_DES3_SELECTED) == 0) {
- ret = _gss_check_compat(minor_status, ctx->target,
- "broken_des3_mic", &use_compat, TRUE);
+ ret = check_compat(minor_status, ctx->target,
+ "broken_des3_mic", &use_compat, TRUE);
if (ret)
return ret;
- ret = _gss_check_compat(minor_status, ctx->target,
- "correct_des3_mic", &use_compat, FALSE);
+ ret = check_compat(minor_status, ctx->target,
+ "correct_des3_mic", &use_compat, FALSE);
if (ret)
return ret;
@@ -105,6 +105,7 @@ _gss_DES3_get_mic_compat(OM_uint32 *minor_status, gss_ctx_id_t ctx)
return 0;
}
+#if 0
OM_uint32
gss_krb5_compat_des3_mic(OM_uint32 *minor_status, gss_ctx_id_t ctx, int on)
{
@@ -121,34 +122,4 @@ gss_krb5_compat_des3_mic(OM_uint32 *minor_status, gss_ctx_id_t ctx, int on)
return 0;
}
-
-/*
- * For compatability with the Windows SPNEGO implementation, the
- * default is to ignore the mechListMIC unless the initiator specified
- * CFX or configured in krb5.conf with the option
- * [gssapi]require_mechlist_mic=target-principal-pattern.
- * The option is valid for both initiator and acceptor.
- */
-OM_uint32
-_gss_spnego_require_mechlist_mic(OM_uint32 *minor_status,
- gss_ctx_id_t ctx,
- krb5_boolean *require_mic)
-{
- OM_uint32 ret;
- int is_cfx = 0;
-
- gsskrb5_is_cfx(ctx, &is_cfx);
- if (is_cfx) {
- /* CFX session key was used */
- *require_mic = TRUE;
- } else {
- *require_mic = FALSE;
- ret = _gss_check_compat(minor_status, ctx->target,
- "require_mechlist_mic",
- require_mic, TRUE);
- if (ret)
- return ret;
- }
- *minor_status = 0;
- return GSS_S_COMPLETE;
-}
+#endif
diff --git a/source4/heimdal/lib/gssapi/context_time.c b/source4/heimdal/lib/gssapi/krb5/context_time.c
index ee1dc6fe93..4e9d9f5d1d 100644
--- a/source4/heimdal/lib/gssapi/context_time.c
+++ b/source4/heimdal/lib/gssapi/krb5/context_time.c
@@ -31,12 +31,12 @@
* SUCH DAMAGE.
*/
-#include "gssapi_locl.h"
+#include "krb5/gsskrb5_locl.h"
-RCSID("$Id: context_time.c,v 1.11 2005/12/05 09:19:52 lha Exp $");
+RCSID("$Id: context_time.c,v 1.13 2006/10/07 22:14:19 lha Exp $");
OM_uint32
-gssapi_lifetime_left(OM_uint32 *minor_status,
+_gsskrb5_lifetime_left(OM_uint32 *minor_status,
OM_uint32 lifetime,
OM_uint32 *lifetime_rec)
{
@@ -48,10 +48,10 @@ gssapi_lifetime_left(OM_uint32 *minor_status,
return GSS_S_COMPLETE;
}
- kret = krb5_timeofday(gssapi_krb5_context, &timeret);
+ kret = krb5_timeofday(_gsskrb5_context, &timeret);
if (kret) {
*minor_status = kret;
- gssapi_krb5_set_error_string ();
+ _gsskrb5_set_error_string ();
return GSS_S_FAILURE;
}
@@ -64,7 +64,7 @@ gssapi_lifetime_left(OM_uint32 *minor_status,
}
-OM_uint32 gss_context_time
+OM_uint32 _gsskrb5_context_time
(OM_uint32 * minor_status,
const gss_ctx_id_t context_handle,
OM_uint32 * time_rec
@@ -72,14 +72,15 @@ OM_uint32 gss_context_time
{
OM_uint32 lifetime;
OM_uint32 major_status;
+ const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle;
GSSAPI_KRB5_INIT ();
- HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
- lifetime = context_handle->lifetime;
- HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+ lifetime = ctx->lifetime;
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
- major_status = gssapi_lifetime_left(minor_status, lifetime, time_rec);
+ major_status = _gsskrb5_lifetime_left(minor_status, lifetime, time_rec);
if (major_status != GSS_S_COMPLETE)
return major_status;
diff --git a/source4/heimdal/lib/gssapi/copy_ccache.c b/source4/heimdal/lib/gssapi/krb5/copy_ccache.c
index 782b701e44..99aa2ccb43 100644
--- a/source4/heimdal/lib/gssapi/copy_ccache.c
+++ b/source4/heimdal/lib/gssapi/krb5/copy_ccache.c
@@ -31,10 +31,11 @@
* SUCH DAMAGE.
*/
-#include "gssapi_locl.h"
+#include "krb5/gsskrb5_locl.h"
-RCSID("$Id: copy_ccache.c,v 1.13 2005/11/28 23:05:44 lha Exp $");
+RCSID("$Id: copy_ccache.c,v 1.15 2006/10/07 22:14:22 lha Exp $");
+#if 0
OM_uint32
gss_krb5_copy_ccache(OM_uint32 *minor_status,
gss_cred_id_t cred,
@@ -50,36 +51,37 @@ gss_krb5_copy_ccache(OM_uint32 *minor_status,
return GSS_S_FAILURE;
}
- kret = krb5_cc_copy_cache(gssapi_krb5_context, cred->ccache, out);
+ kret = krb5_cc_copy_cache(_gsskrb5_context, cred->ccache, out);
HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
if (kret) {
*minor_status = kret;
- gssapi_krb5_set_error_string ();
+ _gsskrb5_set_error_string ();
return GSS_S_FAILURE;
}
*minor_status = 0;
return GSS_S_COMPLETE;
}
+#endif
OM_uint32
-gss_krb5_import_cred(OM_uint32 *minor_status,
+_gsskrb5_import_cred(OM_uint32 *minor_status,
krb5_ccache id,
krb5_principal keytab_principal,
krb5_keytab keytab,
gss_cred_id_t *cred)
{
krb5_error_code kret;
- gss_cred_id_t handle;
+ gsskrb5_cred handle;
OM_uint32 ret;
*cred = NULL;
GSSAPI_KRB5_INIT ();
- handle = (gss_cred_id_t)calloc(1, sizeof(*handle));
- if (handle == GSS_C_NO_CREDENTIAL) {
- gssapi_krb5_clear_status ();
+ handle = calloc(1, sizeof(*handle));
+ if (handle == NULL) {
+ _gsskrb5_clear_status ();
*minor_status = ENOMEM;
return (GSS_S_FAILURE);
}
@@ -92,11 +94,11 @@ gss_krb5_import_cred(OM_uint32 *minor_status,
handle->usage |= GSS_C_INITIATE;
- kret = krb5_cc_get_principal(gssapi_krb5_context, id,
+ kret = krb5_cc_get_principal(_gsskrb5_context, id,
&handle->principal);
if (kret) {
free(handle);
- gssapi_krb5_set_error_string ();
+ _gsskrb5_set_error_string ();
*minor_status = kret;
return GSS_S_FAILURE;
}
@@ -104,34 +106,34 @@ gss_krb5_import_cred(OM_uint32 *minor_status,
if (keytab_principal) {
krb5_boolean match;
- match = krb5_principal_compare(gssapi_krb5_context,
+ match = krb5_principal_compare(_gsskrb5_context,
handle->principal,
keytab_principal);
if (match == FALSE) {
- krb5_free_principal(gssapi_krb5_context, handle->principal);
+ krb5_free_principal(_gsskrb5_context, handle->principal);
free(handle);
- gssapi_krb5_clear_status ();
+ _gsskrb5_clear_status ();
*minor_status = EINVAL;
return GSS_S_FAILURE;
}
}
- ret = _gssapi_krb5_ccache_lifetime(minor_status,
+ ret = __gsskrb5_ccache_lifetime(minor_status,
id,
handle->principal,
&handle->lifetime);
if (ret != GSS_S_COMPLETE) {
- krb5_free_principal(gssapi_krb5_context, handle->principal);
+ krb5_free_principal(_gsskrb5_context, handle->principal);
free(handle);
return ret;
}
- kret = krb5_cc_get_full_name(gssapi_krb5_context, id, &str);
+ kret = krb5_cc_get_full_name(_gsskrb5_context, id, &str);
if (kret)
goto out;
- kret = krb5_cc_resolve(gssapi_krb5_context, str, &handle->ccache);
+ kret = krb5_cc_resolve(_gsskrb5_context, str, &handle->ccache);
free(str);
if (kret)
goto out;
@@ -144,18 +146,18 @@ gss_krb5_import_cred(OM_uint32 *minor_status,
handle->usage |= GSS_C_ACCEPT;
if (keytab_principal && handle->principal == NULL) {
- kret = krb5_copy_principal(gssapi_krb5_context,
+ kret = krb5_copy_principal(_gsskrb5_context,
keytab_principal,
&handle->principal);
if (kret)
goto out;
}
- kret = krb5_kt_get_full_name(gssapi_krb5_context, keytab, &str);
+ kret = krb5_kt_get_full_name(_gsskrb5_context, keytab, &str);
if (kret)
goto out;
- kret = krb5_kt_resolve(gssapi_krb5_context, str, &handle->keytab);
+ kret = krb5_kt_resolve(_gsskrb5_context, str, &handle->keytab);
free(str);
if (kret)
goto out;
@@ -163,10 +165,10 @@ gss_krb5_import_cred(OM_uint32 *minor_status,
if (id || keytab) {
- ret = gss_create_empty_oid_set(minor_status, &handle->mechanisms);
+ ret = _gsskrb5_create_empty_oid_set(minor_status, &handle->mechanisms);
if (ret == GSS_S_COMPLETE)
- ret = gss_add_oid_set_member(minor_status, GSS_KRB5_MECHANISM,
- &handle->mechanisms);
+ ret = _gsskrb5_add_oid_set_member(minor_status, GSS_KRB5_MECHANISM,
+ &handle->mechanisms);
if (ret != GSS_S_COMPLETE) {
kret = *minor_status;
goto out;
@@ -174,107 +176,16 @@ gss_krb5_import_cred(OM_uint32 *minor_status,
}
*minor_status = 0;
- *cred = handle;
+ *cred = (gss_cred_id_t)handle;
return GSS_S_COMPLETE;
out:
- gssapi_krb5_set_error_string ();
+ _gsskrb5_set_error_string ();
if (handle->principal)
- krb5_free_principal(gssapi_krb5_context, handle->principal);
+ krb5_free_principal(_gsskrb5_context, handle->principal);
HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
free(handle);
*minor_status = kret;
return GSS_S_FAILURE;
}
-
-OM_uint32
-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)
-{
- krb5_error_code ret;
- krb5_data data;
-
- ad_data->value = NULL;
- ad_data->length = 0;
-
- HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
- if (context_handle->ticket == NULL) {
- HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
- *minor_status = EINVAL;
- return GSS_S_FAILURE;
- }
-
- ret = krb5_ticket_get_authorization_data_type(gssapi_krb5_context,
- context_handle->ticket,
- ad_type,
- &data);
- HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
- if (ret) {
- *minor_status = ret;
- return GSS_S_FAILURE;
- }
-
- ad_data->value = malloc(data.length);
- if (ad_data->value == NULL) {
- krb5_data_free(&data);
- *minor_status = ENOMEM;
- return GSS_S_FAILURE;
- }
-
- ad_data->length = data.length;
- memcpy(ad_data->value, data.data, ad_data->length);
- krb5_data_free(&data);
-
- *minor_status = 0;
- return GSS_S_COMPLETE;
-}
-
-OM_uint32
-gsskrb5_extract_authtime_from_sec_context(OM_uint32 *minor_status,
- gss_ctx_id_t context_handle,
- time_t *authtime)
-{
- HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
- if (context_handle->ticket == NULL) {
- HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
- *minor_status = EINVAL;
- return GSS_S_FAILURE;
- }
-
- *authtime = context_handle->ticket->ticket.authtime;
- HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
-
- *minor_status = 0;
- return GSS_S_COMPLETE;
-}
-
-OM_uint32 gss_krb5_copy_service_keyblock
- (OM_uint32 *minor_status,
- gss_ctx_id_t context_handle,
- struct EncryptionKey **out)
-{
- krb5_error_code ret;
-
- HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
- if (context_handle->service_keyblock == NULL) {
- HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
- *minor_status = EINVAL;
- return GSS_S_FAILURE;
- }
-
- ret = krb5_copy_keyblock(gssapi_krb5_context,
- context_handle->service_keyblock,
- out);
-
- HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
- if (ret) {
- *minor_status = ret;
- return GSS_S_FAILURE;
- }
-
- *minor_status = 0;
- return GSS_S_COMPLETE;
-}
diff --git a/source4/heimdal/lib/gssapi/create_emtpy_oid_set.c b/source4/heimdal/lib/gssapi/krb5/create_emtpy_oid_set.c
index 1a25e0d781..550995125a 100644
--- a/source4/heimdal/lib/gssapi/create_emtpy_oid_set.c
+++ b/source4/heimdal/lib/gssapi/krb5/create_emtpy_oid_set.c
@@ -31,11 +31,11 @@
* SUCH DAMAGE.
*/
-#include "gssapi_locl.h"
+#include "krb5/gsskrb5_locl.h"
-RCSID("$Id: create_emtpy_oid_set.c,v 1.5 2003/03/16 17:47:07 lha Exp $");
+RCSID("$Id: create_emtpy_oid_set.c,v 1.7 2006/10/07 22:14:24 lha Exp $");
-OM_uint32 gss_create_empty_oid_set (
+OM_uint32 _gsskrb5_create_empty_oid_set (
OM_uint32 * minor_status,
gss_OID_set * oid_set
)
diff --git a/source4/heimdal/lib/gssapi/decapsulate.c b/source4/heimdal/lib/gssapi/krb5/decapsulate.c
index 08df361776..eadec1ef03 100644
--- a/source4/heimdal/lib/gssapi/decapsulate.c
+++ b/source4/heimdal/lib/gssapi/krb5/decapsulate.c
@@ -31,9 +31,9 @@
* SUCH DAMAGE.
*/
-#include "gssapi_locl.h"
+#include "krb5/gsskrb5_locl.h"
-RCSID("$Id: decapsulate.c,v 1.12 2005/06/16 20:40:49 lha Exp $");
+RCSID("$Id: decapsulate.c,v 1.16 2006/10/07 22:14:26 lha Exp $");
/*
* return the length of the mechanism in token or -1
@@ -41,7 +41,7 @@ RCSID("$Id: decapsulate.c,v 1.12 2005/06/16 20:40:49 lha Exp $");
*/
ssize_t
-gssapi_krb5_get_mech (const u_char *ptr,
+_gsskrb5_get_mech (const u_char *ptr,
size_t total_len,
const u_char **mech_ret)
{
@@ -76,7 +76,7 @@ _gssapi_verify_mech_header(u_char **str,
const u_char *p;
ssize_t mech_len;
- mech_len = gssapi_krb5_get_mech (*str, total_len, &p);
+ mech_len = _gsskrb5_get_mech (*str, total_len, &p);
if (mech_len < 0)
return GSS_S_DEFECTIVE_TOKEN;
@@ -92,9 +92,9 @@ _gssapi_verify_mech_header(u_char **str,
}
OM_uint32
-gssapi_krb5_verify_header(u_char **str,
+_gsskrb5_verify_header(u_char **str,
size_t total_len,
- const u_char *type,
+ const void *type,
gss_OID oid)
{
OM_uint32 ret;
@@ -110,7 +110,7 @@ gssapi_krb5_verify_header(u_char **str,
if (len < 2)
return GSS_S_DEFECTIVE_TOKEN;
- if ((*str)[0] != type[0] || (*str)[1] != type[1])
+ if (memcmp (*str, type, 2) != 0)
return GSS_S_DEFECTIVE_TOKEN;
*str += 2;
@@ -154,17 +154,17 @@ _gssapi_decapsulate(
*/
OM_uint32
-gssapi_krb5_decapsulate(OM_uint32 *minor_status,
+_gsskrb5_decapsulate(OM_uint32 *minor_status,
gss_buffer_t input_token_buffer,
krb5_data *out_data,
- const char *type,
+ const void *type,
gss_OID oid)
{
u_char *p;
OM_uint32 ret;
p = input_token_buffer->value;
- ret = gssapi_krb5_verify_header(&p,
+ ret = _gsskrb5_verify_header(&p,
input_token_buffer->length,
type,
oid);
diff --git a/source4/heimdal/lib/gssapi/delete_sec_context.c b/source4/heimdal/lib/gssapi/krb5/delete_sec_context.c
index f1842def7c..e890d7d2c2 100644
--- a/source4/heimdal/lib/gssapi/delete_sec_context.c
+++ b/source4/heimdal/lib/gssapi/krb5/delete_sec_context.c
@@ -31,16 +31,17 @@
* SUCH DAMAGE.
*/
-#include "gssapi_locl.h"
+#include "krb5/gsskrb5_locl.h"
-RCSID("$Id: delete_sec_context.c,v 1.16 2006/01/16 13:12:29 lha Exp $");
+RCSID("$Id: delete_sec_context.c,v 1.19 2006/10/07 22:14:28 lha Exp $");
-OM_uint32 gss_delete_sec_context
- (OM_uint32 * minor_status,
- gss_ctx_id_t * context_handle,
- gss_buffer_t output_token
- )
+OM_uint32
+_gsskrb5_delete_sec_context(OM_uint32 * minor_status,
+ gss_ctx_id_t * context_handle,
+ gss_buffer_t output_token)
{
+ gsskrb5_ctx ctx;
+
GSSAPI_KRB5_INIT ();
*minor_status = 0;
@@ -53,31 +54,27 @@ OM_uint32 gss_delete_sec_context
if (*context_handle == GSS_C_NO_CONTEXT)
return GSS_S_COMPLETE;
- HEIMDAL_MUTEX_lock(&(*context_handle)->ctx_id_mutex);
+ ctx = (gsskrb5_ctx) *context_handle;
+ *context_handle = GSS_C_NO_CONTEXT;
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
- krb5_auth_con_free (gssapi_krb5_context,
- (*context_handle)->auth_context);
- if((*context_handle)->source)
- krb5_free_principal (gssapi_krb5_context,
- (*context_handle)->source);
- if((*context_handle)->target)
- krb5_free_principal (gssapi_krb5_context,
- (*context_handle)->target);
- if ((*context_handle)->ticket)
- krb5_free_ticket (gssapi_krb5_context,
- (*context_handle)->ticket);
- if ((*context_handle)->service_keyblock)
- krb5_free_keyblock (gssapi_krb5_context,
- (*context_handle)->service_keyblock);
- if((*context_handle)->order)
- _gssapi_msg_order_destroy(&(*context_handle)->order);
- if ((*context_handle)->fwd_data.length > 0)
- free((*context_handle)->fwd_data.data);
+ krb5_auth_con_free (_gsskrb5_context, ctx->auth_context);
+ if(ctx->source)
+ krb5_free_principal (_gsskrb5_context, ctx->source);
+ if(ctx->target)
+ krb5_free_principal (_gsskrb5_context, ctx->target);
+ if (ctx->ticket)
+ krb5_free_ticket (_gsskrb5_context, ctx->ticket);
+ if(ctx->order)
+ _gssapi_msg_order_destroy(&ctx->order);
+ if (ctx->service_keyblock)
+ krb5_free_keyblock (_gsskrb5_context, ctx->service_keyblock);
+ krb5_data_free(&ctx->fwd_data);
- HEIMDAL_MUTEX_unlock(&(*context_handle)->ctx_id_mutex);
- HEIMDAL_MUTEX_destroy(&(*context_handle)->ctx_id_mutex);
- memset(*context_handle, 0, sizeof(**context_handle));
- free (*context_handle);
- *context_handle = GSS_C_NO_CONTEXT;
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ HEIMDAL_MUTEX_destroy(&ctx->ctx_id_mutex);
+ memset(ctx, 0, sizeof(*ctx));
+ free (ctx);
return GSS_S_COMPLETE;
}
diff --git a/source4/heimdal/lib/gssapi/display_name.c b/source4/heimdal/lib/gssapi/krb5/display_name.c
index 27a232fd3c..8fce7d8572 100644
--- a/source4/heimdal/lib/gssapi/display_name.c
+++ b/source4/heimdal/lib/gssapi/krb5/display_name.c
@@ -31,28 +31,27 @@
* SUCH DAMAGE.
*/
-#include "gssapi_locl.h"
+#include "krb5/gsskrb5_locl.h"
-RCSID("$Id: display_name.c,v 1.9 2003/03/16 17:46:11 lha Exp $");
+RCSID("$Id: display_name.c,v 1.12 2006/10/07 22:14:31 lha Exp $");
-OM_uint32 gss_display_name
+OM_uint32 _gsskrb5_display_name
(OM_uint32 * minor_status,
const gss_name_t input_name,
gss_buffer_t output_name_buffer,
gss_OID * output_name_type
)
{
+ krb5_const_principal name = (krb5_const_principal)input_name;
krb5_error_code kret;
char *buf;
size_t len;
GSSAPI_KRB5_INIT ();
- kret = krb5_unparse_name (gssapi_krb5_context,
- input_name,
- &buf);
+ kret = krb5_unparse_name (_gsskrb5_context, name, &buf);
if (kret) {
*minor_status = kret;
- gssapi_krb5_set_error_string ();
+ _gsskrb5_set_error_string ();
return GSS_S_FAILURE;
}
len = strlen (buf);
diff --git a/source4/heimdal/lib/gssapi/display_status.c b/source4/heimdal/lib/gssapi/krb5/display_status.c
index 0aa88bb57c..11926ca557 100644
--- a/source4/heimdal/lib/gssapi/display_status.c
+++ b/source4/heimdal/lib/gssapi/krb5/display_status.c
@@ -31,9 +31,9 @@
* SUCH DAMAGE.
*/
-#include "gssapi_locl.h"
+#include "krb5/gsskrb5_locl.h"
-RCSID("$Id: display_status.c,v 1.14 2005/10/12 07:23:03 lha Exp $");
+RCSID("$Id: display_status.c,v 1.16 2006/10/07 22:14:33 lha Exp $");
static const char *
calling_error(OM_uint32 v)
@@ -112,9 +112,9 @@ supplementary_error(OM_uint32 v)
}
void
-gssapi_krb5_clear_status (void)
+_gsskrb5_clear_status (void)
{
- struct gssapi_thr_context *ctx = gssapi_get_thread_context(1);
+ struct gssapi_thr_context *ctx = _gsskrb5_get_thread_context(1);
if (ctx == NULL)
return;
HEIMDAL_MUTEX_lock(&ctx->mutex);
@@ -125,9 +125,9 @@ gssapi_krb5_clear_status (void)
}
void
-gssapi_krb5_set_status (const char *fmt, ...)
+_gsskrb5_set_status (const char *fmt, ...)
{
- struct gssapi_thr_context *ctx = gssapi_get_thread_context(1);
+ struct gssapi_thr_context *ctx = _gsskrb5_get_thread_context(1);
va_list args;
if (ctx == NULL)
@@ -143,22 +143,22 @@ gssapi_krb5_set_status (const char *fmt, ...)
}
void
-gssapi_krb5_set_error_string (void)
+_gsskrb5_set_error_string (void)
{
char *e;
- e = krb5_get_error_string(gssapi_krb5_context);
+ e = krb5_get_error_string(_gsskrb5_context);
if (e) {
- gssapi_krb5_set_status("%s", e);
- krb5_free_error_string(gssapi_krb5_context, e);
+ _gsskrb5_set_status("%s", e);
+ krb5_free_error_string(_gsskrb5_context, e);
} else
- gssapi_krb5_clear_status();
+ _gsskrb5_clear_status();
}
char *
-gssapi_krb5_get_error_string (void)
+_gsskrb5_get_error_string (void)
{
- struct gssapi_thr_context *ctx = gssapi_get_thread_context(0);
+ struct gssapi_thr_context *ctx = _gsskrb5_get_thread_context(0);
char *ret;
if (ctx == NULL)
@@ -170,7 +170,7 @@ gssapi_krb5_get_error_string (void)
return ret;
}
-OM_uint32 gss_display_status
+OM_uint32 _gsskrb5_display_status
(OM_uint32 *minor_status,
OM_uint32 status_value,
int status_type,
@@ -200,9 +200,9 @@ OM_uint32 gss_display_status
calling_error(GSS_CALLING_ERROR(status_value)),
routine_error(GSS_ROUTINE_ERROR(status_value)));
} else if (status_type == GSS_C_MECH_CODE) {
- buf = gssapi_krb5_get_error_string ();
+ buf = _gsskrb5_get_error_string ();
if (buf == NULL) {
- const char *tmp = krb5_get_err_text (gssapi_krb5_context,
+ const char *tmp = krb5_get_err_text (_gsskrb5_context,
status_value);
if (tmp == NULL)
asprintf(&buf, "unknown mech error-code %u",
diff --git a/source4/heimdal/lib/gssapi/duplicate_name.c b/source4/heimdal/lib/gssapi/krb5/duplicate_name.c
index 2b54e90ec8..475ae61efc 100644
--- a/source4/heimdal/lib/gssapi/duplicate_name.c
+++ b/source4/heimdal/lib/gssapi/krb5/duplicate_name.c
@@ -31,26 +31,26 @@
* SUCH DAMAGE.
*/
-#include "gssapi_locl.h"
+#include "krb5/gsskrb5_locl.h"
-RCSID("$Id: duplicate_name.c,v 1.7 2003/03/16 17:44:26 lha Exp $");
+RCSID("$Id: duplicate_name.c,v 1.10 2006/10/07 22:14:35 lha Exp $");
-OM_uint32 gss_duplicate_name (
+OM_uint32 _gsskrb5_duplicate_name (
OM_uint32 * minor_status,
const gss_name_t src_name,
gss_name_t * dest_name
)
{
+ krb5_const_principal src = (krb5_const_principal)src_name;
+ krb5_principal *dest = (krb5_principal *)dest_name;
krb5_error_code kret;
GSSAPI_KRB5_INIT ();
- kret = krb5_copy_principal (gssapi_krb5_context,
- src_name,
- dest_name);
+ kret = krb5_copy_principal (_gsskrb5_context, src, dest);
if (kret) {
*minor_status = kret;
- gssapi_krb5_set_error_string ();
+ _gsskrb5_set_error_string ();
return GSS_S_FAILURE;
} else {
*minor_status = 0;
diff --git a/source4/heimdal/lib/gssapi/encapsulate.c b/source4/heimdal/lib/gssapi/krb5/encapsulate.c
index 4d488a6c42..a015a95103 100644
--- a/source4/heimdal/lib/gssapi/encapsulate.c
+++ b/source4/heimdal/lib/gssapi/krb5/encapsulate.c
@@ -31,9 +31,9 @@
* SUCH DAMAGE.
*/
-#include "gssapi_locl.h"
+#include "krb5/gsskrb5_locl.h"
-RCSID("$Id: encapsulate.c,v 1.8 2003/09/04 18:08:55 lha Exp $");
+RCSID("$Id: encapsulate.c,v 1.12 2006/10/14 10:02:56 lha Exp $");
void
_gssapi_encap_length (size_t data_len,
@@ -45,13 +45,13 @@ _gssapi_encap_length (size_t data_len,
*len = 1 + 1 + mech->length + data_len;
- len_len = length_len(*len);
+ len_len = der_length_len(*len);
*total_len = 1 + len_len + *len;
}
void
-gssapi_krb5_encap_length (size_t data_len,
+_gsskrb5_encap_length (size_t data_len,
size_t *len,
size_t *total_len,
const gss_OID mech)
@@ -59,28 +59,30 @@ gssapi_krb5_encap_length (size_t data_len,
_gssapi_encap_length(data_len + 2, len, total_len, mech);
}
-u_char *
-gssapi_krb5_make_header (u_char *p,
+void *
+_gsskrb5_make_header (void *ptr,
size_t len,
- const u_char *type,
+ const void *type,
const gss_OID mech)
{
+ u_char *p = ptr;
p = _gssapi_make_mech_header(p, len, mech);
memcpy (p, type, 2);
p += 2;
return p;
}
-u_char *
-_gssapi_make_mech_header(u_char *p,
+void *
+_gssapi_make_mech_header(void *ptr,
size_t len,
const gss_OID mech)
{
+ u_char *p = ptr;
int e;
size_t len_len, foo;
*p++ = 0x60;
- len_len = length_len(len);
+ len_len = der_length_len(len);
e = der_put_length (p + len_len - 1, len_len, len, &foo);
if(e || foo != len_len)
abort ();
@@ -105,7 +107,7 @@ _gssapi_encapsulate(
)
{
size_t len, outer_len;
- u_char *p;
+ void *p;
_gssapi_encap_length (in_data->length, &len, &outer_len, mech);
@@ -127,18 +129,18 @@ _gssapi_encapsulate(
*/
OM_uint32
-gssapi_krb5_encapsulate(
+_gsskrb5_encapsulate(
OM_uint32 *minor_status,
const krb5_data *in_data,
gss_buffer_t output_token,
- const u_char *type,
+ const void *type,
const gss_OID mech
)
{
size_t len, outer_len;
u_char *p;
- gssapi_krb5_encap_length (in_data->length, &len, &outer_len, mech);
+ _gsskrb5_encap_length (in_data->length, &len, &outer_len, mech);
output_token->length = outer_len;
output_token->value = malloc (outer_len);
@@ -147,7 +149,7 @@ gssapi_krb5_encapsulate(
return GSS_S_FAILURE;
}
- p = gssapi_krb5_make_header (output_token->value, len, type, mech);
+ p = _gsskrb5_make_header (output_token->value, len, type, mech);
memcpy (p, in_data->data, in_data->length);
return GSS_S_COMPLETE;
}
diff --git a/source4/heimdal/lib/gssapi/krb5/export_name.c b/source4/heimdal/lib/gssapi/krb5/export_name.c
new file mode 100644
index 0000000000..d00c458898
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/krb5/export_name.c
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 1997, 1999, 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 "krb5/gsskrb5_locl.h"
+
+RCSID("$Id: export_name.c,v 1.8 2006/10/07 22:14:40 lha Exp $");
+
+OM_uint32 _gsskrb5_export_name
+ (OM_uint32 * minor_status,
+ const gss_name_t input_name,
+ gss_buffer_t exported_name
+ )
+{
+ krb5_const_principal princ = (krb5_const_principal)input_name;
+ krb5_error_code kret;
+ char *buf, *name;
+ size_t len;
+
+ GSSAPI_KRB5_INIT ();
+ kret = krb5_unparse_name (_gsskrb5_context, princ, &name);
+ if (kret) {
+ *minor_status = kret;
+ _gsskrb5_set_error_string ();
+ return GSS_S_FAILURE;
+ }
+ len = strlen (name);
+
+ exported_name->length = 10 + len + GSS_KRB5_MECHANISM->length;
+ exported_name->value = malloc(exported_name->length);
+ if (exported_name->value == NULL) {
+ free (name);
+ *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] = ((GSS_KRB5_MECHANISM->length + 2) >> 8) & 0xff;
+ buf[1] = (GSS_KRB5_MECHANISM->length + 2) & 0xff;
+ buf+= 2;
+ buf[0] = 0x06;
+ buf[1] = (GSS_KRB5_MECHANISM->length) & 0xFF;
+ buf+= 2;
+
+ memcpy(buf, GSS_KRB5_MECHANISM->elements, GSS_KRB5_MECHANISM->length);
+ buf += GSS_KRB5_MECHANISM->length;
+
+ buf[0] = (len >> 24) & 0xff;
+ buf[1] = (len >> 16) & 0xff;
+ buf[2] = (len >> 8) & 0xff;
+ buf[3] = (len) & 0xff;
+ buf += 4;
+
+ memcpy (buf, name, len);
+
+ free (name);
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
diff --git a/source4/heimdal/lib/gssapi/krb5/export_sec_context.c b/source4/heimdal/lib/gssapi/krb5/export_sec_context.c
new file mode 100644
index 0000000000..aff03a0b67
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/krb5/export_sec_context.c
@@ -0,0 +1,239 @@
+/*
+ * Copyright (c) 1999 - 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 "krb5/gsskrb5_locl.h"
+
+RCSID("$Id: export_sec_context.c,v 1.11 2006/10/07 22:14:42 lha Exp $");
+
+OM_uint32
+_gsskrb5_export_sec_context (
+ OM_uint32 * minor_status,
+ gss_ctx_id_t * context_handle,
+ gss_buffer_t interprocess_token
+ )
+{
+ const gsskrb5_ctx ctx = (const gsskrb5_ctx) *context_handle;
+ krb5_storage *sp;
+ krb5_auth_context ac;
+ OM_uint32 ret = GSS_S_COMPLETE;
+ krb5_data data;
+ gss_buffer_desc buffer;
+ int flags;
+ OM_uint32 minor;
+ krb5_error_code kret;
+
+ GSSAPI_KRB5_INIT ();
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+
+ if (!(ctx->flags & GSS_C_TRANS_FLAG)) {
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ *minor_status = 0;
+ return GSS_S_UNAVAILABLE;
+ }
+
+ sp = krb5_storage_emem ();
+ if (sp == NULL) {
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ ac = ctx->auth_context;
+
+ /* flagging included fields */
+
+ flags = 0;
+ if (ac->local_address)
+ flags |= SC_LOCAL_ADDRESS;
+ if (ac->remote_address)
+ flags |= SC_REMOTE_ADDRESS;
+ if (ac->keyblock)
+ flags |= SC_KEYBLOCK;
+ if (ac->local_subkey)
+ flags |= SC_LOCAL_SUBKEY;
+ if (ac->remote_subkey)
+ flags |= SC_REMOTE_SUBKEY;
+
+ kret = krb5_store_int32 (sp, flags);
+ if (kret) {
+ *minor_status = kret;
+ goto failure;
+ }
+
+ /* marshall auth context */
+
+ kret = krb5_store_int32 (sp, ac->flags);
+ if (kret) {
+ *minor_status = kret;
+ goto failure;
+ }
+ if (ac->local_address) {
+ kret = krb5_store_address (sp, *ac->local_address);
+ if (kret) {
+ *minor_status = kret;
+ goto failure;
+ }
+ }
+ if (ac->remote_address) {
+ kret = krb5_store_address (sp, *ac->remote_address);
+ if (kret) {
+ *minor_status = kret;
+ goto failure;
+ }
+ }
+ kret = krb5_store_int16 (sp, ac->local_port);
+ if (kret) {
+ *minor_status = kret;
+ goto failure;
+ }
+ kret = krb5_store_int16 (sp, ac->remote_port);
+ if (kret) {
+ *minor_status = kret;
+ goto failure;
+ }
+ if (ac->keyblock) {
+ kret = krb5_store_keyblock (sp, *ac->keyblock);
+ if (kret) {
+ *minor_status = kret;
+ goto failure;
+ }
+ }
+ if (ac->local_subkey) {
+ kret = krb5_store_keyblock (sp, *ac->local_subkey);
+ if (kret) {
+ *minor_status = kret;
+ goto failure;
+ }
+ }
+ if (ac->remote_subkey) {
+ kret = krb5_store_keyblock (sp, *ac->remote_subkey);
+ if (kret) {
+ *minor_status = kret;
+ goto failure;
+ }
+ }
+ kret = krb5_store_int32 (sp, ac->local_seqnumber);
+ if (kret) {
+ *minor_status = kret;
+ goto failure;
+ }
+ kret = krb5_store_int32 (sp, ac->remote_seqnumber);
+ if (kret) {
+ *minor_status = kret;
+ goto failure;
+ }
+
+ kret = krb5_store_int32 (sp, ac->keytype);
+ if (kret) {
+ *minor_status = kret;
+ goto failure;
+ }
+ kret = krb5_store_int32 (sp, ac->cksumtype);
+ if (kret) {
+ *minor_status = kret;
+ goto failure;
+ }
+
+ /* names */
+
+ ret = _gsskrb5_export_name (minor_status,
+ (gss_name_t)ctx->source, &buffer);
+ if (ret)
+ goto failure;
+ data.data = buffer.value;
+ data.length = buffer.length;
+ kret = krb5_store_data (sp, data);
+ _gsskrb5_release_buffer (&minor, &buffer);
+ if (kret) {
+ *minor_status = kret;
+ goto failure;
+ }
+
+ ret = _gsskrb5_export_name (minor_status,
+ (gss_name_t)ctx->target, &buffer);
+ if (ret)
+ goto failure;
+ data.data = buffer.value;
+ data.length = buffer.length;
+
+ ret = GSS_S_FAILURE;
+
+ kret = krb5_store_data (sp, data);
+ _gsskrb5_release_buffer (&minor, &buffer);
+ if (kret) {
+ *minor_status = kret;
+ goto failure;
+ }
+
+ kret = krb5_store_int32 (sp, ctx->flags);
+ if (kret) {
+ *minor_status = kret;
+ goto failure;
+ }
+ kret = krb5_store_int32 (sp, ctx->more_flags);
+ if (kret) {
+ *minor_status = kret;
+ goto failure;
+ }
+ kret = krb5_store_int32 (sp, ctx->lifetime);
+ if (kret) {
+ *minor_status = kret;
+ goto failure;
+ }
+ kret = _gssapi_msg_order_export(sp, ctx->order);
+ if (kret ) {
+ *minor_status = kret;
+ goto failure;
+ }
+
+ kret = krb5_storage_to_data (sp, &data);
+ krb5_storage_free (sp);
+ if (kret) {
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+ interprocess_token->length = data.length;
+ interprocess_token->value = data.data;
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ ret = _gsskrb5_delete_sec_context (minor_status, context_handle,
+ GSS_C_NO_BUFFER);
+ if (ret != GSS_S_COMPLETE)
+ _gsskrb5_release_buffer (NULL, interprocess_token);
+ *minor_status = 0;
+ return ret;
+ failure:
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ krb5_storage_free (sp);
+ return ret;
+}
diff --git a/source4/heimdal/lib/gssapi/external.c b/source4/heimdal/lib/gssapi/krb5/external.c
index f8c1d23f98..7419bc2fe8 100644
--- a/source4/heimdal/lib/gssapi/external.c
+++ b/source4/heimdal/lib/gssapi/krb5/external.c
@@ -31,9 +31,10 @@
* SUCH DAMAGE.
*/
-#include "gssapi_locl.h"
+#include "krb5/gsskrb5_locl.h"
+#include <gssapi_mech.h>
-RCSID("$Id: external.c,v 1.7 2005/08/23 11:59:47 lha Exp $");
+RCSID("$Id: external.c,v 1.18 2006/10/20 21:50:24 lha Exp $");
/*
* The implementation must reserve static storage for a
@@ -226,18 +227,6 @@ static gss_OID_desc gss_krb5_mechanism_oid_desc =
gss_OID GSS_KRB5_MECHANISM = &gss_krb5_mechanism_oid_desc;
/*
- * RFC2478, SPNEGO:
- * The security mechanism of the initial
- * negotiation token is identified by the Object Identifier
- * iso.org.dod.internet.security.mechanism.snego (1.3.6.1.5.5.2).
- */
-
-static gss_OID_desc gss_spnego_mechanism_oid_desc =
-{6, rk_UNCONST("\x2b\x06\x01\x05\x05\x02")};
-
-gss_OID GSS_SPNEGO_MECHANISM = &gss_spnego_mechanism_oid_desc;
-
-/*
* draft-ietf-cat-iakerb-09, IAKERB:
* The mechanism ID for IAKERB proxy GSS-API Kerberos, in accordance
* with the mechanism proposed by SPNEGO [7] for negotiating protocol
@@ -261,7 +250,159 @@ static gss_OID_desc gss_iakerb_min_msg_mechanism_oid_desc =
gss_OID GSS_IAKERB_MIN_MSG_MECHANISM = &gss_iakerb_min_msg_mechanism_oid_desc;
/*
+ *
+ */
+
+static gss_OID_desc gss_c_peer_has_updated_spnego_oid_desc =
+{9, (void *)"\x2b\x06\x01\x04\x01\xa9\x4a\x13\x05"};
+
+gss_OID GSS_C_PEER_HAS_UPDATED_SPNEGO = &gss_c_peer_has_updated_spnego_oid_desc;
+
+/*
+ * 1.2.752.43.13 Heimdal GSS-API Extentions
+ */
+
+/* 1.2.752.43.13.1 */
+static gss_OID_desc gss_krb5_copy_ccache_x_oid_desc =
+{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x01")};
+
+gss_OID GSS_KRB5_COPY_CCACHE_X = &gss_krb5_copy_ccache_x_oid_desc;
+
+/* 1.2.752.43.13.2 */
+static gss_OID_desc gss_krb5_get_tkt_flags_x_oid_desc =
+{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x02")};
+
+gss_OID GSS_KRB5_GET_TKT_FLAGS_X = &gss_krb5_get_tkt_flags_x_oid_desc;
+
+/* 1.2.752.43.13.3 */
+static gss_OID_desc gss_krb5_extract_authz_data_from_sec_context_x_oid_desc =
+{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x03")};
+
+gss_OID GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_X = &gss_krb5_extract_authz_data_from_sec_context_x_oid_desc;
+
+/* 1.2.752.43.13.4 */
+static gss_OID_desc gss_krb5_compat_des3_mic_x_oid_desc =
+{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x04")};
+
+gss_OID GSS_KRB5_COMPAT_DES3_MIC_X = &gss_krb5_compat_des3_mic_x_oid_desc;
+
+/* 1.2.752.43.13.5 */
+static gss_OID_desc gss_krb5_register_acceptor_identity_x_desc =
+{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x05")};
+
+gss_OID GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_X = &gss_krb5_register_acceptor_identity_x_desc;
+
+/* 1.2.752.43.13.6 */
+static gss_OID_desc gss_krb5_export_lucid_context_x_desc =
+{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x06")};
+
+gss_OID GSS_KRB5_EXPORT_LUCID_CONTEXT_X = &gss_krb5_export_lucid_context_x_desc;
+
+/* 1.2.752.43.13.6.1 */
+static gss_OID_desc gss_krb5_export_lucid_context_v1_x_desc =
+{7, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x06\x01")};
+
+gss_OID GSS_KRB5_EXPORT_LUCID_CONTEXT_V1_X = &gss_krb5_export_lucid_context_v1_x_desc;
+
+/* 1.2.752.43.13.7 */
+static gss_OID_desc gss_krb5_set_dns_canonicalize_x_desc =
+{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x07")};
+
+gss_OID GSS_KRB5_SET_DNS_CANONICALIZE_X = &gss_krb5_set_dns_canonicalize_x_desc;
+
+/* 1.2.752.43.13.8 */
+static gss_OID_desc gss_krb5_get_subkey_x_desc =
+{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x08")};
+
+gss_OID GSS_KRB5_GET_SUBKEY_X = &gss_krb5_get_subkey_x_desc;
+
+/* 1.2.752.43.13.9 */
+static gss_OID_desc gss_krb5_get_initiator_subkey_x_desc =
+{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x09")};
+
+gss_OID GSS_KRB5_GET_INITIATOR_SUBKEY_X = &gss_krb5_get_initiator_subkey_x_desc;
+
+/* 1.2.752.43.13.10 */
+static gss_OID_desc gss_krb5_get_acceptor_subkey_x_desc =
+{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0a")};
+
+gss_OID GSS_KRB5_GET_ACCEPTOR_SUBKEY_X = &gss_krb5_get_acceptor_subkey_x_desc;
+
+/* 1.2.752.43.13.11 */
+static gss_OID_desc gss_krb5_send_to_kdc_x_desc =
+{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0b")};
+
+gss_OID GSS_KRB5_SEND_TO_KDC_X = &gss_krb5_send_to_kdc_x_desc;
+
+/* 1.2.752.43.13.12 */
+static gss_OID_desc gss_krb5_get_authtime_x_desc =
+{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0c")};
+
+gss_OID GSS_KRB5_GET_AUTHTIME_X = &gss_krb5_get_authtime_x_desc;
+
+/* 1.2.752.43.13.14 */
+static gss_OID_desc gss_krb5_get_service_keyblock_x_desc =
+{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0d")};
+
+gss_OID GSS_KRB5_GET_SERVICE_KEYBLOCK_X = &gss_krb5_get_service_keyblock_x_desc;
+
+/* 1.2.752.43.14.1 */
+static gss_OID_desc gss_sasl_digest_md5_mechanism_desc =
+{6, rk_UNCONST("\x2a\x85\x70\x2b\x0e\x01") };
+
+gss_OID GSS_SASL_DIGEST_MD5_MECHANISM = &gss_sasl_digest_md5_mechanism_desc;
+
+/*
* Context for krb5 calls.
*/
-krb5_context gssapi_krb5_context;
+krb5_context _gsskrb5_context;
+
+/*
+ *
+ */
+
+static gssapi_mech_interface_desc krb5_mech = {
+ GMI_VERSION,
+ "kerberos 5",
+ {9, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02" },
+ _gsskrb5_acquire_cred,
+ _gsskrb5_release_cred,
+ _gsskrb5_init_sec_context,
+ _gsskrb5_accept_sec_context,
+ _gsskrb5_process_context_token,
+ _gsskrb5_delete_sec_context,
+ _gsskrb5_context_time,
+ _gsskrb5_get_mic,
+ _gsskrb5_verify_mic,
+ _gsskrb5_wrap,
+ _gsskrb5_unwrap,
+ _gsskrb5_display_status,
+ _gsskrb5_indicate_mechs,
+ _gsskrb5_compare_name,
+ _gsskrb5_display_name,
+ _gsskrb5_import_name,
+ _gsskrb5_export_name,
+ _gsskrb5_release_name,
+ _gsskrb5_inquire_cred,
+ _gsskrb5_inquire_context,
+ _gsskrb5_wrap_size_limit,
+ _gsskrb5_add_cred,
+ _gsskrb5_inquire_cred_by_mech,
+ _gsskrb5_export_sec_context,
+ _gsskrb5_import_sec_context,
+ _gsskrb5_inquire_names_for_mech,
+ _gsskrb5_inquire_mechs_for_name,
+ _gsskrb5_canonicalize_name,
+ _gsskrb5_duplicate_name,
+ _gsskrb5_inquire_sec_context_by_oid,
+ _gsskrb5_inquire_cred_by_oid,
+ _gsskrb5_set_sec_context_option,
+ _gsskrb5_set_cred_option
+};
+
+gssapi_mech_interface
+__gss_krb5_initialize(void)
+{
+ return &krb5_mech;
+}
diff --git a/source4/heimdal/lib/gssapi/get_mic.c b/source4/heimdal/lib/gssapi/krb5/get_mic.c
index 76f69cf41c..5a078d634d 100644
--- a/source4/heimdal/lib/gssapi/get_mic.c
+++ b/source4/heimdal/lib/gssapi/krb5/get_mic.c
@@ -31,14 +31,14 @@
* SUCH DAMAGE.
*/
-#include "gssapi_locl.h"
+#include "krb5/gsskrb5_locl.h"
-RCSID("$Id: get_mic.c,v 1.31 2006/05/08 09:55:37 lha Exp $");
+RCSID("$Id: get_mic.c,v 1.34 2006/10/18 15:59:23 lha Exp $");
static OM_uint32
mic_des
(OM_uint32 * minor_status,
- const gss_ctx_id_t context_handle,
+ const gsskrb5_ctx ctx,
gss_qop_t qop_req,
const gss_buffer_t message_buffer,
gss_buffer_t message_token,
@@ -54,7 +54,7 @@ mic_des
int32_t seq_number;
size_t len, total_len;
- gssapi_krb5_encap_length (22, &len, &total_len, GSS_KRB5_MECHANISM);
+ _gsskrb5_encap_length (22, &len, &total_len, GSS_KRB5_MECHANISM);
message_token->length = total_len;
message_token->value = malloc (total_len);
@@ -64,7 +64,7 @@ mic_des
return GSS_S_FAILURE;
}
- p = gssapi_krb5_make_header(message_token->value,
+ p = _gsskrb5_make_header(message_token->value,
len,
"\x01\x01", /* TOK_ID */
GSS_KRB5_MECHANISM);
@@ -92,10 +92,10 @@ mic_des
&schedule, &zero);
memcpy (p - 8, hash, 8); /* SGN_CKSUM */
- HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
/* sequence number */
- krb5_auth_con_getlocalseqnumber (gssapi_krb5_context,
- context_handle->auth_context,
+ krb5_auth_con_getlocalseqnumber (_gsskrb5_context,
+ ctx->auth_context,
&seq_number);
p -= 16; /* SND_SEQ */
@@ -104,17 +104,17 @@ mic_des
p[2] = (seq_number >> 16) & 0xFF;
p[3] = (seq_number >> 24) & 0xFF;
memset (p + 4,
- (context_handle->more_flags & LOCAL) ? 0 : 0xFF,
+ (ctx->more_flags & LOCAL) ? 0 : 0xFF,
4);
DES_set_key (&deskey, &schedule);
DES_cbc_encrypt ((void *)p, (void *)p, 8,
&schedule, (DES_cblock *)(p + 8), DES_ENCRYPT);
- krb5_auth_con_setlocalseqnumber (gssapi_krb5_context,
- context_handle->auth_context,
+ krb5_auth_con_setlocalseqnumber (_gsskrb5_context,
+ ctx->auth_context,
++seq_number);
- HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
memset (deskey, 0, sizeof(deskey));
memset (&schedule, 0, sizeof(schedule));
@@ -126,7 +126,7 @@ mic_des
static OM_uint32
mic_des3
(OM_uint32 * minor_status,
- const gss_ctx_id_t context_handle,
+ const gsskrb5_ctx ctx,
gss_qop_t qop_req,
const gss_buffer_t message_buffer,
gss_buffer_t message_token,
@@ -146,7 +146,7 @@ mic_des3
char *tmp;
char ivec[8];
- gssapi_krb5_encap_length (36, &len, &total_len, GSS_KRB5_MECHANISM);
+ _gsskrb5_encap_length (36, &len, &total_len, GSS_KRB5_MECHANISM);
message_token->length = total_len;
message_token->value = malloc (total_len);
@@ -156,7 +156,7 @@ mic_des3
return GSS_S_FAILURE;
}
- p = gssapi_krb5_make_header(message_token->value,
+ p = _gsskrb5_make_header(message_token->value,
len,
"\x01\x01", /* TOK-ID */
GSS_KRB5_MECHANISM);
@@ -180,18 +180,18 @@ mic_des3
memcpy (tmp, p - 8, 8);
memcpy (tmp + 8, message_buffer->value, message_buffer->length);
- kret = krb5_crypto_init(gssapi_krb5_context, key, 0, &crypto);
+ kret = krb5_crypto_init(_gsskrb5_context, key, 0, &crypto);
if (kret) {
free (message_token->value);
message_token->value = NULL;
message_token->length = 0;
free (tmp);
- gssapi_krb5_set_error_string ();
+ _gsskrb5_set_error_string ();
*minor_status = kret;
return GSS_S_FAILURE;
}
- kret = krb5_create_checksum (gssapi_krb5_context,
+ kret = krb5_create_checksum (_gsskrb5_context,
crypto,
KRB5_KU_USAGE_SIGN,
0,
@@ -199,22 +199,22 @@ mic_des3
message_buffer->length + 8,
&cksum);
free (tmp);
- krb5_crypto_destroy (gssapi_krb5_context, crypto);
+ krb5_crypto_destroy (_gsskrb5_context, crypto);
if (kret) {
free (message_token->value);
message_token->value = NULL;
message_token->length = 0;
- gssapi_krb5_set_error_string ();
+ _gsskrb5_set_error_string ();
*minor_status = kret;
return GSS_S_FAILURE;
}
memcpy (p + 8, cksum.checksum.data, cksum.checksum.length);
- HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
/* sequence number */
- krb5_auth_con_getlocalseqnumber (gssapi_krb5_context,
- context_handle->auth_context,
+ krb5_auth_con_getlocalseqnumber (_gsskrb5_context,
+ ctx->auth_context,
&seq_number);
seq[0] = (seq_number >> 0) & 0xFF;
@@ -222,35 +222,35 @@ mic_des3
seq[2] = (seq_number >> 16) & 0xFF;
seq[3] = (seq_number >> 24) & 0xFF;
memset (seq + 4,
- (context_handle->more_flags & LOCAL) ? 0 : 0xFF,
+ (ctx->more_flags & LOCAL) ? 0 : 0xFF,
4);
- kret = krb5_crypto_init(gssapi_krb5_context, key,
+ kret = krb5_crypto_init(_gsskrb5_context, key,
ETYPE_DES3_CBC_NONE, &crypto);
if (kret) {
free (message_token->value);
message_token->value = NULL;
message_token->length = 0;
- gssapi_krb5_set_error_string ();
+ _gsskrb5_set_error_string ();
*minor_status = kret;
return GSS_S_FAILURE;
}
- if (context_handle->more_flags & COMPAT_OLD_DES3)
+ if (ctx->more_flags & COMPAT_OLD_DES3)
memset(ivec, 0, 8);
else
memcpy(ivec, p + 8, 8);
- kret = krb5_encrypt_ivec (gssapi_krb5_context,
+ kret = krb5_encrypt_ivec (_gsskrb5_context,
crypto,
KRB5_KU_USAGE_SEQ,
seq, 8, &encdata, ivec);
- krb5_crypto_destroy (gssapi_krb5_context, crypto);
+ krb5_crypto_destroy (_gsskrb5_context, crypto);
if (kret) {
free (message_token->value);
message_token->value = NULL;
message_token->length = 0;
- gssapi_krb5_set_error_string ();
+ _gsskrb5_set_error_string ();
*minor_status = kret;
return GSS_S_FAILURE;
}
@@ -260,17 +260,17 @@ mic_des3
memcpy (p, encdata.data, encdata.length);
krb5_data_free (&encdata);
- krb5_auth_con_setlocalseqnumber (gssapi_krb5_context,
- context_handle->auth_context,
+ krb5_auth_con_setlocalseqnumber (_gsskrb5_context,
+ ctx->auth_context,
++seq_number);
- HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
free_Checksum (&cksum);
*minor_status = 0;
return GSS_S_COMPLETE;
}
-OM_uint32 gss_get_mic
+OM_uint32 _gsskrb5_get_mic
(OM_uint32 * minor_status,
const gss_ctx_id_t context_handle,
gss_qop_t qop_req,
@@ -278,37 +278,40 @@ OM_uint32 gss_get_mic
gss_buffer_t message_token
)
{
+ const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle;
krb5_keyblock *key;
OM_uint32 ret;
krb5_keytype keytype;
- ret = gss_krb5_get_subkey(context_handle, &key);
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+ ret = _gsskrb5i_get_token_key(ctx, &key);
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
if (ret) {
- gssapi_krb5_set_error_string ();
+ _gsskrb5_set_error_string ();
*minor_status = ret;
return GSS_S_FAILURE;
}
- krb5_enctype_to_keytype (gssapi_krb5_context, key->keytype, &keytype);
+ krb5_enctype_to_keytype (_gsskrb5_context, key->keytype, &keytype);
switch (keytype) {
case KEYTYPE_DES :
- ret = mic_des (minor_status, context_handle, qop_req,
+ ret = mic_des (minor_status, ctx, qop_req,
message_buffer, message_token, key);
break;
case KEYTYPE_DES3 :
- ret = mic_des3 (minor_status, context_handle, qop_req,
+ ret = mic_des3 (minor_status, ctx, qop_req,
message_buffer, message_token, key);
break;
case KEYTYPE_ARCFOUR:
case KEYTYPE_ARCFOUR_56:
- ret = _gssapi_get_mic_arcfour (minor_status, context_handle, qop_req,
+ ret = _gssapi_get_mic_arcfour (minor_status, ctx, qop_req,
message_buffer, message_token, key);
break;
default :
- ret = _gssapi_mic_cfx (minor_status, context_handle, qop_req,
+ ret = _gssapi_mic_cfx (minor_status, ctx, qop_req,
message_buffer, message_token, key);
break;
}
- krb5_free_keyblock (gssapi_krb5_context, key);
+ krb5_free_keyblock (_gsskrb5_context, key);
return ret;
}
diff --git a/source4/heimdal/lib/gssapi/krb5/gsskrb5-private.h b/source4/heimdal/lib/gssapi/krb5/gsskrb5-private.h
new file mode 100644
index 0000000000..426c0ab200
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/krb5/gsskrb5-private.h
@@ -0,0 +1,705 @@
+/* This is a generated file */
+#ifndef __gsskrb5_private_h__
+#define __gsskrb5_private_h__
+
+#include <stdarg.h>
+
+gssapi_mech_interface
+__gss_krb5_initialize (void);
+
+OM_uint32
+__gsskrb5_ccache_lifetime (
+ OM_uint32 */*minor_status*/,
+ krb5_ccache /*id*/,
+ krb5_principal /*principal*/,
+ OM_uint32 */*lifetime*/);
+
+OM_uint32
+_gss_DES3_get_mic_compat (
+ OM_uint32 */*minor_status*/,
+ gsskrb5_ctx /*ctx*/);
+
+OM_uint32
+_gssapi_decapsulate (
+ OM_uint32 */*minor_status*/,
+ gss_buffer_t /*input_token_buffer*/,
+ krb5_data */*out_data*/,
+ const gss_OID mech );
+
+void
+_gssapi_encap_length (
+ size_t /*data_len*/,
+ size_t */*len*/,
+ size_t */*total_len*/,
+ const gss_OID /*mech*/);
+
+OM_uint32
+_gssapi_encapsulate (
+ OM_uint32 */*minor_status*/,
+ const krb5_data */*in_data*/,
+ gss_buffer_t /*output_token*/,
+ const gss_OID mech );
+
+OM_uint32
+_gssapi_get_mic_arcfour (
+ OM_uint32 * /*minor_status*/,
+ const gsskrb5_ctx /*context_handle*/,
+ gss_qop_t /*qop_req*/,
+ const gss_buffer_t /*message_buffer*/,
+ gss_buffer_t /*message_token*/,
+ krb5_keyblock */*key*/);
+
+void *
+_gssapi_make_mech_header (
+ void */*ptr*/,
+ size_t /*len*/,
+ const gss_OID /*mech*/);
+
+OM_uint32
+_gssapi_mic_cfx (
+ OM_uint32 */*minor_status*/,
+ const gsskrb5_ctx /*context_handle*/,
+ gss_qop_t /*qop_req*/,
+ const gss_buffer_t /*message_buffer*/,
+ gss_buffer_t /*message_token*/,
+ krb5_keyblock */*key*/);
+
+OM_uint32
+_gssapi_msg_order_check (
+ struct gss_msg_order */*o*/,
+ OM_uint32 /*seq_num*/);
+
+OM_uint32
+_gssapi_msg_order_create (
+ OM_uint32 */*minor_status*/,
+ struct gss_msg_order **/*o*/,
+ OM_uint32 /*flags*/,
+ OM_uint32 /*seq_num*/,
+ OM_uint32 /*jitter_window*/,
+ int /*use_64*/);
+
+OM_uint32
+_gssapi_msg_order_destroy (struct gss_msg_order **/*m*/);
+
+krb5_error_code
+_gssapi_msg_order_export (
+ krb5_storage */*sp*/,
+ struct gss_msg_order */*o*/);
+
+OM_uint32
+_gssapi_msg_order_f (OM_uint32 /*flags*/);
+
+OM_uint32
+_gssapi_msg_order_import (
+ OM_uint32 */*minor_status*/,
+ krb5_storage */*sp*/,
+ struct gss_msg_order **/*o*/);
+
+OM_uint32
+_gssapi_unwrap_arcfour (
+ OM_uint32 */*minor_status*/,
+ const gsskrb5_ctx /*context_handle*/,
+ const gss_buffer_t /*input_message_buffer*/,
+ gss_buffer_t /*output_message_buffer*/,
+ int */*conf_state*/,
+ gss_qop_t */*qop_state*/,
+ krb5_keyblock */*key*/);
+
+OM_uint32
+_gssapi_unwrap_cfx (
+ OM_uint32 */*minor_status*/,
+ const gsskrb5_ctx /*context_handle*/,
+ const gss_buffer_t /*input_message_buffer*/,
+ gss_buffer_t /*output_message_buffer*/,
+ int */*conf_state*/,
+ gss_qop_t */*qop_state*/,
+ krb5_keyblock */*key*/);
+
+OM_uint32
+_gssapi_verify_mech_header (
+ u_char **/*str*/,
+ size_t /*total_len*/,
+ gss_OID /*mech*/);
+
+OM_uint32
+_gssapi_verify_mic_arcfour (
+ OM_uint32 * /*minor_status*/,
+ const gsskrb5_ctx /*context_handle*/,
+ const gss_buffer_t /*message_buffer*/,
+ const gss_buffer_t /*token_buffer*/,
+ gss_qop_t * /*qop_state*/,
+ krb5_keyblock */*key*/,
+ char */*type*/);
+
+OM_uint32
+_gssapi_verify_mic_cfx (
+ OM_uint32 */*minor_status*/,
+ const gsskrb5_ctx /*context_handle*/,
+ const gss_buffer_t /*message_buffer*/,
+ const gss_buffer_t /*token_buffer*/,
+ gss_qop_t */*qop_state*/,
+ krb5_keyblock */*key*/);
+
+OM_uint32
+_gssapi_verify_pad (
+ gss_buffer_t /*wrapped_token*/,
+ size_t /*datalen*/,
+ size_t */*padlen*/);
+
+OM_uint32
+_gssapi_wrap_arcfour (
+ OM_uint32 * /*minor_status*/,
+ const gsskrb5_ctx /*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*/,
+ krb5_keyblock */*key*/);
+
+OM_uint32
+_gssapi_wrap_cfx (
+ OM_uint32 */*minor_status*/,
+ const gsskrb5_ctx /*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*/,
+ krb5_keyblock */*key*/);
+
+OM_uint32
+_gssapi_wrap_size_arcfour (
+ OM_uint32 */*minor_status*/,
+ const gsskrb5_ctx /*ctx*/,
+ int /*conf_req_flag*/,
+ gss_qop_t /*qop_req*/,
+ OM_uint32 /*req_output_size*/,
+ OM_uint32 */*max_input_size*/,
+ krb5_keyblock */*key*/);
+
+OM_uint32
+_gssapi_wrap_size_cfx (
+ OM_uint32 */*minor_status*/,
+ const gsskrb5_ctx /*context_handle*/,
+ int /*conf_req_flag*/,
+ gss_qop_t /*qop_req*/,
+ OM_uint32 /*req_output_size*/,
+ OM_uint32 */*max_input_size*/,
+ krb5_keyblock */*key*/);
+
+OM_uint32
+_gsskrb5_accept_sec_context (
+ OM_uint32 * /*minor_status*/,
+ gss_ctx_id_t * /*context_handle*/,
+ const gss_cred_id_t /*acceptor_cred_handle*/,
+ const gss_buffer_t /*input_token_buffer*/,
+ 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
+_gsskrb5_acquire_cred (
+ OM_uint32 * /*minor_status*/,
+ const gss_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 );
+
+OM_uint32
+_gsskrb5_add_cred (
+ OM_uint32 */*minor_status*/,
+ const gss_cred_id_t /*input_cred_handle*/,
+ const gss_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*/);
+
+OM_uint32
+_gsskrb5_add_oid_set_member (
+ OM_uint32 * /*minor_status*/,
+ const gss_OID /*member_oid*/,
+ gss_OID_set * oid_set );
+
+OM_uint32
+_gsskrb5_canonicalize_name (
+ OM_uint32 * /*minor_status*/,
+ const gss_name_t /*input_name*/,
+ const gss_OID /*mech_type*/,
+ gss_name_t * output_name );
+
+void
+_gsskrb5_clear_status (void);
+
+OM_uint32
+_gsskrb5_compare_name (
+ OM_uint32 * /*minor_status*/,
+ const gss_name_t /*name1*/,
+ const gss_name_t /*name2*/,
+ int * name_equal );
+
+OM_uint32
+_gsskrb5_context_time (
+ OM_uint32 * /*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ OM_uint32 * time_rec );
+
+OM_uint32
+_gsskrb5_create_8003_checksum (
+ OM_uint32 */*minor_status*/,
+ const gss_channel_bindings_t /*input_chan_bindings*/,
+ OM_uint32 /*flags*/,
+ const krb5_data */*fwd_data*/,
+ Checksum */*result*/);
+
+OM_uint32
+_gsskrb5_create_ctx (
+ OM_uint32 * /*minor_status*/,
+ gss_ctx_id_t * /*context_handle*/,
+ const gss_channel_bindings_t /*input_chan_bindings*/,
+ enum gss_ctx_id_t_state /*state*/);
+
+OM_uint32
+_gsskrb5_create_empty_oid_set (
+ OM_uint32 * /*minor_status*/,
+ gss_OID_set * oid_set );
+
+OM_uint32
+_gsskrb5_decapsulate (
+ OM_uint32 */*minor_status*/,
+ gss_buffer_t /*input_token_buffer*/,
+ krb5_data */*out_data*/,
+ const void */*type*/,
+ gss_OID /*oid*/);
+
+krb5_error_code
+_gsskrb5_decode_be_om_uint32 (
+ const void */*ptr*/,
+ OM_uint32 */*n*/);
+
+krb5_error_code
+_gsskrb5_decode_om_uint32 (
+ const void */*ptr*/,
+ OM_uint32 */*n*/);
+
+OM_uint32
+_gsskrb5_delete_sec_context (
+ OM_uint32 * /*minor_status*/,
+ gss_ctx_id_t * /*context_handle*/,
+ gss_buffer_t /*output_token*/);
+
+OM_uint32
+_gsskrb5_display_name (
+ OM_uint32 * /*minor_status*/,
+ const gss_name_t /*input_name*/,
+ gss_buffer_t /*output_name_buffer*/,
+ gss_OID * output_name_type );
+
+OM_uint32
+_gsskrb5_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
+_gsskrb5_duplicate_name (
+ OM_uint32 * /*minor_status*/,
+ const gss_name_t /*src_name*/,
+ gss_name_t * dest_name );
+
+void
+_gsskrb5_encap_length (
+ size_t /*data_len*/,
+ size_t */*len*/,
+ size_t */*total_len*/,
+ const gss_OID /*mech*/);
+
+OM_uint32
+_gsskrb5_encapsulate (
+ OM_uint32 */*minor_status*/,
+ const krb5_data */*in_data*/,
+ gss_buffer_t /*output_token*/,
+ const void */*type*/,
+ const gss_OID mech );
+
+krb5_error_code
+_gsskrb5_encode_be_om_uint32 (
+ OM_uint32 /*n*/,
+ u_char */*p*/);
+
+krb5_error_code
+_gsskrb5_encode_om_uint32 (
+ OM_uint32 /*n*/,
+ u_char */*p*/);
+
+OM_uint32
+_gsskrb5_export_name (
+ OM_uint32 * /*minor_status*/,
+ const gss_name_t /*input_name*/,
+ gss_buffer_t exported_name );
+
+OM_uint32
+_gsskrb5_export_sec_context (
+ OM_uint32 * /*minor_status*/,
+ gss_ctx_id_t * /*context_handle*/,
+ gss_buffer_t interprocess_token );
+
+char *
+_gsskrb5_get_error_string (void);
+
+ssize_t
+_gsskrb5_get_mech (
+ const u_char */*ptr*/,
+ size_t /*total_len*/,
+ const u_char **/*mech_ret*/);
+
+OM_uint32
+_gsskrb5_get_mic (
+ OM_uint32 * /*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ gss_qop_t /*qop_req*/,
+ const gss_buffer_t /*message_buffer*/,
+ gss_buffer_t message_token );
+
+struct gssapi_thr_context *
+_gsskrb5_get_thread_context (int /*createp*/);
+
+OM_uint32
+_gsskrb5_get_tkt_flags (
+ OM_uint32 */*minor_status*/,
+ gsskrb5_ctx /*ctx*/,
+ OM_uint32 */*tkt_flags*/);
+
+OM_uint32
+_gsskrb5_import_cred (
+ OM_uint32 */*minor_status*/,
+ krb5_ccache /*id*/,
+ krb5_principal /*keytab_principal*/,
+ krb5_keytab /*keytab*/,
+ gss_cred_id_t */*cred*/);
+
+OM_uint32
+_gsskrb5_import_name (
+ OM_uint32 * /*minor_status*/,
+ const gss_buffer_t /*input_name_buffer*/,
+ const gss_OID /*input_name_type*/,
+ gss_name_t * output_name );
+
+OM_uint32
+_gsskrb5_import_sec_context (
+ OM_uint32 * /*minor_status*/,
+ const gss_buffer_t /*interprocess_token*/,
+ gss_ctx_id_t * context_handle );
+
+OM_uint32
+_gsskrb5_indicate_mechs (
+ OM_uint32 * /*minor_status*/,
+ gss_OID_set * mech_set );
+
+krb5_error_code
+_gsskrb5_init (void);
+
+OM_uint32
+_gsskrb5_init_sec_context (
+ OM_uint32 * /*minor_status*/,
+ const gss_cred_id_t /*initiator_cred_handle*/,
+ gss_ctx_id_t * /*context_handle*/,
+ const gss_name_t /*target_name*/,
+ const gss_OID /*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
+_gsskrb5_inquire_context (
+ OM_uint32 * /*minor_status*/,
+ const gss_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 * open_context );
+
+OM_uint32
+_gsskrb5_inquire_cred (
+ OM_uint32 * /*minor_status*/,
+ const gss_cred_id_t /*cred_handle*/,
+ gss_name_t * /*output_name*/,
+ OM_uint32 * /*lifetime*/,
+ gss_cred_usage_t * /*cred_usage*/,
+ gss_OID_set * mechanisms );
+
+OM_uint32
+_gsskrb5_inquire_cred_by_mech (
+ OM_uint32 * /*minor_status*/,
+ const gss_cred_id_t /*cred_handle*/,
+ const gss_OID /*mech_type*/,
+ gss_name_t * /*name*/,
+ OM_uint32 * /*initiator_lifetime*/,
+ OM_uint32 * /*acceptor_lifetime*/,
+ gss_cred_usage_t * cred_usage );
+
+OM_uint32
+_gsskrb5_inquire_cred_by_oid (
+ OM_uint32 * /*minor_status*/,
+ const gss_cred_id_t /*cred_handle*/,
+ const gss_OID /*desired_object*/,
+ gss_buffer_set_t */*data_set*/);
+
+OM_uint32
+_gsskrb5_inquire_mechs_for_name (
+ OM_uint32 * /*minor_status*/,
+ const gss_name_t /*input_name*/,
+ gss_OID_set * mech_types );
+
+OM_uint32
+_gsskrb5_inquire_names_for_mech (
+ OM_uint32 * /*minor_status*/,
+ const gss_OID /*mechanism*/,
+ gss_OID_set * name_types );
+
+OM_uint32
+_gsskrb5_inquire_sec_context_by_oid (
+ OM_uint32 */*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ const gss_OID /*desired_object*/,
+ gss_buffer_set_t */*data_set*/);
+
+OM_uint32
+_gsskrb5_krb5_ccache_name (
+ OM_uint32 */*minor_status*/,
+ const char */*name*/,
+ const char **/*out_name*/);
+
+OM_uint32
+_gsskrb5_lifetime_left (
+ OM_uint32 */*minor_status*/,
+ OM_uint32 /*lifetime*/,
+ OM_uint32 */*lifetime_rec*/);
+
+void *
+_gsskrb5_make_header (
+ void */*ptr*/,
+ size_t /*len*/,
+ const void */*type*/,
+ const gss_OID /*mech*/);
+
+OM_uint32
+_gsskrb5_process_context_token (
+ OM_uint32 */*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ const gss_buffer_t token_buffer );
+
+OM_uint32
+_gsskrb5_register_acceptor_identity (const char */*identity*/);
+
+OM_uint32
+_gsskrb5_release_buffer (
+ OM_uint32 * /*minor_status*/,
+ gss_buffer_t buffer );
+
+OM_uint32
+_gsskrb5_release_cred (
+ OM_uint32 * /*minor_status*/,
+ gss_cred_id_t * cred_handle );
+
+OM_uint32
+_gsskrb5_release_name (
+ OM_uint32 * /*minor_status*/,
+ gss_name_t * input_name );
+
+OM_uint32
+_gsskrb5_release_oid_set (
+ OM_uint32 * /*minor_status*/,
+ gss_OID_set * set );
+
+OM_uint32
+_gsskrb5_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 );
+
+OM_uint32
+_gsskrb5_set_cred_option (
+ OM_uint32 */*minor_status*/,
+ gss_cred_id_t */*cred_handle*/,
+ const gss_OID /*desired_object*/,
+ const gss_buffer_t /*value*/);
+
+void
+_gsskrb5_set_error_string (void);
+
+OM_uint32
+_gsskrb5_set_sec_context_option (
+ OM_uint32 */*minor_status*/,
+ gss_ctx_id_t */*context_handle*/,
+ const gss_OID /*desired_object*/,
+ const gss_buffer_t /*value*/);
+
+void
+_gsskrb5_set_status (
+ const char */*fmt*/,
+ ...);
+
+OM_uint32
+_gsskrb5_sign (
+ OM_uint32 * /*minor_status*/,
+ gss_ctx_id_t /*context_handle*/,
+ int /*qop_req*/,
+ gss_buffer_t /*message_buffer*/,
+ gss_buffer_t message_token );
+
+OM_uint32
+_gsskrb5_test_oid_set_member (
+ OM_uint32 * /*minor_status*/,
+ const gss_OID /*member*/,
+ const gss_OID_set /*set*/,
+ int * present );
+
+OM_uint32
+_gsskrb5_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 );
+
+OM_uint32
+_gsskrb5_unwrap (
+ OM_uint32 * /*minor_status*/,
+ const gss_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 );
+
+OM_uint32
+_gsskrb5_verify (
+ OM_uint32 * /*minor_status*/,
+ gss_ctx_id_t /*context_handle*/,
+ gss_buffer_t /*message_buffer*/,
+ gss_buffer_t /*token_buffer*/,
+ int * qop_state );
+
+OM_uint32
+_gsskrb5_verify_8003_checksum (
+ OM_uint32 */*minor_status*/,
+ const gss_channel_bindings_t /*input_chan_bindings*/,
+ const Checksum */*cksum*/,
+ OM_uint32 */*flags*/,
+ krb5_data */*fwd_data*/);
+
+OM_uint32
+_gsskrb5_verify_header (
+ u_char **/*str*/,
+ size_t /*total_len*/,
+ const void */*type*/,
+ gss_OID /*oid*/);
+
+OM_uint32
+_gsskrb5_verify_mic (
+ OM_uint32 * /*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ const gss_buffer_t /*message_buffer*/,
+ const gss_buffer_t /*token_buffer*/,
+ gss_qop_t * qop_state );
+
+OM_uint32
+_gsskrb5_verify_mic_internal (
+ OM_uint32 * /*minor_status*/,
+ const gsskrb5_ctx /*context_handle*/,
+ const gss_buffer_t /*message_buffer*/,
+ const gss_buffer_t /*token_buffer*/,
+ gss_qop_t * /*qop_state*/,
+ char * type );
+
+OM_uint32
+_gsskrb5_wrap (
+ OM_uint32 * /*minor_status*/,
+ const gss_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 );
+
+OM_uint32
+_gsskrb5_wrap_size_limit (
+ OM_uint32 * /*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ int /*conf_req_flag*/,
+ gss_qop_t /*qop_req*/,
+ OM_uint32 /*req_output_size*/,
+ OM_uint32 * max_input_size );
+
+krb5_error_code
+_gsskrb5cfx_max_wrap_length_cfx (
+ krb5_crypto /*crypto*/,
+ int /*conf_req_flag*/,
+ size_t /*input_length*/,
+ OM_uint32 */*output_length*/);
+
+krb5_error_code
+_gsskrb5cfx_wrap_length_cfx (
+ krb5_crypto /*crypto*/,
+ int /*conf_req_flag*/,
+ size_t /*input_length*/,
+ size_t */*output_length*/,
+ size_t */*cksumsize*/,
+ uint16_t */*padlength*/);
+
+krb5_error_code
+_gsskrb5i_address_to_krb5addr (
+ OM_uint32 /*gss_addr_type*/,
+ gss_buffer_desc */*gss_addr*/,
+ int16_t /*port*/,
+ krb5_address */*address*/);
+
+krb5_error_code
+_gsskrb5i_get_acceptor_subkey (
+ const gsskrb5_ctx /*ctx*/,
+ krb5_keyblock **/*key*/);
+
+krb5_error_code
+_gsskrb5i_get_initiator_subkey (
+ const gsskrb5_ctx /*ctx*/,
+ krb5_keyblock **/*key*/);
+
+OM_uint32
+_gsskrb5i_get_token_key (
+ const gsskrb5_ctx /*ctx*/,
+ krb5_keyblock **/*key*/);
+
+void
+_gsskrb5i_is_cfx (
+ gsskrb5_ctx /*ctx*/,
+ int */*is_cfx*/);
+
+#endif /* __gsskrb5_private_h__ */
diff --git a/source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h b/source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h
new file mode 100644
index 0000000000..4d814032c3
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 1997 - 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: gsskrb5_locl.h,v 1.6 2006/10/07 22:14:49 lha Exp $ */
+
+#ifndef GSSKRB5_LOCL_H
+#define GSSKRB5_LOCL_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <krb5_locl.h>
+#include <gssapi.h>
+#include <gssapi_mech.h>
+#include <assert.h>
+
+#include "cfx.h"
+
+/*
+ *
+ */
+
+struct gss_msg_order;
+
+typedef struct {
+ struct krb5_auth_context_data *auth_context;
+ krb5_principal source, target;
+ OM_uint32 flags;
+ enum { LOCAL = 1, OPEN = 2,
+ COMPAT_OLD_DES3 = 4,
+ COMPAT_OLD_DES3_SELECTED = 8,
+ ACCEPTOR_SUBKEY = 16
+ } more_flags;
+ enum gss_ctx_id_t_state {
+ /* initiator states */
+ INITIATOR_START,
+ INITIATOR_WAIT_FOR_MUTAL,
+ INITIATOR_READY,
+ /* acceptor states */
+ ACCEPTOR_START,
+ ACCEPTOR_WAIT_FOR_DCESTYLE,
+ ACCEPTOR_READY
+ } state;
+ struct krb5_ticket *ticket;
+ OM_uint32 lifetime;
+ HEIMDAL_MUTEX ctx_id_mutex;
+ struct gss_msg_order *order;
+ krb5_keyblock *service_keyblock;
+ krb5_data fwd_data;
+} *gsskrb5_ctx;
+
+typedef struct {
+ krb5_principal principal;
+ int cred_flags;
+#define GSS_CF_DESTROY_CRED_ON_RELEASE 1
+ struct krb5_keytab_data *keytab;
+ OM_uint32 lifetime;
+ gss_cred_usage_t usage;
+ gss_OID_set mechanisms;
+ struct krb5_ccache_data *ccache;
+ HEIMDAL_MUTEX cred_id_mutex;
+} *gsskrb5_cred;
+
+typedef struct Principal *gsskrb5_name;
+
+/*
+ *
+ */
+
+extern krb5_context _gsskrb5_context;
+
+extern krb5_keytab _gsskrb5_keytab;
+extern HEIMDAL_MUTEX gssapi_keytab_mutex;
+
+struct gssapi_thr_context {
+ HEIMDAL_MUTEX mutex;
+ char *error_string;
+};
+
+/*
+ * Prototypes
+ */
+
+#include <krb5/gsskrb5-private.h>
+
+#define GSSAPI_KRB5_INIT() do { \
+ krb5_error_code kret_gss_init; \
+ if((kret_gss_init = _gsskrb5_init ()) != 0) { \
+ *minor_status = kret_gss_init; \
+ return GSS_S_FAILURE; \
+ } \
+} while (0)
+
+/* sec_context flags */
+
+#define SC_LOCAL_ADDRESS 0x01
+#define SC_REMOTE_ADDRESS 0x02
+#define SC_KEYBLOCK 0x04
+#define SC_LOCAL_SUBKEY 0x08
+#define SC_REMOTE_SUBKEY 0x10
+
+#endif
diff --git a/source4/heimdal/lib/gssapi/import_name.c b/source4/heimdal/lib/gssapi/krb5/import_name.c
index d393aa1a51..dc24ed5cf2 100644
--- a/source4/heimdal/lib/gssapi/import_name.c
+++ b/source4/heimdal/lib/gssapi/krb5/import_name.c
@@ -31,30 +31,31 @@
* SUCH DAMAGE.
*/
-#include "gssapi_locl.h"
+#include "krb5/gsskrb5_locl.h"
-RCSID("$Id: import_name.c,v 1.14 2006/02/15 11:59:10 lha Exp $");
+RCSID("$Id: import_name.c,v 1.17 2006/10/07 22:14:51 lha Exp $");
static OM_uint32
parse_krb5_name (OM_uint32 *minor_status,
const char *name,
gss_name_t *output_name)
{
+ krb5_principal princ;
krb5_error_code kerr;
- kerr = krb5_parse_name (gssapi_krb5_context, name, output_name);
+ kerr = krb5_parse_name (_gsskrb5_context, name, &princ);
- if (kerr == 0)
+ if (kerr == 0) {
+ *output_name = (gss_name_t)princ;
return GSS_S_COMPLETE;
- else if (kerr == KRB5_PARSE_ILLCHAR || kerr == KRB5_PARSE_MALFORMED) {
- gssapi_krb5_set_error_string ();
- *minor_status = kerr;
- return GSS_S_BAD_NAME;
- } else {
- gssapi_krb5_set_error_string ();
- *minor_status = kerr;
- return GSS_S_FAILURE;
}
+ _gsskrb5_set_error_string ();
+ *minor_status = kerr;
+
+ if (kerr == KRB5_PARSE_ILLCHAR || kerr == KRB5_PARSE_MALFORMED)
+ return GSS_S_BAD_NAME;
+
+ return GSS_S_FAILURE;
}
static OM_uint32
@@ -91,8 +92,7 @@ import_hostbased_name (OM_uint32 *minor_status,
char *p;
char *host;
char local_hostname[MAXHOSTNAMELEN];
-
- *output_name = NULL;
+ krb5_principal princ = NULL;
tmp = malloc (input_name_buffer->length + 1);
if (tmp == NULL) {
@@ -117,24 +117,24 @@ import_hostbased_name (OM_uint32 *minor_status,
host = local_hostname;
}
- kerr = krb5_sname_to_principal (gssapi_krb5_context,
+ kerr = krb5_sname_to_principal (_gsskrb5_context,
host,
tmp,
KRB5_NT_SRV_HST,
- output_name);
+ &princ);
free (tmp);
*minor_status = kerr;
- if (kerr == 0)
+ if (kerr == 0) {
+ *output_name = (gss_name_t)princ;
return GSS_S_COMPLETE;
- else if (kerr == KRB5_PARSE_ILLCHAR || kerr == KRB5_PARSE_MALFORMED) {
- gssapi_krb5_set_error_string ();
+ }
+ _gsskrb5_set_error_string ();
*minor_status = kerr;
+
+ if (kerr == KRB5_PARSE_ILLCHAR || kerr == KRB5_PARSE_MALFORMED)
return GSS_S_BAD_NAME;
- } else {
- gssapi_krb5_set_error_string ();
- *minor_status = kerr;
- return GSS_S_FAILURE;
- }
+
+ return GSS_S_FAILURE;
}
static OM_uint32
@@ -184,18 +184,7 @@ import_export_name (OM_uint32 *minor_status,
return ret;
}
-int
-gss_oid_equal(const gss_OID a, const gss_OID b)
-{
- if (a == b)
- return 1;
- else if (a == GSS_C_NO_OID || b == GSS_C_NO_OID || a->length != b->length)
- return 0;
- else
- return memcmp(a->elements, b->elements, a->length) == 0;
-}
-
-OM_uint32 gss_import_name
+OM_uint32 _gsskrb5_import_name
(OM_uint32 * minor_status,
const gss_buffer_t input_name_buffer,
const gss_OID input_name_type,
diff --git a/source4/heimdal/lib/gssapi/krb5/import_sec_context.c b/source4/heimdal/lib/gssapi/krb5/import_sec_context.c
new file mode 100644
index 0000000000..8131e2621d
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/krb5/import_sec_context.c
@@ -0,0 +1,229 @@
+/*
+ * Copyright (c) 1999 - 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 "krb5/gsskrb5_locl.h"
+
+RCSID("$Id: import_sec_context.c,v 1.17 2006/10/07 22:14:53 lha Exp $");
+
+OM_uint32
+_gsskrb5_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;
+ krb5_error_code kret;
+ krb5_storage *sp;
+ krb5_auth_context ac;
+ krb5_address local, remote;
+ krb5_address *localp, *remotep;
+ krb5_data data;
+ gss_buffer_desc buffer;
+ krb5_keyblock keyblock;
+ int32_t tmp;
+ int32_t flags;
+ gsskrb5_ctx ctx;
+ gss_name_t name;
+
+ GSSAPI_KRB5_INIT ();
+
+ *context_handle = GSS_C_NO_CONTEXT;
+
+ localp = remotep = NULL;
+
+ sp = krb5_storage_from_mem (interprocess_token->value,
+ interprocess_token->length);
+ if (sp == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ ctx = calloc(1, sizeof(*ctx));
+ if (ctx == NULL) {
+ *minor_status = ENOMEM;
+ krb5_storage_free (sp);
+ return GSS_S_FAILURE;
+ }
+ HEIMDAL_MUTEX_init(&ctx->ctx_id_mutex);
+
+ kret = krb5_auth_con_init (_gsskrb5_context,
+ &ctx->auth_context);
+ if (kret) {
+ _gsskrb5_set_error_string ();
+ *minor_status = kret;
+ ret = GSS_S_FAILURE;
+ goto failure;
+ }
+
+ /* flags */
+
+ *minor_status = 0;
+
+ if (krb5_ret_int32 (sp, &flags) != 0)
+ goto failure;
+
+ /* retrieve the auth context */
+
+ ac = ctx->auth_context;
+ if (krb5_ret_uint32 (sp, &ac->flags) != 0)
+ goto failure;
+ if (flags & SC_LOCAL_ADDRESS) {
+ if (krb5_ret_address (sp, localp = &local) != 0)
+ goto failure;
+ }
+
+ if (flags & SC_REMOTE_ADDRESS) {
+ if (krb5_ret_address (sp, remotep = &remote) != 0)
+ goto failure;
+ }
+
+ krb5_auth_con_setaddrs (_gsskrb5_context, ac, localp, remotep);
+ if (localp)
+ krb5_free_address (_gsskrb5_context, localp);
+ if (remotep)
+ krb5_free_address (_gsskrb5_context, remotep);
+ localp = remotep = NULL;
+
+ if (krb5_ret_int16 (sp, &ac->local_port) != 0)
+ goto failure;
+
+ if (krb5_ret_int16 (sp, &ac->remote_port) != 0)
+ goto failure;
+ if (flags & SC_KEYBLOCK) {
+ if (krb5_ret_keyblock (sp, &keyblock) != 0)
+ goto failure;
+ krb5_auth_con_setkey (_gsskrb5_context, ac, &keyblock);
+ krb5_free_keyblock_contents (_gsskrb5_context, &keyblock);
+ }
+ if (flags & SC_LOCAL_SUBKEY) {
+ if (krb5_ret_keyblock (sp, &keyblock) != 0)
+ goto failure;
+ krb5_auth_con_setlocalsubkey (_gsskrb5_context, ac, &keyblock);
+ krb5_free_keyblock_contents (_gsskrb5_context, &keyblock);
+ }
+ if (flags & SC_REMOTE_SUBKEY) {
+ if (krb5_ret_keyblock (sp, &keyblock) != 0)
+ goto failure;
+ krb5_auth_con_setremotesubkey (_gsskrb5_context, ac, &keyblock);
+ krb5_free_keyblock_contents (_gsskrb5_context, &keyblock);
+ }
+ if (krb5_ret_uint32 (sp, &ac->local_seqnumber))
+ goto failure;
+ if (krb5_ret_uint32 (sp, &ac->remote_seqnumber))
+ goto failure;
+
+ if (krb5_ret_int32 (sp, &tmp) != 0)
+ goto failure;
+ ac->keytype = tmp;
+ if (krb5_ret_int32 (sp, &tmp) != 0)
+ goto failure;
+ ac->cksumtype = tmp;
+
+ /* names */
+
+ if (krb5_ret_data (sp, &data))
+ goto failure;
+ buffer.value = data.data;
+ buffer.length = data.length;
+
+ ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NT_EXPORT_NAME,
+ &name);
+ if (ret) {
+ ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NO_OID,
+ &name);
+ if (ret) {
+ krb5_data_free (&data);
+ goto failure;
+ }
+ }
+ ctx->source = (krb5_principal)name;
+ krb5_data_free (&data);
+
+ if (krb5_ret_data (sp, &data) != 0)
+ goto failure;
+ buffer.value = data.data;
+ buffer.length = data.length;
+
+ ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NT_EXPORT_NAME,
+ &name);
+ if (ret) {
+ ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NO_OID,
+ &name);
+ if (ret) {
+ krb5_data_free (&data);
+ goto failure;
+ }
+ }
+ ctx->target = (krb5_principal)name;
+ krb5_data_free (&data);
+
+ if (krb5_ret_int32 (sp, &tmp))
+ goto failure;
+ ctx->flags = tmp;
+ if (krb5_ret_int32 (sp, &tmp))
+ goto failure;
+ ctx->more_flags = tmp;
+ if (krb5_ret_int32 (sp, &tmp))
+ goto failure;
+ ctx->lifetime = tmp;
+
+ ret = _gssapi_msg_order_import(minor_status, sp, &ctx->order);
+ if (ret)
+ goto failure;
+
+ krb5_storage_free (sp);
+
+ *context_handle = (gss_ctx_id_t)ctx;
+
+ return GSS_S_COMPLETE;
+
+failure:
+ krb5_auth_con_free (_gsskrb5_context,
+ ctx->auth_context);
+ if (ctx->source != NULL)
+ krb5_free_principal(_gsskrb5_context, ctx->source);
+ if (ctx->target != NULL)
+ krb5_free_principal(_gsskrb5_context, ctx->target);
+ if (localp)
+ krb5_free_address (_gsskrb5_context, localp);
+ if (remotep)
+ krb5_free_address (_gsskrb5_context, remotep);
+ if(ctx->order)
+ _gssapi_msg_order_destroy(&ctx->order);
+ HEIMDAL_MUTEX_destroy(&ctx->ctx_id_mutex);
+ krb5_storage_free (sp);
+ free (ctx);
+ *context_handle = GSS_C_NO_CONTEXT;
+ return ret;
+}
diff --git a/source4/heimdal/lib/gssapi/krb5/indicate_mechs.c b/source4/heimdal/lib/gssapi/krb5/indicate_mechs.c
new file mode 100644
index 0000000000..3827533219
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/krb5/indicate_mechs.c
@@ -0,0 +1,58 @@
+/*
+ * 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 "krb5/gsskrb5_locl.h"
+
+RCSID("$Id: indicate_mechs.c,v 1.9 2006/10/07 22:14:56 lha Exp $");
+
+OM_uint32 _gsskrb5_indicate_mechs
+ (OM_uint32 * minor_status,
+ gss_OID_set * mech_set
+ )
+{
+ OM_uint32 ret, junk;
+
+ ret = _gsskrb5_create_empty_oid_set(minor_status, mech_set);
+ if (ret)
+ return ret;
+
+ ret = _gsskrb5_add_oid_set_member(minor_status,
+ GSS_KRB5_MECHANISM, mech_set);
+ if (ret) {
+ _gsskrb5_release_oid_set(&junk, mech_set);
+ return ret;
+ }
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
diff --git a/source4/heimdal/lib/gssapi/init.c b/source4/heimdal/lib/gssapi/krb5/init.c
index 11d7c9bb9f..cbef8740b7 100644
--- a/source4/heimdal/lib/gssapi/init.c
+++ b/source4/heimdal/lib/gssapi/krb5/init.c
@@ -31,15 +31,11 @@
* SUCH DAMAGE.
*/
-#include "gssapi_locl.h"
+#include "krb5/gsskrb5_locl.h"
-RCSID("$Id: init.c,v 1.7 2003/07/22 19:50:11 lha Exp $");
+RCSID("$Id: init.c,v 1.9 2006/10/07 22:14:58 lha Exp $");
-#ifdef _SAMBA_BUILD_
-#include "auth/kerberos/krb5_init_context.h"
-#endif
-
-static HEIMDAL_MUTEX gssapi_krb5_context_mutex = HEIMDAL_MUTEX_INITIALIZER;
+static HEIMDAL_MUTEX _gsskrb5_context_mutex = HEIMDAL_MUTEX_INITIALIZER;
static int created_key;
static HEIMDAL_thread_key gssapi_context_key;
@@ -58,12 +54,12 @@ gssapi_destroy_thread_context(void *ptr)
struct gssapi_thr_context *
-gssapi_get_thread_context(int createp)
+_gsskrb5_get_thread_context(int createp)
{
struct gssapi_thr_context *ctx;
int ret;
- HEIMDAL_MUTEX_lock(&gssapi_krb5_context_mutex);
+ HEIMDAL_MUTEX_lock(&_gsskrb5_context_mutex);
if (!created_key)
abort();
@@ -80,72 +76,36 @@ gssapi_get_thread_context(int createp)
if (ret)
goto fail;
}
- HEIMDAL_MUTEX_unlock(&gssapi_krb5_context_mutex);
+ HEIMDAL_MUTEX_unlock(&_gsskrb5_context_mutex);
return ctx;
fail:
- HEIMDAL_MUTEX_unlock(&gssapi_krb5_context_mutex);
+ HEIMDAL_MUTEX_unlock(&_gsskrb5_context_mutex);
if (ctx)
free(ctx);
return NULL;
}
-#ifdef _SAMBA_BUILD_
-/* Init krb5 with an event context. Disgusting Samba-specific hack */
-
-krb5_error_code
-gssapi_krb5_init_ev (void *event_context)
+krb5_error_code
+_gsskrb5_init (void)
{
- static struct smb_krb5_context *smb_krb5_context;
krb5_error_code ret = 0;
- HEIMDAL_MUTEX_lock(&gssapi_krb5_context_mutex);
+ HEIMDAL_MUTEX_lock(&_gsskrb5_context_mutex);
- if(smb_krb5_context == NULL) {
- ret = smb_krb5_init_context(event_context, &smb_krb5_context);
- }
+ if(_gsskrb5_context == NULL)
+ ret = krb5_init_context (&_gsskrb5_context);
if (ret == 0 && !created_key) {
HEIMDAL_key_create(&gssapi_context_key,
gssapi_destroy_thread_context,
ret);
if (ret) {
- smb_krb5_free_context(smb_krb5_context);
- smb_krb5_context = NULL;
+ krb5_free_context(_gsskrb5_context);
+ _gsskrb5_context = NULL;
} else
created_key = 1;
}
- if (ret == 0) {
- gssapi_krb5_context = smb_krb5_context->krb5_context;
- }
- HEIMDAL_MUTEX_unlock(&gssapi_krb5_context_mutex);
- return ret;
-}
-#endif
-
-krb5_error_code
-gssapi_krb5_init (void)
-{
- krb5_error_code ret = 0;
-#ifdef _SAMBA_BUILD_
- ret = gssapi_krb5_init_ev(NULL);
-#else
- HEIMDAL_MUTEX_lock(&gssapi_krb5_context_mutex);
-
- if(gssapi_krb5_context == NULL) {
- ret = krb5_init_context (&gssapi_krb5_context);
- }
- if (ret == 0 && !created_key) {
- HEIMDAL_key_create(&gssapi_context_key,
- gssapi_destroy_thread_context,
- ret);
- if (ret) {
- krb5_free_context(gssapi_krb5_context);
- gssapi_krb5_context = NULL;
- } else
- created_key = 1;
- }
+ HEIMDAL_MUTEX_unlock(&_gsskrb5_context_mutex);
- HEIMDAL_MUTEX_unlock(&gssapi_krb5_context_mutex);
-#endif
return ret;
}
diff --git a/source4/heimdal/lib/gssapi/krb5/init_sec_context.c b/source4/heimdal/lib/gssapi/krb5/init_sec_context.c
new file mode 100644
index 0000000000..00f2543833
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/krb5/init_sec_context.c
@@ -0,0 +1,789 @@
+/*
+ * Copyright (c) 1997 - 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 "krb5/gsskrb5_locl.h"
+
+RCSID("$Id: init_sec_context.c,v 1.72 2006/10/24 23:03:19 lha Exp $");
+
+/*
+ * copy the addresses from `input_chan_bindings' (if any) to
+ * the auth context `ac'
+ */
+
+static OM_uint32
+set_addresses (krb5_auth_context ac,
+ const gss_channel_bindings_t input_chan_bindings)
+{
+ /* Port numbers are expected to be in application_data.value,
+ * initator's port first */
+
+ krb5_address initiator_addr, acceptor_addr;
+ krb5_error_code kret;
+
+ if (input_chan_bindings == GSS_C_NO_CHANNEL_BINDINGS
+ || input_chan_bindings->application_data.length !=
+ 2 * sizeof(ac->local_port))
+ return 0;
+
+ memset(&initiator_addr, 0, sizeof(initiator_addr));
+ memset(&acceptor_addr, 0, sizeof(acceptor_addr));
+
+ ac->local_port =
+ *(int16_t *) input_chan_bindings->application_data.value;
+
+ ac->remote_port =
+ *((int16_t *) input_chan_bindings->application_data.value + 1);
+
+ kret = _gsskrb5i_address_to_krb5addr(input_chan_bindings->acceptor_addrtype,
+ &input_chan_bindings->acceptor_address,
+ ac->remote_port,
+ &acceptor_addr);
+ if (kret)
+ return kret;
+
+ kret = _gsskrb5i_address_to_krb5addr(input_chan_bindings->initiator_addrtype,
+ &input_chan_bindings->initiator_address,
+ ac->local_port,
+ &initiator_addr);
+ if (kret) {
+ krb5_free_address (_gsskrb5_context, &acceptor_addr);
+ return kret;
+ }
+
+ kret = krb5_auth_con_setaddrs(_gsskrb5_context,
+ ac,
+ &initiator_addr, /* local address */
+ &acceptor_addr); /* remote address */
+
+ krb5_free_address (_gsskrb5_context, &initiator_addr);
+ krb5_free_address (_gsskrb5_context, &acceptor_addr);
+
+#if 0
+ free(input_chan_bindings->application_data.value);
+ input_chan_bindings->application_data.value = NULL;
+ input_chan_bindings->application_data.length = 0;
+#endif
+
+ return kret;
+}
+
+OM_uint32
+_gsskrb5_create_ctx(
+ OM_uint32 * minor_status,
+ gss_ctx_id_t * context_handle,
+ const gss_channel_bindings_t input_chan_bindings,
+ enum gss_ctx_id_t_state state)
+{
+ krb5_error_code kret;
+ gsskrb5_ctx ctx;
+
+ *context_handle = NULL;
+
+ ctx = malloc(sizeof(*ctx));
+ if (ctx == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ ctx->auth_context = NULL;
+ ctx->source = NULL;
+ ctx->target = NULL;
+ ctx->state = state;
+ ctx->flags = 0;
+ ctx->more_flags = 0;
+ ctx->service_keyblock = NULL;
+ ctx->ticket = NULL;
+ krb5_data_zero(&ctx->fwd_data);
+ ctx->lifetime = GSS_C_INDEFINITE;
+ ctx->order = NULL;
+ HEIMDAL_MUTEX_init(&ctx->ctx_id_mutex);
+
+ kret = krb5_auth_con_init (_gsskrb5_context, &ctx->auth_context);
+ if (kret) {
+ *minor_status = kret;
+ _gsskrb5_set_error_string ();
+
+ HEIMDAL_MUTEX_destroy(&ctx->ctx_id_mutex);
+
+ return GSS_S_FAILURE;
+ }
+
+ kret = set_addresses(ctx->auth_context, input_chan_bindings);
+ if (kret) {
+ *minor_status = kret;
+
+ HEIMDAL_MUTEX_destroy(&ctx->ctx_id_mutex);
+
+ krb5_auth_con_free(_gsskrb5_context, ctx->auth_context);
+
+ return GSS_S_BAD_BINDINGS;
+ }
+
+ /*
+ * We need a sequence number
+ */
+
+ krb5_auth_con_addflags(_gsskrb5_context,
+ ctx->auth_context,
+ KRB5_AUTH_CONTEXT_DO_SEQUENCE |
+ KRB5_AUTH_CONTEXT_CLEAR_FORWARDED_CRED,
+ NULL);
+
+ *context_handle = (gss_ctx_id_t)ctx;
+
+ return GSS_S_COMPLETE;
+}
+
+
+static OM_uint32
+gsskrb5_get_creds(
+ OM_uint32 * minor_status,
+ krb5_ccache ccache,
+ gsskrb5_ctx ctx,
+ krb5_const_principal target_name,
+ OM_uint32 time_req,
+ OM_uint32 * time_rec,
+ krb5_creds ** cred)
+{
+ OM_uint32 ret;
+ krb5_error_code kret;
+ krb5_creds this_cred;
+ OM_uint32 lifetime_rec;
+
+ *cred = NULL;
+
+ memset(&this_cred, 0, sizeof(this_cred));
+ this_cred.client = ctx->source;
+ this_cred.server = ctx->target;
+
+ if (time_req && time_req != GSS_C_INDEFINITE) {
+ krb5_timestamp ts;
+
+ krb5_timeofday (_gsskrb5_context, &ts);
+ this_cred.times.endtime = ts + time_req;
+ } else {
+ this_cred.times.endtime = 0;
+ }
+
+ this_cred.session.keytype = KEYTYPE_NULL;
+
+ kret = krb5_get_credentials(_gsskrb5_context,
+ 0,
+ ccache,
+ &this_cred,
+ cred);
+ if (kret) {
+ _gsskrb5_set_error_string ();
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+
+ ctx->lifetime = (*cred)->times.endtime;
+
+ ret = _gsskrb5_lifetime_left(minor_status, ctx->lifetime, &lifetime_rec);
+ if (ret) return ret;
+
+ if (lifetime_rec == 0) {
+ *minor_status = 0;
+ return GSS_S_CONTEXT_EXPIRED;
+ }
+
+ if (time_rec) *time_rec = lifetime_rec;
+
+ return GSS_S_COMPLETE;
+}
+
+static OM_uint32
+gsskrb5_initiator_ready(
+ OM_uint32 * minor_status,
+ gsskrb5_ctx ctx)
+{
+ OM_uint32 ret;
+ int32_t seq_number;
+ int is_cfx = 0;
+ OM_uint32 flags = ctx->flags;
+
+ krb5_auth_getremoteseqnumber (_gsskrb5_context,
+ ctx->auth_context,
+ &seq_number);
+
+ _gsskrb5i_is_cfx(ctx, &is_cfx);
+
+ ret = _gssapi_msg_order_create(minor_status,
+ &ctx->order,
+ _gssapi_msg_order_f(flags),
+ seq_number, 0, is_cfx);
+ if (ret) return ret;
+
+ ctx->state = INITIATOR_READY;
+ ctx->more_flags |= OPEN;
+
+ return GSS_S_COMPLETE;
+}
+
+/*
+ * handle delegated creds in init-sec-context
+ */
+
+static void
+do_delegation (krb5_auth_context ac,
+ krb5_ccache ccache,
+ krb5_creds *cred,
+ krb5_const_principal name,
+ krb5_data *fwd_data,
+ uint32_t *flags)
+{
+ krb5_creds creds;
+ KDCOptions fwd_flags;
+ krb5_error_code kret;
+
+ memset (&creds, 0, sizeof(creds));
+ krb5_data_zero (fwd_data);
+
+ kret = krb5_cc_get_principal(_gsskrb5_context, ccache, &creds.client);
+ if (kret)
+ goto out;
+
+ kret = krb5_build_principal(_gsskrb5_context,
+ &creds.server,
+ strlen(creds.client->realm),
+ creds.client->realm,
+ KRB5_TGS_NAME,
+ creds.client->realm,
+ NULL);
+ if (kret)
+ goto out;
+
+ creds.times.endtime = 0;
+
+ memset(&fwd_flags, 0, sizeof(fwd_flags));
+ fwd_flags.forwarded = 1;
+ fwd_flags.forwardable = 1;
+
+ if ( /*target_name->name.name_type != KRB5_NT_SRV_HST ||*/
+ name->name.name_string.len < 2)
+ goto out;
+
+ kret = krb5_get_forwarded_creds(_gsskrb5_context,
+ ac,
+ ccache,
+ KDCOptions2int(fwd_flags),
+ name->name.name_string.val[1],
+ &creds,
+ fwd_data);
+
+ out:
+ if (kret)
+ *flags &= ~GSS_C_DELEG_FLAG;
+ else
+ *flags |= GSS_C_DELEG_FLAG;
+
+ if (creds.client)
+ krb5_free_principal(_gsskrb5_context, creds.client);
+ if (creds.server)
+ krb5_free_principal(_gsskrb5_context, creds.server);
+}
+
+/*
+ * first stage of init-sec-context
+ */
+
+static OM_uint32
+init_auth
+(OM_uint32 * minor_status,
+ gsskrb5_cred initiator_cred_handle,
+ gsskrb5_ctx ctx,
+ krb5_const_principal name,
+ const gss_OID 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 ret = GSS_S_FAILURE;
+ krb5_error_code kret;
+ krb5_flags ap_options;
+ krb5_creds *cred = NULL;
+ krb5_data outbuf;
+ krb5_ccache ccache = NULL;
+ uint32_t flags;
+ krb5_data authenticator;
+ Checksum cksum;
+ krb5_enctype enctype;
+ krb5_data fwd_data;
+ OM_uint32 lifetime_rec;
+
+ krb5_data_zero(&outbuf);
+ krb5_data_zero(&fwd_data);
+
+ *minor_status = 0;
+
+ if (actual_mech_type)
+ *actual_mech_type = GSS_KRB5_MECHANISM;
+
+ if (initiator_cred_handle == NULL) {
+ kret = krb5_cc_default (_gsskrb5_context, &ccache);
+ if (kret) {
+ _gsskrb5_set_error_string ();
+ *minor_status = kret;
+ ret = GSS_S_FAILURE;
+ goto failure;
+ }
+ } else
+ ccache = initiator_cred_handle->ccache;
+
+ kret = krb5_cc_get_principal (_gsskrb5_context, ccache, &ctx->source);
+ if (kret) {
+ _gsskrb5_set_error_string ();
+ *minor_status = kret;
+ ret = GSS_S_FAILURE;
+ goto failure;
+ }
+
+ kret = krb5_copy_principal (_gsskrb5_context, name, &ctx->target);
+ if (kret) {
+ _gsskrb5_set_error_string ();
+ *minor_status = kret;
+ ret = GSS_S_FAILURE;
+ goto failure;
+ }
+
+ ret = _gss_DES3_get_mic_compat(minor_status, ctx);
+ if (ret)
+ goto failure;
+
+
+ ret = gsskrb5_get_creds(minor_status,
+ ccache,
+ ctx,
+ ctx->target,
+ time_req,
+ time_rec,
+ &cred);
+ if (ret)
+ goto failure;
+
+ ctx->lifetime = cred->times.endtime;
+
+ ret = _gsskrb5_lifetime_left(minor_status,
+ ctx->lifetime,
+ &lifetime_rec);
+ if (ret) {
+ goto failure;
+ }
+
+ if (lifetime_rec == 0) {
+ *minor_status = 0;
+ ret = GSS_S_CONTEXT_EXPIRED;
+ goto failure;
+ }
+
+ krb5_auth_con_setkey(_gsskrb5_context,
+ ctx->auth_context,
+ &cred->session);
+
+ kret = krb5_auth_con_generatelocalsubkey(_gsskrb5_context,
+ ctx->auth_context,
+ &cred->session);
+ if(kret) {
+ _gsskrb5_set_error_string ();
+ *minor_status = kret;
+ ret = GSS_S_FAILURE;
+ goto failure;
+ }
+
+ /*
+ * If the credential doesn't have ok-as-delegate, check what local
+ * policy say about ok-as-delegate, default is FALSE that makes
+ * code ignore the KDC setting and follow what the application
+ * requested. If its TRUE, strip of the GSS_C_DELEG_FLAG if the
+ * KDC doesn't set ok-as-delegate.
+ */
+ if (!cred->flags.b.ok_as_delegate) {
+ krb5_boolean delegate;
+
+ krb5_appdefault_boolean(_gsskrb5_context,
+ "gssapi", name->realm,
+ "ok-as-delegate", FALSE, &delegate);
+ if (delegate)
+ req_flags &= ~GSS_C_DELEG_FLAG;
+ }
+
+ flags = 0;
+ ap_options = 0;
+ if (req_flags & GSS_C_DELEG_FLAG)
+ do_delegation (ctx->auth_context,
+ ccache, cred, name, &fwd_data, &flags);
+
+ if (req_flags & GSS_C_MUTUAL_FLAG) {
+ flags |= GSS_C_MUTUAL_FLAG;
+ ap_options |= AP_OPTS_MUTUAL_REQUIRED;
+ }
+
+ if (req_flags & GSS_C_REPLAY_FLAG)
+ flags |= GSS_C_REPLAY_FLAG;
+ if (req_flags & GSS_C_SEQUENCE_FLAG)
+ flags |= GSS_C_SEQUENCE_FLAG;
+ if (req_flags & GSS_C_ANON_FLAG)
+ ; /* XXX */
+ if (req_flags & GSS_C_DCE_STYLE) {
+ /* GSS_C_DCE_STYLE implies GSS_C_MUTUAL_FLAG */
+ flags |= GSS_C_DCE_STYLE | GSS_C_MUTUAL_FLAG;
+ ap_options |= AP_OPTS_MUTUAL_REQUIRED;
+ }
+ if (req_flags & GSS_C_IDENTIFY_FLAG)
+ flags |= GSS_C_IDENTIFY_FLAG;
+ if (req_flags & GSS_C_EXTENDED_ERROR_FLAG)
+ flags |= GSS_C_EXTENDED_ERROR_FLAG;
+
+ flags |= GSS_C_CONF_FLAG;
+ flags |= GSS_C_INTEG_FLAG;
+ flags |= GSS_C_TRANS_FLAG;
+
+ if (ret_flags)
+ *ret_flags = flags;
+ ctx->flags = flags;
+ ctx->more_flags |= LOCAL;
+
+ ret = _gsskrb5_create_8003_checksum (minor_status,
+ input_chan_bindings,
+ flags,
+ &fwd_data,
+ &cksum);
+ krb5_data_free (&fwd_data);
+ if (ret)
+ goto failure;
+
+ enctype = ctx->auth_context->keyblock->keytype;
+
+ kret = krb5_build_authenticator (_gsskrb5_context,
+ ctx->auth_context,
+ enctype,
+ cred,
+ &cksum,
+ NULL,
+ &authenticator,
+ KRB5_KU_AP_REQ_AUTH);
+
+ if (kret) {
+ _gsskrb5_set_error_string ();
+ *minor_status = kret;
+ ret = GSS_S_FAILURE;
+ goto failure;
+ }
+
+ kret = krb5_build_ap_req (_gsskrb5_context,
+ enctype,
+ cred,
+ ap_options,
+ authenticator,
+ &outbuf);
+
+ if (kret) {
+ _gsskrb5_set_error_string ();
+ *minor_status = kret;
+ ret = GSS_S_FAILURE;
+ goto failure;
+ }
+
+ ret = _gsskrb5_encapsulate (minor_status, &outbuf, output_token,
+ (u_char *)"\x01\x00", GSS_KRB5_MECHANISM);
+ if (ret)
+ goto failure;
+
+ krb5_data_free (&outbuf);
+ krb5_free_creds(_gsskrb5_context, cred);
+ free_Checksum(&cksum);
+ if (initiator_cred_handle == NULL)
+ krb5_cc_close(_gsskrb5_context, ccache);
+
+ if (flags & GSS_C_MUTUAL_FLAG) {
+ ctx->state = INITIATOR_WAIT_FOR_MUTAL;
+ return GSS_S_CONTINUE_NEEDED;
+ }
+
+ return gsskrb5_initiator_ready(minor_status, ctx);
+failure:
+ if(cred)
+ krb5_free_creds(_gsskrb5_context, cred);
+ if (ccache && initiator_cred_handle == NULL)
+ krb5_cc_close(_gsskrb5_context, ccache);
+
+ return ret;
+
+}
+
+static OM_uint32
+repl_mutual
+ (OM_uint32 * minor_status,
+ gsskrb5_ctx ctx,
+ const gss_OID 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 ret;
+ krb5_error_code kret;
+ krb5_data indata;
+ krb5_ap_rep_enc_part *repl;
+ int is_cfx = 0;
+
+ output_token->length = 0;
+ output_token->value = NULL;
+
+ if (actual_mech_type)
+ *actual_mech_type = GSS_KRB5_MECHANISM;
+
+ if (req_flags & GSS_C_DCE_STYLE) {
+ /* There is no OID wrapping. */
+ indata.length = input_token->length;
+ indata.data = input_token->value;
+ } else {
+ ret = _gsskrb5_decapsulate (minor_status,
+ input_token,
+ &indata,
+ "\x02\x00",
+ GSS_KRB5_MECHANISM);
+ if (ret) {
+ /* XXX - Handle AP_ERROR */
+ return ret;
+ }
+ }
+
+ kret = krb5_rd_rep (_gsskrb5_context,
+ ctx->auth_context,
+ &indata,
+ &repl);
+ if (kret) {
+ _gsskrb5_set_error_string ();
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+ krb5_free_ap_rep_enc_part (_gsskrb5_context,
+ repl);
+
+ _gsskrb5i_is_cfx(ctx, &is_cfx);
+ if (is_cfx) {
+ krb5_keyblock *key = NULL;
+
+ kret = krb5_auth_con_getremotesubkey(_gsskrb5_context,
+ ctx->auth_context,
+ &key);
+ if (kret == 0 && key != NULL) {
+ ctx->more_flags |= ACCEPTOR_SUBKEY;
+ krb5_free_keyblock (_gsskrb5_context, key);
+ }
+ }
+
+
+ *minor_status = 0;
+ if (time_rec) {
+ ret = _gsskrb5_lifetime_left(minor_status,
+ ctx->lifetime,
+ time_rec);
+ } else {
+ ret = GSS_S_COMPLETE;
+ }
+ if (ret_flags)
+ *ret_flags = ctx->flags;
+
+ if (req_flags & GSS_C_DCE_STYLE) {
+ int32_t con_flags;
+ krb5_data outbuf;
+
+ /* Do don't do sequence number for the mk-rep */
+ krb5_auth_con_removeflags(_gsskrb5_context,
+ ctx->auth_context,
+ KRB5_AUTH_CONTEXT_DO_SEQUENCE,
+ &con_flags);
+
+ kret = krb5_mk_rep(_gsskrb5_context,
+ ctx->auth_context,
+ &outbuf);
+ if (kret) {
+ _gsskrb5_set_error_string ();
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+
+ output_token->length = outbuf.length;
+ output_token->value = outbuf.data;
+
+ krb5_auth_con_removeflags(_gsskrb5_context,
+ ctx->auth_context,
+ KRB5_AUTH_CONTEXT_DO_SEQUENCE,
+ NULL);
+ }
+
+ return gsskrb5_initiator_ready(minor_status, ctx);
+}
+
+/*
+ * gss_init_sec_context
+ */
+
+OM_uint32 _gsskrb5_init_sec_context
+(OM_uint32 * minor_status,
+ const gss_cred_id_t initiator_cred_handle,
+ gss_ctx_id_t * context_handle,
+ const gss_name_t target_name,
+ const gss_OID 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
+ )
+{
+ gsskrb5_cred cred = (gsskrb5_cred)initiator_cred_handle;
+ krb5_const_principal name = (krb5_const_principal)target_name;
+ gsskrb5_ctx ctx;
+ OM_uint32 ret;
+
+ GSSAPI_KRB5_INIT ();
+
+ output_token->length = 0;
+ output_token->value = NULL;
+
+ if (context_handle == NULL) {
+ *minor_status = 0;
+ return GSS_S_FAILURE | GSS_S_CALL_BAD_STRUCTURE;
+ }
+
+ if (ret_flags)
+ *ret_flags = 0;
+ if (time_rec)
+ *time_rec = 0;
+
+ if (target_name == GSS_C_NO_NAME) {
+ if (actual_mech_type)
+ *actual_mech_type = GSS_C_NO_OID;
+ *minor_status = 0;
+ return GSS_S_BAD_NAME;
+ }
+
+ if (mech_type != GSS_C_NO_OID &&
+ !gss_oid_equal(mech_type, GSS_KRB5_MECHANISM))
+ return GSS_S_BAD_MECH;
+
+ if (input_token == GSS_C_NO_BUFFER || input_token->length == 0) {
+ OM_uint32 ret;
+
+ if (*context_handle != GSS_C_NO_CONTEXT) {
+ *minor_status = 0;
+ return GSS_S_FAILURE | GSS_S_CALL_BAD_STRUCTURE;
+ }
+
+ ret = _gsskrb5_create_ctx(minor_status,
+ context_handle,
+ input_chan_bindings,
+ INITIATOR_START);
+ if (ret)
+ return ret;
+ }
+
+ if (*context_handle == GSS_C_NO_CONTEXT) {
+ *minor_status = 0;
+ return GSS_S_FAILURE | GSS_S_CALL_BAD_STRUCTURE;
+ }
+
+ ctx = (gsskrb5_ctx) *context_handle;
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+
+ switch (ctx->state) {
+ case INITIATOR_START:
+ ret = init_auth(minor_status,
+ cred,
+ ctx,
+ name,
+ mech_type,
+ req_flags,
+ time_req,
+ input_chan_bindings,
+ input_token,
+ actual_mech_type,
+ output_token,
+ ret_flags,
+ time_rec);
+ break;
+ case INITIATOR_WAIT_FOR_MUTAL:
+ ret = repl_mutual(minor_status,
+ ctx,
+ mech_type,
+ req_flags,
+ time_req,
+ input_chan_bindings,
+ input_token,
+ actual_mech_type,
+ output_token,
+ ret_flags,
+ time_rec);
+ break;
+ case INITIATOR_READY:
+ /*
+ * If we get there, the caller have called
+ * gss_init_sec_context() one time too many.
+ */
+ *minor_status = 0;
+ ret = GSS_S_BAD_STATUS;
+ break;
+ default:
+ *minor_status = 0;
+ ret = GSS_S_BAD_STATUS;
+ break;
+ }
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+
+ /* destroy context in case of error */
+ if (GSS_ERROR(ret)) {
+ OM_uint32 min2;
+ _gsskrb5_delete_sec_context(&min2, context_handle, GSS_C_NO_BUFFER);
+ }
+
+ return ret;
+
+}
diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_context.c b/source4/heimdal/lib/gssapi/krb5/inquire_context.c
new file mode 100644
index 0000000000..ef43e6852c
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/krb5/inquire_context.c
@@ -0,0 +1,108 @@
+/*
+ * 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 "krb5/gsskrb5_locl.h"
+
+RCSID("$Id: inquire_context.c,v 1.10 2006/10/07 22:15:03 lha Exp $");
+
+OM_uint32 _gsskrb5_inquire_context (
+ OM_uint32 * minor_status,
+ const gss_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 * open_context
+ )
+{
+ OM_uint32 ret;
+ gsskrb5_ctx ctx = (gsskrb5_ctx)context_handle;
+ gss_name_t name;
+
+ if (src_name)
+ *src_name = GSS_C_NO_NAME;
+ if (targ_name)
+ *targ_name = GSS_C_NO_NAME;
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+
+ if (src_name) {
+ name = (gss_name_t)ctx->source;
+ ret = _gsskrb5_duplicate_name (minor_status, name, src_name);
+ if (ret)
+ goto failed;
+ }
+
+ if (targ_name) {
+ name = (gss_name_t)ctx->target;
+ ret = _gsskrb5_duplicate_name (minor_status, name, targ_name);
+ if (ret)
+ goto failed;
+ }
+
+ if (lifetime_rec) {
+ ret = _gsskrb5_lifetime_left(minor_status,
+ ctx->lifetime,
+ lifetime_rec);
+ if (ret)
+ goto failed;
+ }
+
+ if (mech_type)
+ *mech_type = GSS_KRB5_MECHANISM;
+
+ if (ctx_flags)
+ *ctx_flags = ctx->flags;
+
+ if (locally_initiated)
+ *locally_initiated = ctx->more_flags & LOCAL;
+
+ if (open_context)
+ *open_context = ctx->more_flags & OPEN;
+
+ *minor_status = 0;
+
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ return GSS_S_COMPLETE;
+
+failed:
+ if (src_name)
+ _gsskrb5_release_name(NULL, src_name);
+ if (targ_name)
+ _gsskrb5_release_name(NULL, targ_name);
+
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ return ret;
+}
diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_cred.c b/source4/heimdal/lib/gssapi/krb5/inquire_cred.c
new file mode 100644
index 0000000000..0593729365
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/krb5/inquire_cred.c
@@ -0,0 +1,178 @@
+/*
+ * 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 "krb5/gsskrb5_locl.h"
+
+RCSID("$Id: inquire_cred.c,v 1.12 2006/10/07 22:15:06 lha Exp $");
+
+OM_uint32 _gsskrb5_inquire_cred
+(OM_uint32 * minor_status,
+ const gss_cred_id_t cred_handle,
+ gss_name_t * output_name,
+ OM_uint32 * lifetime,
+ gss_cred_usage_t * cred_usage,
+ gss_OID_set * mechanisms
+ )
+{
+ gss_cred_id_t aqcred_init = GSS_C_NO_CREDENTIAL;
+ gss_cred_id_t aqcred_accept = GSS_C_NO_CREDENTIAL;
+ gsskrb5_cred acred = NULL, icred = NULL;
+ OM_uint32 ret;
+
+ *minor_status = 0;
+
+ if (output_name)
+ *output_name = NULL;
+ if (mechanisms)
+ *mechanisms = GSS_C_NO_OID_SET;
+
+ if (cred_handle == GSS_C_NO_CREDENTIAL) {
+ ret = _gsskrb5_acquire_cred(minor_status,
+ GSS_C_NO_NAME,
+ GSS_C_INDEFINITE,
+ GSS_C_NO_OID_SET,
+ GSS_C_ACCEPT,
+ &aqcred_accept,
+ NULL,
+ NULL);
+ if (ret == GSS_S_COMPLETE)
+ acred = (gsskrb5_cred)aqcred_accept;
+
+ ret = _gsskrb5_acquire_cred(minor_status,
+ GSS_C_NO_NAME,
+ GSS_C_INDEFINITE,
+ GSS_C_NO_OID_SET,
+ GSS_C_INITIATE,
+ &aqcred_init,
+ NULL,
+ NULL);
+ if (ret == GSS_S_COMPLETE)
+ acred = (gsskrb5_cred)aqcred_init;
+
+ if (icred == NULL && acred == NULL) {
+ *minor_status = 0;
+ return GSS_S_NO_CRED;
+ }
+ } else
+ acred = (gsskrb5_cred)cred_handle;
+
+ if (acred)
+ HEIMDAL_MUTEX_lock(&acred->cred_id_mutex);
+ if (icred)
+ HEIMDAL_MUTEX_lock(&icred->cred_id_mutex);
+
+ if (output_name != NULL) {
+ if (icred && icred->principal != NULL) {
+ gss_name_t name;
+
+ if (acred)
+ name = (gss_name_t)acred->principal;
+ else
+ name = (gss_name_t)icred->principal;
+
+ ret = _gsskrb5_duplicate_name(minor_status, name, output_name);
+ if (ret)
+ goto out;
+ } else if (acred && acred->usage == GSS_C_ACCEPT) {
+ krb5_principal princ;
+ *minor_status = krb5_sname_to_principal(_gsskrb5_context, NULL,
+ NULL, KRB5_NT_SRV_HST,
+ &princ);
+ if (*minor_status) {
+ ret = GSS_S_FAILURE;
+ goto out;
+ }
+ *output_name = (gss_name_t)princ;
+ } else {
+ krb5_principal princ;
+ *minor_status = krb5_get_default_principal(_gsskrb5_context,
+ &princ);
+ if (*minor_status) {
+ ret = GSS_S_FAILURE;
+ goto out;
+ }
+ *output_name = (gss_name_t)princ;
+ }
+ }
+ if (lifetime != NULL) {
+ OM_uint32 alife = GSS_C_INDEFINITE, ilife = GSS_C_INDEFINITE;
+
+ if (acred) alife = acred->lifetime;
+ if (icred) ilife = icred->lifetime;
+
+ ret = _gsskrb5_lifetime_left(minor_status,
+ min(alife,ilife),
+ lifetime);
+ if (ret)
+ goto out;
+ }
+ if (cred_usage != NULL) {
+ if (acred && icred)
+ *cred_usage = GSS_C_BOTH;
+ else if (acred)
+ *cred_usage = GSS_C_ACCEPT;
+ else if (icred)
+ *cred_usage = GSS_C_INITIATE;
+ else
+ abort();
+ }
+
+ if (mechanisms != NULL) {
+ ret = _gsskrb5_create_empty_oid_set(minor_status, mechanisms);
+ if (ret)
+ goto out;
+ if (acred)
+ ret = _gsskrb5_add_oid_set_member(minor_status,
+ &acred->mechanisms->elements[0],
+ mechanisms);
+ if (ret == GSS_S_COMPLETE && icred)
+ ret = _gsskrb5_add_oid_set_member(minor_status,
+ &icred->mechanisms->elements[0],
+ mechanisms);
+ if (ret)
+ goto out;
+ }
+ ret = GSS_S_COMPLETE;
+out:
+ if (acred)
+ HEIMDAL_MUTEX_unlock(&acred->cred_id_mutex);
+ if (icred)
+ HEIMDAL_MUTEX_unlock(&icred->cred_id_mutex);
+
+ if (aqcred_init != GSS_C_NO_CREDENTIAL)
+ ret = _gsskrb5_release_cred(minor_status, &aqcred_init);
+ if (aqcred_accept != GSS_C_NO_CREDENTIAL)
+ ret = _gsskrb5_release_cred(minor_status, &aqcred_accept);
+
+ return ret;
+}
diff --git a/source4/heimdal/lib/gssapi/arcfour.h b/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_mech.c
index 0406b64b09..954a5e3119 100644
--- a/source4/heimdal/lib/gssapi/arcfour.h
+++ b/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_mech.c
@@ -31,53 +31,53 @@
* SUCH DAMAGE.
*/
-/* $Id: arcfour.h,v 1.5 2004/03/07 22:30:57 lha Exp $ */
+#include "krb5/gsskrb5_locl.h"
-#ifndef GSSAPI_ARCFOUR_H_
-#define GSSAPI_ARCFOUR_H_ 1
+RCSID("$Id: inquire_cred_by_mech.c,v 1.4 2006/10/07 22:15:08 lha Exp $");
-#define GSS_ARCFOUR_WRAP_TOKEN_SIZE 32
-#define GSS_ARCFOUR_WRAP_TOKEN_OFFSET 13
+OM_uint32 _gsskrb5_inquire_cred_by_mech (
+ OM_uint32 * minor_status,
+ const gss_cred_id_t cred_handle,
+ const gss_OID mech_type,
+ gss_name_t * name,
+ OM_uint32 * initiator_lifetime,
+ OM_uint32 * acceptor_lifetime,
+ gss_cred_usage_t * cred_usage
+ )
+{
+ OM_uint32 ret;
+ OM_uint32 lifetime;
-OM_uint32 _gssapi_wrap_arcfour(OM_uint32 *minor_status,
- const gss_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,
- krb5_keyblock *key);
+ if (gss_oid_equal(mech_type, GSS_C_NO_OID) == 0 &&
+ gss_oid_equal(mech_type, GSS_KRB5_MECHANISM) == 0) {
+ *minor_status = EINVAL;
+ return GSS_S_BAD_MECH;
+ }
-OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status,
- const gss_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,
- krb5_keyblock *key);
+ ret = _gsskrb5_inquire_cred (minor_status,
+ cred_handle,
+ name,
+ &lifetime,
+ cred_usage,
+ NULL);
+
+ if (ret == 0 && cred_handle != GSS_C_NO_CREDENTIAL) {
+ gsskrb5_cred cred = (gsskrb5_cred)cred_handle;
+ gss_cred_usage_t usage;
-OM_uint32 _gssapi_get_mic_arcfour(OM_uint32 *minor_status,
- const gss_ctx_id_t context_handle,
- gss_qop_t qop_req,
- const gss_buffer_t message_buffer,
- gss_buffer_t message_token,
- krb5_keyblock *key);
+ HEIMDAL_MUTEX_lock(&cred->cred_id_mutex);
+ usage = cred->usage;
+ HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
-OM_uint32 _gssapi_verify_mic_arcfour(OM_uint32 *minor_status,
- const gss_ctx_id_t context_handle,
- const gss_buffer_t message_buffer,
- const gss_buffer_t token_buffer,
- gss_qop_t *qop_state,
- krb5_keyblock *key,
- char *type);
-OM_uint32
-_gssapi_wrap_size_arcfour(OM_uint32 * minor_status,
- const gss_ctx_id_t context_handle,
- int conf_req_flag,
- gss_qop_t qop_req,
- OM_uint32 req_input_size,
- OM_uint32 * output_size,
- OM_uint32 * padlen,
- krb5_keyblock *key);
+ if (initiator_lifetime) {
+ if (usage == GSS_C_INITIATE || usage == GSS_C_BOTH)
+ *initiator_lifetime = lifetime;
+ }
+ if (acceptor_lifetime) {
+ if (usage == GSS_C_ACCEPT || usage == GSS_C_BOTH)
+ *acceptor_lifetime = lifetime;
+ }
+ }
-#endif /* GSSAPI_ARCFOUR_H_ */
+ return ret;
+}
diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_oid.c b/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_oid.c
new file mode 100644
index 0000000000..26927c740c
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_oid.c
@@ -0,0 +1,81 @@
+/*
+ * 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 "krb5/gsskrb5_locl.h"
+
+RCSID("$Id: inquire_cred_by_oid.c,v 1.4 2006/10/07 22:15:10 lha Exp $");
+
+OM_uint32 _gsskrb5_inquire_cred_by_oid
+ (OM_uint32 * minor_status,
+ const gss_cred_id_t cred_handle,
+ const gss_OID desired_object,
+ gss_buffer_set_t *data_set)
+{
+ gsskrb5_cred cred = (gsskrb5_cred)cred_handle;
+ krb5_error_code ret;
+ gss_buffer_desc buffer;
+ char *str;
+
+ if (gss_oid_equal(desired_object, GSS_KRB5_COPY_CCACHE_X) == 0) {
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ HEIMDAL_MUTEX_lock(&cred->cred_id_mutex);
+
+ if (cred->ccache == NULL) {
+ HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ ret = krb5_cc_get_full_name(_gsskrb5_context, cred->ccache, &str);
+ HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
+ if (ret) {
+ *minor_status = ret;
+ _gsskrb5_set_error_string ();
+ return GSS_S_FAILURE;
+ }
+
+ buffer.value = str;
+ buffer.length = strlen(str);
+
+ ret = gss_add_buffer_set_member(minor_status, &buffer, data_set);
+ if (ret != GSS_S_COMPLETE)
+ _gsskrb5_clear_status ();
+
+ free(str);
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
+
diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_mechs_for_name.c b/source4/heimdal/lib/gssapi/krb5/inquire_mechs_for_name.c
new file mode 100644
index 0000000000..5c1f082f45
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/krb5/inquire_mechs_for_name.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 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 "krb5/gsskrb5_locl.h"
+
+RCSID("$Id: inquire_mechs_for_name.c,v 1.3 2006/10/07 22:15:13 lha Exp $");
+
+OM_uint32 _gsskrb5_inquire_mechs_for_name (
+ OM_uint32 * minor_status,
+ const gss_name_t input_name,
+ gss_OID_set * mech_types
+ )
+{
+ OM_uint32 ret;
+
+ ret = _gsskrb5_create_empty_oid_set(minor_status, mech_types);
+ if (ret)
+ return ret;
+
+ ret = _gsskrb5_add_oid_set_member(minor_status,
+ GSS_KRB5_MECHANISM,
+ mech_types);
+ if (ret)
+ _gsskrb5_release_oid_set(NULL, mech_types);
+
+ return ret;
+}
diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_names_for_mech.c b/source4/heimdal/lib/gssapi/krb5/inquire_names_for_mech.c
new file mode 100644
index 0000000000..5d8aefab1c
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/krb5/inquire_names_for_mech.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 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 "krb5/gsskrb5_locl.h"
+
+RCSID("$Id: inquire_names_for_mech.c,v 1.3 2006/10/07 22:15:15 lha Exp $");
+
+
+static gss_OID *name_list[] = {
+ &GSS_C_NT_HOSTBASED_SERVICE,
+ &GSS_C_NT_USER_NAME,
+ &GSS_KRB5_NT_PRINCIPAL_NAME,
+ &GSS_C_NT_EXPORT_NAME,
+ NULL
+};
+
+OM_uint32 _gsskrb5_inquire_names_for_mech (
+ OM_uint32 * minor_status,
+ const gss_OID mechanism,
+ gss_OID_set * name_types
+ )
+{
+ OM_uint32 ret;
+ int i;
+
+ *minor_status = 0;
+
+ if (gss_oid_equal(mechanism, GSS_KRB5_MECHANISM) == 0 &&
+ gss_oid_equal(mechanism, GSS_C_NULL_OID) == 0) {
+ *name_types = GSS_C_NO_OID_SET;
+ return GSS_S_BAD_MECH;
+ }
+
+ ret = _gsskrb5_create_empty_oid_set(minor_status, name_types);
+ if (ret != GSS_S_COMPLETE)
+ return ret;
+
+ for (i = 0; name_list[i] != NULL; i++) {
+ ret = _gsskrb5_add_oid_set_member(minor_status,
+ *(name_list[i]),
+ name_types);
+ if (ret != GSS_S_COMPLETE)
+ break;
+ }
+
+ if (ret != GSS_S_COMPLETE)
+ _gsskrb5_release_oid_set(NULL, name_types);
+
+ return GSS_S_COMPLETE;
+}
diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_sec_context_by_oid.c b/source4/heimdal/lib/gssapi/krb5/inquire_sec_context_by_oid.c
new file mode 100644
index 0000000000..0b46cc5495
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/krb5/inquire_sec_context_by_oid.c
@@ -0,0 +1,559 @@
+/*
+ * 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 "krb5/gsskrb5_locl.h"
+
+RCSID("$Id: inquire_sec_context_by_oid.c,v 1.8 2006/10/24 15:55:28 lha Exp $");
+
+static int
+oid_prefix_equal(gss_OID oid_enc, gss_OID prefix_enc, unsigned *suffix)
+{
+ int ret;
+ heim_oid oid;
+ heim_oid prefix;
+
+ *suffix = 0;
+
+ ret = der_get_oid(oid_enc->elements, oid_enc->length,
+ &oid, NULL);
+ if (ret) {
+ return 0;
+ }
+
+ ret = der_get_oid(prefix_enc->elements, prefix_enc->length,
+ &prefix, NULL);
+ if (ret) {
+ der_free_oid(&oid);
+ return 0;
+ }
+
+ ret = 0;
+
+ if (oid.length - 1 == prefix.length) {
+ *suffix = oid.components[oid.length - 1];
+ oid.length--;
+ ret = (der_heim_oid_cmp(&oid, &prefix) == 0);
+ oid.length++;
+ }
+
+ der_free_oid(&oid);
+ der_free_oid(&prefix);
+
+ return ret;
+}
+
+static OM_uint32 inquire_sec_context_tkt_flags
+ (OM_uint32 *minor_status,
+ const gsskrb5_ctx context_handle,
+ gss_buffer_set_t *data_set)
+{
+ OM_uint32 tkt_flags;
+ unsigned char buf[4];
+ gss_buffer_desc value;
+
+ HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
+
+ if (context_handle->ticket == NULL) {
+ HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+ _gsskrb5_set_status("No ticket from which to obtain flags");
+ *minor_status = EINVAL;
+ return GSS_S_BAD_MECH;
+ }
+
+ tkt_flags = TicketFlags2int(context_handle->ticket->ticket.flags);
+ HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+
+ _gsskrb5_encode_om_uint32(tkt_flags, buf);
+ value.length = sizeof(buf);
+ value.value = buf;
+
+ return gss_add_buffer_set_member(minor_status,
+ &value,
+ data_set);
+}
+
+enum keytype { ACCEPTOR_KEY, INITIATOR_KEY, TOKEN_KEY };
+
+static OM_uint32 inquire_sec_context_get_subkey
+ (OM_uint32 *minor_status,
+ const gsskrb5_ctx context_handle,
+ enum keytype keytype,
+ gss_buffer_set_t *data_set)
+{
+ krb5_keyblock *key = NULL;
+ krb5_storage *sp = NULL;
+ krb5_data data;
+ OM_uint32 maj_stat = GSS_S_COMPLETE;
+ krb5_error_code ret;
+
+ krb5_data_zero(&data);
+
+ sp = krb5_storage_emem();
+ if (sp == NULL) {
+ _gsskrb5_clear_status();
+ ret = ENOMEM;
+ goto out;
+ }
+
+ HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
+ switch(keytype) {
+ case ACCEPTOR_KEY:
+ ret = _gsskrb5i_get_acceptor_subkey(context_handle, &key);
+ if (ret)
+ _gsskrb5_set_error_string ();
+ break;
+ case INITIATOR_KEY:
+ ret = _gsskrb5i_get_initiator_subkey(context_handle, &key);
+ if (ret)
+ _gsskrb5_set_error_string ();
+ break;
+ case TOKEN_KEY:
+ ret = _gsskrb5i_get_token_key(context_handle, &key);
+ if (ret)
+ _gsskrb5_set_error_string ();
+ break;
+ default:
+ _gsskrb5_set_status("%d is not a valid subkey type", keytype);
+ ret = EINVAL;
+ break;
+ }
+ HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+ if (ret)
+ goto out;
+
+ ret = krb5_store_keyblock(sp, *key);
+ krb5_free_keyblock (_gsskrb5_context, key);
+ if (ret) {
+ _gsskrb5_set_error_string ();
+ goto out;
+ }
+
+ ret = krb5_storage_to_data(sp, &data);
+ if (ret) {
+ _gsskrb5_set_error_string ();
+ goto out;
+ }
+
+ {
+ gss_buffer_desc value;
+
+ value.length = data.length;
+ value.value = data.data;
+
+ maj_stat = gss_add_buffer_set_member(minor_status,
+ &value,
+ data_set);
+ }
+
+out:
+ krb5_data_free(&data);
+ if (sp)
+ krb5_storage_free(sp);
+ if (ret) {
+ *minor_status = ret;
+ maj_stat = GSS_S_FAILURE;
+ }
+ return maj_stat;
+}
+
+static OM_uint32 inquire_sec_context_authz_data
+ (OM_uint32 *minor_status,
+ const gsskrb5_ctx context_handle,
+ unsigned ad_type,
+ gss_buffer_set_t *data_set)
+{
+ krb5_data data;
+ gss_buffer_desc ad_data;
+ OM_uint32 ret;
+
+ *minor_status = 0;
+ *data_set = GSS_C_NO_BUFFER_SET;
+
+ HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
+ if (context_handle->ticket == NULL) {
+ HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+ *minor_status = EINVAL;
+ _gsskrb5_set_status("No ticket to obtain authz data from");
+ return GSS_S_NO_CONTEXT;
+ }
+
+ ret = krb5_ticket_get_authorization_data_type(_gsskrb5_context,
+ context_handle->ticket,
+ ad_type,
+ &data);
+ HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+ if (ret) {
+ _gsskrb5_set_error_string ();
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ ad_data.value = data.data;
+ ad_data.length = data.length;
+
+ ret = gss_add_buffer_set_member(minor_status,
+ &ad_data,
+ data_set);
+
+ krb5_data_free(&data);
+
+ return ret;
+}
+
+static OM_uint32 inquire_sec_context_has_updated_spnego
+ (OM_uint32 *minor_status,
+ const gsskrb5_ctx context_handle,
+ gss_buffer_set_t *data_set)
+{
+ int is_updated = 0;
+
+ *minor_status = 0;
+ *data_set = GSS_C_NO_BUFFER_SET;
+
+ /*
+ * For Windows SPNEGO implementations, both the initiator and the
+ * acceptor are assumed to have been updated if a "newer" [CLAR] or
+ * different enctype is negotiated for use by the Kerberos GSS-API
+ * mechanism.
+ */
+ HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
+ _gsskrb5i_is_cfx(context_handle, &is_updated);
+ if (is_updated == 0) {
+ krb5_keyblock *acceptor_subkey;
+
+ if (context_handle->more_flags & LOCAL)
+ acceptor_subkey = context_handle->auth_context->remote_subkey;
+ else
+ acceptor_subkey = context_handle->auth_context->local_subkey;
+
+ if (acceptor_subkey != NULL)
+ is_updated = (acceptor_subkey->keytype !=
+ context_handle->auth_context->keyblock->keytype);
+ }
+ HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+
+ return is_updated ? GSS_S_COMPLETE : GSS_S_FAILURE;
+}
+
+/*
+ *
+ */
+
+static OM_uint32
+export_lucid_sec_context_v1(OM_uint32 *minor_status,
+ gsskrb5_ctx context_handle,
+ gss_buffer_set_t *data_set)
+{
+ krb5_storage *sp = NULL;
+ OM_uint32 major_status = GSS_S_COMPLETE;
+ krb5_error_code ret;
+ krb5_keyblock *key = NULL;
+ int32_t number;
+ int is_cfx;
+ krb5_data data;
+
+ *minor_status = 0;
+
+ GSSAPI_KRB5_INIT ();
+
+ HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
+
+ _gsskrb5i_is_cfx(context_handle, &is_cfx);
+
+ sp = krb5_storage_emem();
+ if (sp == NULL) {
+ _gsskrb5_clear_status();
+ ret = ENOMEM;
+ goto out;
+ }
+
+ ret = krb5_store_int32(sp, 1);
+ if (ret) goto out;
+ ret = krb5_store_int32(sp, (context_handle->more_flags & LOCAL) ? 1 : 0);
+ if (ret) goto out;
+ ret = krb5_store_int32(sp, context_handle->lifetime);
+ if (ret) goto out;
+ krb5_auth_con_getlocalseqnumber (_gsskrb5_context,
+ context_handle->auth_context,
+ &number);
+ ret = krb5_store_uint32(sp, (uint32_t)0); /* store top half as zero */
+ ret = krb5_store_uint32(sp, (uint32_t)number);
+ krb5_auth_getremoteseqnumber (_gsskrb5_context,
+ context_handle->auth_context,
+ &number);
+ ret = krb5_store_uint32(sp, (uint32_t)0); /* store top half as zero */
+ ret = krb5_store_uint32(sp, (uint32_t)number);
+ ret = krb5_store_int32(sp, (is_cfx) ? 1 : 0);
+ if (ret) goto out;
+
+ ret = _gsskrb5i_get_token_key(context_handle, &key);
+ if (ret) goto out;
+
+ if (is_cfx == 0) {
+ int sign_alg, seal_alg;
+
+ switch (key->keytype) {
+ case ETYPE_DES_CBC_CRC:
+ case ETYPE_DES_CBC_MD4:
+ case ETYPE_DES_CBC_MD5:
+ sign_alg = 0;
+ seal_alg = 0;
+ break;
+ case ETYPE_DES3_CBC_MD5:
+ case ETYPE_DES3_CBC_SHA1:
+ sign_alg = 4;
+ seal_alg = 2;
+ break;
+ case ETYPE_ARCFOUR_HMAC_MD5:
+ case ETYPE_ARCFOUR_HMAC_MD5_56:
+ sign_alg = 17;
+ seal_alg = 16;
+ break;
+ default:
+ sign_alg = -1;
+ seal_alg = -1;
+ break;
+ }
+ ret = krb5_store_int32(sp, sign_alg);
+ if (ret) goto out;
+ ret = krb5_store_int32(sp, seal_alg);
+ if (ret) goto out;
+ /* ctx_key */
+ ret = krb5_store_keyblock(sp, *key);
+ if (ret) goto out;
+ } else {
+ int subkey_p = (context_handle->more_flags & ACCEPTOR_SUBKEY) ? 1 : 0;
+
+ /* have_acceptor_subkey */
+ ret = krb5_store_int32(sp, subkey_p);
+ if (ret) goto out;
+ /* ctx_key */
+ ret = krb5_store_keyblock(sp, *key);
+ if (ret) goto out;
+ /* acceptor_subkey */
+ if (subkey_p) {
+ ret = krb5_store_keyblock(sp, *key);
+ if (ret) goto out;
+ }
+ }
+ ret = krb5_storage_to_data(sp, &data);
+ if (ret) goto out;
+
+ {
+ gss_buffer_desc ad_data;
+
+ ad_data.value = data.data;
+ ad_data.length = data.length;
+
+ ret = gss_add_buffer_set_member(minor_status, &ad_data, data_set);
+ krb5_data_free(&data);
+ if (ret)
+ goto out;
+ }
+
+out:
+ if (key)
+ krb5_free_keyblock (_gsskrb5_context, key);
+ if (sp)
+ krb5_storage_free(sp);
+ if (ret) {
+ *minor_status = ret;
+ major_status = GSS_S_FAILURE;
+ }
+ HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+ return major_status;
+}
+
+static OM_uint32
+get_authtime(OM_uint32 *minor_status,
+ gsskrb5_ctx ctx,
+ gss_buffer_set_t *data_set)
+
+{
+ gss_buffer_desc value;
+ OM_uint32 authtime;
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+ if (ctx->ticket == NULL) {
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ _gsskrb5_set_status("No ticket to obtain auth time from");
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ authtime = ctx->ticket->ticket.authtime;
+
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+
+ value.length = 4;
+ value.value = malloc(value.length);
+ if (!value.value) {
+ _gsskrb5_clear_status();
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ _gsskrb5_encode_om_uint32(authtime, value.value);
+
+ return gss_add_buffer_set_member(minor_status,
+ &value,
+ data_set);
+}
+
+
+static OM_uint32
+get_service_keyblock
+ (OM_uint32 *minor_status,
+ gsskrb5_ctx ctx,
+ gss_buffer_set_t *data_set)
+{
+ krb5_storage *sp = NULL;
+ krb5_data data;
+ OM_uint32 maj_stat = GSS_S_COMPLETE;
+ krb5_error_code ret = EINVAL;
+
+ sp = krb5_storage_emem();
+ if (sp == NULL) {
+ _gsskrb5_clear_status();
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+ if (ctx->service_keyblock == NULL) {
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ _gsskrb5_set_status("No service keyblock on gssapi context");
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ krb5_data_zero(&data);
+
+ ret = krb5_store_keyblock(sp, *ctx->service_keyblock);
+
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+
+ if (ret)
+ goto out;
+
+ ret = krb5_storage_to_data(sp, &data);
+ if (ret)
+ goto out;
+
+ {
+ gss_buffer_desc value;
+
+ value.length = data.length;
+ value.value = data.data;
+
+ maj_stat = gss_add_buffer_set_member(minor_status,
+ &value,
+ data_set);
+ }
+
+out:
+ krb5_data_free(&data);
+ if (sp)
+ krb5_storage_free(sp);
+ if (ret) {
+ _gsskrb5_set_error_string ();
+ *minor_status = ret;
+ maj_stat = GSS_S_FAILURE;
+ }
+ return maj_stat;
+}
+/*
+ *
+ */
+
+OM_uint32 _gsskrb5_inquire_sec_context_by_oid
+ (OM_uint32 *minor_status,
+ const gss_ctx_id_t context_handle,
+ const gss_OID desired_object,
+ gss_buffer_set_t *data_set)
+{
+ const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle;
+ unsigned suffix;
+
+ if (ctx == NULL) {
+ *minor_status = EINVAL;
+ return GSS_S_NO_CONTEXT;
+ }
+
+ if (gss_oid_equal(desired_object, GSS_KRB5_GET_TKT_FLAGS_X)) {
+ return inquire_sec_context_tkt_flags(minor_status,
+ ctx,
+ data_set);
+ } else if (gss_oid_equal(desired_object, GSS_C_PEER_HAS_UPDATED_SPNEGO)) {
+ return inquire_sec_context_has_updated_spnego(minor_status,
+ ctx,
+ data_set);
+ } else if (gss_oid_equal(desired_object, GSS_KRB5_GET_SUBKEY_X)) {
+ return inquire_sec_context_get_subkey(minor_status,
+ ctx,
+ TOKEN_KEY,
+ data_set);
+ } else if (gss_oid_equal(desired_object, GSS_KRB5_GET_INITIATOR_SUBKEY_X)) {
+ return inquire_sec_context_get_subkey(minor_status,
+ ctx,
+ INITIATOR_KEY,
+ data_set);
+ } else if (gss_oid_equal(desired_object, GSS_KRB5_GET_ACCEPTOR_SUBKEY_X)) {
+ return inquire_sec_context_get_subkey(minor_status,
+ ctx,
+ ACCEPTOR_KEY,
+ data_set);
+ } else if (gss_oid_equal(desired_object, GSS_KRB5_GET_AUTHTIME_X)) {
+ return get_authtime(minor_status, ctx, data_set);
+ } else if (oid_prefix_equal(desired_object,
+ GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_X,
+ &suffix)) {
+ return inquire_sec_context_authz_data(minor_status,
+ ctx,
+ suffix,
+ data_set);
+ } else if (oid_prefix_equal(desired_object,
+ GSS_KRB5_EXPORT_LUCID_CONTEXT_X,
+ &suffix)) {
+ if (suffix == 1)
+ return export_lucid_sec_context_v1(minor_status,
+ ctx,
+ data_set);
+ *minor_status = 0;
+ return GSS_S_FAILURE;
+ } else if (gss_oid_equal(desired_object, GSS_KRB5_GET_SERVICE_KEYBLOCK_X)) {
+ return get_service_keyblock(minor_status, ctx, data_set);
+ } else {
+ *minor_status = 0;
+ return GSS_S_FAILURE;
+ }
+}
+
diff --git a/source4/heimdal/lib/gssapi/krb5/process_context_token.c b/source4/heimdal/lib/gssapi/krb5/process_context_token.c
new file mode 100644
index 0000000000..99568c9dd0
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/krb5/process_context_token.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 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 "krb5/gsskrb5_locl.h"
+
+RCSID("$Id: process_context_token.c,v 1.4 2006/10/07 22:15:19 lha Exp $");
+
+OM_uint32 _gsskrb5_process_context_token (
+ OM_uint32 *minor_status,
+ const gss_ctx_id_t context_handle,
+ const gss_buffer_t token_buffer
+ )
+{
+ OM_uint32 ret = GSS_S_FAILURE;
+ gss_buffer_desc empty_buffer;
+ gss_qop_t qop_state;
+
+ empty_buffer.length = 0;
+ empty_buffer.value = NULL;
+
+ qop_state = GSS_C_QOP_DEFAULT;
+
+ ret = _gsskrb5_verify_mic_internal(minor_status,
+ (gsskrb5_ctx)context_handle,
+ token_buffer, &empty_buffer,
+ GSS_C_QOP_DEFAULT, "\x01\x02");
+
+ if (ret == GSS_S_COMPLETE)
+ ret = _gsskrb5_delete_sec_context(minor_status,
+ rk_UNCONST(&context_handle),
+ GSS_C_NO_BUFFER);
+ if (ret == GSS_S_COMPLETE)
+ *minor_status = 0;
+
+ return ret;
+}
diff --git a/source4/heimdal/lib/gssapi/release_buffer.c b/source4/heimdal/lib/gssapi/krb5/release_buffer.c
index 258b76f627..b62ad02117 100644
--- a/source4/heimdal/lib/gssapi/release_buffer.c
+++ b/source4/heimdal/lib/gssapi/krb5/release_buffer.c
@@ -31,11 +31,11 @@
* SUCH DAMAGE.
*/
-#include "gssapi_locl.h"
+#include "krb5/gsskrb5_locl.h"
-RCSID("$Id: release_buffer.c,v 1.5 2003/03/16 17:58:20 lha Exp $");
+RCSID("$Id: release_buffer.c,v 1.7 2006/10/07 22:15:22 lha Exp $");
-OM_uint32 gss_release_buffer
+OM_uint32 _gsskrb5_release_buffer
(OM_uint32 * minor_status,
gss_buffer_t buffer
)
diff --git a/source4/heimdal/lib/gssapi/release_cred.c b/source4/heimdal/lib/gssapi/krb5/release_cred.c
index fc9fc3fc01..662461ccfd 100644
--- a/source4/heimdal/lib/gssapi/release_cred.c
+++ b/source4/heimdal/lib/gssapi/krb5/release_cred.c
@@ -31,43 +31,46 @@
* SUCH DAMAGE.
*/
-#include "gssapi_locl.h"
+#include "krb5/gsskrb5_locl.h"
-RCSID("$Id: release_cred.c,v 1.11 2005/11/02 08:57:35 lha Exp $");
+RCSID("$Id: release_cred.c,v 1.13 2006/10/07 22:15:24 lha Exp $");
-OM_uint32 gss_release_cred
+OM_uint32 _gsskrb5_release_cred
(OM_uint32 * minor_status,
gss_cred_id_t * cred_handle
)
{
+ gsskrb5_cred cred;
+
*minor_status = 0;
- if (*cred_handle == GSS_C_NO_CREDENTIAL) {
+ if (*cred_handle == NULL)
return GSS_S_COMPLETE;
- }
+
+ cred = (gsskrb5_cred)*cred_handle;
+ *cred_handle = GSS_C_NO_CREDENTIAL;
GSSAPI_KRB5_INIT ();
- HEIMDAL_MUTEX_lock(&(*cred_handle)->cred_id_mutex);
+ HEIMDAL_MUTEX_lock(&cred->cred_id_mutex);
- if ((*cred_handle)->principal != NULL)
- krb5_free_principal(gssapi_krb5_context, (*cred_handle)->principal);
- if ((*cred_handle)->keytab != NULL)
- krb5_kt_close(gssapi_krb5_context, (*cred_handle)->keytab);
- if ((*cred_handle)->ccache != NULL) {
+ if (cred->principal != NULL)
+ krb5_free_principal(_gsskrb5_context, cred->principal);
+ if (cred->keytab != NULL)
+ krb5_kt_close(_gsskrb5_context, cred->keytab);
+ if (cred->ccache != NULL) {
const krb5_cc_ops *ops;
- ops = krb5_cc_get_ops(gssapi_krb5_context, (*cred_handle)->ccache);
- if ((*cred_handle)->cred_flags & GSS_CF_DESTROY_CRED_ON_RELEASE)
- krb5_cc_destroy(gssapi_krb5_context, (*cred_handle)->ccache);
+ ops = krb5_cc_get_ops(_gsskrb5_context, cred->ccache);
+ if (cred->cred_flags & GSS_CF_DESTROY_CRED_ON_RELEASE)
+ krb5_cc_destroy(_gsskrb5_context, cred->ccache);
else
- krb5_cc_close(gssapi_krb5_context, (*cred_handle)->ccache);
+ krb5_cc_close(_gsskrb5_context, cred->ccache);
}
- gss_release_oid_set(NULL, &(*cred_handle)->mechanisms);
- HEIMDAL_MUTEX_unlock(&(*cred_handle)->cred_id_mutex);
- HEIMDAL_MUTEX_destroy(&(*cred_handle)->cred_id_mutex);
- memset(*cred_handle, 0, sizeof(**cred_handle));
- free(*cred_handle);
- *cred_handle = GSS_C_NO_CREDENTIAL;
+ _gsskrb5_release_oid_set(NULL, &cred->mechanisms);
+ HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
+ HEIMDAL_MUTEX_destroy(&cred->cred_id_mutex);
+ memset(cred, 0, sizeof(*cred));
+ free(cred);
return GSS_S_COMPLETE;
}
diff --git a/source4/heimdal/lib/gssapi/release_name.c b/source4/heimdal/lib/gssapi/krb5/release_name.c
index 6894ffae49..a92ad939a5 100644
--- a/source4/heimdal/lib/gssapi/release_name.c
+++ b/source4/heimdal/lib/gssapi/krb5/release_name.c
@@ -31,20 +31,25 @@
* SUCH DAMAGE.
*/
-#include "gssapi_locl.h"
+#include "krb5/gsskrb5_locl.h"
-RCSID("$Id: release_name.c,v 1.7 2003/03/16 17:52:48 lha Exp $");
+RCSID("$Id: release_name.c,v 1.10 2006/10/07 22:15:26 lha Exp $");
-OM_uint32 gss_release_name
+OM_uint32 _gsskrb5_release_name
(OM_uint32 * minor_status,
gss_name_t * input_name
)
{
+ krb5_principal name = (krb5_principal)*input_name;
+
GSSAPI_KRB5_INIT ();
+
if (minor_status)
*minor_status = 0;
- krb5_free_principal(gssapi_krb5_context,
- *input_name);
+
*input_name = GSS_C_NO_NAME;
+
+ krb5_free_principal(_gsskrb5_context, name);
+
return GSS_S_COMPLETE;
}
diff --git a/source4/heimdal/lib/gssapi/release_oid_set.c b/source4/heimdal/lib/gssapi/krb5/release_oid_set.c
index 04eb01565f..a9f79a3082 100644
--- a/source4/heimdal/lib/gssapi/release_oid_set.c
+++ b/source4/heimdal/lib/gssapi/krb5/release_oid_set.c
@@ -31,11 +31,11 @@
* SUCH DAMAGE.
*/
-#include "gssapi_locl.h"
+#include "krb5/gsskrb5_locl.h"
-RCSID("$Id: release_oid_set.c,v 1.5 2003/03/16 17:53:25 lha Exp $");
+RCSID("$Id: release_oid_set.c,v 1.7 2006/10/07 22:15:30 lha Exp $");
-OM_uint32 gss_release_oid_set
+OM_uint32 _gsskrb5_release_oid_set
(OM_uint32 * minor_status,
gss_OID_set * set
)
diff --git a/source4/heimdal/lib/gssapi/sequence.c b/source4/heimdal/lib/gssapi/krb5/sequence.c
index 35a9b924af..3014edd04d 100755
--- a/source4/heimdal/lib/gssapi/sequence.c
+++ b/source4/heimdal/lib/gssapi/krb5/sequence.c
@@ -31,9 +31,9 @@
* SUCH DAMAGE.
*/
-#include "gssapi_locl.h"
+#include "krb5/gsskrb5_locl.h"
-RCSID("$Id: sequence.c,v 1.6 2006/04/12 17:43:39 lha Exp $");
+RCSID("$Id: sequence.c,v 1.8 2006/10/07 22:15:32 lha Exp $");
#define DEFAULT_JITTER_WINDOW 20
@@ -159,8 +159,8 @@ _gssapi_msg_order_check(struct gss_msg_order *o, OM_uint32 seq_num)
r = (o->flags & (GSS_C_REPLAY_FLAG|GSS_C_SEQUENCE_FLAG))==GSS_C_REPLAY_FLAG;
- /* sequence number larger than largest sequence number
- * or smaller than the first sequence number */
+ /* sequence number larger then largest sequence number
+ * or smaller then the first sequence number */
if (seq_num > o->elem[0]
|| seq_num < o->first_seq
|| o->length == 0)
diff --git a/source4/heimdal/lib/gssapi/krb5/set_cred_option.c b/source4/heimdal/lib/gssapi/krb5/set_cred_option.c
new file mode 100644
index 0000000000..5807ef0166
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/krb5/set_cred_option.c
@@ -0,0 +1,152 @@
+/*
+ * 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 "krb5/gsskrb5_locl.h"
+
+RCSID("$Id: set_cred_option.c,v 1.4 2006/10/24 20:14:13 lha Exp $");
+
+static gss_OID_desc gss_krb5_import_cred_x_oid_desc =
+{9, (void *)"\x2b\x06\x01\x04\x01\xa9\x4a\x13\x04"}; /* XXX */
+
+gss_OID GSS_KRB5_IMPORT_CRED_X = &gss_krb5_import_cred_x_oid_desc;
+
+static OM_uint32
+import_cred(OM_uint32 *minor_status,
+ gss_cred_id_t *cred_handle,
+ const gss_buffer_t value)
+{
+ OM_uint32 major_stat;
+ krb5_error_code ret;
+ krb5_principal keytab_principal = NULL;
+ krb5_keytab keytab = NULL;
+ krb5_storage *sp = NULL;
+ krb5_ccache id = NULL;
+ char *str;
+
+ if (cred_handle == NULL || *cred_handle != GSS_C_NO_CREDENTIAL) {
+ *minor_status = 0;
+ return GSS_S_FAILURE;
+ }
+
+ sp = krb5_storage_from_mem(value->value, value->length);
+ if (sp == NULL) {
+ *minor_status = 0;
+ return GSS_S_FAILURE;
+ }
+
+ /* credential cache name */
+ ret = krb5_ret_string(sp, &str);
+ if (ret) {
+ *minor_status = ret;
+ major_stat = GSS_S_FAILURE;
+ goto out;
+ }
+ if (str[0]) {
+ ret = krb5_cc_resolve(_gsskrb5_context, str, &id);
+ if (ret) {
+ *minor_status = ret;
+ major_stat = GSS_S_FAILURE;
+ goto out;
+ }
+ }
+ free(str);
+ str = NULL;
+
+ /* keytab principal name */
+ ret = krb5_ret_string(sp, &str);
+ if (ret == 0 && str[0])
+ ret = krb5_parse_name(_gsskrb5_context, str, &keytab_principal);
+ if (ret) {
+ *minor_status = ret;
+ major_stat = GSS_S_FAILURE;
+ goto out;
+ }
+ free(str);
+ str = NULL;
+
+ /* keytab principal */
+ ret = krb5_ret_string(sp, &str);
+ if (ret) {
+ *minor_status = ret;
+ major_stat = GSS_S_FAILURE;
+ goto out;
+ }
+ if (str[0]) {
+ ret = krb5_kt_resolve(_gsskrb5_context, str, &keytab);
+ if (ret) {
+ *minor_status = ret;
+ major_stat = GSS_S_FAILURE;
+ goto out;
+ }
+ }
+ free(str);
+ str = NULL;
+
+ major_stat = _gsskrb5_import_cred(minor_status, id, keytab_principal,
+ keytab, cred_handle);
+out:
+ if (id)
+ krb5_cc_close(_gsskrb5_context, id);
+ if (keytab_principal)
+ krb5_free_principal(_gsskrb5_context, keytab_principal);
+ if (keytab)
+ krb5_kt_close(_gsskrb5_context, keytab);
+ if (str)
+ free(str);
+ if (sp)
+ krb5_storage_free(sp);
+
+ return major_stat;
+}
+
+
+OM_uint32
+_gsskrb5_set_cred_option
+ (OM_uint32 *minor_status,
+ gss_cred_id_t *cred_handle,
+ const gss_OID desired_object,
+ const gss_buffer_t value)
+{
+ GSSAPI_KRB5_INIT ();
+
+ if (value == GSS_C_NO_BUFFER) {
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ if (gss_oid_equal(desired_object, GSS_KRB5_IMPORT_CRED_X)) {
+ return import_cred(minor_status, cred_handle, value);
+ }
+
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+}
diff --git a/source4/heimdal/lib/gssapi/krb5/set_sec_context_option.c b/source4/heimdal/lib/gssapi/krb5/set_sec_context_option.c
new file mode 100644
index 0000000000..67f5e8e722
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/krb5/set_sec_context_option.c
@@ -0,0 +1,147 @@
+/*
+ * 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.
+ */
+
+/*
+ * glue routine for _gsskrb5_inquire_sec_context_by_oid
+ */
+
+#include "krb5/gsskrb5_locl.h"
+
+RCSID("$Id: set_sec_context_option.c,v 1.6 2006/10/20 18:58:22 lha Exp $");
+
+static OM_uint32
+get_bool(OM_uint32 *minor_status,
+ const gss_buffer_t value,
+ int *flag)
+{
+ if (value->value == NULL || value->length != 1) {
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+ *flag = *((const char *)value->value) != 0;
+ return GSS_S_COMPLETE;
+}
+
+OM_uint32
+_gsskrb5_set_sec_context_option
+ (OM_uint32 *minor_status,
+ gss_ctx_id_t *context_handle,
+ const gss_OID desired_object,
+ const gss_buffer_t value)
+{
+ OM_uint32 maj_stat;
+
+ GSSAPI_KRB5_INIT ();
+
+ if (value == GSS_C_NO_BUFFER) {
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ if (gss_oid_equal(desired_object, GSS_KRB5_COMPAT_DES3_MIC_X)) {
+ gsskrb5_ctx ctx;
+ int flag;
+
+ if (*context_handle == GSS_C_NO_CONTEXT) {
+ *minor_status = EINVAL;
+ return GSS_S_NO_CONTEXT;
+ }
+
+ maj_stat = get_bool(minor_status, value, &flag);
+ if (maj_stat != GSS_S_COMPLETE)
+ return maj_stat;
+
+ ctx = (gsskrb5_ctx)*context_handle;
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+ if (flag)
+ ctx->more_flags |= COMPAT_OLD_DES3;
+ else
+ ctx->more_flags &= ~COMPAT_OLD_DES3;
+ ctx->more_flags |= COMPAT_OLD_DES3_SELECTED;
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ return GSS_S_COMPLETE;
+ } else if (gss_oid_equal(desired_object, GSS_KRB5_SET_DNS_CANONICALIZE_X)) {
+ int flag;
+
+ maj_stat = get_bool(minor_status, value, &flag);
+ if (maj_stat != GSS_S_COMPLETE)
+ return maj_stat;
+
+ krb5_set_dns_canonicalize_hostname(_gsskrb5_context, flag);
+ return GSS_S_COMPLETE;
+
+ } else if (gss_oid_equal(desired_object, GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_X)) {
+ char *str;
+
+ if (value == NULL || value->length == 0) {
+ str = NULL;
+ } else {
+ str = malloc(value->length + 1);
+ if (str) {
+ *minor_status = 0;
+ return GSS_S_UNAVAILABLE;
+ }
+ memcpy(str, value->value, value->length);
+ str[value->length] = '\0';
+ }
+
+ _gsskrb5_register_acceptor_identity(str);
+ free(str);
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+
+ } else if (gss_oid_equal(desired_object, GSS_KRB5_SEND_TO_KDC_X)) {
+
+ if (value == NULL || value->length == 0) {
+ krb5_set_send_to_kdc_func(_gsskrb5_context, NULL, NULL);
+ } else {
+ struct gsskrb5_send_to_kdc c;
+
+ if (value->length != sizeof(c)) {
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+ memcpy(&c, value->value, sizeof(c));
+ krb5_set_send_to_kdc_func(_gsskrb5_context,
+ (krb5_send_to_kdc_func)c.func,
+ c.ptr);
+ }
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+ }
+
+
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+}
diff --git a/source4/heimdal/lib/gssapi/test_oid_set_member.c b/source4/heimdal/lib/gssapi/krb5/test_oid_set_member.c
index e747c5acc1..5a0ac4418f 100644
--- a/source4/heimdal/lib/gssapi/test_oid_set_member.c
+++ b/source4/heimdal/lib/gssapi/krb5/test_oid_set_member.c
@@ -31,25 +31,25 @@
* SUCH DAMAGE.
*/
-#include "gssapi_locl.h"
+#include "krb5/gsskrb5_locl.h"
-RCSID("$Id: test_oid_set_member.c,v 1.5 2003/03/16 17:54:06 lha Exp $");
+RCSID("$Id: test_oid_set_member.c,v 1.7 2006/10/07 22:15:50 lha Exp $");
-OM_uint32 gss_test_oid_set_member (
- OM_uint32 * minor_status,
+OM_uint32 _gsskrb5_test_oid_set_member
+ (OM_uint32 * minor_status,
const gss_OID member,
const gss_OID_set set,
int * present
)
{
- size_t i;
+ size_t i;
- *minor_status = 0;
- *present = 0;
- for (i = 0; i < set->count; ++i)
- if (gss_oid_equal(member, &set->elements[i]) != 0) {
- *present = 1;
- break;
- }
- return GSS_S_COMPLETE;
+ *minor_status = 0;
+ *present = 0;
+ for (i = 0; i < set->count; ++i)
+ if (gss_oid_equal(member, &set->elements[i]) != 0) {
+ *present = 1;
+ break;
+ }
+ return GSS_S_COMPLETE;
}
diff --git a/source4/heimdal/lib/gssapi/unwrap.c b/source4/heimdal/lib/gssapi/krb5/unwrap.c
index c358c1aa24..758390080c 100644
--- a/source4/heimdal/lib/gssapi/unwrap.c
+++ b/source4/heimdal/lib/gssapi/krb5/unwrap.c
@@ -31,14 +31,14 @@
* SUCH DAMAGE.
*/
-#include "gssapi_locl.h"
+#include "krb5/gsskrb5_locl.h"
-RCSID("$Id: unwrap.c,v 1.34 2005/04/27 17:50:40 lha Exp $");
+RCSID("$Id: unwrap.c,v 1.38 2006/10/18 15:59:28 lha Exp $");
static OM_uint32
unwrap_des
(OM_uint32 * minor_status,
- const gss_ctx_id_t context_handle,
+ const gsskrb5_ctx context_handle,
const gss_buffer_t input_message_buffer,
gss_buffer_t output_message_buffer,
int * conf_state,
@@ -54,14 +54,14 @@ unwrap_des
DES_cblock deskey;
DES_cblock zero;
int i;
- int32_t seq_number;
+ uint32_t seq_number;
size_t padlength;
OM_uint32 ret;
int cstate;
int cmp;
p = input_message_buffer->value;
- ret = gssapi_krb5_verify_header (&p,
+ ret = _gsskrb5_verify_header (&p,
input_message_buffer->length,
"\x02\x01",
GSS_KRB5_MECHANISM);
@@ -138,7 +138,7 @@ unwrap_des
memset (&schedule, 0, sizeof(schedule));
seq = p;
- gssapi_decode_om_uint32(seq, &seq_number);
+ _gsskrb5_decode_om_uint32(seq, &seq_number);
if (context_handle->more_flags & LOCAL)
cmp = memcmp(&seq[4], "\xff\xff\xff\xff", 4);
@@ -174,7 +174,7 @@ unwrap_des
static OM_uint32
unwrap_des3
(OM_uint32 * minor_status,
- const gss_ctx_id_t context_handle,
+ const gsskrb5_ctx context_handle,
const gss_buffer_t input_message_buffer,
gss_buffer_t output_message_buffer,
int * conf_state,
@@ -187,7 +187,7 @@ unwrap_des3
u_char *seq;
krb5_data seq_data;
u_char cksum[20];
- int32_t seq_number;
+ uint32_t seq_number;
size_t padlength;
OM_uint32 ret;
int cstate;
@@ -196,7 +196,7 @@ unwrap_des3
int cmp;
p = input_message_buffer->value;
- ret = gssapi_krb5_verify_header (&p,
+ ret = _gsskrb5_verify_header (&p,
input_message_buffer->length,
"\x02\x01",
GSS_KRB5_MECHANISM);
@@ -226,18 +226,18 @@ unwrap_des3
/* decrypt data */
krb5_data tmp;
- ret = krb5_crypto_init(gssapi_krb5_context, key,
+ ret = krb5_crypto_init(_gsskrb5_context, key,
ETYPE_DES3_CBC_NONE, &crypto);
if (ret) {
- gssapi_krb5_set_error_string ();
+ _gsskrb5_set_error_string ();
*minor_status = ret;
return GSS_S_FAILURE;
}
- ret = krb5_decrypt(gssapi_krb5_context, crypto, KRB5_KU_USAGE_SEAL,
+ ret = krb5_decrypt(_gsskrb5_context, crypto, KRB5_KU_USAGE_SEAL,
p, input_message_buffer->length - len, &tmp);
- krb5_crypto_destroy(gssapi_krb5_context, crypto);
+ krb5_crypto_destroy(_gsskrb5_context, crypto);
if (ret) {
- gssapi_krb5_set_error_string ();
+ _gsskrb5_set_error_string ();
*minor_status = ret;
return GSS_S_FAILURE;
}
@@ -259,10 +259,10 @@ unwrap_des3
p -= 28;
- ret = krb5_crypto_init(gssapi_krb5_context, key,
+ ret = krb5_crypto_init(_gsskrb5_context, key,
ETYPE_DES3_CBC_NONE, &crypto);
if (ret) {
- gssapi_krb5_set_error_string ();
+ _gsskrb5_set_error_string ();
*minor_status = ret;
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
return GSS_S_FAILURE;
@@ -271,15 +271,15 @@ unwrap_des3
DES_cblock ivec;
memcpy(&ivec, p + 8, 8);
- ret = krb5_decrypt_ivec (gssapi_krb5_context,
+ ret = krb5_decrypt_ivec (_gsskrb5_context,
crypto,
KRB5_KU_USAGE_SEQ,
p, 8, &seq_data,
&ivec);
}
- krb5_crypto_destroy (gssapi_krb5_context, crypto);
+ krb5_crypto_destroy (_gsskrb5_context, crypto);
if (ret) {
- gssapi_krb5_set_error_string ();
+ _gsskrb5_set_error_string ();
*minor_status = ret;
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
return GSS_S_FAILURE;
@@ -292,7 +292,7 @@ unwrap_des3
}
seq = seq_data.data;
- gssapi_decode_om_uint32(seq, &seq_number);
+ _gsskrb5_decode_om_uint32(seq, &seq_number);
if (context_handle->more_flags & LOCAL)
cmp = memcmp(&seq[4], "\xff\xff\xff\xff", 4);
@@ -325,21 +325,21 @@ unwrap_des3
csum.checksum.length = 20;
csum.checksum.data = cksum;
- ret = krb5_crypto_init(gssapi_krb5_context, key, 0, &crypto);
+ ret = krb5_crypto_init(_gsskrb5_context, key, 0, &crypto);
if (ret) {
- gssapi_krb5_set_error_string ();
+ _gsskrb5_set_error_string ();
*minor_status = ret;
return GSS_S_FAILURE;
}
- ret = krb5_verify_checksum (gssapi_krb5_context, crypto,
+ ret = krb5_verify_checksum (_gsskrb5_context, crypto,
KRB5_KU_USAGE_SIGN,
p + 20,
input_message_buffer->length - len + 8,
&csum);
- krb5_crypto_destroy (gssapi_krb5_context, crypto);
+ krb5_crypto_destroy (_gsskrb5_context, crypto);
if (ret) {
- gssapi_krb5_set_error_string ();
+ _gsskrb5_set_error_string ();
*minor_status = ret;
return GSS_S_FAILURE;
}
@@ -357,7 +357,7 @@ unwrap_des3
return GSS_S_COMPLETE;
}
-OM_uint32 gss_unwrap
+OM_uint32 _gsskrb5_unwrap
(OM_uint32 * minor_status,
const gss_ctx_id_t context_handle,
const gss_buffer_t input_message_buffer,
@@ -369,45 +369,48 @@ OM_uint32 gss_unwrap
krb5_keyblock *key;
OM_uint32 ret;
krb5_keytype keytype;
+ gsskrb5_ctx ctx = (gsskrb5_ctx) context_handle;
output_message_buffer->value = NULL;
output_message_buffer->length = 0;
if (qop_state != NULL)
*qop_state = GSS_C_QOP_DEFAULT;
- ret = gss_krb5_get_subkey(context_handle, &key);
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+ ret = _gsskrb5i_get_token_key(ctx, &key);
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
if (ret) {
- gssapi_krb5_set_error_string ();
+ _gsskrb5_set_error_string ();
*minor_status = ret;
return GSS_S_FAILURE;
}
- krb5_enctype_to_keytype (gssapi_krb5_context, key->keytype, &keytype);
+ krb5_enctype_to_keytype (_gsskrb5_context, key->keytype, &keytype);
*minor_status = 0;
switch (keytype) {
case KEYTYPE_DES :
- ret = unwrap_des (minor_status, context_handle,
+ ret = unwrap_des (minor_status, ctx,
input_message_buffer, output_message_buffer,
conf_state, qop_state, key);
break;
case KEYTYPE_DES3 :
- ret = unwrap_des3 (minor_status, context_handle,
+ ret = unwrap_des3 (minor_status, ctx,
input_message_buffer, output_message_buffer,
conf_state, qop_state, key);
break;
case KEYTYPE_ARCFOUR:
case KEYTYPE_ARCFOUR_56:
- ret = _gssapi_unwrap_arcfour (minor_status, context_handle,
+ ret = _gssapi_unwrap_arcfour (minor_status, ctx,
input_message_buffer, output_message_buffer,
conf_state, qop_state, key);
break;
default :
- ret = _gssapi_unwrap_cfx (minor_status, context_handle,
+ ret = _gssapi_unwrap_cfx (minor_status, ctx,
input_message_buffer, output_message_buffer,
conf_state, qop_state, key);
break;
}
- krb5_free_keyblock (gssapi_krb5_context, key);
+ krb5_free_keyblock (_gsskrb5_context, key);
return ret;
}
diff --git a/source4/heimdal/lib/gssapi/verify_mic.c b/source4/heimdal/lib/gssapi/krb5/verify_mic.c
index 7b7d437e99..920937cafc 100644
--- a/source4/heimdal/lib/gssapi/verify_mic.c
+++ b/source4/heimdal/lib/gssapi/krb5/verify_mic.c
@@ -31,14 +31,14 @@
* SUCH DAMAGE.
*/
-#include "gssapi_locl.h"
+#include "krb5/gsskrb5_locl.h"
-RCSID("$Id: verify_mic.c,v 1.32 2005/04/27 17:51:04 lha Exp $");
+RCSID("$Id: verify_mic.c,v 1.36 2006/10/18 15:59:30 lha Exp $");
static OM_uint32
verify_mic_des
(OM_uint32 * minor_status,
- const gss_ctx_id_t context_handle,
+ const gsskrb5_ctx context_handle,
const gss_buffer_t message_buffer,
const gss_buffer_t token_buffer,
gss_qop_t * qop_state,
@@ -52,12 +52,12 @@ verify_mic_des
DES_key_schedule schedule;
DES_cblock zero;
DES_cblock deskey;
- int32_t seq_number;
+ uint32_t seq_number;
OM_uint32 ret;
int cmp;
p = token_buffer->value;
- ret = gssapi_krb5_verify_header (&p,
+ ret = _gsskrb5_verify_header (&p,
token_buffer->length,
type,
GSS_KRB5_MECHANISM);
@@ -104,7 +104,7 @@ verify_mic_des
memset (&schedule, 0, sizeof(schedule));
seq = p;
- gssapi_decode_om_uint32(seq, &seq_number);
+ _gsskrb5_decode_om_uint32(seq, &seq_number);
if (context_handle->more_flags & LOCAL)
cmp = memcmp(&seq[4], "\xff\xff\xff\xff", 4);
@@ -130,7 +130,7 @@ verify_mic_des
static OM_uint32
verify_mic_des3
(OM_uint32 * minor_status,
- const gss_ctx_id_t context_handle,
+ const gsskrb5_ctx context_handle,
const gss_buffer_t message_buffer,
const gss_buffer_t token_buffer,
gss_qop_t * qop_state,
@@ -140,7 +140,7 @@ verify_mic_des3
{
u_char *p;
u_char *seq;
- int32_t seq_number;
+ uint32_t seq_number;
OM_uint32 ret;
krb5_crypto crypto;
krb5_data seq_data;
@@ -150,7 +150,7 @@ verify_mic_des3
char ivec[8];
p = token_buffer->value;
- ret = gssapi_krb5_verify_header (&p,
+ ret = _gsskrb5_verify_header (&p,
token_buffer->length,
type,
GSS_KRB5_MECHANISM);
@@ -164,10 +164,10 @@ verify_mic_des3
return GSS_S_BAD_MIC;
p += 4;
- ret = krb5_crypto_init(gssapi_krb5_context, key,
+ ret = krb5_crypto_init(_gsskrb5_context, key,
ETYPE_DES3_CBC_NONE, &crypto);
if (ret){
- gssapi_krb5_set_error_string ();
+ _gsskrb5_set_error_string ();
*minor_status = ret;
return GSS_S_FAILURE;
}
@@ -180,14 +180,14 @@ retry:
else
memcpy(ivec, p + 8, 8);
- ret = krb5_decrypt_ivec (gssapi_krb5_context,
+ ret = krb5_decrypt_ivec (_gsskrb5_context,
crypto,
KRB5_KU_USAGE_SEQ,
p, 8, &seq_data, ivec);
if (ret) {
if (docompat++) {
- gssapi_krb5_set_error_string ();
- krb5_crypto_destroy (gssapi_krb5_context, crypto);
+ _gsskrb5_set_error_string ();
+ krb5_crypto_destroy (_gsskrb5_context, crypto);
*minor_status = ret;
return GSS_S_FAILURE;
} else
@@ -197,7 +197,7 @@ retry:
if (seq_data.length != 8) {
krb5_data_free (&seq_data);
if (docompat++) {
- krb5_crypto_destroy (gssapi_krb5_context, crypto);
+ krb5_crypto_destroy (_gsskrb5_context, crypto);
return GSS_S_BAD_MIC;
} else
goto retry;
@@ -206,7 +206,7 @@ retry:
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
seq = seq_data.data;
- gssapi_decode_om_uint32(seq, &seq_number);
+ _gsskrb5_decode_om_uint32(seq, &seq_number);
if (context_handle->more_flags & LOCAL)
cmp = memcmp(&seq[4], "\xff\xff\xff\xff", 4);
@@ -215,7 +215,7 @@ retry:
krb5_data_free (&seq_data);
if (cmp != 0) {
- krb5_crypto_destroy (gssapi_krb5_context, crypto);
+ krb5_crypto_destroy (_gsskrb5_context, crypto);
*minor_status = 0;
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
return GSS_S_BAD_MIC;
@@ -223,7 +223,7 @@ retry:
ret = _gssapi_msg_order_check(context_handle->order, seq_number);
if (ret) {
- krb5_crypto_destroy (gssapi_krb5_context, crypto);
+ krb5_crypto_destroy (_gsskrb5_context, crypto);
*minor_status = 0;
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
return ret;
@@ -233,7 +233,7 @@ retry:
tmp = malloc (message_buffer->length + 8);
if (tmp == NULL) {
- krb5_crypto_destroy (gssapi_krb5_context, crypto);
+ krb5_crypto_destroy (_gsskrb5_context, crypto);
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
*minor_status = ENOMEM;
return GSS_S_FAILURE;
@@ -246,28 +246,28 @@ retry:
csum.checksum.length = 20;
csum.checksum.data = p + 8;
- ret = krb5_verify_checksum (gssapi_krb5_context, crypto,
+ ret = krb5_verify_checksum (_gsskrb5_context, crypto,
KRB5_KU_USAGE_SIGN,
tmp, message_buffer->length + 8,
&csum);
free (tmp);
if (ret) {
- gssapi_krb5_set_error_string ();
- krb5_crypto_destroy (gssapi_krb5_context, crypto);
+ _gsskrb5_set_error_string ();
+ krb5_crypto_destroy (_gsskrb5_context, crypto);
*minor_status = ret;
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
return GSS_S_BAD_MIC;
}
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
- krb5_crypto_destroy (gssapi_krb5_context, crypto);
+ krb5_crypto_destroy (_gsskrb5_context, crypto);
return GSS_S_COMPLETE;
}
OM_uint32
-gss_verify_mic_internal
+_gsskrb5_verify_mic_internal
(OM_uint32 * minor_status,
- const gss_ctx_id_t context_handle,
+ const gsskrb5_ctx context_handle,
const gss_buffer_t message_buffer,
const gss_buffer_t token_buffer,
gss_qop_t * qop_state,
@@ -278,14 +278,16 @@ gss_verify_mic_internal
OM_uint32 ret;
krb5_keytype keytype;
- ret = gss_krb5_get_subkey(context_handle, &key);
+ HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
+ ret = _gsskrb5i_get_token_key(context_handle, &key);
+ HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
if (ret) {
- gssapi_krb5_set_error_string ();
+ _gsskrb5_set_error_string ();
*minor_status = ret;
return GSS_S_FAILURE;
}
*minor_status = 0;
- krb5_enctype_to_keytype (gssapi_krb5_context, key->keytype, &keytype);
+ krb5_enctype_to_keytype (_gsskrb5_context, key->keytype, &keytype);
switch (keytype) {
case KEYTYPE_DES :
ret = verify_mic_des (minor_status, context_handle,
@@ -309,13 +311,13 @@ gss_verify_mic_internal
key);
break;
}
- krb5_free_keyblock (gssapi_krb5_context, key);
+ krb5_free_keyblock (_gsskrb5_context, key);
return ret;
}
OM_uint32
-gss_verify_mic
+_gsskrb5_verify_mic
(OM_uint32 * minor_status,
const gss_ctx_id_t context_handle,
const gss_buffer_t message_buffer,
@@ -328,9 +330,10 @@ gss_verify_mic
if (qop_state != NULL)
*qop_state = GSS_C_QOP_DEFAULT;
- ret = gss_verify_mic_internal(minor_status, context_handle,
- message_buffer, token_buffer,
- qop_state, "\x01\x01");
+ ret = _gsskrb5_verify_mic_internal(minor_status,
+ (gsskrb5_ctx)context_handle,
+ message_buffer, token_buffer,
+ qop_state, "\x01\x01");
return ret;
}
diff --git a/source4/heimdal/lib/gssapi/wrap.c b/source4/heimdal/lib/gssapi/krb5/wrap.c
index 7072ca2754..8514137999 100644
--- a/source4/heimdal/lib/gssapi/wrap.c
+++ b/source4/heimdal/lib/gssapi/krb5/wrap.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997 - 2003 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2003 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -31,110 +31,84 @@
* SUCH DAMAGE.
*/
-#include "gssapi_locl.h"
+#include "krb5/gsskrb5_locl.h"
-RCSID("$Id: wrap.c,v 1.33 2006/05/05 10:27:36 lha Exp $");
+RCSID("$Id: wrap.c,v 1.37 2006/10/18 15:59:33 lha Exp $");
-OM_uint32
-gsskrb5_get_initiator_subkey(OM_uint32 *minor_status,
- gss_ctx_id_t context_handle,
- gss_buffer_t key)
+/*
+ * Return initiator subkey, or if that doesn't exists, the subkey.
+ */
+
+krb5_error_code
+_gsskrb5i_get_initiator_subkey(const gsskrb5_ctx ctx, krb5_keyblock **key)
{
krb5_error_code ret;
- krb5_keyblock *skey = NULL;
-
- HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
- if (context_handle->more_flags & LOCAL) {
- ret = krb5_auth_con_getlocalsubkey(gssapi_krb5_context,
- context_handle->auth_context,
- &skey);
- if (ret) {
- *minor_status = ret;
- return GSS_KRB5_S_KG_NO_SUBKEY; /* XXX */
- }
-
+ *key = NULL;
+
+ if (ctx->more_flags & LOCAL) {
+ ret = krb5_auth_con_getlocalsubkey(_gsskrb5_context,
+ ctx->auth_context,
+ key);
} else {
- ret = krb5_auth_con_getremotesubkey(gssapi_krb5_context,
- context_handle->auth_context,
- &skey);
- if (ret) {
- *minor_status = ret;
- return GSS_KRB5_S_KG_NO_SUBKEY; /* XXX */
- }
-
+ ret = krb5_auth_con_getremotesubkey(_gsskrb5_context,
+ ctx->auth_context,
+ key);
}
-
- /* If there was no subkey, perhaps try this... */
- if(skey == NULL) {
- krb5_auth_con_getkey(gssapi_krb5_context,
- context_handle->auth_context,
- &skey);
+ if (*key == NULL)
+ ret = krb5_auth_con_getkey(_gsskrb5_context,
+ ctx->auth_context,
+ key);
+ if (*key == NULL) {
+ _gsskrb5_set_status("No initiator subkey available");
+ return GSS_KRB5_S_KG_NO_SUBKEY;
}
+ return ret;
+}
- HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+krb5_error_code
+_gsskrb5i_get_acceptor_subkey(const gsskrb5_ctx ctx, krb5_keyblock **key)
+{
+ krb5_error_code ret;
+ *key = NULL;
- /* ensure never to segfault */
- if(skey == NULL) {
- return GSS_KRB5_S_KG_NO_SUBKEY; /* XXX */
+ if (ctx->more_flags & LOCAL) {
+ ret = krb5_auth_con_getremotesubkey(_gsskrb5_context,
+ ctx->auth_context,
+ key);
+ } else {
+ ret = krb5_auth_con_getlocalsubkey(_gsskrb5_context,
+ ctx->auth_context,
+ key);
}
-
- key->length = skey->keyvalue.length;
- key->value = malloc (key->length);
- if (!key->value) {
- krb5_free_keyblock(gssapi_krb5_context, skey);
- *minor_status = ENOMEM;
- return GSS_S_FAILURE;
+ if (*key == NULL) {
+ _gsskrb5_set_status("No acceptor subkey available");
+ return GSS_KRB5_S_KG_NO_SUBKEY;
}
- memcpy(key->value, skey->keyvalue.data, key->length);
- krb5_free_keyblock(gssapi_krb5_context, skey);
- return 0;
+ return ret;
}
OM_uint32
-gss_krb5_get_subkey(const gss_ctx_id_t context_handle,
- krb5_keyblock **key)
+_gsskrb5i_get_token_key(const gsskrb5_ctx ctx, krb5_keyblock **key)
{
- krb5_keyblock *skey = NULL;
-
- HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
- if (context_handle->more_flags & LOCAL) {
- krb5_auth_con_getremotesubkey(gssapi_krb5_context,
- context_handle->auth_context,
- &skey);
- } else {
- krb5_auth_con_getlocalsubkey(gssapi_krb5_context,
- context_handle->auth_context,
- &skey);
+ _gsskrb5i_get_acceptor_subkey(ctx, key);
+ if(*key == NULL) {
+ /*
+ * Only use the initiator subkey or ticket session key if an
+ * acceptor subkey was not required.
+ */
+ if ((ctx->more_flags & ACCEPTOR_SUBKEY) == 0)
+ _gsskrb5i_get_initiator_subkey(ctx, key);
}
- /*
- * Only use the initiator subkey or ticket session key if
- * an acceptor subkey was not required.
- */
- if (skey == NULL &&
- (context_handle->more_flags & ACCEPTOR_SUBKEY) == 0) {
- if (context_handle->more_flags & LOCAL) {
- krb5_auth_con_getlocalsubkey(gssapi_krb5_context,
- context_handle->auth_context,
- &skey);
- } else {
- krb5_auth_con_getremotesubkey(gssapi_krb5_context,
- context_handle->auth_context,
- &skey);
- }
- if(skey == NULL)
- krb5_auth_con_getkey(gssapi_krb5_context,
- context_handle->auth_context,
- &skey);
+ if (*key == NULL) {
+ _gsskrb5_set_status("No token key available");
+ return GSS_KRB5_S_KG_NO_SUBKEY;
}
- HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
- if(skey == NULL)
- return GSS_KRB5_S_KG_NO_SUBKEY; /* XXX */
- *key = skey;
+ _gsskrb5_clear_status();
return 0;
}
static OM_uint32
-sub_wrap_size_limit (
+sub_wrap_size (
OM_uint32 req_output_size,
OM_uint32 * max_input_size,
int blocksize,
@@ -145,7 +119,7 @@ sub_wrap_size_limit (
len = 8 + req_output_size + blocksize + extrasize;
- gssapi_krb5_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM);
+ _gsskrb5_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM);
total_len -= req_output_size; /* token length */
if (total_len < req_output_size) {
@@ -158,7 +132,7 @@ sub_wrap_size_limit (
}
OM_uint32
-gss_wrap_size_limit (
+_gsskrb5_wrap_size_limit (
OM_uint32 * minor_status,
const gss_ctx_id_t context_handle,
int conf_req_flag,
@@ -170,118 +144,38 @@ gss_wrap_size_limit (
krb5_keyblock *key;
OM_uint32 ret;
krb5_keytype keytype;
- OM_uint32 output_size;
- OM_uint32 blocksize;
+ const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle;
- ret = gss_krb5_get_subkey(context_handle, &key);
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+ ret = _gsskrb5i_get_token_key(ctx, &key);
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
if (ret) {
- gssapi_krb5_set_error_string ();
+ _gsskrb5_set_error_string ();
*minor_status = ret;
return GSS_S_FAILURE;
}
- krb5_enctype_to_keytype (gssapi_krb5_context, key->keytype, &keytype);
+ krb5_enctype_to_keytype (_gsskrb5_context, key->keytype, &keytype);
switch (keytype) {
case KEYTYPE_DES :
- ret = sub_wrap_size_limit(req_output_size, max_input_size, 8, 22);
- break;
- case KEYTYPE_DES3 :
- ret = sub_wrap_size_limit(req_output_size, max_input_size, 8, 34);
+ ret = sub_wrap_size(req_output_size, max_input_size, 8, 22);
break;
case KEYTYPE_ARCFOUR:
case KEYTYPE_ARCFOUR_56:
- ret = _gssapi_wrap_size_arcfour(minor_status, context_handle,
+ ret = _gssapi_wrap_size_arcfour(minor_status, ctx,
conf_req_flag, qop_req,
- req_output_size, &output_size,
- &blocksize, key);
-
- if (output_size > req_output_size) {
- *max_input_size = req_output_size - (output_size - req_output_size);
- (*max_input_size) &= (~(OM_uint32)(blocksize - 1));
- } else {
- *max_input_size = 0;
- }
- break;
- default :
- ret = _gssapi_wrap_size_cfx(minor_status, context_handle,
- conf_req_flag, qop_req,
- req_output_size, &output_size,
- &blocksize, key);
- if (output_size > req_output_size) {
- *max_input_size = req_output_size - (output_size - req_output_size);
- (*max_input_size) &= (~(OM_uint32)(blocksize - 1));
- } else {
- *max_input_size = 0;
- }
- break;
- }
- krb5_free_keyblock (gssapi_krb5_context, key);
- *minor_status = 0;
- return ret;
-}
-
-static OM_uint32
-sub_wrap_size (
- OM_uint32 req_input_size,
- OM_uint32 * output_size,
- int blocksize,
- int extrasize
- )
-{
- size_t len, total_len, padlength, datalen;
-
- padlength = blocksize - (req_input_size % blocksize);
- datalen = req_input_size + padlength + 8;
- len = datalen + extrasize;
- gssapi_krb5_encap_length (len, &len, &total_len, GSS_KRB5_MECHANISM);
-
- *output_size = total_len;
-
- return GSS_S_COMPLETE;
-}
-
-OM_uint32
-gsskrb5_wrap_size (
- OM_uint32 * minor_status,
- const gss_ctx_id_t context_handle,
- int conf_req_flag,
- gss_qop_t qop_req,
- OM_uint32 req_input_size,
- OM_uint32 * output_size
- )
-{
- krb5_keyblock *key;
- OM_uint32 ret, padlen;
- krb5_keytype keytype;
-
- ret = gss_krb5_get_subkey(context_handle, &key);
- if (ret) {
- gssapi_krb5_set_error_string ();
- *minor_status = ret;
- return GSS_S_FAILURE;
- }
- krb5_enctype_to_keytype (gssapi_krb5_context, key->keytype, &keytype);
-
- switch (keytype) {
- case KEYTYPE_DES :
- ret = sub_wrap_size(req_input_size, output_size, 8, 22);
+ req_output_size, max_input_size, key);
break;
case KEYTYPE_DES3 :
- ret = sub_wrap_size(req_input_size, output_size, 8, 34);
- break;
- case KEYTYPE_ARCFOUR:
- case KEYTYPE_ARCFOUR_56:
- ret = _gssapi_wrap_size_arcfour(minor_status, context_handle,
- conf_req_flag, qop_req,
- req_input_size, output_size, &padlen, key);
+ ret = sub_wrap_size(req_output_size, max_input_size, 8, 34);
break;
default :
- ret = _gssapi_wrap_size_cfx(minor_status, context_handle,
+ ret = _gssapi_wrap_size_cfx(minor_status, ctx,
conf_req_flag, qop_req,
- req_input_size, output_size, &padlen, key);
+ req_output_size, max_input_size, key);
break;
}
- krb5_free_keyblock (gssapi_krb5_context, key);
+ krb5_free_keyblock (_gsskrb5_context, key);
*minor_status = 0;
return ret;
}
@@ -289,7 +183,7 @@ gsskrb5_wrap_size (
static OM_uint32
wrap_des
(OM_uint32 * minor_status,
- const gss_ctx_id_t context_handle,
+ const gsskrb5_ctx ctx,
int conf_req_flag,
gss_qop_t qop_req,
const gss_buffer_t input_message_buffer,
@@ -311,7 +205,7 @@ wrap_des
padlength = 8 - (input_message_buffer->length % 8);
datalen = input_message_buffer->length + padlength + 8;
len = datalen + 22;
- gssapi_krb5_encap_length (len, &len, &total_len, GSS_KRB5_MECHANISM);
+ _gsskrb5_encap_length (len, &len, &total_len, GSS_KRB5_MECHANISM);
output_message_buffer->length = total_len;
output_message_buffer->value = malloc (total_len);
@@ -321,7 +215,7 @@ wrap_des
return GSS_S_FAILURE;
}
- p = gssapi_krb5_make_header(output_message_buffer->value,
+ p = _gsskrb5_make_header(output_message_buffer->value,
len,
"\x02\x01", /* TOK_ID */
GSS_KRB5_MECHANISM);
@@ -363,9 +257,9 @@ wrap_des
memcpy (p - 8, hash, 8);
/* sequence number */
- HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
- krb5_auth_con_getlocalseqnumber (gssapi_krb5_context,
- context_handle->auth_context,
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+ krb5_auth_con_getlocalseqnumber (_gsskrb5_context,
+ ctx->auth_context,
&seq_number);
p -= 16;
@@ -374,17 +268,17 @@ wrap_des
p[2] = (seq_number >> 16) & 0xFF;
p[3] = (seq_number >> 24) & 0xFF;
memset (p + 4,
- (context_handle->more_flags & LOCAL) ? 0 : 0xFF,
+ (ctx->more_flags & LOCAL) ? 0 : 0xFF,
4);
DES_set_key (&deskey, &schedule);
DES_cbc_encrypt ((void *)p, (void *)p, 8,
&schedule, (DES_cblock *)(p + 8), DES_ENCRYPT);
- krb5_auth_con_setlocalseqnumber (gssapi_krb5_context,
- context_handle->auth_context,
+ krb5_auth_con_setlocalseqnumber (_gsskrb5_context,
+ ctx->auth_context,
++seq_number);
- HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
/* encrypt the data */
p += 16;
@@ -415,7 +309,7 @@ wrap_des
static OM_uint32
wrap_des3
(OM_uint32 * minor_status,
- const gss_ctx_id_t context_handle,
+ const gsskrb5_ctx ctx,
int conf_req_flag,
gss_qop_t qop_req,
const gss_buffer_t input_message_buffer,
@@ -436,7 +330,7 @@ wrap_des3
padlength = 8 - (input_message_buffer->length % 8);
datalen = input_message_buffer->length + padlength + 8;
len = datalen + 34;
- gssapi_krb5_encap_length (len, &len, &total_len, GSS_KRB5_MECHANISM);
+ _gsskrb5_encap_length (len, &len, &total_len, GSS_KRB5_MECHANISM);
output_message_buffer->length = total_len;
output_message_buffer->value = malloc (total_len);
@@ -446,7 +340,7 @@ wrap_des3
return GSS_S_FAILURE;
}
- p = gssapi_krb5_make_header(output_message_buffer->value,
+ p = _gsskrb5_make_header(output_message_buffer->value,
len,
"\x02\x01", /* TOK_ID */
GSS_KRB5_MECHANISM);
@@ -472,9 +366,9 @@ wrap_des3
input_message_buffer->length);
memset (p + 28 + 8 + input_message_buffer->length, padlength, padlength);
- ret = krb5_crypto_init(gssapi_krb5_context, key, 0, &crypto);
+ ret = krb5_crypto_init(_gsskrb5_context, key, 0, &crypto);
if (ret) {
- gssapi_krb5_set_error_string ();
+ _gsskrb5_set_error_string ();
free (output_message_buffer->value);
output_message_buffer->length = 0;
output_message_buffer->value = NULL;
@@ -482,16 +376,16 @@ wrap_des3
return GSS_S_FAILURE;
}
- ret = krb5_create_checksum (gssapi_krb5_context,
+ ret = krb5_create_checksum (_gsskrb5_context,
crypto,
KRB5_KU_USAGE_SIGN,
0,
p + 20,
datalen + 8,
&cksum);
- krb5_crypto_destroy (gssapi_krb5_context, crypto);
+ krb5_crypto_destroy (_gsskrb5_context, crypto);
if (ret) {
- gssapi_krb5_set_error_string ();
+ _gsskrb5_set_error_string ();
free (output_message_buffer->value);
output_message_buffer->length = 0;
output_message_buffer->value = NULL;
@@ -505,10 +399,10 @@ wrap_des3
memcpy (p + 8, cksum.checksum.data, cksum.checksum.length);
free_Checksum (&cksum);
- HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
/* sequence number */
- krb5_auth_con_getlocalseqnumber (gssapi_krb5_context,
- context_handle->auth_context,
+ krb5_auth_con_getlocalseqnumber (_gsskrb5_context,
+ ctx->auth_context,
&seq_number);
seq[0] = (seq_number >> 0) & 0xFF;
@@ -516,11 +410,11 @@ wrap_des3
seq[2] = (seq_number >> 16) & 0xFF;
seq[3] = (seq_number >> 24) & 0xFF;
memset (seq + 4,
- (context_handle->more_flags & LOCAL) ? 0 : 0xFF,
+ (ctx->more_flags & LOCAL) ? 0 : 0xFF,
4);
- ret = krb5_crypto_init(gssapi_krb5_context, key, ETYPE_DES3_CBC_NONE,
+ ret = krb5_crypto_init(_gsskrb5_context, key, ETYPE_DES3_CBC_NONE,
&crypto);
if (ret) {
free (output_message_buffer->value);
@@ -534,15 +428,15 @@ wrap_des3
DES_cblock ivec;
memcpy (&ivec, p + 8, 8);
- ret = krb5_encrypt_ivec (gssapi_krb5_context,
+ ret = krb5_encrypt_ivec (_gsskrb5_context,
crypto,
KRB5_KU_USAGE_SEQ,
seq, 8, &encdata,
&ivec);
}
- krb5_crypto_destroy (gssapi_krb5_context, crypto);
+ krb5_crypto_destroy (_gsskrb5_context, crypto);
if (ret) {
- gssapi_krb5_set_error_string ();
+ _gsskrb5_set_error_string ();
free (output_message_buffer->value);
output_message_buffer->length = 0;
output_message_buffer->value = NULL;
@@ -555,10 +449,10 @@ wrap_des3
memcpy (p, encdata.data, encdata.length);
krb5_data_free (&encdata);
- krb5_auth_con_setlocalseqnumber (gssapi_krb5_context,
- context_handle->auth_context,
+ krb5_auth_con_setlocalseqnumber (_gsskrb5_context,
+ ctx->auth_context,
++seq_number);
- HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
/* encrypt the data */
p += 28;
@@ -566,21 +460,21 @@ wrap_des3
if(conf_req_flag) {
krb5_data tmp;
- ret = krb5_crypto_init(gssapi_krb5_context, key,
+ ret = krb5_crypto_init(_gsskrb5_context, key,
ETYPE_DES3_CBC_NONE, &crypto);
if (ret) {
- gssapi_krb5_set_error_string ();
+ _gsskrb5_set_error_string ();
free (output_message_buffer->value);
output_message_buffer->length = 0;
output_message_buffer->value = NULL;
*minor_status = ret;
return GSS_S_FAILURE;
}
- ret = krb5_encrypt(gssapi_krb5_context, crypto, KRB5_KU_USAGE_SEAL,
+ ret = krb5_encrypt(_gsskrb5_context, crypto, KRB5_KU_USAGE_SEAL,
p, datalen, &tmp);
- krb5_crypto_destroy(gssapi_krb5_context, crypto);
+ krb5_crypto_destroy(_gsskrb5_context, crypto);
if (ret) {
- gssapi_krb5_set_error_string ();
+ _gsskrb5_set_error_string ();
free (output_message_buffer->value);
output_message_buffer->length = 0;
output_message_buffer->value = NULL;
@@ -598,7 +492,7 @@ wrap_des3
return GSS_S_COMPLETE;
}
-OM_uint32 gss_wrap
+OM_uint32 _gsskrb5_wrap
(OM_uint32 * minor_status,
const gss_ctx_id_t context_handle,
int conf_req_flag,
@@ -611,38 +505,41 @@ OM_uint32 gss_wrap
krb5_keyblock *key;
OM_uint32 ret;
krb5_keytype keytype;
+ const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle;
- ret = gss_krb5_get_subkey(context_handle, &key);
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+ ret = _gsskrb5i_get_token_key(ctx, &key);
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
if (ret) {
- gssapi_krb5_set_error_string ();
+ _gsskrb5_set_error_string ();
*minor_status = ret;
return GSS_S_FAILURE;
}
- krb5_enctype_to_keytype (gssapi_krb5_context, key->keytype, &keytype);
+ krb5_enctype_to_keytype (_gsskrb5_context, key->keytype, &keytype);
switch (keytype) {
case KEYTYPE_DES :
- ret = wrap_des (minor_status, context_handle, conf_req_flag,
+ ret = wrap_des (minor_status, ctx, conf_req_flag,
qop_req, input_message_buffer, conf_state,
output_message_buffer, key);
break;
case KEYTYPE_DES3 :
- ret = wrap_des3 (minor_status, context_handle, conf_req_flag,
+ ret = wrap_des3 (minor_status, ctx, conf_req_flag,
qop_req, input_message_buffer, conf_state,
output_message_buffer, key);
break;
case KEYTYPE_ARCFOUR:
case KEYTYPE_ARCFOUR_56:
- ret = _gssapi_wrap_arcfour (minor_status, context_handle, conf_req_flag,
+ ret = _gssapi_wrap_arcfour (minor_status, ctx, conf_req_flag,
qop_req, input_message_buffer, conf_state,
output_message_buffer, key);
break;
default :
- ret = _gssapi_wrap_cfx (minor_status, context_handle, conf_req_flag,
+ ret = _gssapi_wrap_cfx (minor_status, ctx, conf_req_flag,
qop_req, input_message_buffer, conf_state,
output_message_buffer, key);
break;
}
- krb5_free_keyblock (gssapi_krb5_context, key);
+ krb5_free_keyblock (_gsskrb5_context, key);
return ret;
}
diff --git a/source4/heimdal/lib/gssapi/mech/context.h b/source4/heimdal/lib/gssapi/mech/context.h
new file mode 100644
index 0000000000..7a215dd7d8
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/context.h
@@ -0,0 +1,35 @@
+/*-
+ * 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: context.h,v 1.2 2006/06/28 09:00:25 lha Exp $
+ */
+
+#include <gssapi_mech.h>
+
+struct _gss_context {
+ gssapi_mech_interface gc_mech;
+ gss_ctx_id_t gc_ctx;
+};
diff --git a/source4/heimdal/lib/gssapi/mech/cred.h b/source4/heimdal/lib/gssapi/mech/cred.h
new file mode 100644
index 0000000000..df89e79727
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/cred.h
@@ -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/cred.h,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ * $Id: cred.h,v 1.3 2006/10/05 18:26:54 lha Exp $
+ */
+
+struct _gss_mechanism_cred {
+ SLIST_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 */
+};
+SLIST_HEAD(_gss_mechanism_cred_list, _gss_mechanism_cred);
+
+struct _gss_cred {
+ gss_cred_usage_t gc_usage;
+ struct _gss_mechanism_cred_list gc_mc;
+};
+
diff --git a/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c b/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c
new file mode 100644
index 0000000000..4d634bf20f
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c
@@ -0,0 +1,223 @@
+/*-
+ * 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"
+RCSID("$Id: gss_accept_sec_context.c,v 1.6 2006/10/25 00:45:12 lha Exp $");
+
+OM_uint32 gss_accept_sec_context(OM_uint32 *minor_status,
+ gss_ctx_id_t *context_handle,
+ const gss_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;
+ gssapi_mech_interface m;
+ 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_cred_id_t acceptor_mc, delegated_mc;
+ gss_name_t src_mn;
+ int allocated_ctx;
+
+ *minor_status = 0;
+ if (src_name) *src_name = 0;
+ if (mech_type) *mech_type = 0;
+ if (ret_flags) *ret_flags = 0;
+ if (time_rec) *time_rec = 0;
+ if (delegated_cred_handle) *delegated_cred_handle = 0;
+ output_token->length = 0;
+ output_token->value = 0;
+
+ /*
+ * If this is the first call (*context_handle is NULL), we must
+ * parse the input token to figure out the mechanism to use.
+ */
+ if (*context_handle == GSS_C_NO_CONTEXT) {
+ unsigned char *p = input_token->value;
+ size_t len = input_token->length;
+ size_t a, b;
+ gss_OID_desc mech_oid;
+
+ /*
+ * Token must start with [APPLICATION 0] SEQUENCE.
+ * But if it doesn't assume its DCE-STYLE Kerberos!
+ */
+ if (len == 0)
+ return (GSS_S_DEFECTIVE_TOKEN);
+ if (*p != 0x60) {
+ mech_oid = *GSS_KRB5_MECHANISM;
+ } else {
+ p++;
+ len--;
+
+ /*
+ * Decode the length and make sure it agrees with the
+ * token length.
+ */
+ if (len == 0)
+ return (GSS_S_DEFECTIVE_TOKEN);
+ if ((*p & 0x80) == 0) {
+ a = *p;
+ p++;
+ len--;
+ } else {
+ b = *p & 0x7f;
+ p++;
+ len--;
+ if (len < b)
+ return (GSS_S_DEFECTIVE_TOKEN);
+ a = 0;
+ while (b) {
+ a = (a << 8) | *p;
+ p++;
+ len--;
+ b--;
+ }
+ }
+ if (a != len)
+ return (GSS_S_DEFECTIVE_TOKEN);
+
+ /*
+ * Decode the OID for the mechanism. Simplify life by
+ * assuming that the OID length is less than 128 bytes.
+ */
+ if (len < 2 || *p != 0x06)
+ return (GSS_S_DEFECTIVE_TOKEN);
+ if ((p[1] & 0x80) || p[1] > (len - 2))
+ return (GSS_S_DEFECTIVE_TOKEN);
+ mech_oid.length = p[1];
+ p += 2;
+ len -= 2;
+ mech_oid.elements = p;
+ }
+ /*
+ * Now that we have a mechanism, we can find the
+ * implementation.
+ */
+ ctx = malloc(sizeof(struct _gss_context));
+ if (!ctx) {
+ *minor_status = ENOMEM;
+ return (GSS_S_DEFECTIVE_TOKEN);
+ }
+ memset(ctx, 0, sizeof(struct _gss_context));
+ m = ctx->gc_mech = __gss_get_mechanism(&mech_oid);
+ if (!m) {
+ free(ctx);
+ return (GSS_S_BAD_MECH);
+ }
+ allocated_ctx = 1;
+ } else {
+ m = ctx->gc_mech;
+ allocated_ctx = 0;
+ }
+
+ if (cred) {
+ SLIST_FOREACH(mc, &cred->gc_mc, gmc_link)
+ if (mc->gmc_mech == m)
+ break;
+ if (!mc)
+ return (GSS_S_BAD_MECH);
+ acceptor_mc = mc->gmc_cred;
+ } else {
+ acceptor_mc = GSS_C_NO_CREDENTIAL;
+ }
+ delegated_mc = GSS_C_NO_CREDENTIAL;
+
+ mech_ret_flags = 0;
+ major_status = m->gm_accept_sec_context(minor_status,
+ &ctx->gc_ctx,
+ acceptor_mc,
+ input_token,
+ input_chan_bindings,
+ &src_mn,
+ mech_type,
+ output_token,
+ &mech_ret_flags,
+ time_rec,
+ &delegated_mc);
+ if (major_status != GSS_S_COMPLETE &&
+ major_status != GSS_S_CONTINUE_NEEDED)
+ return (major_status);
+
+ if (!src_name) {
+ m->gm_release_name(minor_status, &src_mn);
+ } else {
+ /*
+ * Make a new name and mark it as an MN.
+ */
+ struct _gss_name *name = _gss_make_name(m, src_mn);
+
+ if (!name) {
+ m->gm_release_name(minor_status, &src_mn);
+ return (GSS_S_FAILURE);
+ }
+ *src_name = (gss_name_t) name;
+ }
+
+ if (mech_ret_flags & GSS_C_DELEG_FLAG) {
+ if (!delegated_cred_handle) {
+ m->gm_release_cred(minor_status, &delegated_mc);
+ *ret_flags &= ~GSS_C_DELEG_FLAG;
+ } else {
+ struct _gss_cred *dcred;
+ struct _gss_mechanism_cred *dmc;
+
+ dcred = malloc(sizeof(struct _gss_cred));
+ if (!dcred) {
+ *minor_status = ENOMEM;
+ return (GSS_S_FAILURE);
+ }
+ SLIST_INIT(&dcred->gc_mc);
+ dmc = malloc(sizeof(struct _gss_mechanism_cred));
+ if (!dmc) {
+ free(dcred);
+ *minor_status = ENOMEM;
+ return (GSS_S_FAILURE);
+ }
+ m->gm_inquire_cred(minor_status, delegated_mc,
+ 0, 0, &dcred->gc_usage, 0);
+ dmc->gmc_mech = m;
+ dmc->gmc_mech_oid = &m->gm_mech_oid;
+ dmc->gmc_cred = delegated_mc;
+ SLIST_INSERT_HEAD(&dcred->gc_mc, dmc, gmc_link);
+
+ *delegated_cred_handle = (gss_cred_id_t) dcred;
+ }
+ }
+
+ if (ret_flags)
+ *ret_flags = mech_ret_flags;
+ *context_handle = (gss_ctx_id_t) ctx;
+ return (major_status);
+}
diff --git a/source4/heimdal/lib/gssapi/mech/gss_acquire_cred.c b/source4/heimdal/lib/gssapi/mech/gss_acquire_cred.c
new file mode 100644
index 0000000000..0b3554c0fa
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_acquire_cred.c
@@ -0,0 +1,164 @@
+/*-
+ * 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"
+RCSID("$Id: gss_acquire_cred.c,v 1.4 2006/10/25 00:44:55 lha Exp $");
+
+OM_uint32
+gss_acquire_cred(OM_uint32 *minor_status,
+ const gss_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)
+{
+ OM_uint32 major_status;
+ gss_OID_set mechs = desired_mechs;
+ gss_OID_set_desc set;
+ struct _gss_name *name = (struct _gss_name *) desired_name;
+ gssapi_mech_interface m;
+ struct _gss_cred *cred;
+ struct _gss_mechanism_cred *mc;
+ OM_uint32 min_time, cred_time;
+ int i;
+
+ _gss_load_mech();
+
+ /*
+ * First make sure that at least one of the requested
+ * mechanisms is one that we support.
+ */
+ if (mechs) {
+ for (i = 0; i < mechs->count; i++) {
+ int t;
+ gss_test_oid_set_member(minor_status,
+ &mechs->elements[i], _gss_mech_oids, &t);
+ if (t)
+ break;
+ }
+ if (i == mechs->count) {
+ *output_cred_handle = 0;
+ *minor_status = 0;
+ return (GSS_S_BAD_MECH);
+ }
+ }
+
+ if (actual_mechs) {
+ major_status = gss_create_empty_oid_set(minor_status,
+ actual_mechs);
+ if (major_status)
+ return (major_status);
+ }
+
+ cred = malloc(sizeof(struct _gss_cred));
+ if (!cred) {
+ if (actual_mechs)
+ gss_release_oid_set(minor_status, actual_mechs);
+ *minor_status = ENOMEM;
+ return (GSS_S_FAILURE);
+ }
+ cred->gc_usage = cred_usage;
+ SLIST_INIT(&cred->gc_mc);
+
+ if (mechs == GSS_C_NO_OID_SET)
+ mechs = _gss_mech_oids;
+
+ set.count = 1;
+ min_time = GSS_C_INDEFINITE;
+ for (i = 0; i < mechs->count; i++) {
+ struct _gss_mechanism_name *mn = NULL;
+
+ m = __gss_get_mechanism(&mechs->elements[i]);
+ if (!m)
+ continue;
+
+ if (desired_name != GSS_C_NO_NAME) {
+ mn = _gss_find_mn(name, &mechs->elements[i]);
+ if (!mn)
+ continue;
+ }
+
+ mc = malloc(sizeof(struct _gss_mechanism_cred));
+ if (!mc) {
+ continue;
+ }
+ SLIST_INIT(&cred->gc_mc);
+ mc->gmc_mech = m;
+ mc->gmc_mech_oid = &m->gm_mech_oid;
+
+ /*
+ * XXX Probably need to do something with actual_mechs.
+ */
+ set.elements = &mechs->elements[i];
+ major_status = m->gm_acquire_cred(minor_status,
+ (desired_name != GSS_C_NO_NAME
+ ? mn->gmn_name : GSS_C_NO_NAME),
+ time_req, &set, cred_usage,
+ &mc->gmc_cred, NULL, &cred_time);
+ if (major_status) {
+ free(mc);
+ continue;
+ }
+ if (cred_time < min_time)
+ min_time = cred_time;
+
+ if (actual_mechs) {
+ major_status = gss_add_oid_set_member(minor_status,
+ mc->gmc_mech_oid, actual_mechs);
+ if (major_status) {
+ m->gm_release_cred(minor_status,
+ &mc->gmc_cred);
+ free(mc);
+ continue;
+ }
+ }
+
+ SLIST_INSERT_HEAD(&cred->gc_mc, mc, gmc_link);
+ }
+
+ /*
+ * If we didn't manage to create a single credential, return
+ * an error.
+ */
+ if (!SLIST_FIRST(&cred->gc_mc)) {
+ free(cred);
+ if (actual_mechs)
+ gss_release_oid_set(minor_status, actual_mechs);
+ *output_cred_handle = 0;
+ *minor_status = 0;
+ return (GSS_S_NO_CRED);
+ }
+
+ if (time_rec)
+ *time_rec = min_time;
+ *output_cred_handle = (gss_cred_id_t) cred;
+ *minor_status = 0;
+ return (GSS_S_COMPLETE);
+}
diff --git a/source4/heimdal/lib/gssapi/mech/gss_add_cred.c b/source4/heimdal/lib/gssapi/mech/gss_add_cred.c
new file mode 100644
index 0000000000..beffd54e29
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_add_cred.c
@@ -0,0 +1,175 @@
+/*-
+ * 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"
+RCSID("$Id: gss_add_cred.c,v 1.3 2006/06/29 08:23:53 lha Exp $");
+
+static struct _gss_mechanism_cred *
+_gss_copy_cred(struct _gss_mechanism_cred *mc)
+{
+ struct _gss_mechanism_cred *new_mc;
+ gssapi_mech_interface m = mc->gmc_mech;
+ OM_uint32 major_status, minor_status;
+ gss_name_t name;
+ gss_cred_id_t cred;
+ OM_uint32 initiator_lifetime, acceptor_lifetime;
+ gss_cred_usage_t cred_usage;
+
+ major_status = m->gm_inquire_cred_by_mech(&minor_status,
+ mc->gmc_cred, mc->gmc_mech_oid,
+ &name, &initiator_lifetime, &acceptor_lifetime, &cred_usage);
+ if (major_status)
+ return (0);
+
+ major_status = m->gm_add_cred(&minor_status,
+ GSS_C_NO_CREDENTIAL, name, mc->gmc_mech_oid,
+ cred_usage, initiator_lifetime, acceptor_lifetime,
+ &cred, 0, 0, 0);
+ m->gm_release_name(&minor_status, &name);
+
+ if (major_status)
+ return (0);
+
+ new_mc = malloc(sizeof(struct _gss_mechanism_cred));
+ if (!new_mc) {
+ m->gm_release_cred(&minor_status, &cred);
+ return (0);
+ }
+ new_mc->gmc_mech = m;
+ new_mc->gmc_mech_oid = &m->gm_mech_oid;
+ new_mc->gmc_cred = cred;
+
+ return (new_mc);
+}
+
+OM_uint32
+gss_add_cred(OM_uint32 *minor_status,
+ const gss_cred_id_t input_cred_handle,
+ const gss_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)
+{
+ OM_uint32 major_status;
+ gssapi_mech_interface m;
+ struct _gss_cred *cred = (struct _gss_cred *) input_cred_handle;
+ struct _gss_cred *new_cred;
+ gss_cred_id_t release_cred;
+ struct _gss_mechanism_cred *mc, *target_mc, *copy_mc;
+ struct _gss_mechanism_name *mn;
+ OM_uint32 junk;
+
+ *output_cred_handle = 0;
+ *minor_status = 0;
+
+ new_cred = malloc(sizeof(struct _gss_cred));
+ if (!new_cred) {
+ *minor_status = ENOMEM;
+ return (GSS_S_FAILURE);
+ }
+ new_cred->gc_usage = cred_usage;
+ SLIST_INIT(&new_cred->gc_mc);
+
+ /*
+ * We go through all the mc attached to the input_cred_handle
+ * and check the mechanism. If it matches, we call
+ * gss_add_cred for that mechanism, otherwise we copy the mc
+ * to new_cred.
+ */
+ target_mc = 0;
+ if (cred) {
+ SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) {
+ if (gss_oid_equal(mc->gmc_mech_oid, desired_mech)) {
+ target_mc = mc;
+ }
+ copy_mc = _gss_copy_cred(mc);
+ if (!copy_mc) {
+ release_cred = (gss_cred_id_t)new_cred;
+ gss_release_cred(&junk, &release_cred);
+ *minor_status = ENOMEM;
+ return (GSS_S_FAILURE);
+ }
+ SLIST_INSERT_HEAD(&new_cred->gc_mc, copy_mc, gmc_link);
+ }
+ }
+
+ /*
+ * Figure out a suitable mn, if any.
+ */
+ if (desired_name) {
+ mn = _gss_find_mn((struct _gss_name *) desired_name,
+ desired_mech);
+ if (!mn) {
+ free(new_cred);
+ return (GSS_S_BAD_NAME);
+ }
+ } else {
+ mn = 0;
+ }
+
+ m = __gss_get_mechanism(desired_mech);
+
+ mc = malloc(sizeof(struct _gss_mechanism_cred));
+ if (!mc) {
+ release_cred = (gss_cred_id_t)new_cred;
+ gss_release_cred(&junk, &release_cred);
+ *minor_status = ENOMEM;
+ return (GSS_S_FAILURE);
+ }
+ mc->gmc_mech = m;
+ mc->gmc_mech_oid = &m->gm_mech_oid;
+
+ major_status = m->gm_add_cred(minor_status,
+ target_mc ? target_mc->gmc_cred : GSS_C_NO_CREDENTIAL,
+ desired_name ? mn->gmn_name : GSS_C_NO_NAME,
+ desired_mech,
+ cred_usage,
+ initiator_time_req,
+ acceptor_time_req,
+ &mc->gmc_cred,
+ actual_mechs,
+ initiator_time_rec,
+ acceptor_time_rec);
+
+ if (major_status) {
+ release_cred = (gss_cred_id_t)new_cred;
+ gss_release_cred(&junk, &release_cred);
+ free(mc);
+ return (major_status);
+ }
+ SLIST_INSERT_HEAD(&new_cred->gc_mc, mc, gmc_link);
+ *output_cred_handle = (gss_cred_id_t) new_cred;
+
+ return (GSS_S_COMPLETE);
+}
+
diff --git a/source4/heimdal/lib/gssapi/ccache_name.c b/source4/heimdal/lib/gssapi/mech/gss_add_oid_set_member.c
index 3bebb83c1f..5806cec009 100755..100644
--- a/source4/heimdal/lib/gssapi/ccache_name.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_add_oid_set_member.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2001, 2003 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -31,50 +31,37 @@
* SUCH DAMAGE.
*/
-#include "gssapi_locl.h"
-
-RCSID("$Id: ccache_name.c,v 1.2 2005/06/16 20:38:49 lha Exp $");
-
-char *last_out_name;
+#include "mech_locl.h"
+RCSID("$Id: gss_add_oid_set_member.c,v 1.3 2006/10/22 09:36:13 lha Exp $");
OM_uint32
-gss_krb5_ccache_name(OM_uint32 *minor_status,
- const char *name,
- const char **out_name)
+gss_add_oid_set_member (OM_uint32 * minor_status,
+ const gss_OID member_oid,
+ gss_OID_set * oid_set)
{
- krb5_error_code kret;
-
- *minor_status = 0;
+ gss_OID tmp;
+ size_t n;
+ OM_uint32 res;
+ int present;
- GSSAPI_KRB5_INIT();
+ res = gss_test_oid_set_member(minor_status, member_oid, *oid_set, &present);
+ if (res != GSS_S_COMPLETE)
+ return res;
- if (out_name) {
- const char *n;
-
- if (last_out_name) {
- free(last_out_name);
- last_out_name = NULL;
- }
-
- n = krb5_cc_default_name(gssapi_krb5_context);
- if (n == NULL) {
- *minor_status = ENOMEM;
- gssapi_krb5_set_error_string ();
- return GSS_S_FAILURE;
- }
- last_out_name = strdup(n);
- if (last_out_name == NULL) {
- *minor_status = ENOMEM;
- return GSS_S_FAILURE;
- }
- *out_name = last_out_name;
+ if (present) {
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
}
- kret = krb5_cc_set_default_name(gssapi_krb5_context, name);
- if (kret) {
- *minor_status = kret;
- gssapi_krb5_set_error_string ();
+ 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;
+ (*oid_set)->count = n;
+ (*oid_set)->elements[n-1] = *member_oid;
+ *minor_status = 0;
return GSS_S_COMPLETE;
}
diff --git a/source4/heimdal/lib/gssapi/mech/gss_buffer_set.c b/source4/heimdal/lib/gssapi/mech/gss_buffer_set.c
new file mode 100644
index 0000000000..9e9bd5e790
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_buffer_set.c
@@ -0,0 +1,125 @@
+/*
+ * 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"
+RCSID("$Id: gss_buffer_set.c,v 1.2 2006/10/24 21:53:02 lha Exp $");
+
+OM_uint32
+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;
+}
+
+OM_uint32
+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;
+}
+
+OM_uint32
+gss_release_buffer_set(OM_uint32 * minor_status,
+ gss_buffer_set_t *buffer_set)
+{
+ int 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/source4/heimdal/lib/gssapi/mech/gss_canonicalize_name.c b/source4/heimdal/lib/gssapi/mech/gss_canonicalize_name.c
new file mode 100644
index 0000000000..38a464be46
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_canonicalize_name.c
@@ -0,0 +1,87 @@
+/*-
+ * 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_canonicalize_name.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+RCSID("$Id: gss_canonicalize_name.c,v 1.2 2006/06/28 09:00:25 lha Exp $");
+
+OM_uint32
+gss_canonicalize_name(OM_uint32 *minor_status,
+ const gss_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_get_mechanism(mech_type);
+ gss_name_t new_canonical_name;
+
+ *minor_status = 0;
+ *output_name = 0;
+
+ mn = _gss_find_mn(name, mech_type);
+ if (!mn) {
+ return (GSS_S_BAD_MECH);
+ }
+
+ m = mn->gmn_mech;
+ major_status = m->gm_canonicalize_name(minor_status,
+ mn->gmn_name, mech_type, &new_canonical_name);
+ if (major_status)
+ return (major_status);
+
+ /*
+ * Now we make a new name and mark it as an MN.
+ */
+ *minor_status = 0;
+ name = malloc(sizeof(struct _gss_name));
+ if (!name) {
+ m->gm_release_name(minor_status, &new_canonical_name);
+ *minor_status = ENOMEM;
+ return (GSS_S_FAILURE);
+ }
+ memset(name, 0, sizeof(struct _gss_name));
+
+ mn = malloc(sizeof(struct _gss_mechanism_name));
+ if (!mn) {
+ m->gm_release_name(minor_status, &new_canonical_name);
+ free(name);
+ *minor_status = ENOMEM;
+ return (GSS_S_FAILURE);
+ }
+
+ SLIST_INIT(&name->gn_mn);
+ mn->gmn_mech = m;
+ mn->gmn_mech_oid = &m->gm_mech_oid;
+ mn->gmn_name = new_canonical_name;
+ SLIST_INSERT_HEAD(&name->gn_mn, mn, gmn_link);
+
+ *output_name = (gss_name_t) name;
+
+ return (GSS_S_COMPLETE);
+}
diff --git a/source4/heimdal/lib/gssapi/mech/gss_compare_name.c b/source4/heimdal/lib/gssapi/mech/gss_compare_name.c
new file mode 100644
index 0000000000..1068bfabf6
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_compare_name.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_compare_name.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+RCSID("$Id: gss_compare_name.c,v 1.2 2006/06/28 09:00:25 lha Exp $");
+
+OM_uint32
+gss_compare_name(OM_uint32 *minor_status,
+ const gss_name_t name1_arg,
+ const gss_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) {
+ *name_equal = 1;
+ if (!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, name1->gn_value.value,
+ name1->gn_value.length)) {
+ *name_equal = 0;
+ }
+ } else {
+ struct _gss_mechanism_name *mn1;
+ struct _gss_mechanism_name *mn2;
+
+ SLIST_FOREACH(mn1, &name1->gn_mn, gmn_link) {
+ mn2 = _gss_find_mn(name2, mn1->gmn_mech_oid);
+ if (mn2) {
+ return (mn1->gmn_mech->gm_compare_name(
+ minor_status,
+ mn1->gmn_name,
+ mn2->gmn_name,
+ name_equal));
+ }
+ }
+ *name_equal = 0;
+ }
+
+ *minor_status = 0;
+ return (GSS_S_COMPLETE);
+}
diff --git a/source4/heimdal/lib/gssapi/mech/gss_context_time.c b/source4/heimdal/lib/gssapi/mech/gss_context_time.c
new file mode 100644
index 0000000000..4b17381776
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_context_time.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_context_time.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+RCSID("$Id: gss_context_time.c,v 1.2 2006/06/28 09:00:25 lha Exp $");
+
+OM_uint32
+gss_context_time(OM_uint32 *minor_status,
+ const gss_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/source4/heimdal/lib/gssapi/mech/gss_create_empty_oid_set.c b/source4/heimdal/lib/gssapi/mech/gss_create_empty_oid_set.c
new file mode 100644
index 0000000000..7298ec9e83
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_create_empty_oid_set.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_create_empty_oid_set.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+RCSID("$Id: gss_create_empty_oid_set.c,v 1.2 2006/06/28 09:00:25 lha Exp $");
+
+OM_uint32
+gss_create_empty_oid_set(OM_uint32 *minor_status,
+ gss_OID_set *oid_set)
+{
+ gss_OID_set set;
+
+ *minor_status = 0;
+ *oid_set = 0;
+
+ 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/source4/heimdal/lib/gssapi/mech/gss_decapsulate_token.c b/source4/heimdal/lib/gssapi/mech/gss_decapsulate_token.c
new file mode 100644
index 0000000000..8ebb848188
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_decapsulate_token.c
@@ -0,0 +1,74 @@
+/*
+ * 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"
+RCSID("$Id: gss_decapsulate_token.c,v 1.2 2006/10/14 10:04:45 lha Exp $");
+
+OM_uint32
+gss_decapsulate_token(gss_buffer_t input_token,
+ gss_OID oid,
+ gss_buffer_t output_token)
+{
+ GSSAPIContextToken ct;
+ heim_oid o;
+ OM_uint32 status;
+ int ret;
+ size_t size;
+
+ output_token->length = 0;
+ output_token->value = NULL;
+
+ 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_FAILURE;
+ }
+
+ 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_FAILURE;
+ }
+ der_free_oid(&o);
+
+ return status;
+}
diff --git a/source4/heimdal/lib/gssapi/mech/gss_delete_sec_context.c b/source4/heimdal/lib/gssapi/mech/gss_delete_sec_context.c
new file mode 100644
index 0000000000..06ef8e6d09
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_delete_sec_context.c
@@ -0,0 +1,58 @@
+/*-
+ * 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"
+RCSID("$Id: gss_delete_sec_context.c,v 1.2 2006/06/28 09:00:25 lha Exp $");
+
+OM_uint32
+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;
+
+ *minor_status = 0;
+ if (ctx) {
+ /*
+ * 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);
+ } else if (output_token != GSS_C_NO_BUFFER) {
+ output_token->length = 0;
+ output_token->value = 0;
+ }
+ free(ctx);
+ *context_handle = 0;
+ }
+
+ return (GSS_S_COMPLETE);
+}
diff --git a/source4/heimdal/lib/gssapi/mech/gss_display_name.c b/source4/heimdal/lib/gssapi/mech/gss_display_name.c
new file mode 100644
index 0000000000..79f62a7a4f
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_display_name.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_display_name.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+RCSID("$Id: gss_display_name.c,v 1.2 2006/06/28 09:00:25 lha Exp $");
+
+OM_uint32
+gss_display_name(OM_uint32 *minor_status,
+ const gss_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;
+
+ /*
+ * 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 {
+ SLIST_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/source4/heimdal/lib/gssapi/mech/gss_display_status.c b/source4/heimdal/lib/gssapi/mech/gss_display_status.c
new file mode 100644
index 0000000000..7871f5338b
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_display_status.c
@@ -0,0 +1,184 @@
+/*-
+ * 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"
+RCSID("$Id: gss_display_status.c,v 1.4 2006/07/19 11:02:33 lha Exp $");
+
+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[] = {
+ NULL, /* 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 == 0)
+ return "";
+ else 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];
+}
+
+
+OM_uint32
+gss_display_status(OM_uint32 *minor_status,
+ OM_uint32 status_value,
+ int status_type,
+ const gss_OID mech_type,
+ OM_uint32 *message_content,
+ gss_buffer_t status_string)
+{
+ OM_uint32 major_status;
+
+ *minor_status = 0;
+ switch (status_type) {
+ case GSS_C_GSS_CODE: {
+ char *buf;
+
+ if (GSS_SUPPLEMENTARY_INFO(status_value))
+ asprintf(&buf, "%s", supplementary_error(
+ GSS_SUPPLEMENTARY_INFO(status_value)));
+ else
+ asprintf (&buf, "%s %s",
+ calling_error(GSS_CALLING_ERROR(status_value)),
+ routine_error(GSS_ROUTINE_ERROR(status_value)));
+
+ status_string->length = strlen(buf);
+ status_string->value = buf;
+
+ return GSS_S_COMPLETE;
+ }
+ case GSS_C_MECH_CODE: {
+ gssapi_mech_interface m;
+ m = __gss_get_mechanism(mech_type);
+ if (m) {
+ major_status = m->gm_display_status(minor_status,
+ status_value, status_type, mech_type,
+ message_content, status_string);
+ if (major_status == GSS_S_COMPLETE)
+ return (GSS_S_COMPLETE);
+ }
+ }
+ }
+ status_string->value = NULL;
+ status_string->length = 0;
+ return (GSS_S_BAD_STATUS);
+}
diff --git a/source4/heimdal/lib/gssapi/mech/gss_duplicate_name.c b/source4/heimdal/lib/gssapi/mech/gss_duplicate_name.c
new file mode 100644
index 0000000000..5ef828f472
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_duplicate_name.c
@@ -0,0 +1,75 @@
+/*-
+ * 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"
+RCSID("$Id: gss_duplicate_name.c,v 1.2 2006/06/28 09:00:25 lha Exp $");
+
+OM_uint32 gss_duplicate_name(OM_uint32 *minor_status,
+ const gss_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;
+
+ /*
+ * If this name has a value (i.e. it didn't come from
+ * gss_canonicalize_name(), we re-import the thing. Otherwise,
+ * we make an empty name to hold the MN copy.
+ */
+ 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;
+ } else {
+ new_name = malloc(sizeof(struct _gss_name));
+ if (!new_name) {
+ *minor_status = ENOMEM;
+ return (GSS_S_FAILURE);
+ }
+ memset(new_name, 0, sizeof(struct _gss_name));
+ SLIST_INIT(&name->gn_mn);
+ *dest_name = (gss_name_t) new_name;
+ }
+
+ /*
+ * Import the new name into any mechanisms listed in the
+ * original name. We could probably get away with only doing
+ * this if the original was canonical.
+ */
+ SLIST_FOREACH(mn, &name->gn_mn, gmn_link) {
+ _gss_find_mn(new_name, mn->gmn_mech_oid);
+ }
+
+ return (GSS_S_COMPLETE);
+}
diff --git a/source4/heimdal/lib/gssapi/mech/gss_duplicate_oid.c b/source4/heimdal/lib/gssapi/mech/gss_duplicate_oid.c
new file mode 100644
index 0000000000..bfb0e75315
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_duplicate_oid.c
@@ -0,0 +1,67 @@
+/*
+ * 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"
+RCSID("$Id: gss_duplicate_oid.c,v 1.1 2006/06/28 09:07:07 lha Exp $");
+
+OM_uint32 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;
+ }
+
+ *dest_oid = malloc(sizeof(**dest_oid));
+ if (*dest_oid == GSS_C_NO_OID) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ (*dest_oid)->elements = malloc(src_oid->length);
+ if ((*dest_oid)->elements == NULL) {
+ free(*dest_oid);
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ memcpy((*dest_oid)->elements, src_oid->elements, src_oid->length);
+ (*dest_oid)->length = src_oid->length;
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
diff --git a/source4/heimdal/lib/gssapi/mech/gss_encapsulate_token.c b/source4/heimdal/lib/gssapi/mech/gss_encapsulate_token.c
new file mode 100644
index 0000000000..d1285815ee
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_encapsulate_token.c
@@ -0,0 +1,69 @@
+/*
+ * 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"
+RCSID("$Id: gss_encapsulate_token.c,v 1.2 2006/10/14 10:05:12 lha Exp $");
+
+OM_uint32
+gss_encapsulate_token(gss_buffer_t input_token,
+ gss_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) {
+ output_token->value = NULL;
+ output_token->length = 0;
+ 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) {
+ output_token->length = 0;
+ output_token->value = NULL;
+ return GSS_S_FAILURE;
+ }
+ if (output_token->length != size)
+ abort();
+
+ return GSS_S_COMPLETE;
+}
diff --git a/source4/heimdal/lib/gssapi/mech/gss_export_name.c b/source4/heimdal/lib/gssapi/mech/gss_export_name.c
new file mode 100644
index 0000000000..bc1c39c8ee
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_export_name.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_export_name.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+RCSID("$Id: gss_export_name.c,v 1.3 2006/07/05 22:41:57 lha Exp $");
+
+OM_uint32
+gss_export_name(OM_uint32 *minor_status,
+ const gss_name_t input_name,
+ gss_buffer_t exported_name)
+{
+ struct _gss_name *name = (struct _gss_name *) input_name;
+ struct _gss_mechanism_name *mn;
+
+ exported_name->value = NULL;
+ exported_name->length = 0;
+
+ /*
+ * If this name already has any attached MNs, export the first
+ * one, otherwise export based on the first mechanism in our
+ * list.
+ */
+ mn = SLIST_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);
+}
diff --git a/source4/heimdal/lib/gssapi/mech/gss_export_sec_context.c b/source4/heimdal/lib/gssapi/mech/gss_export_sec_context.c
new file mode 100644
index 0000000000..1acc72b33d
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_export_sec_context.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_export_sec_context.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+RCSID("$Id: gss_export_sec_context.c,v 1.2 2006/06/28 09:00:25 lha Exp $");
+
+OM_uint32
+gss_export_sec_context(OM_uint32 *minor_status,
+ gss_ctx_id_t *context_handle,
+ gss_buffer_t interprocess_token)
+{
+ OM_uint32 major_status;
+ struct _gss_context *ctx = (struct _gss_context *) *context_handle;
+ gssapi_mech_interface m = ctx->gc_mech;
+ gss_buffer_desc buf;
+
+ major_status = m->gm_export_sec_context(minor_status,
+ &ctx->gc_ctx, &buf);
+
+ if (major_status == GSS_S_COMPLETE) {
+ unsigned char *p;
+
+ free(ctx);
+ *context_handle = GSS_C_NO_CONTEXT;
+ interprocess_token->length = buf.length
+ + 2 + m->gm_mech_oid.length;
+ interprocess_token->value = malloc(interprocess_token->length);
+ if (!interprocess_token->value) {
+ /*
+ * We are in trouble here - the context is
+ * already gone. This is allowed as long as we
+ * set the caller's context_handle to
+ * GSS_C_NO_CONTEXT, which we did above.
+ * Return GSS_S_FAILURE.
+ */
+ *minor_status = ENOMEM;
+ return (GSS_S_FAILURE);
+ }
+ p = interprocess_token->value;
+ p[0] = m->gm_mech_oid.length >> 8;
+ p[1] = m->gm_mech_oid.length;
+ memcpy(p + 2, m->gm_mech_oid.elements, m->gm_mech_oid.length);
+ memcpy(p + 2 + m->gm_mech_oid.length, buf.value, buf.length);
+ gss_release_buffer(minor_status, &buf);
+ }
+
+ return (major_status);
+}
diff --git a/source4/heimdal/lib/gssapi/mech/gss_get_mic.c b/source4/heimdal/lib/gssapi/mech/gss_get_mic.c
new file mode 100644
index 0000000000..e9a8f294a4
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_get_mic.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_get_mic.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+RCSID("$Id: gss_get_mic.c,v 1.2 2006/06/28 09:00:25 lha Exp $");
+
+OM_uint32
+gss_get_mic(OM_uint32 *minor_status,
+ const gss_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 = ctx->gc_mech;
+
+ return (m->gm_get_mic(minor_status, ctx->gc_ctx, qop_req,
+ message_buffer, message_token));
+}
diff --git a/source4/heimdal/lib/gssapi/mech/gss_import_name.c b/source4/heimdal/lib/gssapi/mech/gss_import_name.c
new file mode 100644
index 0000000000..9684301ba4
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_import_name.c
@@ -0,0 +1,214 @@
+/*-
+ * 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"
+RCSID("$Id: gss_import_name.c,v 1.3 2006/06/29 21:23:13 lha Exp $");
+
+static OM_uint32
+_gss_import_export_name(OM_uint32 *minor_status,
+ const gss_buffer_t input_name_buffer,
+ 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;
+
+ *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 || p[1] != 1)
+ return (GSS_S_BAD_NAME);
+ p += 2;
+ len -= 2;
+
+ /*
+ * 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 (len < t + 4)
+ return (GSS_S_BAD_NAME);
+ p += t;
+ len -= t;
+
+ t = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
+ p += 4;
+ len -= 4;
+
+ if (len != t)
+ return (GSS_S_BAD_NAME);
+
+ m = __gss_get_mechanism(&mech_oid);
+ if (!m)
+ return (GSS_S_BAD_MECH);
+
+ /*
+ * Ask the mechanism to import the name.
+ */
+ major_status = m->gm_import_name(minor_status,
+ input_name_buffer, GSS_C_NT_EXPORT_NAME, &new_canonical_name);
+
+ /*
+ * Now we make a new name and mark it as an MN.
+ */
+ name = _gss_make_name(m, new_canonical_name);
+ 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);
+}
+
+OM_uint32
+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)
+{
+ gss_OID name_type = input_name_type;
+ OM_uint32 major_status;
+ struct _gss_name *name;
+
+ if (input_name_buffer->length == 0) {
+ *minor_status = 0;
+ *output_name = 0;
+ return (GSS_S_BAD_NAME);
+ }
+
+ /*
+ * Use GSS_NT_USER_NAME as default name type.
+ */
+ if (name_type == GSS_C_NO_OID)
+ name_type = GSS_C_NT_USER_NAME;
+
+ /*
+ * 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)) {
+ return _gss_import_export_name(minor_status,
+ input_name_buffer, output_name);
+ }
+
+ /*
+ * Only allow certain name types. This is pretty bogus - we
+ * should figure out the list of supported name types using
+ * gss_inquire_names_for_mech.
+ */
+ if (!gss_oid_equal(name_type, GSS_C_NT_USER_NAME)
+ && !gss_oid_equal(name_type, GSS_C_NT_MACHINE_UID_NAME)
+ && !gss_oid_equal(name_type, GSS_C_NT_STRING_UID_NAME)
+ && !gss_oid_equal(name_type, GSS_C_NT_HOSTBASED_SERVICE_X)
+ && !gss_oid_equal(name_type, GSS_C_NT_HOSTBASED_SERVICE)
+ && !gss_oid_equal(name_type, GSS_C_NT_ANONYMOUS)
+ && !gss_oid_equal(name_type, GSS_KRB5_NT_PRINCIPAL_NAME)) {
+ *minor_status = 0;
+ *output_name = 0;
+ return (GSS_S_BAD_NAMETYPE);
+ }
+
+ *minor_status = 0;
+ name = malloc(sizeof(struct _gss_name));
+ if (!name) {
+ *minor_status = ENOMEM;
+ return (GSS_S_FAILURE);
+ }
+ memset(name, 0, sizeof(struct _gss_name));
+
+ major_status = _gss_copy_oid(minor_status,
+ name_type, &name->gn_type);
+ if (major_status) {
+ free(name);
+ return (GSS_S_FAILURE);
+ }
+
+ major_status = _gss_copy_buffer(minor_status,
+ input_name_buffer, &name->gn_value);
+ if (major_status) {
+ gss_name_t rname = (gss_name_t)name;
+ gss_release_name(minor_status, &rname);
+ return (GSS_S_FAILURE);
+ }
+
+ SLIST_INIT(&name->gn_mn);
+
+ *output_name = (gss_name_t) name;
+ return (GSS_S_COMPLETE);
+}
diff --git a/source4/heimdal/lib/gssapi/mech/gss_import_sec_context.c b/source4/heimdal/lib/gssapi/mech/gss_import_sec_context.c
new file mode 100644
index 0000000000..5466f97cf4
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_import_sec_context.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_import_sec_context.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+RCSID("$Id: gss_import_sec_context.c,v 1.2 2006/06/28 09:00:25 lha Exp $");
+
+OM_uint32
+gss_import_sec_context(OM_uint32 *minor_status,
+ const gss_buffer_t interprocess_token,
+ gss_ctx_id_t *context_handle)
+{
+ OM_uint32 major_status;
+ gssapi_mech_interface m;
+ struct _gss_context *ctx;
+ gss_OID_desc mech_oid;
+ gss_buffer_desc buf;
+ unsigned char *p;
+ size_t len;
+
+ *minor_status = 0;
+ *context_handle = 0;
+
+ /*
+ * We added an oid to the front of the token in
+ * gss_export_sec_context.
+ */
+ p = interprocess_token->value;
+ len = interprocess_token->length;
+ if (len < 2)
+ return (GSS_S_DEFECTIVE_TOKEN);
+ mech_oid.length = (p[0] << 8) | p[1];
+ if (len < mech_oid.length + 2)
+ return (GSS_S_DEFECTIVE_TOKEN);
+ mech_oid.elements = p + 2;
+ buf.length = len - 2 - mech_oid.length;
+ buf.value = p + 2 + mech_oid.length;
+
+ m = __gss_get_mechanism(&mech_oid);
+ if (!m)
+ return (GSS_S_DEFECTIVE_TOKEN);
+
+ ctx = malloc(sizeof(struct _gss_context));
+ if (!ctx) {
+ *minor_status = ENOMEM;
+ return (GSS_S_FAILURE);
+ }
+ ctx->gc_mech = m;
+ major_status = m->gm_import_sec_context(minor_status,
+ &buf, &ctx->gc_ctx);
+ if (major_status != GSS_S_COMPLETE) {
+ free(ctx);
+ } else {
+ *context_handle = (gss_ctx_id_t) ctx;
+ }
+
+ return (major_status);
+}
diff --git a/source4/heimdal/lib/gssapi/mech/gss_indicate_mechs.c b/source4/heimdal/lib/gssapi/mech/gss_indicate_mechs.c
new file mode 100644
index 0000000000..0da6c48834
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_indicate_mechs.c
@@ -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/gss_indicate_mechs.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+RCSID("$Id: gss_indicate_mechs.c,v 1.3 2006/07/05 22:36:49 lha Exp $");
+
+OM_uint32
+gss_indicate_mechs(OM_uint32 *minor_status,
+ gss_OID_set *mech_set)
+{
+ struct _gss_mech_switch *m;
+ OM_uint32 major_status;
+ gss_OID_set set;
+ int i;
+
+ _gss_load_mech();
+
+ major_status = gss_create_empty_oid_set(minor_status, mech_set);
+ if (major_status)
+ return (major_status);
+
+ SLIST_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;
+ for (i = 0; i < set->count; i++)
+ major_status = gss_add_oid_set_member(
+ minor_status, &set->elements[i], mech_set);
+ gss_release_oid_set(minor_status, &set);
+ } else {
+ major_status = gss_add_oid_set_member(
+ minor_status, &m->gm_mech_oid, mech_set);
+ }
+ }
+
+ *minor_status = 0;
+ return (GSS_S_COMPLETE);
+}
diff --git a/source4/heimdal/lib/gssapi/mech/gss_init_sec_context.c b/source4/heimdal/lib/gssapi/mech/gss_init_sec_context.c
new file mode 100644
index 0000000000..ccaf91ba9d
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_init_sec_context.c
@@ -0,0 +1,133 @@
+/*-
+ * 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_init_sec_context.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+RCSID("$Id: gss_init_sec_context.c,v 1.3 2006/07/06 22:30:09 lha Exp $");
+
+OM_uint32
+gss_init_sec_context(OM_uint32 * minor_status,
+ const gss_cred_id_t initiator_cred_handle,
+ gss_ctx_id_t * context_handle,
+ const gss_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;
+ struct _gss_name *name = (struct _gss_name *) target_name;
+ struct _gss_mechanism_name *mn;
+ struct _gss_context *ctx = (struct _gss_context *) *context_handle;
+ struct _gss_cred *cred = (struct _gss_cred *) initiator_cred_handle;
+ struct _gss_mechanism_cred *mc;
+ gss_cred_id_t cred_handle;
+ int allocated_ctx;
+ gss_OID mech_type = input_mech_type;
+
+ *minor_status = 0;
+
+ /*
+ * 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) {
+ if (mech_type == NULL)
+ mech_type = GSS_KRB5_MECHANISM;
+
+ 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);
+ 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.
+ */
+ mn = _gss_find_mn(name, mech_type);
+ if (mn == NULL) {
+ if (allocated_ctx)
+ free(ctx);
+ return GSS_S_BAD_NAME;
+ }
+
+ /*
+ * If we have a cred, find the cred for this mechanism.
+ */
+ cred_handle = GSS_C_NO_CREDENTIAL;
+ if (cred) {
+ SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) {
+ if (gss_oid_equal(mech_type, mc->gmc_mech_oid)) {
+ cred_handle = mc->gmc_cred;
+ break;
+ }
+ }
+ }
+
+ major_status = m->gm_init_sec_context(minor_status,
+ cred_handle,
+ &ctx->gc_ctx,
+ mn->gmn_name,
+ 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);
+ } else {
+ *context_handle = (gss_ctx_id_t) ctx;
+ }
+
+ return (major_status);
+}
diff --git a/source4/heimdal/lib/gssapi/mech/gss_inquire_context.c b/source4/heimdal/lib/gssapi/mech/gss_inquire_context.c
new file mode 100644
index 0000000000..88bbb3941f
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_inquire_context.c
@@ -0,0 +1,85 @@
+/*-
+ * 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"
+RCSID("$Id: gss_inquire_context.c,v 1.2 2006/06/28 09:00:25 lha Exp $");
+
+OM_uint32
+gss_inquire_context(OM_uint32 *minor_status,
+ const gss_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 *open)
+{
+ OM_uint32 major_status;
+ struct _gss_context *ctx = (struct _gss_context *) context_handle;
+ gssapi_mech_interface m = ctx->gc_mech;
+ struct _gss_name *name;
+ gss_name_t src_mn, targ_mn;
+
+ major_status = m->gm_inquire_context(minor_status,
+ ctx->gc_ctx,
+ src_name ? &src_mn : 0,
+ targ_name ? &targ_mn : 0,
+ lifetime_rec,
+ mech_type,
+ ctx_flags,
+ locally_initiated,
+ open);
+
+ if (src_name) *src_name = 0;
+ if (targ_name) *targ_name = 0;
+
+ if (major_status != GSS_S_COMPLETE) {
+ return (major_status);
+ }
+
+ if (src_name) {
+ name = _gss_make_name(m, src_mn);
+ if (!name) {
+ minor_status = 0;
+ return (GSS_S_FAILURE);
+ }
+ *src_name = (gss_name_t) name;
+ }
+
+ if (targ_name) {
+ name = _gss_make_name(m, targ_mn);
+ if (!name) {
+ minor_status = 0;
+ return (GSS_S_FAILURE);
+ }
+ *targ_name = (gss_name_t) name;
+ }
+
+ return (GSS_S_COMPLETE);
+}
diff --git a/source4/heimdal/lib/gssapi/mech/gss_inquire_cred.c b/source4/heimdal/lib/gssapi/mech/gss_inquire_cred.c
new file mode 100644
index 0000000000..223140205d
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_inquire_cred.c
@@ -0,0 +1,168 @@
+/*-
+ * 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"
+RCSID("$Id: gss_inquire_cred.c,v 1.5 2006/07/20 02:03:18 lha Exp $");
+
+OM_uint32
+gss_inquire_cred(OM_uint32 *minor_status,
+ const gss_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 = 0;
+
+ _gss_load_mech();
+
+ *minor_status = 0;
+ if (name_ret)
+ *name_ret = 0;
+ if (lifetime)
+ *lifetime = 0;
+ if (cred_usage)
+ *cred_usage = 0;
+
+ if (name_ret) {
+ name = malloc(sizeof(struct _gss_name));
+ if (!name) {
+ *minor_status = ENOMEM;
+ return (GSS_S_FAILURE);
+ }
+ memset(name, 0, sizeof(struct _gss_name));
+ SLIST_INIT(&name->gn_mn);
+ } else {
+ name = 0;
+ }
+
+ 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;
+
+ SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) {
+ gss_name_t mc_name;
+ OM_uint32 mc_lifetime;
+
+ major_status = mc->gmc_mech->gm_inquire_cred(minor_status,
+ mc->gmc_cred, &mc_name, &mc_lifetime, NULL, NULL);
+ if (major_status)
+ continue;
+
+ 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;
+ SLIST_INSERT_HEAD(&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++;
+ }
+ } else {
+ SLIST_FOREACH(m, &_gss_mechs, gm_link) {
+ gss_name_t mc_name;
+ OM_uint32 mc_lifetime;
+
+ major_status = m->gm_mech.gm_inquire_cred(minor_status,
+ GSS_C_NO_CREDENTIAL, &mc_name, &mc_lifetime,
+ cred_usage, NULL);
+ if (major_status)
+ continue;
+
+ 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;
+ SLIST_INSERT_HEAD(&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++;
+ }
+ }
+
+ if (found == 0) {
+ gss_release_oid_set(minor_status, mechanisms);
+ *minor_status = 0;
+ return (GSS_S_NO_CRED);
+ }
+
+ *minor_status = 0;
+ if (name_ret)
+ *name_ret = (gss_name_t) name;
+ if (lifetime)
+ *lifetime = min_lifetime;
+ if (cred && cred_usage)
+ *cred_usage = cred->gc_usage;
+ return (GSS_S_COMPLETE);
+}
diff --git a/source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_mech.c b/source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_mech.c
new file mode 100644
index 0000000000..771a6956a5
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_mech.c
@@ -0,0 +1,79 @@
+/*-
+ * 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"
+RCSID("$Id: gss_inquire_cred_by_mech.c,v 1.2 2006/06/28 09:00:25 lha Exp $");
+
+OM_uint32
+gss_inquire_cred_by_mech(OM_uint32 *minor_status,
+ const gss_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;
+
+ m = __gss_get_mechanism(mech_type);
+ if (!m)
+ return (GSS_S_NO_CRED);
+
+ if (cred_handle != GSS_C_NO_CREDENTIAL) {
+ struct _gss_cred *cred = (struct _gss_cred *) cred_handle;
+ SLIST_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)
+ return (major_status);
+
+ name = _gss_make_name(m, mn);
+ if (!name) {
+ m->gm_release_name(minor_status, &mn);
+ return (GSS_S_NO_CRED);
+ }
+
+ *cred_name = (gss_name_t) name;
+ return (GSS_S_COMPLETE);
+}
diff --git a/source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_oid.c b/source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_oid.c
new file mode 100644
index 0000000000..3cfe89af21
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_oid.c
@@ -0,0 +1,82 @@
+/*
+ * 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"
+RCSID("$Id: gss_inquire_cred_by_oid.c,v 1.2 2006/06/28 16:20:41 lha Exp $");
+
+OM_uint32
+gss_inquire_cred_by_oid (OM_uint32 *minor_status,
+ const gss_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;
+
+ if (cred == NULL)
+ return GSS_S_NO_CRED;
+
+ SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) {
+ gss_buffer_set_t rset = GSS_C_NO_BUFFER_SET;
+ int i;
+
+ m = mc->gmc_mech;
+ if (m == NULL)
+ 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)
+ continue;
+
+ for (i = 0; i < rset->count; i++) {
+ status = gss_add_buffer_set_member(minor_status,
+ &rset->elements[i], &set);
+ if (status != GSS_S_COMPLETE)
+ break;
+ }
+ gss_release_buffer_set(minor_status, &rset);
+ }
+ if (set == GSS_C_NO_BUFFER_SET)
+ status = GSS_S_FAILURE;
+ *data_set = set;
+ return status;
+}
+
diff --git a/source4/heimdal/lib/gssapi/mech/gss_inquire_mechs_for_name.c b/source4/heimdal/lib/gssapi/mech/gss_inquire_mechs_for_name.c
new file mode 100644
index 0000000000..7052bf8b72
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_inquire_mechs_for_name.c
@@ -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/gss_inquire_mechs_for_name.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+RCSID("$Id: gss_inquire_mechs_for_name.c,v 1.3 2006/07/20 02:04:00 lha Exp $");
+
+OM_uint32
+gss_inquire_mechs_for_name(OM_uint32 *minor_status,
+ const gss_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.
+ */
+ SLIST_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/source4/heimdal/lib/gssapi/mech/gss_inquire_names_for_mech.c b/source4/heimdal/lib/gssapi/mech/gss_inquire_names_for_mech.c
new file mode 100644
index 0000000000..2293163b03
--- /dev/null
+++ b/source4/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"
+RCSID("$Id: gss_inquire_names_for_mech.c,v 1.2 2006/06/28 09:00:25 lha Exp $");
+
+OM_uint32
+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;
+ 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 ms;
+ gss_release_oid_set(&ms, 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 ms;
+ gss_release_oid_set(&ms, name_types);
+ return (major_status);
+ }
+ }
+
+ return (GSS_S_COMPLETE);
+}
diff --git a/source4/heimdal/lib/gssapi/mech/gss_inquire_sec_context_by_oid.c b/source4/heimdal/lib/gssapi/mech/gss_inquire_sec_context_by_oid.c
new file mode 100644
index 0000000000..7f5632ac55
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_inquire_sec_context_by_oid.c
@@ -0,0 +1,69 @@
+/*
+ * 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"
+RCSID("$Id: gss_inquire_sec_context_by_oid.c,v 1.1 2006/06/28 09:07:08 lha Exp $");
+
+OM_uint32
+gss_inquire_sec_context_by_oid (OM_uint32 *minor_status,
+ const gss_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;
+
+ 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);
+ else
+ major_status = GSS_S_BAD_MECH;
+
+ return major_status;
+}
+
diff --git a/source4/heimdal/lib/gssapi/mech/gss_krb5.c b/source4/heimdal/lib/gssapi/mech/gss_krb5.c
new file mode 100644
index 0000000000..c6ea3cecb7
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_krb5.c
@@ -0,0 +1,710 @@
+/*-
+ * 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"
+RCSID("$Id: gss_krb5.c,v 1.13 2006/10/20 22:05:02 lha Exp $");
+
+#include <krb5.h>
+#include <roken.h>
+
+
+OM_uint32
+gss_krb5_copy_ccache(OM_uint32 *minor_status,
+ gss_cred_id_t cred,
+ krb5_ccache out)
+{
+ gss_buffer_set_t data_set = GSS_C_NO_BUFFER_SET;
+ krb5_context context;
+ krb5_error_code kret;
+ krb5_ccache id;
+ OM_uint32 ret;
+ char *str;
+
+ ret = gss_inquire_cred_by_oid(minor_status,
+ cred,
+ GSS_KRB5_COPY_CCACHE_X,
+ &data_set);
+ if (ret)
+ return ret;
+
+ 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;
+ }
+
+ kret = krb5_init_context(&context);
+ if (kret) {
+ *minor_status = kret;
+ gss_release_buffer_set(minor_status, &data_set);
+ return GSS_S_FAILURE;
+ }
+
+ kret = asprintf(&str, "%.*s", (int)data_set->elements[0].length,
+ (char *)data_set->elements[0].value);
+ gss_release_buffer_set(minor_status, &data_set);
+ if (kret == -1) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ kret = krb5_cc_resolve(context, str, &id);
+ free(str);
+ if (kret) {
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+
+ kret = krb5_cc_copy_cache(context, id, out);
+ krb5_cc_close(context, id);
+ krb5_free_context(context);
+ if (kret) {
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+
+ return ret;
+}
+
+OM_uint32
+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;
+ }
+
+ krb5_storage_to_data(sp, &data);
+
+ 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;
+}
+
+OM_uint32
+gsskrb5_register_acceptor_identity(const char *identity)
+{
+ struct _gss_mech_switch *m;
+ gss_buffer_desc buffer;
+ OM_uint32 junk;
+
+ _gss_load_mech();
+
+ buffer.value = rk_UNCONST(identity);
+ buffer.length = strlen(identity);
+
+ SLIST_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_REGISTER_ACCEPTOR_IDENTITY_X, &buffer);
+ }
+
+ return (GSS_S_COMPLETE);
+}
+
+OM_uint32
+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);
+
+ SLIST_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));
+}
+
+
+OM_uint32
+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) {
+ ret = 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_release_buffer_set(minor_status, &data_set);
+ if (sp)
+ krb5_storage_free(sp);
+ if (context)
+ krb5_free_context(context);
+
+ if (ret) {
+ if (ctx)
+ gss_krb5_free_lucid_sec_context(NULL, ctx);
+
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
+
+OM_uint32
+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;
+}
+
+OM_uint32
+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;
+ }
+
+ SLIST_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);
+}
+
+OM_uint32
+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;
+ krb5_error_code ret;
+ OM_uint32 time32;
+
+ if (context_handle == GSS_C_NO_CONTEXT) {
+ _gsskrb5_set_status("no context handle");
+ *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) {
+ _gsskrb5_set_status("no buffers returned");
+ gss_release_buffer_set(minor_status, &data_set);
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ if (data_set->count != 1) {
+ _gsskrb5_set_status("%d != 1 buffers returned", data_set->count);
+ 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);
+ _gsskrb5_set_status("Error extracting authtime from security context: only got %d < 4 bytes",
+ data_set->elements[0].length);
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ ret = _gsskrb5_decode_om_uint32(data_set->elements[0].value, &time32);
+ if (ret) {
+ gss_release_buffer_set(minor_status, &data_set);
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+ *authtime = time32;
+
+ gss_release_buffer_set(minor_status, &data_set);
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
+
+OM_uint32
+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;
+ gss_OID_desc authz_oid_flat;
+ heim_oid authz_oid;
+ heim_oid new_authz_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,
+ &authz_oid, NULL) != 0) {
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ new_authz_oid.length = authz_oid.length + 1;
+ new_authz_oid.components = malloc(new_authz_oid.length * sizeof(*new_authz_oid.components));
+ if (!new_authz_oid.components) {
+ free(authz_oid.components);
+
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ memcpy(new_authz_oid.components, authz_oid.components,
+ authz_oid.length * sizeof(*authz_oid.components));
+
+ free(authz_oid.components);
+
+ new_authz_oid.components[new_authz_oid.length - 1] = ad_type;
+
+ authz_oid_flat.length = der_length_oid(&new_authz_oid);
+ authz_oid_flat.elements = malloc(authz_oid_flat.length);
+
+ if (!authz_oid_flat.elements) {
+ free(new_authz_oid.components);
+
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ if (der_put_oid((unsigned char *)authz_oid_flat.elements + authz_oid_flat.length - 1,
+ authz_oid_flat.length,
+ &new_authz_oid, &size) != 0) {
+ free(new_authz_oid.components);
+
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ free(new_authz_oid.components);
+
+ /* FINALLY, we have the OID */
+
+ maj_stat =
+ gss_inquire_sec_context_by_oid (minor_status,
+ context_handle,
+ &authz_oid_flat,
+ &data_set);
+
+ free(authz_oid_flat.elements);
+
+ 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_storage *sp = NULL;
+
+ ret = _gsskrb5_init();
+ if(ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ if (context_handle == GSS_C_NO_CONTEXT) {
+ _gsskrb5_set_status("no context handle");
+ *minor_status = EINVAL;
+ 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) {
+ _gsskrb5_set_status("no buffers returned");
+ gss_release_buffer_set(minor_status, &data_set);
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ if (data_set->count != 1) {
+ _gsskrb5_set_status("%d != 1 buffers returned", data_set->count);
+ gss_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_release_buffer_set(minor_status, &data_set);
+ if (sp)
+ krb5_storage_free(sp);
+ if (ret) {
+ _gsskrb5_set_error_string();
+ if (keyblock) {
+ krb5_free_keyblock(_gsskrb5_context, *keyblock);
+ }
+
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
+
+OM_uint32
+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);
+}
+
+OM_uint32
+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);
+}
+
+OM_uint32
+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_ACCEPTOR_SUBKEY_X,
+ keyblock);
+}
diff --git a/source4/heimdal/lib/gssapi/mech/gss_mech_switch.c b/source4/heimdal/lib/gssapi/mech/gss_mech_switch.c
new file mode 100644
index 0000000000..3d01ba69d4
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_mech_switch.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_mech_switch.c,v 1.2 2006/02/04 09:40:21 dfr Exp $
+ */
+
+#include "mech_locl.h"
+#include <heim_threads.h>
+RCSID("$Id: gss_mech_switch.c,v 1.7 2006/10/09 11:13:30 lha Exp $");
+
+#ifndef _PATH_GSS_MECH
+#define _PATH_GSS_MECH "/etc/gss/mech"
+#endif
+
+struct _gss_mech_switch_list _gss_mechs = { 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 oid)
+{
+ int number_count, i, j;
+ int byte_count;
+ const char *p, *q;
+ char *res;
+
+ /*
+ * 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;
+ 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 (!res) {
+ res = malloc(byte_count);
+ if (!res)
+ return (ENOMEM);
+ oid->length = byte_count;
+ oid->elements = res;
+ }
+ }
+
+ return (0);
+}
+
+#define SYM(name) \
+do { \
+ m->gm_mech.gm_ ## name = dlsym(so, "gss_" #name); \
+ if (!m->gm_mech.gm_ ## name) { \
+ fprintf(stderr, "can't find symbol gss_" #name "\n"); \
+ goto bad; \
+ } \
+} while (0)
+
+#define OPTSYM(name) \
+do { \
+ m->gm_mech.gm_ ## name = dlsym(so, "gss_" #name); \
+} while (0)
+
+/*
+ *
+ */
+static int
+add_builtin(gssapi_mech_interface mech)
+{
+ struct _gss_mech_switch *m;
+ OM_uint32 minor_status;
+
+ m = malloc(sizeof(*m));
+ if (m == NULL)
+ return 1;
+ m->gm_so = NULL;
+ m->gm_mech = *mech;
+ m->gm_mech_oid = mech->gm_mech_oid; /* XXX */
+ gss_add_oid_set_member(&minor_status,
+ &m->gm_mech.gm_mech_oid, &_gss_mech_oids);
+
+ SLIST_INSERT_HEAD(&_gss_mechs, m, gm_link);
+ return 0;
+}
+
+/*
+ * Load the mechanisms file (/etc/gss/mech).
+ */
+void
+_gss_load_mech(void)
+{
+ OM_uint32 major_status, minor_status;
+ FILE *fp;
+ char buf[256];
+ char *p;
+ char *name, *oid, *lib, *kobj;
+ struct _gss_mech_switch *m;
+ void *so;
+
+
+ HEIMDAL_MUTEX_lock(&_gss_mech_mutex);
+
+ if (SLIST_FIRST(&_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;
+ }
+
+ add_builtin(__gss_krb5_initialize());
+ add_builtin(__gss_spnego_initialize());
+
+ fp = fopen(_PATH_GSS_MECH, "r");
+ if (!fp) {
+/* perror(_PATH_GSS_MECH); */
+ HEIMDAL_MUTEX_unlock(&_gss_mech_mutex);
+ return;
+ }
+
+ while (fgets(buf, sizeof(buf), fp)) {
+ 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;
+
+#ifndef RTLD_LOCAL
+#define RTLD_LOCAL 0
+#endif
+
+ so = dlopen(lib, RTLD_LOCAL);
+ if (!so) {
+/* fprintf(stderr, "dlopen: %s\n", dlerror()); */
+ continue;
+ }
+
+ m = malloc(sizeof(*m));
+ if (!m)
+ break;
+ m->gm_so = so;
+ if (_gss_string_to_oid(oid, &m->gm_mech.gm_mech_oid)) {
+ free(m);
+ continue;
+ }
+
+ major_status = gss_add_oid_set_member(&minor_status,
+ &m->gm_mech.gm_mech_oid, &_gss_mech_oids);
+ if (major_status) {
+ free(m->gm_mech.gm_mech_oid.elements);
+ free(m);
+ continue;
+ }
+
+ 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);
+ SYM(display_status);
+ SYM(indicate_mechs);
+ SYM(compare_name);
+ SYM(display_name);
+ SYM(import_name);
+ SYM(export_name);
+ SYM(release_name);
+ SYM(inquire_cred);
+ SYM(inquire_context);
+ SYM(wrap_size_limit);
+ SYM(add_cred);
+ SYM(inquire_cred_by_mech);
+ SYM(export_sec_context);
+ SYM(import_sec_context);
+ SYM(inquire_names_for_mech);
+ SYM(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);
+ OPTSYM(set_cred_option);
+
+ SLIST_INSERT_HEAD(&_gss_mechs, m, gm_link);
+ continue;
+
+ bad:
+ free(m->gm_mech.gm_mech_oid.elements);
+ free(m);
+ dlclose(so);
+ continue;
+ }
+ fclose(fp);
+ HEIMDAL_MUTEX_unlock(&_gss_mech_mutex);
+}
+
+gssapi_mech_interface
+__gss_get_mechanism(gss_OID mech)
+{
+ struct _gss_mech_switch *m;
+
+ _gss_load_mech();
+ SLIST_FOREACH(m, &_gss_mechs, gm_link) {
+ if (gss_oid_equal(&m->gm_mech.gm_mech_oid, mech))
+ return &m->gm_mech;
+ }
+ return NULL;
+}
diff --git a/source4/heimdal/lib/gssapi/mech/gss_names.c b/source4/heimdal/lib/gssapi/mech/gss_names.c
new file mode 100644
index 0000000000..833c582006
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_names.c
@@ -0,0 +1,105 @@
+/*-
+ * 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_names.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+RCSID("$Id: gss_names.c,v 1.2 2006/06/28 09:00:25 lha Exp $");
+
+struct _gss_mechanism_name *
+_gss_find_mn(struct _gss_name *name, gss_OID mech)
+{
+ OM_uint32 major_status, minor_status;
+ gssapi_mech_interface m;
+ struct _gss_mechanism_name *mn;
+
+ SLIST_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 (0);
+
+ m = __gss_get_mechanism(mech);
+ if (!m)
+ return (0);
+
+ mn = malloc(sizeof(struct _gss_mechanism_name));
+ if (!mn)
+ return (0);
+
+ major_status = m->gm_import_name(&minor_status,
+ &name->gn_value,
+ (name->gn_type.elements
+ ? &name->gn_type : GSS_C_NO_OID),
+ &mn->gmn_name);
+ if (major_status) {
+ free(mn);
+ return (0);
+ }
+
+ mn->gmn_mech = m;
+ mn->gmn_mech_oid = &m->gm_mech_oid;
+ SLIST_INSERT_HEAD(&name->gn_mn, mn, gmn_link);
+ }
+ return (mn);
+}
+
+/*
+ * Make a name from an MN.
+ */
+struct _gss_name *
+_gss_make_name(gssapi_mech_interface m, gss_name_t new_mn)
+{
+ struct _gss_name *name;
+ struct _gss_mechanism_name *mn;
+
+ name = malloc(sizeof(struct _gss_name));
+ if (!name)
+ return (0);
+ memset(name, 0, sizeof(struct _gss_name));
+
+ mn = malloc(sizeof(struct _gss_mechanism_name));
+ if (!mn) {
+ free(name);
+ return (0);
+ }
+
+ SLIST_INIT(&name->gn_mn);
+ mn->gmn_mech = m;
+ mn->gmn_mech_oid = &m->gm_mech_oid;
+ mn->gmn_name = new_mn;
+ SLIST_INSERT_HEAD(&name->gn_mn, mn, gmn_link);
+
+ return (name);
+}
+
diff --git a/source4/heimdal/lib/gssapi/mech/gss_oid_equal.c b/source4/heimdal/lib/gssapi/mech/gss_oid_equal.c
new file mode 100644
index 0000000000..1a8b811f37
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_oid_equal.c
@@ -0,0 +1,45 @@
+/*
+ * 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"
+RCSID("$Id: gss_oid_equal.c,v 1.1 2006/06/28 09:07:08 lha Exp $");
+
+int
+gss_oid_equal(const gss_OID a, const gss_OID b)
+{
+ if (a == b)
+ 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/source4/heimdal/lib/gssapi/mech/gss_process_context_token.c b/source4/heimdal/lib/gssapi/mech/gss_process_context_token.c
new file mode 100644
index 0000000000..1e6f39979f
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_process_context_token.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_process_context_token.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+RCSID("$Id: gss_process_context_token.c,v 1.2 2006/06/28 09:00:25 lha Exp $");
+
+OM_uint32
+gss_process_context_token(OM_uint32 *minor_status,
+ const gss_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/source4/heimdal/lib/gssapi/mech/gss_release_buffer.c b/source4/heimdal/lib/gssapi/mech/gss_release_buffer.c
new file mode 100644
index 0000000000..66705bb40e
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_release_buffer.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_buffer.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+RCSID("$Id: gss_release_buffer.c,v 1.2 2006/06/28 09:00:25 lha Exp $");
+
+OM_uint32
+gss_release_buffer(OM_uint32 *minor_status,
+ gss_buffer_t buffer)
+{
+
+ *minor_status = 0;
+ if (buffer->value)
+ free(buffer->value);
+ buffer->length = 0;
+ buffer->value = 0;
+
+ return (GSS_S_COMPLETE);
+}
diff --git a/source4/heimdal/lib/gssapi/mech/gss_release_cred.c b/source4/heimdal/lib/gssapi/mech/gss_release_cred.c
new file mode 100644
index 0000000000..760621c861
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_release_cred.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_release_cred.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+RCSID("$Id: gss_release_cred.c,v 1.2 2006/06/28 09:00:25 lha Exp $");
+
+OM_uint32
+gss_release_cred(OM_uint32 *minor_status, gss_cred_id_t *cred_handle)
+{
+ struct _gss_cred *cred = (struct _gss_cred *) *cred_handle;
+ struct _gss_mechanism_cred *mc;
+
+ if (*cred_handle == GSS_C_NO_CREDENTIAL)
+ return (GSS_S_COMPLETE);
+
+ while (SLIST_FIRST(&cred->gc_mc)) {
+ mc = SLIST_FIRST(&cred->gc_mc);
+ SLIST_REMOVE_HEAD(&cred->gc_mc, gmc_link);
+ mc->gmc_mech->gm_release_cred(minor_status, &mc->gmc_cred);
+ free(mc);
+ }
+ free(cred);
+
+ *minor_status = 0;
+ *cred_handle = 0;
+ return (GSS_S_COMPLETE);
+}
diff --git a/source4/heimdal/lib/gssapi/mech/gss_release_name.c b/source4/heimdal/lib/gssapi/mech/gss_release_name.c
new file mode 100644
index 0000000000..1286cd3b79
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_release_name.c
@@ -0,0 +1,55 @@
+/*-
+ * 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"
+RCSID("$Id: gss_release_name.c,v 1.3 2006/10/22 07:59:06 lha Exp $");
+
+OM_uint32
+gss_release_name(OM_uint32 *minor_status,
+ gss_name_t *input_name)
+{
+ struct _gss_name *name = (struct _gss_name *) *input_name;
+
+ *minor_status = 0;
+ if (name) {
+ if (name->gn_type.elements)
+ free(name->gn_type.elements);
+ while (SLIST_FIRST(&name->gn_mn)) {
+ struct _gss_mechanism_name *mn;
+ mn = SLIST_FIRST(&name->gn_mn);
+ SLIST_REMOVE_HEAD(&name->gn_mn, gmn_link);
+ mn->gmn_mech->gm_release_name(minor_status,
+ &mn->gmn_name);
+ free(mn);
+ }
+ gss_release_buffer(minor_status, &name->gn_value);
+ free(name);
+ *input_name = GSS_C_NO_NAME;
+ }
+ return (GSS_S_COMPLETE);
+}
diff --git a/source4/heimdal/lib/gssapi/mech/gss_release_oid.c b/source4/heimdal/lib/gssapi/mech/gss_release_oid.c
new file mode 100644
index 0000000000..fc84fabd29
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_release_oid.c
@@ -0,0 +1,59 @@
+/*
+ * 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"
+
+RCSID("$Id: gss_release_oid.c,v 1.1 2006/06/30 09:34:54 lha Exp $");
+
+OM_uint32
+gss_release_oid(OM_uint32 *minor_status, gss_OID *oid)
+{
+ gss_OID o = *oid;
+
+ *oid = GSS_C_NO_OID;
+
+ if (minor_status != NULL)
+ *minor_status = 0;
+
+ if (o == GSS_C_NO_OID)
+ return GSS_S_COMPLETE;
+
+ if (o->elements != NULL) {
+ free(o->elements);
+ o->elements = NULL;
+ }
+ o->length = 0;
+ free(o);
+
+ return GSS_S_COMPLETE;
+}
diff --git a/source4/heimdal/lib/gssapi/mech/gss_release_oid_set.c b/source4/heimdal/lib/gssapi/mech/gss_release_oid_set.c
new file mode 100644
index 0000000000..101657e4fb
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_release_oid_set.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_release_oid_set.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+RCSID("$Id: gss_release_oid_set.c,v 1.2 2006/06/28 09:00:25 lha Exp $");
+
+OM_uint32
+gss_release_oid_set(OM_uint32 *minor_status,
+ gss_OID_set *set)
+{
+
+ *minor_status = 0;
+ if (*set) {
+ if ((*set)->elements)
+ free((*set)->elements);
+ free(*set);
+ *set = 0;
+ }
+ return (GSS_S_COMPLETE);
+}
diff --git a/source4/heimdal/lib/gssapi/mech/gss_seal.c b/source4/heimdal/lib/gssapi/mech/gss_seal.c
new file mode 100644
index 0000000000..2f66f90d4f
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_seal.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_seal.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+RCSID("$Id: gss_seal.c,v 1.2 2006/06/28 09:00:25 lha Exp $");
+
+OM_uint32
+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/source4/heimdal/lib/gssapi/mech/gss_set_cred_option.c b/source4/heimdal/lib/gssapi/mech/gss_set_cred_option.c
new file mode 100644
index 0000000000..f8e013da18
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_set_cred_option.c
@@ -0,0 +1,115 @@
+/*
+ * 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"
+RCSID("$Id: gss_set_cred_option.c,v 1.7 2006/07/01 08:50:49 lha Exp $");
+
+OM_uint32
+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 = malloc(sizeof(*cred));
+ if (cred == NULL)
+ return GSS_S_FAILURE;
+
+ cred->gc_usage = GSS_C_BOTH; /* XXX */
+ SLIST_INIT(&cred->gc_mc);
+
+ SLIST_FOREACH(m, &_gss_mechs, gm_link) {
+
+ if (m->gm_mech.gm_set_cred_option == NULL)
+ continue;
+
+ mc = malloc(sizeof(*mc));
+ if (mc == NULL) {
+ /* XXX free the other mc's */
+ 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;
+ SLIST_INSERT_HEAD(&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;
+
+ SLIST_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_BAD_MECH)
+ one_ok = 1;
+ }
+ }
+ if (one_ok) {
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+ }
+ return major_status;
+}
+
diff --git a/source4/heimdal/lib/gssapi/mech/gss_set_sec_context_option.c b/source4/heimdal/lib/gssapi/mech/gss_set_sec_context_option.c
new file mode 100644
index 0000000000..aa562a23b6
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_set_sec_context_option.c
@@ -0,0 +1,69 @@
+/*
+ * 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"
+RCSID("$Id: gss_set_sec_context_option.c,v 1.2 2006/06/28 14:39:00 lha Exp $");
+
+OM_uint32
+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 m;
+
+ *minor_status = 0;
+
+ if (context_handle == NULL)
+ return GSS_S_NO_CONTEXT;
+
+ ctx = (struct _gss_context *) *context_handle;
+
+ if (ctx == NULL)
+ return GSS_S_NO_CONTEXT;
+
+ m = ctx->gc_mech;
+
+ if (m == NULL)
+ return GSS_S_BAD_MECH;
+
+ if (m->gm_set_sec_context_option != NULL)
+ major_status = m->gm_set_sec_context_option(minor_status,
+ &ctx->gc_ctx, object, value);
+ else
+ major_status = GSS_S_BAD_MECH;
+
+ return major_status;
+}
+
diff --git a/source4/heimdal/lib/gssapi/mech/gss_sign.c b/source4/heimdal/lib/gssapi/mech/gss_sign.c
new file mode 100644
index 0000000000..8c854e5e43
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_sign.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_sign.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+RCSID("$Id: gss_sign.c,v 1.2 2006/06/28 09:00:25 lha Exp $");
+
+OM_uint32
+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/source4/heimdal/lib/gssapi/mech/gss_test_oid_set_member.c b/source4/heimdal/lib/gssapi/mech/gss_test_oid_set_member.c
new file mode 100644
index 0000000000..a71a8b7c92
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_test_oid_set_member.c
@@ -0,0 +1,47 @@
+/*-
+ * 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"
+RCSID("$Id: gss_test_oid_set_member.c,v 1.2 2006/06/28 09:00:25 lha Exp $");
+
+OM_uint32
+gss_test_oid_set_member(OM_uint32 *minor_status,
+ const gss_OID member,
+ const gss_OID_set set,
+ int *present)
+{
+ int 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/source4/heimdal/lib/gssapi/mech/gss_unseal.c b/source4/heimdal/lib/gssapi/mech/gss_unseal.c
new file mode 100644
index 0000000000..128dc7883c
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_unseal.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_unseal.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+RCSID("$Id: gss_unseal.c,v 1.2 2006/06/28 09:00:25 lha Exp $");
+
+OM_uint32
+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/source4/heimdal/lib/gssapi/mech/gss_unwrap.c b/source4/heimdal/lib/gssapi/mech/gss_unwrap.c
new file mode 100644
index 0000000000..1c9484b18d
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_unwrap.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_unwrap.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+RCSID("$Id: gss_unwrap.c,v 1.2 2006/06/28 09:00:25 lha Exp $");
+
+OM_uint32
+gss_unwrap(OM_uint32 *minor_status,
+ const gss_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 = 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/source4/heimdal/lib/gssapi/mech/gss_utils.c b/source4/heimdal/lib/gssapi/mech/gss_utils.c
new file mode 100644
index 0000000000..33ee033209
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_utils.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_utils.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+RCSID("$Id: gss_utils.c,v 1.2 2006/06/28 09:00:25 lha Exp $");
+
+OM_uint32
+_gss_copy_oid(OM_uint32 *minor_status,
+ const gss_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) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ to_oid->length = len;
+ memcpy(to_oid->elements, from_oid->elements, len);
+ 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;
+ return GSS_S_FAILURE;
+ }
+ to_buf->length = len;
+ memcpy(to_buf->value, from_buf->value, len);
+ return (GSS_S_COMPLETE);
+}
+
diff --git a/source4/heimdal/lib/gssapi/mech/gss_verify.c b/source4/heimdal/lib/gssapi/mech/gss_verify.c
new file mode 100644
index 0000000000..a99d17e2d7
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_verify.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_verify.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+RCSID("$Id: gss_verify.c,v 1.2 2006/06/28 09:00:25 lha Exp $");
+
+OM_uint32
+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/source4/heimdal/lib/gssapi/mech/gss_verify_mic.c b/source4/heimdal/lib/gssapi/mech/gss_verify_mic.c
new file mode 100644
index 0000000000..b51ed7a8c4
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_verify_mic.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_verify_mic.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+RCSID("$Id: gss_verify_mic.c,v 1.2 2006/06/28 09:00:25 lha Exp $");
+
+OM_uint32
+gss_verify_mic(OM_uint32 *minor_status,
+ const gss_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 = ctx->gc_mech;
+
+ return (m->gm_verify_mic(minor_status, ctx->gc_ctx,
+ message_buffer, token_buffer, qop_state));
+}
diff --git a/source4/heimdal/lib/gssapi/mech/gss_wrap.c b/source4/heimdal/lib/gssapi/mech/gss_wrap.c
new file mode 100644
index 0000000000..a97ec1308f
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_wrap.c
@@ -0,0 +1,47 @@
+/*-
+ * 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"
+RCSID("$Id: gss_wrap.c,v 1.2 2006/06/28 09:00:26 lha Exp $");
+
+OM_uint32
+gss_wrap(OM_uint32 *minor_status,
+ const gss_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 = 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/source4/heimdal/lib/gssapi/mech/gss_wrap_size_limit.c b/source4/heimdal/lib/gssapi/mech/gss_wrap_size_limit.c
new file mode 100644
index 0000000000..27493aa90d
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_wrap_size_limit.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_wrap_size_limit.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+RCSID("$Id: gss_wrap_size_limit.c,v 1.2 2006/06/28 09:00:26 lha Exp $");
+
+OM_uint32
+gss_wrap_size_limit(OM_uint32 *minor_status,
+ const gss_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 = 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/source4/heimdal/lib/gssapi/mech/gssapi.asn1 b/source4/heimdal/lib/gssapi/mech/gssapi.asn1
new file mode 100644
index 0000000000..544618b7d4
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gssapi.asn1
@@ -0,0 +1,12 @@
+-- $Id: gssapi.asn1,v 1.3 2006/10/18 21:08:19 lha Exp $
+
+GSS-API DEFINITIONS ::= BEGIN
+
+IMPORTS heim_any_set FROM heim;
+
+GSSAPIContextToken ::= [APPLICATION 0] IMPLICIT SEQUENCE {
+ thisMech OBJECT IDENTIFIER,
+ innerContextToken heim_any_set
+}
+
+END \ No newline at end of file
diff --git a/source4/heimdal/lib/gssapi/mech/mech_locl.h b/source4/heimdal/lib/gssapi/mech/mech_locl.h
new file mode 100644
index 0000000000..f5db15c5fa
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/mech_locl.h
@@ -0,0 +1,63 @@
+/*
+ * 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: mech_locl.h,v 1.4 2006/10/07 18:25:27 lha Exp $ */
+
+#include <config.h>
+
+#include <krb5-types.h>
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <dlfcn.h>
+#include <errno.h>
+
+#include <gssapi_asn1.h>
+#include <der.h>
+
+#include <roken.h>
+
+#include <gssapi.h>
+#include <gssapi_mech.h>
+
+#include "mechqueue.h"
+
+#include "context.h"
+#include "cred.h"
+#include "mech_switch.h"
+#include "name.h"
+#include "utils.h"
diff --git a/source4/heimdal/lib/gssapi/mech/mech_switch.h b/source4/heimdal/lib/gssapi/mech/mech_switch.h
new file mode 100644
index 0000000000..0984d36ef3
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/mech_switch.h
@@ -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/mech_switch.h,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ * $Id: mech_switch.h,v 1.3 2006/10/05 18:31:53 lha Exp $
+ */
+
+#include <gssapi_mech.h>
+
+struct _gss_mech_switch {
+ SLIST_ENTRY(_gss_mech_switch) gm_link;
+ gss_OID_desc gm_mech_oid;
+ void *gm_so;
+ gssapi_mech_interface_desc gm_mech;
+};
+SLIST_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/source4/heimdal/lib/gssapi/mech/mechqueue.h b/source4/heimdal/lib/gssapi/mech/mechqueue.h
new file mode 100644
index 0000000000..8434b76c00
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/mechqueue.h
@@ -0,0 +1,101 @@
+/* $NetBSD: queue.h,v 1.39 2004/04/18 14:25:34 lukem Exp $ */
+
+/*
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. 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 University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)queue.h 8.5 (Berkeley) 8/20/94
+ */
+
+#ifndef _MECHQUEUE_H_
+#define _MECHQUEUE_H_
+
+#ifndef SLIST_HEAD
+
+/*
+ * Singly-linked List definitions.
+ */
+#define SLIST_HEAD(name, type) \
+struct name { \
+ struct type *slh_first; /* first element */ \
+}
+
+#define SLIST_HEAD_INITIALIZER(head) \
+ { NULL }
+
+#define SLIST_ENTRY(type) \
+struct { \
+ struct type *sle_next; /* next element */ \
+}
+
+/*
+ * Singly-linked List functions.
+ */
+#define SLIST_INIT(head) do { \
+ (head)->slh_first = NULL; \
+} while (/*CONSTCOND*/0)
+
+#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
+ (elm)->field.sle_next = (slistelm)->field.sle_next; \
+ (slistelm)->field.sle_next = (elm); \
+} while (/*CONSTCOND*/0)
+
+#define SLIST_INSERT_HEAD(head, elm, field) do { \
+ (elm)->field.sle_next = (head)->slh_first; \
+ (head)->slh_first = (elm); \
+} while (/*CONSTCOND*/0)
+
+#define SLIST_REMOVE_HEAD(head, field) do { \
+ (head)->slh_first = (head)->slh_first->field.sle_next; \
+} while (/*CONSTCOND*/0)
+
+#define SLIST_REMOVE(head, elm, type, field) do { \
+ if ((head)->slh_first == (elm)) { \
+ SLIST_REMOVE_HEAD((head), field); \
+ } \
+ else { \
+ struct type *curelm = (head)->slh_first; \
+ while(curelm->field.sle_next != (elm)) \
+ curelm = curelm->field.sle_next; \
+ curelm->field.sle_next = \
+ curelm->field.sle_next->field.sle_next; \
+ } \
+} while (/*CONSTCOND*/0)
+
+#define SLIST_FOREACH(var, head, field) \
+ for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next)
+
+/*
+ * Singly-linked List access methods.
+ */
+#define SLIST_EMPTY(head) ((head)->slh_first == NULL)
+#define SLIST_FIRST(head) ((head)->slh_first)
+#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
+
+#endif /* SLIST_HEAD */
+
+#endif /* !_MECHQUEUE_H_ */
diff --git a/source4/heimdal/lib/gssapi/mech/name.h b/source4/heimdal/lib/gssapi/mech/name.h
new file mode 100644
index 0000000000..3e7443ba20
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/name.h
@@ -0,0 +1,47 @@
+/*-
+ * 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: name.h,v 1.4 2006/10/05 18:36:07 lha Exp $
+ */
+
+struct _gss_mechanism_name {
+ SLIST_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 */
+};
+SLIST_HEAD(_gss_mechanism_name_list, _gss_mechanism_name);
+
+struct _gss_name {
+ gss_OID_desc gn_type; /* type of name */
+ gss_buffer_desc gn_value; /* value (as imported) */
+ struct _gss_mechanism_name_list gn_mn; /* list of MNs */
+};
+
+struct _gss_mechanism_name *
+ _gss_find_mn(struct _gss_name *name, gss_OID mech);
+struct _gss_name *
+ _gss_make_name(gssapi_mech_interface m, gss_name_t new_mn);
diff --git a/source4/heimdal/lib/gssapi/mech/utils.h b/source4/heimdal/lib/gssapi/mech/utils.h
new file mode 100644
index 0000000000..75a507298c
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/utils.h
@@ -0,0 +1,32 @@
+/*-
+ * 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: utils.h,v 1.3 2006/07/20 01:48:25 lha Exp $
+ */
+
+OM_uint32 _gss_copy_oid(OM_uint32 *, const gss_OID, gss_OID);
+OM_uint32 _gss_copy_buffer(OM_uint32 *minor_status,
+ const gss_buffer_t from_buf, gss_buffer_t to_buf);
diff --git a/source4/heimdal/lib/gssapi/spnego.asn1 b/source4/heimdal/lib/gssapi/spnego.asn1
deleted file mode 100755
index 5dc767cf76..0000000000
--- a/source4/heimdal/lib/gssapi/spnego.asn1
+++ /dev/null
@@ -1,42 +0,0 @@
--- $Id: spnego.asn1,v 1.4 2004/03/07 13:38:08 lha Exp $
-
-SPNEGO DEFINITIONS ::=
-BEGIN
-
-MechType::= OBJECT IDENTIFIER
-
-MechTypeList ::= SEQUENCE OF MechType
-
-ContextFlags ::= BIT STRING {
- delegFlag (0),
- mutualFlag (1),
- replayFlag (2),
- sequenceFlag (3),
- anonFlag (4),
- confFlag (5),
- integFlag (6)
-}
-
-NegTokenInit ::= SEQUENCE {
- mechTypes [0] MechTypeList OPTIONAL,
- reqFlags [1] ContextFlags OPTIONAL,
- mechToken [2] OCTET STRING OPTIONAL,
- mechListMIC [3] OCTET STRING OPTIONAL
- }
-
-NegTokenTarg ::= SEQUENCE {
- negResult [0] ENUMERATED {
- accept_completed (0),
- accept_incomplete (1),
- reject (2) } OPTIONAL,
- supportedMech [1] MechType OPTIONAL,
- responseToken [2] OCTET STRING OPTIONAL,
- mechListMIC [3] OCTET STRING OPTIONAL
-}
-
-NegotiationToken ::= CHOICE {
- negTokenInit[0] NegTokenInit,
- negTokenTarg[1] NegTokenTarg
-}
-
-END
diff --git a/source4/heimdal/lib/gssapi/spnego/accept_sec_context.c b/source4/heimdal/lib/gssapi/spnego/accept_sec_context.c
new file mode 100644
index 0000000000..8a885a3e2f
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/spnego/accept_sec_context.c
@@ -0,0 +1,873 @@
+/*
+ * Copyright (c) 1997 - 2004 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * Portions Copyright (c) 2004 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.
+ *
+ * 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 "spnego/spnego_locl.h"
+
+RCSID("$Id: accept_sec_context.c,v 1.6 2006/10/07 22:26:57 lha Exp $");
+
+OM_uint32
+_gss_spnego_encode_response(OM_uint32 *minor_status,
+ const NegTokenResp *resp,
+ gss_buffer_t data,
+ u_char **ret_buf)
+{
+ OM_uint32 ret;
+ u_char *buf;
+ size_t buf_size, buf_len;
+
+ buf_size = 1024;
+ buf = malloc(buf_size);
+ if (buf == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ do {
+ ret = encode_NegTokenResp(buf + buf_size - 1,
+ buf_size,
+ resp, &buf_len);
+ if (ret == 0) {
+ size_t tmp;
+
+ ret = der_put_length_and_tag(buf + buf_size - buf_len - 1,
+ buf_size - buf_len,
+ buf_len,
+ ASN1_C_CONTEXT,
+ CONS,
+ 1,
+ &tmp);
+ if (ret == 0)
+ buf_len += tmp;
+ }
+ if (ret) {
+ if (ret == ASN1_OVERFLOW) {
+ u_char *tmp;
+
+ buf_size *= 2;
+ tmp = realloc (buf, buf_size);
+ if (tmp == NULL) {
+ *minor_status = ENOMEM;
+ free(buf);
+ return GSS_S_FAILURE;
+ }
+ buf = tmp;
+ } else {
+ *minor_status = ret;
+ free(buf);
+ return GSS_S_FAILURE;
+ }
+ }
+ } while (ret == ASN1_OVERFLOW);
+
+ data->value = buf + buf_size - buf_len;
+ data->length = buf_len;
+ *ret_buf = buf;
+
+ return GSS_S_COMPLETE;
+}
+
+static OM_uint32
+send_reject (OM_uint32 *minor_status,
+ gss_buffer_t output_token)
+{
+ NegTokenResp resp;
+ gss_buffer_desc data;
+ u_char *buf;
+ OM_uint32 ret;
+
+ ALLOC(resp.negResult, 1);
+ if (resp.negResult == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ *(resp.negResult) = reject;
+ resp.supportedMech = NULL;
+ resp.responseToken = NULL;
+ resp.mechListMIC = NULL;
+
+ ret = _gss_spnego_encode_response (minor_status, &resp, &data, &buf);
+ free_NegTokenResp(&resp);
+ if (ret != GSS_S_COMPLETE)
+ return ret;
+
+ output_token->value = malloc(data.length);
+ if (output_token->value == NULL) {
+ *minor_status = ENOMEM;
+ ret = GSS_S_FAILURE;
+ } else {
+ output_token->length = data.length;
+ memcpy(output_token->value, data.value, output_token->length);
+ }
+ free(buf);
+ if (ret != GSS_S_COMPLETE)
+ return ret;
+ return GSS_S_BAD_MECH;
+}
+
+OM_uint32
+_gss_spnego_indicate_mechtypelist (OM_uint32 *minor_status,
+ int includeMSCompatOID,
+ const gssspnego_cred cred_handle,
+ MechTypeList *mechtypelist,
+ gss_OID *preferred_mech)
+{
+ OM_uint32 ret;
+ gss_OID_set supported_mechs = GSS_C_NO_OID_SET;
+ int i, count;
+
+ if (cred_handle != NULL) {
+ ret = gss_inquire_cred(minor_status,
+ cred_handle->negotiated_cred_id,
+ NULL,
+ NULL,
+ NULL,
+ &supported_mechs);
+ } else {
+ ret = gss_indicate_mechs(minor_status, &supported_mechs);
+ }
+
+ if (ret != GSS_S_COMPLETE) {
+ return ret;
+ }
+
+ if (supported_mechs->count == 0) {
+ *minor_status = ENOENT;
+ gss_release_oid_set(minor_status, &supported_mechs);
+ return GSS_S_FAILURE;
+ }
+
+ count = supported_mechs->count;
+ if (includeMSCompatOID)
+ count++;
+
+ mechtypelist->len = 0;
+ mechtypelist->val = calloc(count, sizeof(MechType));
+ if (mechtypelist->val == NULL) {
+ *minor_status = ENOMEM;
+ gss_release_oid_set(minor_status, &supported_mechs);
+ return GSS_S_FAILURE;
+ }
+
+ for (i = 0; i < supported_mechs->count; i++) {
+ ret = _gss_spnego_add_mech_type(&supported_mechs->elements[i],
+ includeMSCompatOID,
+ mechtypelist);
+ if (ret != 0) {
+ *minor_status = ENOMEM;
+ ret = GSS_S_FAILURE;
+ break;
+ }
+ }
+
+ if (ret == GSS_S_COMPLETE && preferred_mech != NULL) {
+ ret = gss_duplicate_oid(minor_status,
+ &supported_mechs->elements[0],
+ preferred_mech);
+ }
+
+ if (ret != GSS_S_COMPLETE) {
+ free_MechTypeList(mechtypelist);
+ mechtypelist->len = 0;
+ mechtypelist->val = NULL;
+ }
+ gss_release_oid_set(minor_status, &supported_mechs);
+
+ return ret;
+}
+
+static OM_uint32
+send_supported_mechs (OM_uint32 *minor_status,
+ gss_buffer_t output_token)
+{
+ NegTokenInit ni;
+ char hostname[MAXHOSTNAMELEN], *p;
+ gss_buffer_desc name_buf;
+ gss_OID name_type;
+ gss_name_t target_princ;
+ gss_name_t canon_princ;
+ OM_uint32 ret, minor;
+ u_char *buf;
+ size_t buf_size, buf_len;
+ gss_buffer_desc data;
+
+ memset(&ni, 0, sizeof(ni));
+
+ ni.reqFlags = NULL;
+ ni.mechToken = NULL;
+ ni.negHints = NULL;
+ ni.mechListMIC = NULL;
+
+ ret = _gss_spnego_indicate_mechtypelist(minor_status, 1,
+ NULL,
+ &ni.mechTypes, NULL);
+ if (ret != GSS_S_COMPLETE) {
+ return ret;
+ }
+
+ memset(&target_princ, 0, sizeof(target_princ));
+ if (gethostname(hostname, sizeof(hostname) - 1) != 0) {
+ *minor_status = errno;
+ free_NegTokenInit(&ni);
+ return GSS_S_FAILURE;
+ }
+
+ /* Send the constructed SAM name for this host */
+ for (p = hostname; *p != '\0' && *p != '.'; p++) {
+ *p = toupper((unsigned char)*p);
+ }
+ *p++ = '$';
+ *p = '\0';
+
+ name_buf.length = strlen(hostname);
+ name_buf.value = hostname;
+
+ ret = gss_import_name(minor_status, &name_buf,
+ GSS_C_NO_OID,
+ &target_princ);
+ if (ret != GSS_S_COMPLETE) {
+ return ret;
+ }
+
+ name_buf.length = 0;
+ name_buf.value = NULL;
+
+ /* Canonicalize the name using the preferred mechanism */
+ ret = gss_canonicalize_name(minor_status,
+ target_princ,
+ GSS_C_NO_OID,
+ &canon_princ);
+ if (ret != GSS_S_COMPLETE) {
+ gss_release_name(&minor, &target_princ);
+ return ret;
+ }
+
+ ret = gss_display_name(minor_status, canon_princ,
+ &name_buf, &name_type);
+ if (ret != GSS_S_COMPLETE) {
+ gss_release_name(&minor, &canon_princ);
+ gss_release_name(&minor, &target_princ);
+ return ret;
+ }
+
+ gss_release_name(&minor, &canon_princ);
+ gss_release_name(&minor, &target_princ);
+
+ ALLOC(ni.negHints, 1);
+ if (ni.negHints == NULL) {
+ *minor_status = ENOMEM;
+ gss_release_buffer(&minor, &name_buf);
+ free_NegTokenInit(&ni);
+ return GSS_S_FAILURE;
+ }
+
+ ALLOC(ni.negHints->hintName, 1);
+ if (ni.negHints->hintName == NULL) {
+ *minor_status = ENOMEM;
+ gss_release_buffer(&minor, &name_buf);
+ free_NegTokenInit(&ni);
+ return GSS_S_FAILURE;
+ }
+
+ *(ni.negHints->hintName) = name_buf.value;
+ name_buf.value = NULL;
+ ni.negHints->hintAddress = NULL;
+
+ buf_size = 1024;
+ buf = malloc(buf_size);
+ if (buf == NULL) {
+ free_NegTokenInit(&ni);
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ do {
+ ret = encode_NegTokenInit(buf + buf_size - 1,
+ buf_size,
+ &ni, &buf_len);
+ if (ret == 0) {
+ size_t tmp;
+
+ ret = der_put_length_and_tag(buf + buf_size - buf_len - 1,
+ buf_size - buf_len,
+ buf_len,
+ ASN1_C_CONTEXT,
+ CONS,
+ 0,
+ &tmp);
+ if (ret == 0)
+ buf_len += tmp;
+ }
+ if (ret) {
+ if (ret == ASN1_OVERFLOW) {
+ u_char *tmp;
+
+ buf_size *= 2;
+ tmp = realloc (buf, buf_size);
+ if (tmp == NULL) {
+ *minor_status = ENOMEM;
+ free(buf);
+ free_NegTokenInit(&ni);
+ return GSS_S_FAILURE;
+ }
+ buf = tmp;
+ } else {
+ *minor_status = ret;
+ free(buf);
+ free_NegTokenInit(&ni);
+ return GSS_S_FAILURE;
+ }
+ }
+ } while (ret == ASN1_OVERFLOW);
+
+ data.value = buf + buf_size - buf_len;
+ data.length = buf_len;
+
+ ret = gss_encapsulate_token(&data,
+ GSS_SPNEGO_MECHANISM,
+ output_token);
+ free (buf);
+ free_NegTokenInit (&ni);
+
+ if (ret != GSS_S_COMPLETE)
+ return ret;
+
+ *minor_status = 0;
+
+ return GSS_S_CONTINUE_NEEDED;
+}
+
+static OM_uint32
+send_accept (OM_uint32 *minor_status,
+ gssspnego_ctx context_handle,
+ gss_buffer_t mech_token,
+ int initial_response,
+ gss_buffer_t mech_buf,
+ gss_buffer_t output_token)
+{
+ NegTokenResp resp;
+ gss_buffer_desc data;
+ u_char *buf;
+ OM_uint32 ret;
+ gss_buffer_desc mech_mic_buf;
+
+ memset(&resp, 0, sizeof(resp));
+
+ ALLOC(resp.negResult, 1);
+ if (resp.negResult == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ if (context_handle->open) {
+ if (mech_token != GSS_C_NO_BUFFER
+ && mech_token->length != 0
+ && mech_buf != GSS_C_NO_BUFFER)
+ *(resp.negResult) = accept_incomplete;
+ else
+ *(resp.negResult) = accept_completed;
+ } else {
+ if (initial_response && context_handle->require_mic)
+ *(resp.negResult) = request_mic;
+ else
+ *(resp.negResult) = accept_incomplete;
+ }
+
+ if (initial_response) {
+ ALLOC(resp.supportedMech, 1);
+ if (resp.supportedMech == NULL) {
+ free_NegTokenResp(&resp);
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ ret = der_get_oid(context_handle->preferred_mech_type->elements,
+ context_handle->preferred_mech_type->length,
+ resp.supportedMech,
+ NULL);
+ if (ret) {
+ free_NegTokenResp(&resp);
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ } else {
+ resp.supportedMech = NULL;
+ }
+
+ if (mech_token != GSS_C_NO_BUFFER && mech_token->length != 0) {
+ ALLOC(resp.responseToken, 1);
+ if (resp.responseToken == NULL) {
+ free_NegTokenResp(&resp);
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ resp.responseToken->length = mech_token->length;
+ resp.responseToken->data = mech_token->value;
+ mech_token->length = 0;
+ mech_token->value = NULL;
+ } else {
+ resp.responseToken = NULL;
+ }
+
+ if (mech_buf != GSS_C_NO_BUFFER) {
+ ALLOC(resp.mechListMIC, 1);
+ if (resp.mechListMIC == NULL) {
+ free_NegTokenResp(&resp);
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ ret = gss_get_mic(minor_status,
+ context_handle->negotiated_ctx_id,
+ 0,
+ mech_buf,
+ &mech_mic_buf);
+ if (ret != GSS_S_COMPLETE) {
+ free_NegTokenResp(&resp);
+ return ret;
+ }
+
+ resp.mechListMIC->length = mech_mic_buf.length;
+ resp.mechListMIC->data = mech_mic_buf.value;
+ } else
+ resp.mechListMIC = NULL;
+
+ ret = _gss_spnego_encode_response (minor_status, &resp, &data, &buf);
+ if (ret != GSS_S_COMPLETE) {
+ free_NegTokenResp(&resp);
+ return ret;
+ }
+
+ /*
+ * The response should not be encapsulated, because
+ * it is a SubsequentContextToken (note though RFC 1964
+ * specifies encapsulation for all _Kerberos_ tokens).
+ */
+ output_token->value = malloc(data.length);
+ if (output_token->value == NULL) {
+ *minor_status = ENOMEM;
+ ret = GSS_S_FAILURE;
+ } else {
+ output_token->length = data.length;
+ memcpy(output_token->value, data.value, output_token->length);
+ }
+ free(buf);
+ if (ret != GSS_S_COMPLETE) {
+ free_NegTokenResp(&resp);
+ return ret;
+ }
+
+ ret = (*(resp.negResult) == accept_completed) ? GSS_S_COMPLETE :
+ GSS_S_CONTINUE_NEEDED;
+ free_NegTokenResp(&resp);
+ return ret;
+}
+
+
+static OM_uint32
+verify_mechlist_mic
+ (OM_uint32 *minor_status,
+ gssspnego_ctx context_handle,
+ gss_buffer_t mech_buf,
+ heim_octet_string *mechListMIC
+ )
+{
+ OM_uint32 ret;
+ gss_buffer_desc mic_buf;
+
+ if (context_handle->verified_mic) {
+ /* This doesn't make sense, we've already verified it? */
+ *minor_status = 0;
+ return GSS_S_DUPLICATE_TOKEN;
+ }
+
+ if (mechListMIC == NULL) {
+ *minor_status = 0;
+ return GSS_S_DEFECTIVE_TOKEN;
+ }
+
+ mic_buf.length = mechListMIC->length;
+ mic_buf.value = mechListMIC->data;
+
+ ret = gss_verify_mic(minor_status,
+ context_handle->negotiated_ctx_id,
+ mech_buf,
+ &mic_buf,
+ NULL);
+
+ if (ret != GSS_S_COMPLETE)
+ ret = GSS_S_DEFECTIVE_TOKEN;
+
+ return ret;
+}
+
+OM_uint32
+_gss_spnego_accept_sec_context
+ (OM_uint32 * minor_status,
+ gss_ctx_id_t * context_handle,
+ const gss_cred_id_t acceptor_cred_handle,
+ const gss_buffer_t input_token_buffer,
+ 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 ret, ret2, minor;
+ NegTokenInit ni;
+ NegTokenResp na;
+ size_t ni_len, na_len;
+ int i;
+ gss_buffer_desc data;
+ size_t len, taglen;
+ int initialToken;
+ unsigned int negResult = accept_incomplete;
+ gss_buffer_t mech_input_token = GSS_C_NO_BUFFER;
+ gss_buffer_t mech_output_token = GSS_C_NO_BUFFER;
+ gss_buffer_desc mech_buf;
+ gss_OID preferred_mech_type = GSS_C_NO_OID;
+ gssspnego_ctx ctx;
+ gssspnego_cred acceptor_cred = (gssspnego_cred)acceptor_cred_handle;
+
+ *minor_status = 0;
+
+ output_token->length = 0;
+ output_token->value = NULL;
+
+ if (src_name != NULL)
+ *src_name = GSS_C_NO_NAME;
+
+ if (mech_type != NULL)
+ *mech_type = GSS_C_NO_OID;
+
+ if (ret_flags != NULL)
+ *ret_flags = 0;
+
+ if (time_rec != NULL)
+ *time_rec = 0;
+
+ if (delegated_cred_handle != NULL)
+ *delegated_cred_handle = GSS_C_NO_CREDENTIAL;
+
+ mech_buf.value = NULL;
+
+ if (*context_handle == GSS_C_NO_CONTEXT) {
+ ret = _gss_spnego_alloc_sec_context(minor_status,
+ context_handle);
+ if (ret != GSS_S_COMPLETE)
+ return ret;
+
+ if (input_token_buffer->length == 0) {
+ return send_supported_mechs (minor_status,
+ output_token);
+ }
+ }
+
+ ctx = (gssspnego_ctx)*context_handle;
+
+ /*
+ * The GSS-API encapsulation is only present on the initial
+ * context token (negTokenInit).
+ */
+ ret = gss_decapsulate_token (input_token_buffer,
+ GSS_SPNEGO_MECHANISM,
+ &data);
+ initialToken = (ret == GSS_S_COMPLETE);
+
+ if (!initialToken) {
+ data.value = input_token_buffer->value;
+ data.length = input_token_buffer->length;
+ }
+
+ ret = der_match_tag_and_length(data.value, data.length,
+ ASN1_C_CONTEXT, CONS,
+ initialToken ? 0 : 1,
+ &len, &taglen);
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ if (len > data.length - taglen) {
+ *minor_status = ASN1_OVERRUN;
+ return GSS_S_FAILURE;
+ }
+
+ if (initialToken) {
+ ret = decode_NegTokenInit((const unsigned char *)data.value + taglen,
+ len, &ni, &ni_len);
+ } else {
+ ret = decode_NegTokenResp((const unsigned char *)data.value + taglen,
+ len, &na, &na_len);
+ }
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_DEFECTIVE_TOKEN;
+ }
+
+ if (!initialToken && na.negResult != NULL) {
+ negResult = *(na.negResult);
+ }
+
+ if (negResult == reject || negResult == request_mic) {
+ /* request_mic should only be sent by acceptor */
+ free_NegTokenResp(&na);
+ return GSS_S_DEFECTIVE_TOKEN;
+ }
+
+ if (initialToken) {
+ for (i = 0; i < ni.mechTypes.len; ++i) {
+ /* Call glue layer to find first mech we support */
+ ret = _gss_spnego_select_mech(minor_status, &ni.mechTypes.val[i],
+ &preferred_mech_type);
+ if (ret == 0)
+ break;
+ }
+ if (preferred_mech_type == GSS_C_NO_OID) {
+ free_NegTokenInit(&ni);
+ return GSS_S_BAD_MECH;
+ }
+ }
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+
+ if (initialToken) {
+ ctx->preferred_mech_type = preferred_mech_type;
+ ctx->initiator_mech_types.len = ni.mechTypes.len;
+ ctx->initiator_mech_types.val = ni.mechTypes.val;
+ ni.mechTypes.len = 0;
+ ni.mechTypes.val = NULL;
+ }
+
+ {
+ gss_buffer_desc ibuf, obuf;
+ int require_mic, verify_mic, get_mic;
+ int require_response;
+ heim_octet_string *mic;
+
+ if (initialToken) {
+ if (ni.mechToken != NULL) {
+ ibuf.length = ni.mechToken->length;
+ ibuf.value = ni.mechToken->data;
+ mech_input_token = &ibuf;
+ }
+ } else {
+ if (na.responseToken != NULL) {
+ ibuf.length = na.responseToken->length;
+ ibuf.value = na.responseToken->data;
+ mech_input_token = &ibuf;
+ }
+ }
+
+ if (mech_input_token != GSS_C_NO_BUFFER) {
+ gss_cred_id_t mech_cred;
+ gss_cred_id_t mech_delegated_cred;
+ gss_cred_id_t *mech_delegated_cred_p;
+
+ if (acceptor_cred != NULL)
+ mech_cred = acceptor_cred->negotiated_cred_id;
+ else
+ mech_cred = GSS_C_NO_CREDENTIAL;
+
+ if (delegated_cred_handle != NULL) {
+ mech_delegated_cred = GSS_C_NO_CREDENTIAL;
+ mech_delegated_cred_p = &mech_delegated_cred;
+ } else {
+ mech_delegated_cred_p = NULL;
+ }
+
+ if (ctx->mech_src_name != GSS_C_NO_NAME)
+ gss_release_name(&minor, &ctx->mech_src_name);
+
+ if (ctx->delegated_cred_id != GSS_C_NO_CREDENTIAL)
+ _gss_spnego_release_cred(&minor, &ctx->delegated_cred_id);
+
+ ret = gss_accept_sec_context(&minor,
+ &ctx->negotiated_ctx_id,
+ mech_cred,
+ mech_input_token,
+ input_chan_bindings,
+ &ctx->mech_src_name,
+ &ctx->negotiated_mech_type,
+ &obuf,
+ &ctx->mech_flags,
+ &ctx->mech_time_rec,
+ mech_delegated_cred_p);
+ if (ret == GSS_S_COMPLETE || ret == GSS_S_CONTINUE_NEEDED) {
+ if (mech_delegated_cred_p != NULL &&
+ mech_delegated_cred != GSS_C_NO_CREDENTIAL) {
+ ret2 = _gss_spnego_alloc_cred(minor_status,
+ mech_delegated_cred,
+ &ctx->delegated_cred_id);
+ if (ret2 != GSS_S_COMPLETE)
+ ret = ret2;
+ }
+ mech_output_token = &obuf;
+ }
+ if (ret != GSS_S_COMPLETE && ret != GSS_S_CONTINUE_NEEDED) {
+ if (initialToken)
+ free_NegTokenInit(&ni);
+ else
+ free_NegTokenResp(&na);
+ send_reject (minor_status, output_token);
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ return ret;
+ }
+ if (ret == GSS_S_COMPLETE)
+ ctx->open = 1;
+ } else
+ ret = GSS_S_COMPLETE;
+
+ ret2 = _gss_spnego_require_mechlist_mic(minor_status,
+ ctx,
+ &require_mic);
+ if (ret2)
+ goto out;
+
+ ctx->require_mic = require_mic;
+
+ mic = initialToken ? ni.mechListMIC : na.mechListMIC;
+ if (mic != NULL)
+ require_mic = 1;
+
+ if (ctx->open && require_mic) {
+ if (mech_input_token == GSS_C_NO_BUFFER) { /* Even/One */
+ verify_mic = 1;
+ get_mic = 0;
+ } else if (mech_output_token != GSS_C_NO_BUFFER &&
+ mech_output_token->length == 0) { /* Odd */
+ get_mic = verify_mic = 1;
+ } else { /* Even/One */
+ verify_mic = 0;
+ get_mic = 1;
+ }
+
+ if (verify_mic || get_mic) {
+ int eret;
+ size_t buf_len;
+
+ ASN1_MALLOC_ENCODE(MechTypeList,
+ mech_buf.value, mech_buf.length,
+ &ctx->initiator_mech_types, &buf_len, eret);
+ if (eret) {
+ ret2 = GSS_S_FAILURE;
+ *minor_status = eret;
+ goto out;
+ }
+ if (mech_buf.length != buf_len)
+ abort();
+ }
+
+ if (verify_mic) {
+ ret2 = verify_mechlist_mic(minor_status, ctx, &mech_buf, mic);
+ if (ret2) {
+ if (get_mic)
+ send_reject (minor_status, output_token);
+ goto out;
+ }
+
+ ctx->verified_mic = 1;
+ }
+ } else
+ verify_mic = get_mic = 0;
+
+ if (ctx->mech_flags & GSS_C_DCE_STYLE)
+ require_response = (negResult != accept_completed);
+ else
+ require_response = 0;
+
+ /*
+ * Check whether we need to send a result: there should be only
+ * one accept_completed response sent in the entire negotiation
+ */
+ if ((mech_output_token != GSS_C_NO_BUFFER &&
+ mech_output_token->length != 0)
+ || require_response
+ || get_mic) {
+ ret2 = send_accept (minor_status,
+ ctx,
+ mech_output_token,
+ initialToken,
+ get_mic ? &mech_buf : NULL,
+ output_token);
+ if (ret2)
+ goto out;
+ }
+
+ out:
+ if (ret2 != GSS_S_COMPLETE)
+ ret = ret2;
+ if (mech_output_token != NULL)
+ gss_release_buffer(&minor, mech_output_token);
+ if (mech_buf.value != NULL)
+ free(mech_buf.value);
+ if (initialToken)
+ free_NegTokenInit(&ni);
+ else
+ free_NegTokenResp(&na);
+ }
+
+ if (ret == GSS_S_COMPLETE) {
+ if (src_name != NULL) {
+ ret2 = gss_duplicate_name(minor_status,
+ ctx->mech_src_name,
+ src_name);
+ if (ret2 != GSS_S_COMPLETE)
+ ret = ret2;
+ }
+ if (delegated_cred_handle != NULL) {
+ *delegated_cred_handle = ctx->delegated_cred_id;
+ ctx->delegated_cred_id = GSS_C_NO_CREDENTIAL;
+ }
+ }
+
+ if (mech_type != NULL)
+ *mech_type = ctx->negotiated_mech_type;
+ if (ret_flags != NULL)
+ *ret_flags = ctx->mech_flags;
+ if (time_rec != NULL)
+ *time_rec = ctx->mech_time_rec;
+
+ if (ret == GSS_S_COMPLETE || ret == GSS_S_CONTINUE_NEEDED) {
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ return ret;
+ }
+
+ _gss_spnego_internal_delete_sec_context(&minor, context_handle,
+ GSS_C_NO_BUFFER);
+
+ return ret;
+}
+
diff --git a/source4/heimdal/lib/gssapi/spnego/compat.c b/source4/heimdal/lib/gssapi/spnego/compat.c
new file mode 100644
index 0000000000..aeae088258
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/spnego/compat.c
@@ -0,0 +1,285 @@
+/*
+ * 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 "spnego/spnego_locl.h"
+
+RCSID("$Id: compat.c,v 1.6 2006/10/07 22:26:59 lha Exp $");
+
+/*
+ * Apparently Microsoft got the OID wrong, and used
+ * 1.2.840.48018.1.2.2 instead. We need both this and
+ * the correct Kerberos OID here in order to deal with
+ * this. Because this is manifest in SPNEGO only I'd
+ * prefer to deal with this here rather than inside the
+ * Kerberos mechanism.
+ */
+static gss_OID_desc gss_mskrb_mechanism_oid_desc =
+ {9, (void *)"\x2a\x86\x48\x82\xf7\x12\x01\x02\x02"};
+
+static gss_OID_desc gss_krb5_mechanism_oid_desc =
+ {9, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x02"};
+
+/*
+ * Allocate a SPNEGO context handle
+ */
+OM_uint32 _gss_spnego_alloc_sec_context (OM_uint32 * minor_status,
+ gss_ctx_id_t *context_handle)
+{
+ gssspnego_ctx ctx;
+
+ ctx = calloc(1, sizeof(*ctx));
+ if (ctx == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ ctx->initiator_mech_types.len = 0;
+ ctx->initiator_mech_types.val = NULL;
+ ctx->preferred_mech_type = GSS_C_NO_OID;
+ ctx->negotiated_mech_type = GSS_C_NO_OID;
+ ctx->negotiated_ctx_id = GSS_C_NO_CONTEXT;
+
+ /*
+ * Cache these so we can return them before returning
+ * GSS_S_COMPLETE, even if the mechanism has itself
+ * completed earlier
+ */
+ ctx->mech_flags = 0;
+ ctx->mech_time_rec = 0;
+ ctx->mech_src_name = GSS_C_NO_NAME;
+ ctx->delegated_cred_id = GSS_C_NO_CREDENTIAL;
+
+ ctx->open = 0;
+ ctx->local = 0;
+ ctx->require_mic = 0;
+ ctx->verified_mic = 0;
+
+ HEIMDAL_MUTEX_init(&ctx->ctx_id_mutex);
+
+ *context_handle = (gss_ctx_id_t)ctx;
+
+ return GSS_S_COMPLETE;
+}
+
+/*
+ * Free a SPNEGO context handle. The caller must have acquired
+ * the lock before this is called.
+ */
+OM_uint32 _gss_spnego_internal_delete_sec_context
+ (OM_uint32 *minor_status,
+ gss_ctx_id_t *context_handle,
+ gss_buffer_t output_token
+ )
+{
+ gssspnego_ctx ctx;
+ OM_uint32 ret, minor;
+
+ *minor_status = 0;
+
+ if (context_handle == NULL) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ if (output_token != GSS_C_NO_BUFFER) {
+ output_token->length = 0;
+ output_token->value = NULL;
+ }
+
+ ctx = (gssspnego_ctx)*context_handle;
+ *context_handle = GSS_C_NO_CONTEXT;
+
+ if (ctx == NULL) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ if (ctx->initiator_mech_types.val != NULL)
+ free_MechTypeList(&ctx->initiator_mech_types);
+
+ _gss_spnego_release_cred(&minor, &ctx->delegated_cred_id);
+
+ gss_release_oid(&minor, &ctx->preferred_mech_type);
+ ctx->negotiated_mech_type = GSS_C_NO_OID;
+
+ gss_release_name(&minor, &ctx->mech_src_name);
+
+ if (ctx->negotiated_ctx_id != GSS_C_NO_CONTEXT) {
+ ret = gss_delete_sec_context(minor_status,
+ &ctx->negotiated_ctx_id,
+ output_token);
+ ctx->negotiated_ctx_id = GSS_C_NO_CONTEXT;
+ } else {
+ ret = GSS_S_COMPLETE;
+ }
+
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ HEIMDAL_MUTEX_destroy(&ctx->ctx_id_mutex);
+
+ free(ctx);
+ *context_handle = NULL;
+
+ return ret;
+}
+
+/*
+ * For compatability with the Windows SPNEGO implementation, the
+ * default is to ignore the mechListMIC unless CFX is used and
+ * a non-preferred mechanism was negotiated
+ */
+
+OM_uint32
+_gss_spnego_require_mechlist_mic(OM_uint32 *minor_status,
+ gssspnego_ctx ctx,
+ int *require_mic)
+{
+ gss_buffer_set_t buffer_set = GSS_C_NO_BUFFER_SET;
+ OM_uint32 minor;
+
+ *minor_status = 0;
+ *require_mic = 0;
+
+ if (ctx == NULL) {
+ return GSS_S_COMPLETE;
+ }
+
+ if (ctx->require_mic) {
+ /* Acceptor requested it: mandatory to honour */
+ *require_mic = 1;
+ return GSS_S_COMPLETE;
+ }
+
+ /*
+ * Check whether peer indicated implicit support for updated SPNEGO
+ * (eg. in the Kerberos case by using CFX)
+ */
+ if (gss_inquire_sec_context_by_oid(&minor, ctx->negotiated_ctx_id,
+ GSS_C_PEER_HAS_UPDATED_SPNEGO,
+ &buffer_set) == GSS_S_COMPLETE) {
+ *require_mic = 1;
+ gss_release_buffer_set(&minor, &buffer_set);
+ }
+
+ /* Safe-to-omit MIC rules follow */
+ if (*require_mic) {
+ if (gss_oid_equal(ctx->negotiated_mech_type, ctx->preferred_mech_type)) {
+ *require_mic = 0;
+ } else if (gss_oid_equal(ctx->negotiated_mech_type, &gss_krb5_mechanism_oid_desc) &&
+ gss_oid_equal(ctx->preferred_mech_type, &gss_mskrb_mechanism_oid_desc)) {
+ *require_mic = 0;
+ }
+ }
+
+ return GSS_S_COMPLETE;
+}
+
+int _gss_spnego_add_mech_type(gss_OID mech_type,
+ int includeMSCompatOID,
+ MechTypeList *mechtypelist)
+{
+ int ret;
+
+ if (gss_oid_equal(mech_type, GSS_SPNEGO_MECHANISM))
+ return 0;
+
+ if (includeMSCompatOID &&
+ gss_oid_equal(mech_type, &gss_krb5_mechanism_oid_desc)) {
+ ret = der_get_oid(gss_mskrb_mechanism_oid_desc.elements,
+ gss_mskrb_mechanism_oid_desc.length,
+ &mechtypelist->val[mechtypelist->len],
+ NULL);
+ if (ret)
+ return ret;
+ mechtypelist->len++;
+ }
+ ret = der_get_oid(mech_type->elements,
+ mech_type->length,
+ &mechtypelist->val[mechtypelist->len],
+ NULL);
+ if (ret)
+ return ret;
+ mechtypelist->len++;
+
+ return 0;
+}
+
+OM_uint32
+_gss_spnego_select_mech(OM_uint32 *minor_status,
+ MechType *mechType,
+ gss_OID *mech_p)
+{
+ char mechbuf[64];
+ size_t mech_len;
+ gss_OID_desc oid;
+ OM_uint32 ret;
+
+ ret = der_put_oid ((unsigned char *)mechbuf + sizeof(mechbuf) - 1,
+ sizeof(mechbuf),
+ mechType,
+ &mech_len);
+ if (ret) {
+ return GSS_S_DEFECTIVE_TOKEN;
+ }
+
+ oid.length = mech_len;
+ oid.elements = mechbuf + sizeof(mechbuf) - mech_len;
+
+ if (gss_oid_equal(&oid, GSS_SPNEGO_MECHANISM)) {
+ return GSS_S_BAD_MECH;
+ }
+
+ *minor_status = 0;
+
+ /* Translate broken MS Kebreros OID */
+ if (gss_oid_equal(&oid, &gss_mskrb_mechanism_oid_desc)) {
+ gssapi_mech_interface mech;
+
+ mech = __gss_get_mechanism(&gss_krb5_mechanism_oid_desc);
+ if (mech == NULL)
+ return GSS_S_BAD_MECH;
+
+ ret = gss_duplicate_oid(minor_status,
+ &gss_mskrb_mechanism_oid_desc,
+ mech_p);
+ } else {
+ gssapi_mech_interface mech;
+
+ mech = __gss_get_mechanism(&oid);
+ if (mech == NULL)
+ return GSS_S_BAD_MECH;
+
+ ret = gss_duplicate_oid(minor_status,
+ &mech->gm_mech_oid,
+ mech_p);
+ }
+
+ return ret;
+}
+
diff --git a/source4/heimdal/lib/gssapi/spnego/context_stubs.c b/source4/heimdal/lib/gssapi/spnego/context_stubs.c
new file mode 100644
index 0000000000..902ddbbdf9
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/spnego/context_stubs.c
@@ -0,0 +1,835 @@
+/*
+ * 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 "spnego/spnego_locl.h"
+
+RCSID("$Id: context_stubs.c,v 1.8 2006/10/07 22:27:01 lha Exp $");
+
+static OM_uint32
+spnego_supported_mechs(OM_uint32 *minor_status, gss_OID_set *mechs)
+{
+ OM_uint32 ret, junk;
+ gss_OID_set m;
+ int i;
+
+ ret = gss_indicate_mechs(minor_status, &m);
+ if (ret != GSS_S_COMPLETE)
+ return ret;
+
+ ret = gss_create_empty_oid_set(minor_status, mechs);
+ if (ret != GSS_S_COMPLETE) {
+ gss_release_oid_set(&junk, &m);
+ return ret;
+ }
+
+ for (i = 0; i < m->count; i++) {
+ if (gss_oid_equal(&m->elements[i], GSS_SPNEGO_MECHANISM))
+ continue;
+
+ ret = gss_add_oid_set_member(minor_status, &m->elements[i], mechs);
+ if (ret) {
+ gss_release_oid_set(&junk, &m);
+ gss_release_oid_set(&junk, mechs);
+ return ret;
+ }
+ }
+ return ret;
+}
+
+
+
+OM_uint32 _gss_spnego_process_context_token
+ (OM_uint32 *minor_status,
+ const gss_ctx_id_t context_handle,
+ const gss_buffer_t token_buffer
+ )
+{
+ gss_ctx_id_t context ;
+ gssspnego_ctx ctx;
+ OM_uint32 ret;
+
+ if (context_handle == GSS_C_NO_CONTEXT)
+ return GSS_S_NO_CONTEXT;
+
+ context = context_handle;
+ ctx = (gssspnego_ctx)context_handle;
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+
+ ret = gss_process_context_token(minor_status,
+ ctx->negotiated_ctx_id,
+ token_buffer);
+ if (ret != GSS_S_COMPLETE) {
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ return ret;
+ }
+
+ ctx->negotiated_ctx_id = GSS_C_NO_CONTEXT;
+
+ return _gss_spnego_internal_delete_sec_context(minor_status,
+ &context,
+ GSS_C_NO_BUFFER);
+}
+
+OM_uint32 _gss_spnego_delete_sec_context
+ (OM_uint32 *minor_status,
+ gss_ctx_id_t *context_handle,
+ gss_buffer_t output_token
+ )
+{
+ gssspnego_ctx ctx;
+
+ if (context_handle == NULL || *context_handle == GSS_C_NO_CONTEXT)
+ return GSS_S_NO_CONTEXT;
+
+ ctx = (gssspnego_ctx)*context_handle;
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+
+ return _gss_spnego_internal_delete_sec_context(minor_status,
+ context_handle,
+ output_token);
+}
+
+OM_uint32 _gss_spnego_context_time
+ (OM_uint32 *minor_status,
+ const gss_ctx_id_t context_handle,
+ OM_uint32 *time_rec
+ )
+{
+ gssspnego_ctx ctx;
+ *minor_status = 0;
+
+ if (context_handle == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ ctx = (gssspnego_ctx)context_handle;
+
+ if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ return gss_context_time(minor_status,
+ ctx->negotiated_ctx_id,
+ time_rec);
+}
+
+OM_uint32 _gss_spnego_get_mic
+ (OM_uint32 *minor_status,
+ const gss_ctx_id_t context_handle,
+ gss_qop_t qop_req,
+ const gss_buffer_t message_buffer,
+ gss_buffer_t message_token
+ )
+{
+ gssspnego_ctx ctx;
+
+ *minor_status = 0;
+
+ if (context_handle == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ ctx = (gssspnego_ctx)context_handle;
+
+ if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ return gss_get_mic(minor_status, ctx->negotiated_ctx_id,
+ qop_req, message_buffer, message_token);
+}
+
+OM_uint32 _gss_spnego_verify_mic
+ (OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ const gss_buffer_t message_buffer,
+ const gss_buffer_t token_buffer,
+ gss_qop_t * qop_state
+ )
+{
+ gssspnego_ctx ctx;
+
+ *minor_status = 0;
+
+ if (context_handle == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ ctx = (gssspnego_ctx)context_handle;
+
+ if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ return gss_verify_mic(minor_status,
+ ctx->negotiated_ctx_id,
+ message_buffer,
+ token_buffer,
+ qop_state);
+}
+
+OM_uint32 _gss_spnego_wrap
+ (OM_uint32 * minor_status,
+ const gss_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
+ )
+{
+ gssspnego_ctx ctx;
+
+ *minor_status = 0;
+
+ if (context_handle == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ ctx = (gssspnego_ctx)context_handle;
+
+ if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ return gss_wrap(minor_status,
+ ctx->negotiated_ctx_id,
+ conf_req_flag,
+ qop_req,
+ input_message_buffer,
+ conf_state,
+ output_message_buffer);
+}
+
+OM_uint32 _gss_spnego_unwrap
+ (OM_uint32 * minor_status,
+ const gss_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
+ )
+{
+ gssspnego_ctx ctx;
+
+ *minor_status = 0;
+
+ if (context_handle == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ ctx = (gssspnego_ctx)context_handle;
+
+ if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ return gss_unwrap(minor_status,
+ ctx->negotiated_ctx_id,
+ input_message_buffer,
+ output_message_buffer,
+ conf_state,
+ qop_state);
+}
+
+OM_uint32 _gss_spnego_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
+ )
+{
+ return GSS_S_FAILURE;
+}
+
+OM_uint32 _gss_spnego_compare_name
+ (OM_uint32 *minor_status,
+ const gss_name_t name1,
+ const gss_name_t name2,
+ int * name_equal
+ )
+{
+ return gss_compare_name(minor_status, name1, name2, name_equal);
+}
+
+OM_uint32 _gss_spnego_display_name
+ (OM_uint32 * minor_status,
+ const gss_name_t input_name,
+ gss_buffer_t output_name_buffer,
+ gss_OID * output_name_type
+ )
+{
+ return gss_display_name(minor_status, input_name,
+ output_name_buffer, output_name_type);
+}
+
+OM_uint32 _gss_spnego_import_name
+ (OM_uint32 * minor_status,
+ const gss_buffer_t input_name_buffer,
+ const gss_OID input_name_type,
+ gss_name_t * output_name
+ )
+{
+ return gss_import_name(minor_status, input_name_buffer,
+ input_name_type, output_name);
+}
+
+OM_uint32 _gss_spnego_export_name
+ (OM_uint32 * minor_status,
+ const gss_name_t input_name,
+ gss_buffer_t exported_name
+ )
+{
+ return gss_export_name(minor_status, input_name,
+ exported_name);
+}
+
+OM_uint32 _gss_spnego_release_name
+ (OM_uint32 * minor_status,
+ gss_name_t * input_name
+ )
+{
+ return gss_release_name(minor_status, input_name);
+}
+
+OM_uint32 _gss_spnego_inquire_context (
+ OM_uint32 * minor_status,
+ const gss_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 * open_context
+ )
+{
+ gssspnego_ctx ctx;
+
+ *minor_status = 0;
+
+ if (context_handle == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ ctx = (gssspnego_ctx)context_handle;
+
+ if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ return gss_inquire_context(minor_status,
+ ctx->negotiated_ctx_id,
+ src_name,
+ targ_name,
+ lifetime_rec,
+ mech_type,
+ ctx_flags,
+ locally_initiated,
+ open_context);
+}
+
+OM_uint32 _gss_spnego_wrap_size_limit (
+ OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ int conf_req_flag,
+ gss_qop_t qop_req,
+ OM_uint32 req_output_size,
+ OM_uint32 * max_input_size
+ )
+{
+ gssspnego_ctx ctx;
+
+ *minor_status = 0;
+
+ if (context_handle == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ ctx = (gssspnego_ctx)context_handle;
+
+ if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ return gss_wrap_size_limit(minor_status,
+ ctx->negotiated_ctx_id,
+ conf_req_flag,
+ qop_req,
+ req_output_size,
+ max_input_size);
+}
+
+OM_uint32 _gss_spnego_export_sec_context (
+ OM_uint32 * minor_status,
+ gss_ctx_id_t * context_handle,
+ gss_buffer_t interprocess_token
+ )
+{
+ gssspnego_ctx ctx;
+ OM_uint32 ret;
+
+ *minor_status = 0;
+
+ if (context_handle == NULL) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ ctx = (gssspnego_ctx)*context_handle;
+
+ if (ctx == NULL)
+ return GSS_S_NO_CONTEXT;
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+
+ if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ return GSS_S_NO_CONTEXT;
+ }
+
+ ret = gss_export_sec_context(minor_status,
+ &ctx->negotiated_ctx_id,
+ interprocess_token);
+ if (ret == GSS_S_COMPLETE) {
+ ret = _gss_spnego_internal_delete_sec_context(minor_status,
+ context_handle,
+ GSS_C_NO_BUFFER);
+ if (ret == GSS_S_COMPLETE)
+ return GSS_S_COMPLETE;
+ }
+
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+
+ return ret;
+}
+
+OM_uint32 _gss_spnego_import_sec_context (
+ OM_uint32 * minor_status,
+ const gss_buffer_t interprocess_token,
+ gss_ctx_id_t *context_handle
+ )
+{
+ OM_uint32 ret, minor;
+ gss_ctx_id_t context;
+ gssspnego_ctx ctx;
+
+ ret = _gss_spnego_alloc_sec_context(minor_status, &context);
+ if (ret != GSS_S_COMPLETE) {
+ return ret;
+ }
+ ctx = (gssspnego_ctx)context;
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+
+ ret = gss_import_sec_context(minor_status,
+ interprocess_token,
+ &ctx->negotiated_ctx_id);
+ if (ret != GSS_S_COMPLETE) {
+ _gss_spnego_internal_delete_sec_context(&minor, context_handle, GSS_C_NO_BUFFER);
+ return ret;
+ }
+
+ ctx->open = 1;
+ /* don't bother filling in the rest of the fields */
+
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+
+ *context_handle = (gss_ctx_id_t)ctx;
+
+ return GSS_S_COMPLETE;
+}
+
+OM_uint32 _gss_spnego_inquire_names_for_mech (
+ OM_uint32 * minor_status,
+ const gss_OID mechanism,
+ gss_OID_set * name_types
+ )
+{
+ gss_OID_set mechs, names, n;
+ OM_uint32 ret, junk;
+ int i, j;
+
+ *name_types = NULL;
+
+ ret = spnego_supported_mechs(minor_status, &mechs);
+ if (ret != GSS_S_COMPLETE)
+ return ret;
+
+ ret = gss_create_empty_oid_set(minor_status, &names);
+ if (ret != GSS_S_COMPLETE)
+ goto out;
+
+ for (i = 0; i < mechs->count; i++) {
+ ret = gss_inquire_names_for_mech(minor_status,
+ &mechs->elements[i],
+ &n);
+ if (ret)
+ continue;
+
+ for (j = 0; j < n->count; j++)
+ gss_add_oid_set_member(minor_status,
+ &n->elements[j],
+ &names);
+ gss_release_oid_set(&junk, &n);
+ }
+
+ ret = GSS_S_COMPLETE;
+ *name_types = names;
+out:
+
+ gss_release_oid_set(&junk, &mechs);
+
+ return GSS_S_COMPLETE;
+}
+
+OM_uint32 _gss_spnego_inquire_mechs_for_name (
+ OM_uint32 * minor_status,
+ const gss_name_t input_name,
+ gss_OID_set * mech_types
+ )
+{
+ OM_uint32 ret, junk;
+
+ ret = gss_create_empty_oid_set(minor_status, mech_types);
+ if (ret)
+ return ret;
+
+ ret = gss_add_oid_set_member(minor_status,
+ GSS_SPNEGO_MECHANISM,
+ mech_types);
+ if (ret)
+ gss_release_oid_set(&junk, mech_types);
+
+ return ret;
+}
+
+OM_uint32 _gss_spnego_canonicalize_name (
+ OM_uint32 * minor_status,
+ const gss_name_t input_name,
+ const gss_OID mech_type,
+ gss_name_t * output_name
+ )
+{
+ /* XXX */
+ return gss_duplicate_name(minor_status, input_name, output_name);
+}
+
+OM_uint32 _gss_spnego_duplicate_name (
+ OM_uint32 * minor_status,
+ const gss_name_t src_name,
+ gss_name_t * dest_name
+ )
+{
+ return gss_duplicate_name(minor_status, src_name, dest_name);
+}
+
+OM_uint32 _gss_spnego_sign
+ (OM_uint32 * minor_status,
+ gss_ctx_id_t context_handle,
+ int qop_req,
+ gss_buffer_t message_buffer,
+ gss_buffer_t message_token
+ )
+{
+ gssspnego_ctx ctx;
+
+ *minor_status = 0;
+
+ if (context_handle == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ ctx = (gssspnego_ctx)context_handle;
+
+ if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ return gss_sign(minor_status,
+ ctx->negotiated_ctx_id,
+ qop_req,
+ message_buffer,
+ message_token);
+}
+
+OM_uint32 _gss_spnego_verify
+ (OM_uint32 * minor_status,
+ gss_ctx_id_t context_handle,
+ gss_buffer_t message_buffer,
+ gss_buffer_t token_buffer,
+ int * qop_state
+ )
+{
+ gssspnego_ctx ctx;
+
+ *minor_status = 0;
+
+ if (context_handle == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ ctx = (gssspnego_ctx)context_handle;
+
+ if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ return gss_verify(minor_status,
+ ctx->negotiated_ctx_id,
+ message_buffer,
+ token_buffer,
+ qop_state);
+}
+
+OM_uint32 _gss_spnego_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
+ )
+{
+ gssspnego_ctx ctx;
+
+ *minor_status = 0;
+
+ if (context_handle == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ ctx = (gssspnego_ctx)context_handle;
+
+ if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ return gss_seal(minor_status,
+ ctx->negotiated_ctx_id,
+ conf_req_flag,
+ qop_req,
+ input_message_buffer,
+ conf_state,
+ output_message_buffer);
+}
+
+OM_uint32 _gss_spnego_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
+ )
+{
+ gssspnego_ctx ctx;
+
+ *minor_status = 0;
+
+ if (context_handle == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ ctx = (gssspnego_ctx)context_handle;
+
+ if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ return gss_unseal(minor_status,
+ ctx->negotiated_ctx_id,
+ input_message_buffer,
+ output_message_buffer,
+ conf_state,
+ qop_state);
+}
+
+#if 0
+OM_uint32 _gss_spnego_unwrap_ex
+ (OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ const gss_buffer_t token_header_buffer,
+ const gss_buffer_t associated_data_buffer,
+ const gss_buffer_t input_message_buffer,
+ gss_buffer_t output_message_buffer,
+ int * conf_state,
+ gss_qop_t * qop_state)
+{
+ gssspnego_ctx ctx;
+
+ *minor_status = 0;
+
+ if (context_handle == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ ctx = (gssspnego_ctx)context_handle;
+
+ if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ return gss_unwrap_ex(minor_status,
+ ctx->negotiated_ctx_id,
+ token_header_buffer,
+ associated_data_buffer,
+ input_message_buffer,
+ output_message_buffer,
+ conf_state,
+ qop_state);
+}
+
+OM_uint32 _gss_spnego_wrap_ex
+ (OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ int conf_req_flag,
+ gss_qop_t qop_req,
+ const gss_buffer_t associated_data_buffer,
+ const gss_buffer_t input_message_buffer,
+ int * conf_state,
+ gss_buffer_t output_token_buffer,
+ gss_buffer_t output_message_buffer
+ )
+{
+ gssspnego_ctx ctx;
+
+ *minor_status = 0;
+
+ if (context_handle == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ ctx = (gssspnego_ctx)context_handle;
+
+ if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ if ((ctx->mech_flags & GSS_C_DCE_STYLE) == 0 &&
+ associated_data_buffer->length != input_message_buffer->length) {
+ *minor_status = EINVAL;
+ return GSS_S_BAD_QOP;
+ }
+
+ return gss_wrap_ex(minor_status,
+ ctx->negotiated_ctx_id,
+ conf_req_flag,
+ qop_req,
+ associated_data_buffer,
+ input_message_buffer,
+ conf_state,
+ output_token_buffer,
+ output_message_buffer);
+}
+
+OM_uint32 _gss_spnego_complete_auth_token
+ (OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ gss_buffer_t input_message_buffer)
+{
+ gssspnego_ctx ctx;
+
+ *minor_status = 0;
+
+ if (context_handle == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ ctx = (gssspnego_ctx)context_handle;
+
+ if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ return gss_complete_auth_token(minor_status,
+ ctx->negotiated_ctx_id,
+ input_message_buffer);
+}
+#endif
+
+OM_uint32 _gss_spnego_inquire_sec_context_by_oid
+ (OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ const gss_OID desired_object,
+ gss_buffer_set_t *data_set)
+{
+ gssspnego_ctx ctx;
+
+ *minor_status = 0;
+
+ if (context_handle == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ ctx = (gssspnego_ctx)context_handle;
+
+ if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ return gss_inquire_sec_context_by_oid(minor_status,
+ ctx->negotiated_ctx_id,
+ desired_object,
+ data_set);
+}
+
+OM_uint32 _gss_spnego_set_sec_context_option
+ (OM_uint32 * minor_status,
+ gss_ctx_id_t * context_handle,
+ const gss_OID desired_object,
+ const gss_buffer_t value)
+{
+ gssspnego_ctx ctx;
+
+ *minor_status = 0;
+
+ if (context_handle == NULL || *context_handle == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ ctx = (gssspnego_ctx)context_handle;
+
+ if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ return gss_set_sec_context_option(minor_status,
+ &ctx->negotiated_ctx_id,
+ desired_object,
+ value);
+}
+
diff --git a/source4/heimdal/lib/gssapi/spnego/cred_stubs.c b/source4/heimdal/lib/gssapi/spnego/cred_stubs.c
new file mode 100644
index 0000000000..8f8edab15e
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/spnego/cred_stubs.c
@@ -0,0 +1,291 @@
+/*
+ * 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 "spnego/spnego_locl.h"
+
+RCSID("$Id: cred_stubs.c,v 1.5 2006/10/07 22:27:04 lha Exp $");
+
+OM_uint32
+_gss_spnego_release_cred(OM_uint32 *minor_status, gss_cred_id_t *cred_handle)
+{
+ gssspnego_cred cred;
+ OM_uint32 ret;
+
+ *minor_status = 0;
+
+ if (*cred_handle == GSS_C_NO_CREDENTIAL) {
+ return GSS_S_COMPLETE;
+ }
+ cred = (gssspnego_cred)*cred_handle;
+
+ ret = gss_release_cred(minor_status, &cred->negotiated_cred_id);
+
+ free(cred);
+ *cred_handle = GSS_C_NO_CREDENTIAL;
+
+ return ret;
+}
+
+OM_uint32
+_gss_spnego_alloc_cred(OM_uint32 *minor_status,
+ gss_cred_id_t mech_cred_handle,
+ gss_cred_id_t *cred_handle)
+{
+ gssspnego_cred cred;
+
+ if (*cred_handle != GSS_C_NO_CREDENTIAL) {
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ cred = calloc(1, sizeof(*cred));
+ if (cred == NULL) {
+ *cred_handle = GSS_C_NO_CREDENTIAL;
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ cred->negotiated_cred_id = mech_cred_handle;
+
+ *cred_handle = (gss_cred_id_t)cred;
+
+ return GSS_S_COMPLETE;
+}
+
+/*
+ * For now, just a simple wrapper that avoids recursion. When
+ * we support gss_{get,set}_neg_mechs() we will need to expose
+ * more functionality.
+ */
+OM_uint32 _gss_spnego_acquire_cred
+(OM_uint32 *minor_status,
+ const gss_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
+ )
+{
+ OM_uint32 ret, tmp;
+ gss_OID_set_desc actual_desired_mechs;
+ gss_OID_set mechs;
+ int i, j;
+ gss_cred_id_t cred_handle = GSS_C_NO_CREDENTIAL;
+ gssspnego_cred cred;
+
+ *output_cred_handle = GSS_C_NO_CREDENTIAL;
+
+ ret = gss_indicate_mechs(minor_status, &mechs);
+ if (ret != GSS_S_COMPLETE)
+ return ret;
+
+ /* Remove ourselves from this list */
+ actual_desired_mechs.count = mechs->count;
+ actual_desired_mechs.elements = malloc(actual_desired_mechs.count *
+ sizeof(gss_OID_desc));
+ if (actual_desired_mechs.elements == NULL) {
+ *minor_status = ENOMEM;
+ ret = GSS_S_FAILURE;
+ goto out;
+ }
+
+ for (i = 0, j = 0; i < mechs->count; i++) {
+ if (gss_oid_equal(&mechs->elements[i], GSS_SPNEGO_MECHANISM))
+ continue;
+
+ actual_desired_mechs.elements[j] = mechs->elements[i];
+ j++;
+ }
+ actual_desired_mechs.count = j;
+
+ ret = _gss_spnego_alloc_cred(minor_status, GSS_C_NO_CREDENTIAL,
+ &cred_handle);
+ if (ret != GSS_S_COMPLETE)
+ goto out;
+
+ cred = (gssspnego_cred)cred_handle;
+ ret = gss_acquire_cred(minor_status, desired_name,
+ time_req, &actual_desired_mechs,
+ cred_usage,
+ &cred->negotiated_cred_id,
+ actual_mechs, time_rec);
+ if (ret != GSS_S_COMPLETE)
+ goto out;
+
+ *output_cred_handle = cred_handle;
+
+out:
+ gss_release_oid_set(&tmp, &mechs);
+ if (actual_desired_mechs.elements != NULL) {
+ free(actual_desired_mechs.elements);
+ }
+ if (ret != GSS_S_COMPLETE) {
+ _gss_spnego_release_cred(&tmp, &cred_handle);
+ }
+
+ return ret;
+}
+
+OM_uint32 _gss_spnego_inquire_cred
+ (OM_uint32 * minor_status,
+ const gss_cred_id_t cred_handle,
+ gss_name_t * name,
+ OM_uint32 * lifetime,
+ gss_cred_usage_t * cred_usage,
+ gss_OID_set * mechanisms
+ )
+{
+ gssspnego_cred cred;
+ OM_uint32 ret;
+
+ if (cred_handle == GSS_C_NO_CREDENTIAL) {
+ *minor_status = 0;
+ return GSS_S_NO_CRED;
+ }
+
+ cred = (gssspnego_cred)cred_handle;
+
+ ret = gss_inquire_cred(minor_status,
+ cred->negotiated_cred_id,
+ name,
+ lifetime,
+ cred_usage,
+ mechanisms);
+
+ return ret;
+}
+
+OM_uint32 _gss_spnego_add_cred (
+ OM_uint32 * minor_status,
+ const gss_cred_id_t input_cred_handle,
+ const gss_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
+ )
+{
+ gss_cred_id_t spnego_output_cred_handle = GSS_C_NO_CREDENTIAL;
+ OM_uint32 ret, tmp;
+ gssspnego_cred input_cred, output_cred;
+
+ *output_cred_handle = GSS_C_NO_CREDENTIAL;
+
+ ret = _gss_spnego_alloc_cred(minor_status, GSS_C_NO_CREDENTIAL,
+ &spnego_output_cred_handle);
+ if (ret)
+ return ret;
+
+ input_cred = (gssspnego_cred)input_cred_handle;
+ output_cred = (gssspnego_cred)spnego_output_cred_handle;
+
+ ret = gss_add_cred(minor_status,
+ input_cred->negotiated_cred_id,
+ desired_name,
+ desired_mech,
+ cred_usage,
+ initiator_time_req,
+ acceptor_time_req,
+ &output_cred->negotiated_cred_id,
+ actual_mechs,
+ initiator_time_rec,
+ acceptor_time_rec);
+ if (ret) {
+ _gss_spnego_release_cred(&tmp, &spnego_output_cred_handle);
+ return ret;
+ }
+
+ *output_cred_handle = spnego_output_cred_handle;
+
+ return GSS_S_COMPLETE;
+}
+
+OM_uint32 _gss_spnego_inquire_cred_by_mech (
+ OM_uint32 * minor_status,
+ const gss_cred_id_t cred_handle,
+ const gss_OID mech_type,
+ gss_name_t * name,
+ OM_uint32 * initiator_lifetime,
+ OM_uint32 * acceptor_lifetime,
+ gss_cred_usage_t * cred_usage
+ )
+{
+ gssspnego_cred cred;
+ OM_uint32 ret;
+
+ if (cred_handle == GSS_C_NO_CREDENTIAL) {
+ *minor_status = 0;
+ return GSS_S_NO_CRED;
+ }
+
+ cred = (gssspnego_cred)cred_handle;
+
+ ret = gss_inquire_cred_by_mech(minor_status,
+ cred->negotiated_cred_id,
+ mech_type,
+ name,
+ initiator_lifetime,
+ acceptor_lifetime,
+ cred_usage);
+
+ return ret;
+}
+
+OM_uint32 _gss_spnego_inquire_cred_by_oid
+ (OM_uint32 * minor_status,
+ const gss_cred_id_t cred_handle,
+ const gss_OID desired_object,
+ gss_buffer_set_t *data_set)
+{
+ gssspnego_cred cred;
+ OM_uint32 ret;
+
+ if (cred_handle == GSS_C_NO_CREDENTIAL) {
+ *minor_status = 0;
+ return GSS_S_NO_CRED;
+ }
+ cred = (gssspnego_cred)cred_handle;
+
+ ret = gss_inquire_cred_by_oid(minor_status,
+ cred->negotiated_cred_id,
+ desired_object,
+ data_set);
+
+ return ret;
+}
+
diff --git a/source4/heimdal/lib/gssapi/spnego/external.c b/source4/heimdal/lib/gssapi/spnego/external.c
new file mode 100644
index 0000000000..b7e02a55e1
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/spnego/external.c
@@ -0,0 +1,89 @@
+/*
+ * 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 "spnego/spnego_locl.h"
+#include <gssapi_mech.h>
+
+RCSID("$Id: external.c,v 1.7 2006/10/07 22:27:06 lha Exp $");
+
+/*
+ * RFC2478, SPNEGO:
+ * The security mechanism of the initial
+ * negotiation token is identified by the Object Identifier
+ * iso.org.dod.internet.security.mechanism.snego (1.3.6.1.5.5.2).
+ */
+
+static gssapi_mech_interface_desc spnego_mech = {
+ GMI_VERSION,
+ "spnego",
+ {6, (void *)"\x2b\x06\x01\x05\x05\x02"},
+ _gss_spnego_acquire_cred,
+ _gss_spnego_release_cred,
+ _gss_spnego_init_sec_context,
+ _gss_spnego_accept_sec_context,
+ _gss_spnego_process_context_token,
+ _gss_spnego_internal_delete_sec_context,
+ _gss_spnego_context_time,
+ _gss_spnego_get_mic,
+ _gss_spnego_verify_mic,
+ _gss_spnego_wrap,
+ _gss_spnego_unwrap,
+ _gss_spnego_display_status,
+ NULL,
+ _gss_spnego_compare_name,
+ _gss_spnego_display_name,
+ _gss_spnego_import_name,
+ _gss_spnego_export_name,
+ _gss_spnego_release_name,
+ _gss_spnego_inquire_cred,
+ _gss_spnego_inquire_context,
+ _gss_spnego_wrap_size_limit,
+ _gss_spnego_add_cred,
+ _gss_spnego_inquire_cred_by_mech,
+ _gss_spnego_export_sec_context,
+ _gss_spnego_import_sec_context,
+ _gss_spnego_inquire_names_for_mech,
+ _gss_spnego_inquire_mechs_for_name,
+ _gss_spnego_canonicalize_name,
+ _gss_spnego_duplicate_name
+};
+
+gssapi_mech_interface
+__gss_spnego_initialize(void)
+{
+ return &spnego_mech;
+}
+
+static gss_OID_desc _gss_spnego_mechanism_desc =
+ {6, (void *)"\x2b\x06\x01\x05\x05\x02"};
+
+gss_OID GSS_SPNEGO_MECHANISM = &_gss_spnego_mechanism_desc;
diff --git a/source4/heimdal/lib/gssapi/spnego/init_sec_context.c b/source4/heimdal/lib/gssapi/spnego/init_sec_context.c
new file mode 100644
index 0000000000..5a652fdb2e
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/spnego/init_sec_context.c
@@ -0,0 +1,578 @@
+/*
+ * Copyright (c) 1997 - 2004 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * Portions Copyright (c) 2004 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.
+ *
+ * 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 "spnego/spnego_locl.h"
+
+RCSID("$Id: init_sec_context.c,v 1.6 2006/10/14 10:09:15 lha Exp $");
+
+/*
+ * Send a reply. Note that we only need to send a reply if we
+ * need to send a MIC or a mechanism token. Otherwise, we can
+ * return an empty buffer.
+ *
+ * The return value of this will be returned to the API, so it
+ * must return GSS_S_CONTINUE_NEEDED if a token was generated.
+ */
+static OM_uint32
+spnego_reply_internal(OM_uint32 *minor_status,
+ gssspnego_ctx context_handle,
+ const gss_buffer_t mech_buf,
+ gss_buffer_t mech_token,
+ gss_buffer_t output_token)
+{
+ NegTokenResp resp;
+ gss_buffer_desc mic_buf;
+ OM_uint32 ret;
+ gss_buffer_desc data;
+ u_char *buf;
+
+ if (mech_buf == GSS_C_NO_BUFFER && mech_token->length == 0) {
+ output_token->length = 0;
+ output_token->value = NULL;
+
+ return context_handle->open ? GSS_S_COMPLETE : GSS_S_FAILURE;
+ }
+
+ memset(&resp, 0, sizeof(resp));
+
+ ALLOC(resp.negResult, 1);
+ if (resp.negResult == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ resp.supportedMech = NULL;
+
+ output_token->length = 0;
+ output_token->value = NULL;
+
+ if (mech_token->length == 0) {
+ resp.responseToken = NULL;
+ *(resp.negResult) = accept_completed;
+ } else {
+ ALLOC(resp.responseToken, 1);
+ if (resp.responseToken == NULL) {
+ free_NegTokenResp(&resp);
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ resp.responseToken->length = mech_token->length;
+ resp.responseToken->data = mech_token->value;
+ mech_token->length = 0;
+ mech_token->value = NULL;
+
+ *(resp.negResult) = accept_incomplete;
+ }
+
+ if (mech_buf != GSS_C_NO_BUFFER) {
+ ALLOC(resp.mechListMIC, 1);
+ if (resp.mechListMIC == NULL) {
+ free_NegTokenResp(&resp);
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ ret = gss_get_mic(minor_status,
+ context_handle->negotiated_ctx_id,
+ 0,
+ mech_buf,
+ &mic_buf);
+ if (ret) {
+ free_NegTokenResp(&resp);
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ resp.mechListMIC->length = mic_buf.length;
+ resp.mechListMIC->data = mic_buf.value;
+ } else {
+ resp.mechListMIC = NULL;
+ }
+
+ ret = _gss_spnego_encode_response (minor_status, &resp,
+ &data, &buf);
+ if (ret) {
+ free_NegTokenResp(&resp);
+ return ret;
+ }
+
+ output_token->value = malloc(data.length);
+ if (output_token->value == NULL) {
+ *minor_status = ENOMEM;
+ ret = GSS_S_FAILURE;
+ } else {
+ output_token->length = data.length;
+ memcpy(output_token->value, data.value, output_token->length);
+ }
+ free(buf);
+
+ if (*(resp.negResult) == accept_completed)
+ ret = GSS_S_COMPLETE;
+ else
+ ret = GSS_S_CONTINUE_NEEDED;
+
+ free_NegTokenResp(&resp);
+ return ret;
+}
+
+static OM_uint32
+spnego_initial
+ (OM_uint32 * minor_status,
+ gssspnego_cred cred,
+ gss_ctx_id_t * context_handle,
+ const gss_name_t target_name,
+ const gss_OID 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
+ )
+{
+ NegTokenInit ni;
+ int ret;
+ OM_uint32 sub, minor;
+ gss_buffer_desc mech_token;
+ u_char *buf;
+ size_t buf_size, buf_len;
+ gss_buffer_desc data;
+ size_t ni_len;
+ gss_ctx_id_t context;
+ gssspnego_ctx ctx;
+
+ memset (&ni, 0, sizeof(ni));
+
+ *context_handle = GSS_C_NO_CONTEXT;
+
+ *minor_status = 0;
+
+ sub = _gss_spnego_alloc_sec_context(&minor, &context);
+ if (GSS_ERROR(sub)) {
+ *minor_status = minor;
+ return sub;
+ }
+ ctx = (gssspnego_ctx)context;
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+
+ ctx->local = 1;
+
+ sub = _gss_spnego_indicate_mechtypelist(&minor, 0,
+ cred,
+ &ni.mechTypes,
+ &ctx->preferred_mech_type);
+ if (GSS_ERROR(sub)) {
+ *minor_status = minor;
+ _gss_spnego_internal_delete_sec_context(&minor, &context, GSS_C_NO_BUFFER);
+ return sub;
+ }
+
+ ni.reqFlags = NULL;
+
+ /*
+ * If we have a credential handle, use it to select the mechanism
+ * that we will use
+ */
+
+ /* generate optimistic token */
+ sub = gss_init_sec_context(&minor,
+ (cred != NULL) ? cred->negotiated_cred_id :
+ GSS_C_NO_CREDENTIAL,
+ &ctx->negotiated_ctx_id,
+ target_name,
+ GSS_C_NO_OID,
+ req_flags,
+ time_req,
+ input_chan_bindings,
+ input_token,
+ &ctx->negotiated_mech_type,
+ &mech_token,
+ &ctx->mech_flags,
+ &ctx->mech_time_rec);
+ if (GSS_ERROR(sub)) {
+ free_NegTokenInit(&ni);
+ *minor_status = minor;
+ _gss_spnego_internal_delete_sec_context(&minor, &context, GSS_C_NO_BUFFER);
+ return sub;
+ }
+
+ if (mech_token.length != 0) {
+ ALLOC(ni.mechToken, 1);
+ if (ni.mechToken == NULL) {
+ free_NegTokenInit(&ni);
+ gss_release_buffer(&minor, &mech_token);
+ _gss_spnego_internal_delete_sec_context(&minor, &context, GSS_C_NO_BUFFER);
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ ni.mechToken->length = mech_token.length;
+ ni.mechToken->data = malloc(mech_token.length);
+ if (ni.mechToken->data == NULL && mech_token.length != 0) {
+ free_NegTokenInit(&ni);
+ gss_release_buffer(&minor, &mech_token);
+ *minor_status = ENOMEM;
+ _gss_spnego_internal_delete_sec_context(&minor, &context, GSS_C_NO_BUFFER);
+ return GSS_S_FAILURE;
+ }
+ memcpy(ni.mechToken->data, mech_token.value, mech_token.length);
+ gss_release_buffer(&minor, &mech_token);
+ } else
+ ni.mechToken = NULL;
+
+ ni.mechListMIC = NULL;
+
+ ni_len = length_NegTokenInit(&ni);
+ buf_size = 1 + der_length_len(ni_len) + ni_len;
+
+ buf = malloc(buf_size);
+ if (buf == NULL) {
+ free_NegTokenInit(&ni);
+ *minor_status = ENOMEM;
+ _gss_spnego_internal_delete_sec_context(&minor, &context, GSS_C_NO_BUFFER);
+ return GSS_S_FAILURE;
+ }
+
+ ret = encode_NegTokenInit(buf + buf_size - 1,
+ ni_len,
+ &ni, &buf_len);
+ if (ret == 0 && ni_len != buf_len)
+ abort();
+
+ if (ret == 0) {
+ size_t tmp;
+
+ ret = der_put_length_and_tag(buf + buf_size - buf_len - 1,
+ buf_size - buf_len,
+ buf_len,
+ ASN1_C_CONTEXT,
+ CONS,
+ 0,
+ &tmp);
+ if (ret == 0 && tmp + buf_len != buf_size)
+ abort();
+ }
+ if (ret) {
+ *minor_status = ret;
+ free(buf);
+ free_NegTokenInit(&ni);
+ _gss_spnego_internal_delete_sec_context(&minor, &context, GSS_C_NO_BUFFER);
+ return GSS_S_FAILURE;
+ }
+
+ data.value = buf;
+ data.length = buf_size;
+
+ ctx->initiator_mech_types.len = ni.mechTypes.len;
+ ctx->initiator_mech_types.val = ni.mechTypes.val;
+ ni.mechTypes.len = 0;
+ ni.mechTypes.val = NULL;
+
+ free_NegTokenInit(&ni);
+
+ sub = gss_encapsulate_token(&data,
+ GSS_SPNEGO_MECHANISM,
+ output_token);
+ free (buf);
+
+ if (sub) {
+ _gss_spnego_internal_delete_sec_context(&minor, &context, GSS_C_NO_BUFFER);
+ return sub;
+ }
+
+ if (actual_mech_type)
+ *actual_mech_type = ctx->negotiated_mech_type;
+ if (ret_flags)
+ *ret_flags = ctx->mech_flags;
+ if (time_rec)
+ *time_rec = ctx->mech_time_rec;
+
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+
+ *context_handle = context;
+
+ return GSS_S_CONTINUE_NEEDED;
+}
+
+static OM_uint32
+spnego_reply
+ (OM_uint32 * minor_status,
+ const gssspnego_cred cred,
+ gss_ctx_id_t * context_handle,
+ const gss_name_t target_name,
+ const gss_OID 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 ret, minor;
+ NegTokenResp resp;
+ u_char oidbuf[17];
+ size_t oidlen;
+ size_t len, taglen;
+ gss_OID_desc mech;
+ int require_mic;
+ size_t buf_len;
+ gss_buffer_desc mic_buf, mech_buf;
+ gss_buffer_desc mech_output_token;
+ gssspnego_ctx ctx;
+
+ *minor_status = 0;
+
+ ctx = (gssspnego_ctx)*context_handle;
+
+ output_token->length = 0;
+ output_token->value = NULL;
+
+ mech_output_token.length = 0;
+ mech_output_token.value = NULL;
+
+ mech_buf.value = NULL;
+ mech_buf.length = 0;
+
+ ret = der_match_tag_and_length(input_token->value, input_token->length,
+ ASN1_C_CONTEXT, CONS, 1, &len, &taglen);
+ if (ret)
+ return ret;
+
+ if (len > input_token->length - taglen)
+ return ASN1_OVERRUN;
+
+ ret = decode_NegTokenResp((const unsigned char *)input_token->value+taglen,
+ len, &resp, NULL);
+ if (ret) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ if (resp.negResult == NULL
+ || *(resp.negResult) == reject
+ || resp.supportedMech == NULL) {
+ free_NegTokenResp(&resp);
+ return GSS_S_BAD_MECH;
+ }
+
+ ret = der_put_oid(oidbuf + sizeof(oidbuf) - 1,
+ sizeof(oidbuf),
+ resp.supportedMech,
+ &oidlen);
+ if (ret || (oidlen == GSS_SPNEGO_MECHANISM->length &&
+ memcmp(oidbuf + sizeof(oidbuf) - oidlen,
+ GSS_SPNEGO_MECHANISM->elements,
+ oidlen) == 0)) {
+ /* Avoid recursively embedded SPNEGO */
+ free_NegTokenResp(&resp);
+ return GSS_S_BAD_MECH;
+ }
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+
+ if (resp.responseToken != NULL) {
+ gss_buffer_desc mech_input_token;
+
+ mech_input_token.length = resp.responseToken->length;
+ mech_input_token.value = resp.responseToken->data;
+
+ mech.length = oidlen;
+ mech.elements = oidbuf + sizeof(oidbuf) - oidlen;
+
+ /* Fall through as if the negotiated mechanism
+ was requested explicitly */
+ ret = gss_init_sec_context(&minor,
+ (cred != NULL) ? cred->negotiated_cred_id :
+ GSS_C_NO_CREDENTIAL,
+ &ctx->negotiated_ctx_id,
+ target_name,
+ &mech,
+ req_flags,
+ time_req,
+ input_chan_bindings,
+ &mech_input_token,
+ &ctx->negotiated_mech_type,
+ &mech_output_token,
+ &ctx->mech_flags,
+ &ctx->mech_time_rec);
+ if (GSS_ERROR(ret)) {
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ free_NegTokenResp(&resp);
+ *minor_status = minor;
+ return ret;
+ }
+ if (ret == GSS_S_COMPLETE) {
+ ctx->open = 1;
+ }
+ }
+
+ if (*(resp.negResult) == request_mic) {
+ ctx->require_mic = 1;
+ }
+
+ if (ctx->open) {
+ /*
+ * Verify the mechListMIC if one was provided or CFX was
+ * used and a non-preferred mechanism was selected
+ */
+ if (resp.mechListMIC != NULL) {
+ require_mic = 1;
+ } else {
+ ret = _gss_spnego_require_mechlist_mic(minor_status, ctx,
+ &require_mic);
+ if (ret) {
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ free_NegTokenResp(&resp);
+ gss_release_buffer(&minor, &mech_output_token);
+ return ret;
+ }
+ }
+ } else {
+ require_mic = 0;
+ }
+
+ if (require_mic) {
+ ASN1_MALLOC_ENCODE(MechTypeList, mech_buf.value, mech_buf.length,
+ &ctx->initiator_mech_types, &buf_len, ret);
+ if (ret) {
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ free_NegTokenResp(&resp);
+ gss_release_buffer(&minor, &mech_output_token);
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+ if (mech_buf.length != buf_len)
+ abort();
+
+ if (resp.mechListMIC == NULL) {
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ free(mech_buf.value);
+ free_NegTokenResp(&resp);
+ *minor_status = 0;
+ return GSS_S_DEFECTIVE_TOKEN;
+ }
+ mic_buf.length = resp.mechListMIC->length;
+ mic_buf.value = resp.mechListMIC->data;
+
+ if (mech_output_token.length == 0) {
+ ret = gss_verify_mic(minor_status,
+ ctx->negotiated_ctx_id,
+ &mech_buf,
+ &mic_buf,
+ NULL);
+ if (ret) {
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ free(mech_buf.value);
+ gss_release_buffer(&minor, &mech_output_token);
+ free_NegTokenResp(&resp);
+ return GSS_S_DEFECTIVE_TOKEN;
+ }
+ ctx->verified_mic = 1;
+ }
+ }
+
+ ret = spnego_reply_internal(minor_status, ctx,
+ require_mic ? &mech_buf : NULL,
+ &mech_output_token,
+ output_token);
+
+ if (mech_buf.value != NULL)
+ free(mech_buf.value);
+
+ free_NegTokenResp(&resp);
+ gss_release_buffer(&minor, &mech_output_token);
+
+ if (actual_mech_type)
+ *actual_mech_type = ctx->negotiated_mech_type;
+ if (ret_flags)
+ *ret_flags = ctx->mech_flags;
+ if (time_rec)
+ *time_rec = ctx->mech_time_rec;
+
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ return ret;
+}
+
+OM_uint32 _gss_spnego_init_sec_context
+ (OM_uint32 * minor_status,
+ const gss_cred_id_t initiator_cred_handle,
+ gss_ctx_id_t * context_handle,
+ const gss_name_t target_name,
+ const gss_OID 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
+ )
+{
+ gssspnego_cred cred = (gssspnego_cred)initiator_cred_handle;
+
+ if (*context_handle == GSS_C_NO_CONTEXT)
+ return spnego_initial (minor_status,
+ cred,
+ context_handle,
+ target_name,
+ mech_type,
+ req_flags,
+ time_req,
+ input_chan_bindings,
+ input_token,
+ actual_mech_type,
+ output_token,
+ ret_flags,
+ time_rec);
+ else
+ return spnego_reply (minor_status,
+ cred,
+ context_handle,
+ target_name,
+ mech_type,
+ req_flags,
+ time_req,
+ input_chan_bindings,
+ input_token,
+ actual_mech_type,
+ output_token,
+ ret_flags,
+ time_rec);
+}
+
diff --git a/source4/heimdal/lib/gssapi/spnego/spnego-private.h b/source4/heimdal/lib/gssapi/spnego/spnego-private.h
new file mode 100644
index 0000000000..df50f65580
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/spnego/spnego-private.h
@@ -0,0 +1,347 @@
+/* This is a generated file */
+#ifndef __spnego_private_h__
+#define __spnego_private_h__
+
+#include <stdarg.h>
+
+gssapi_mech_interface
+__gss_spnego_initialize (void);
+
+OM_uint32
+_gss_spnego_accept_sec_context (
+ OM_uint32 * /*minor_status*/,
+ gss_ctx_id_t * /*context_handle*/,
+ const gss_cred_id_t /*acceptor_cred_handle*/,
+ const gss_buffer_t /*input_token_buffer*/,
+ 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
+_gss_spnego_acquire_cred (
+ OM_uint32 */*minor_status*/,
+ const gss_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 );
+
+OM_uint32
+_gss_spnego_add_cred (
+ OM_uint32 * /*minor_status*/,
+ const gss_cred_id_t /*input_cred_handle*/,
+ const gss_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 );
+
+int
+_gss_spnego_add_mech_type (
+ gss_OID /*mech_type*/,
+ int /*includeMSCompatOID*/,
+ MechTypeList */*mechtypelist*/);
+
+OM_uint32
+_gss_spnego_alloc_cred (
+ OM_uint32 */*minor_status*/,
+ gss_cred_id_t /*mech_cred_handle*/,
+ gss_cred_id_t */*cred_handle*/);
+
+OM_uint32
+_gss_spnego_alloc_sec_context (
+ OM_uint32 * /*minor_status*/,
+ gss_ctx_id_t */*context_handle*/);
+
+OM_uint32
+_gss_spnego_canonicalize_name (
+ OM_uint32 * /*minor_status*/,
+ const gss_name_t /*input_name*/,
+ const gss_OID /*mech_type*/,
+ gss_name_t * output_name );
+
+OM_uint32
+_gss_spnego_compare_name (
+ OM_uint32 */*minor_status*/,
+ const gss_name_t /*name1*/,
+ const gss_name_t /*name2*/,
+ int * name_equal );
+
+OM_uint32
+_gss_spnego_context_time (
+ OM_uint32 */*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ OM_uint32 *time_rec );
+
+OM_uint32
+_gss_spnego_delete_sec_context (
+ OM_uint32 */*minor_status*/,
+ gss_ctx_id_t */*context_handle*/,
+ gss_buffer_t output_token );
+
+OM_uint32
+_gss_spnego_display_name (
+ OM_uint32 * /*minor_status*/,
+ const gss_name_t /*input_name*/,
+ gss_buffer_t /*output_name_buffer*/,
+ gss_OID * output_name_type );
+
+OM_uint32
+_gss_spnego_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
+_gss_spnego_duplicate_name (
+ OM_uint32 * /*minor_status*/,
+ const gss_name_t /*src_name*/,
+ gss_name_t * dest_name );
+
+OM_uint32
+_gss_spnego_encode_response (
+ OM_uint32 */*minor_status*/,
+ const NegTokenResp */*resp*/,
+ gss_buffer_t /*data*/,
+ u_char **/*ret_buf*/);
+
+OM_uint32
+_gss_spnego_export_name (
+ OM_uint32 * /*minor_status*/,
+ const gss_name_t /*input_name*/,
+ gss_buffer_t exported_name );
+
+OM_uint32
+_gss_spnego_export_sec_context (
+ OM_uint32 * /*minor_status*/,
+ gss_ctx_id_t * /*context_handle*/,
+ gss_buffer_t interprocess_token );
+
+OM_uint32
+_gss_spnego_get_mic (
+ OM_uint32 */*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ gss_qop_t /*qop_req*/,
+ const gss_buffer_t /*message_buffer*/,
+ gss_buffer_t message_token );
+
+OM_uint32
+_gss_spnego_import_name (
+ OM_uint32 * /*minor_status*/,
+ const gss_buffer_t /*input_name_buffer*/,
+ const gss_OID /*input_name_type*/,
+ gss_name_t * output_name );
+
+OM_uint32
+_gss_spnego_import_sec_context (
+ OM_uint32 * /*minor_status*/,
+ const gss_buffer_t /*interprocess_token*/,
+ gss_ctx_id_t *context_handle );
+
+OM_uint32
+_gss_spnego_indicate_mechtypelist (
+ OM_uint32 */*minor_status*/,
+ int /*includeMSCompatOID*/,
+ const gssspnego_cred /*cred_handle*/,
+ MechTypeList */*mechtypelist*/,
+ gss_OID */*preferred_mech*/);
+
+OM_uint32
+_gss_spnego_init_sec_context (
+ OM_uint32 * /*minor_status*/,
+ const gss_cred_id_t /*initiator_cred_handle*/,
+ gss_ctx_id_t * /*context_handle*/,
+ const gss_name_t /*target_name*/,
+ const gss_OID /*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
+_gss_spnego_inquire_context (
+ OM_uint32 * /*minor_status*/,
+ const gss_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 * open_context );
+
+OM_uint32
+_gss_spnego_inquire_cred (
+ OM_uint32 * /*minor_status*/,
+ const gss_cred_id_t /*cred_handle*/,
+ gss_name_t * /*name*/,
+ OM_uint32 * /*lifetime*/,
+ gss_cred_usage_t * /*cred_usage*/,
+ gss_OID_set * mechanisms );
+
+OM_uint32
+_gss_spnego_inquire_cred_by_mech (
+ OM_uint32 * /*minor_status*/,
+ const gss_cred_id_t /*cred_handle*/,
+ const gss_OID /*mech_type*/,
+ gss_name_t * /*name*/,
+ OM_uint32 * /*initiator_lifetime*/,
+ OM_uint32 * /*acceptor_lifetime*/,
+ gss_cred_usage_t * cred_usage );
+
+OM_uint32
+_gss_spnego_inquire_cred_by_oid (
+ OM_uint32 * /*minor_status*/,
+ const gss_cred_id_t /*cred_handle*/,
+ const gss_OID /*desired_object*/,
+ gss_buffer_set_t */*data_set*/);
+
+OM_uint32
+_gss_spnego_inquire_mechs_for_name (
+ OM_uint32 * /*minor_status*/,
+ const gss_name_t /*input_name*/,
+ gss_OID_set * mech_types );
+
+OM_uint32
+_gss_spnego_inquire_names_for_mech (
+ OM_uint32 * /*minor_status*/,
+ const gss_OID /*mechanism*/,
+ gss_OID_set * name_types );
+
+OM_uint32
+_gss_spnego_inquire_sec_context_by_oid (
+ OM_uint32 * /*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ const gss_OID /*desired_object*/,
+ gss_buffer_set_t */*data_set*/);
+
+OM_uint32
+_gss_spnego_internal_delete_sec_context (
+ OM_uint32 */*minor_status*/,
+ gss_ctx_id_t */*context_handle*/,
+ gss_buffer_t output_token );
+
+OM_uint32
+_gss_spnego_process_context_token (
+ OM_uint32 */*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ const gss_buffer_t token_buffer );
+
+OM_uint32
+_gss_spnego_release_cred (
+ OM_uint32 */*minor_status*/,
+ gss_cred_id_t */*cred_handle*/);
+
+OM_uint32
+_gss_spnego_release_name (
+ OM_uint32 * /*minor_status*/,
+ gss_name_t * input_name );
+
+OM_uint32
+_gss_spnego_require_mechlist_mic (
+ OM_uint32 */*minor_status*/,
+ gssspnego_ctx /*ctx*/,
+ int */*require_mic*/);
+
+OM_uint32
+_gss_spnego_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 );
+
+OM_uint32
+_gss_spnego_select_mech (
+ OM_uint32 */*minor_status*/,
+ MechType */*mechType*/,
+ gss_OID */*mech_p*/);
+
+OM_uint32
+_gss_spnego_set_sec_context_option (
+ OM_uint32 * /*minor_status*/,
+ gss_ctx_id_t * /*context_handle*/,
+ const gss_OID /*desired_object*/,
+ const gss_buffer_t /*value*/);
+
+OM_uint32
+_gss_spnego_sign (
+ OM_uint32 * /*minor_status*/,
+ gss_ctx_id_t /*context_handle*/,
+ int /*qop_req*/,
+ gss_buffer_t /*message_buffer*/,
+ gss_buffer_t message_token );
+
+OM_uint32
+_gss_spnego_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 );
+
+OM_uint32
+_gss_spnego_unwrap (
+ OM_uint32 * /*minor_status*/,
+ const gss_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 );
+
+OM_uint32
+_gss_spnego_verify (
+ OM_uint32 * /*minor_status*/,
+ gss_ctx_id_t /*context_handle*/,
+ gss_buffer_t /*message_buffer*/,
+ gss_buffer_t /*token_buffer*/,
+ int * qop_state );
+
+OM_uint32
+_gss_spnego_verify_mic (
+ OM_uint32 * /*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ const gss_buffer_t /*message_buffer*/,
+ const gss_buffer_t /*token_buffer*/,
+ gss_qop_t * qop_state );
+
+OM_uint32
+_gss_spnego_wrap (
+ OM_uint32 * /*minor_status*/,
+ const gss_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 );
+
+OM_uint32
+_gss_spnego_wrap_size_limit (
+ OM_uint32 * /*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ int /*conf_req_flag*/,
+ gss_qop_t /*qop_req*/,
+ OM_uint32 /*req_output_size*/,
+ OM_uint32 * max_input_size );
+
+#endif /* __spnego_private_h__ */
diff --git a/source4/heimdal/lib/gssapi/spnego/spnego.asn1 b/source4/heimdal/lib/gssapi/spnego/spnego.asn1
new file mode 100644
index 0000000000..187ce0a0a6
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/spnego/spnego.asn1
@@ -0,0 +1,51 @@
+-- $Id: spnego.asn1,v 1.1.1.1 2006/06/28 08:34:45 lha Exp $
+
+SPNEGO DEFINITIONS ::=
+BEGIN
+
+MechType::= OBJECT IDENTIFIER
+
+MechTypeList ::= SEQUENCE OF MechType
+
+ContextFlags ::= BIT STRING {
+ delegFlag (0),
+ mutualFlag (1),
+ replayFlag (2),
+ sequenceFlag (3),
+ anonFlag (4),
+ confFlag (5),
+ integFlag (6)
+}
+
+NegHints ::= SEQUENCE {
+ hintName [0] GeneralString OPTIONAL,
+ hintAddress [1] OCTET STRING OPTIONAL
+}
+
+NegTokenInit ::= SEQUENCE {
+ mechTypes [0] MechTypeList,
+ reqFlags [1] ContextFlags OPTIONAL,
+ mechToken [2] OCTET STRING OPTIONAL,
+ negHints [3] NegHints OPTIONAL,
+ mechListMIC [4] OCTET STRING OPTIONAL
+ }
+
+-- NB: negResult is not OPTIONAL in the new SPNEGO spec but
+-- Windows clients do not always send it
+NegTokenResp ::= SEQUENCE {
+ negResult [0] ENUMERATED {
+ accept_completed (0),
+ accept_incomplete (1),
+ reject (2),
+ request-mic (3) } OPTIONAL,
+ supportedMech [1] MechType OPTIONAL,
+ responseToken [2] OCTET STRING OPTIONAL,
+ mechListMIC [3] OCTET STRING OPTIONAL
+}
+
+NegotiationToken ::= CHOICE {
+ negTokenInit[0] NegTokenInit,
+ negTokenResp[1] NegTokenResp
+}
+
+END
diff --git a/source4/heimdal/lib/gssapi/spnego/spnego_locl.h b/source4/heimdal/lib/gssapi/spnego/spnego_locl.h
new file mode 100644
index 0000000000..571bce5569
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/spnego/spnego_locl.h
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+/* $Id: spnego_locl.h,v 1.11 2006/10/12 06:28:06 lha Exp $ */
+
+#ifndef SPNEGO_LOCL_H
+#define SPNEGO_LOCL_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#ifdef HAVE_PTHREAD_H
+#include <pthread.h>
+#endif
+
+#include <gssapi/gssapi_spnego.h>
+#include <gssapi.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+
+#include <heim_threads.h>
+#include <asn1_err.h>
+
+#include <gssapi_mech.h>
+
+#include "spnego_asn1.h"
+#include <der.h>
+
+#define ALLOC(X, N) (X) = calloc((N), sizeof(*(X)))
+
+typedef struct {
+ gss_cred_id_t negotiated_cred_id;
+} *gssspnego_cred;
+
+typedef struct {
+ MechTypeList initiator_mech_types;
+ gss_OID preferred_mech_type;
+ gss_OID negotiated_mech_type;
+ gss_ctx_id_t negotiated_ctx_id;
+ OM_uint32 mech_flags;
+ OM_uint32 mech_time_rec;
+ gss_name_t mech_src_name;
+ gss_cred_id_t delegated_cred_id;
+ int open : 1;
+ int local : 1;
+ int require_mic : 1;
+ int verified_mic : 1;
+ HEIMDAL_MUTEX ctx_id_mutex;
+} *gssspnego_ctx;
+
+#include <spnego/spnego-private.h>
+
+#endif /* SPNEGO_LOCL_H */