r19604: This is a massive commit, and I appologise in advance for it's size.
authorAndrew Bartlett <abartlet@samba.org>
Tue, 7 Nov 2006 06:59:56 +0000 (06:59 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 19:25:03 +0000 (14:25 -0500)
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)

264 files changed:
source4/auth/credentials/credentials_krb5.h
source4/auth/gensec/gensec_gssapi.c
source4/auth/gensec/gensec_krb5.c
source4/auth/kerberos/kerberos.c
source4/auth/kerberos/kerberos_pac.c
source4/auth/kerberos/krb5_init_context.c
source4/auth/kerberos/krb5_init_context.h
source4/dsdb/samdb/cracknames.c
source4/heimdal/kdc/524.c
source4/heimdal/kdc/default_config.c
source4/heimdal/kdc/digest.c [new file with mode: 0644]
source4/heimdal/kdc/headers.h
source4/heimdal/kdc/kaserver.c
source4/heimdal/kdc/kdc-private.h
source4/heimdal/kdc/kdc-protos.h
source4/heimdal/kdc/kdc.h
source4/heimdal/kdc/kerberos4.c
source4/heimdal/kdc/kerberos5.c
source4/heimdal/kdc/krb5tgs.c [new file with mode: 0644]
source4/heimdal/kdc/misc.c
source4/heimdal/kdc/pkinit.c
source4/heimdal/kdc/process.c
source4/heimdal/lib/asn1/CMS.asn1
source4/heimdal/lib/asn1/asn1-common.h
source4/heimdal/lib/asn1/der-protos.h [new file with mode: 0644]
source4/heimdal/lib/asn1/der.h
source4/heimdal/lib/asn1/der_cmp.c
source4/heimdal/lib/asn1/der_copy.c
source4/heimdal/lib/asn1/der_format.c
source4/heimdal/lib/asn1/der_free.c
source4/heimdal/lib/asn1/der_get.c
source4/heimdal/lib/asn1/der_length.c
source4/heimdal/lib/asn1/der_locl.h
source4/heimdal/lib/asn1/der_put.c
source4/heimdal/lib/asn1/digest.asn1 [new file with mode: 0644]
source4/heimdal/lib/asn1/gen.c
source4/heimdal/lib/asn1/gen_copy.c
source4/heimdal/lib/asn1/gen_decode.c
source4/heimdal/lib/asn1/gen_free.c
source4/heimdal/lib/asn1/gen_length.c
source4/heimdal/lib/asn1/gen_locl.h
source4/heimdal/lib/asn1/gen_seq.c [new file with mode: 0644]
source4/heimdal/lib/asn1/heim_asn1.h
source4/heimdal/lib/asn1/k5.asn1
source4/heimdal/lib/asn1/lex.c
source4/heimdal/lib/asn1/main.c
source4/heimdal/lib/asn1/parse.c
source4/heimdal/lib/asn1/parse.h
source4/heimdal/lib/asn1/pkinit.asn1 [new file with mode: 0644]
source4/heimdal/lib/asn1/rfc2459.asn1 [new file with mode: 0644]
source4/heimdal/lib/asn1/test.asn1
source4/heimdal/lib/asn1/timegm.c [new file with mode: 0644]
source4/heimdal/lib/com_err/lex.c
source4/heimdal/lib/com_err/parse.c
source4/heimdal/lib/com_err/parse.h
source4/heimdal/lib/des/evp.c
source4/heimdal/lib/des/evp.h
source4/heimdal/lib/des/hmac.c
source4/heimdal/lib/des/rand-unix.c [new file with mode: 0644]
source4/heimdal/lib/des/rand.c [new file with mode: 0644]
source4/heimdal/lib/des/ui.c
source4/heimdal/lib/gssapi/accept_sec_context.c [deleted file]
source4/heimdal/lib/gssapi/gssapi.h
source4/heimdal/lib/gssapi/gssapi/gssapi.h [new file with mode: 0644]
source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h [new file with mode: 0644]
source4/heimdal/lib/gssapi/gssapi/gssapi_spnego.h [new file with mode: 0644]
source4/heimdal/lib/gssapi/gssapi_locl.h [deleted file]
source4/heimdal/lib/gssapi/gssapi_mech.h [new file with mode: 0644]
source4/heimdal/lib/gssapi/init_sec_context.c [deleted file]
source4/heimdal/lib/gssapi/inquire_cred.c [deleted file]
source4/heimdal/lib/gssapi/krb5/8003.c [moved from source4/heimdal/lib/gssapi/8003.c with 88% similarity]
source4/heimdal/lib/gssapi/krb5/accept_sec_context.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/krb5/acquire_cred.c [moved from source4/heimdal/lib/gssapi/acquire_cred.c with 63% similarity]
source4/heimdal/lib/gssapi/krb5/add_cred.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/krb5/add_oid_set_member.c [moved from source4/heimdal/lib/gssapi/add_oid_set_member.c with 90% similarity]
source4/heimdal/lib/gssapi/krb5/address_to_krb5addr.c [moved from source4/heimdal/lib/gssapi/address_to_krb5addr.c with 88% similarity]
source4/heimdal/lib/gssapi/krb5/arcfour.c [moved from source4/heimdal/lib/gssapi/arcfour.c with 73% similarity]
source4/heimdal/lib/gssapi/krb5/canonicalize_name.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/krb5/cfx.c [moved from source4/heimdal/lib/gssapi/cfx.c with 74% similarity]
source4/heimdal/lib/gssapi/krb5/cfx.h [moved from source4/heimdal/lib/gssapi/cfx.h with 64% similarity]
source4/heimdal/lib/gssapi/krb5/compare_name.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/krb5/compat.c [moved from source4/heimdal/lib/gssapi/compat.c with 63% similarity]
source4/heimdal/lib/gssapi/krb5/context_time.c [moved from source4/heimdal/lib/gssapi/context_time.c with 82% similarity]
source4/heimdal/lib/gssapi/krb5/copy_ccache.c [moved from source4/heimdal/lib/gssapi/copy_ccache.c with 50% similarity]
source4/heimdal/lib/gssapi/krb5/create_emtpy_oid_set.c [moved from source4/heimdal/lib/gssapi/create_emtpy_oid_set.c with 93% similarity]
source4/heimdal/lib/gssapi/krb5/decapsulate.c [moved from source4/heimdal/lib/gssapi/decapsulate.c with 91% similarity]
source4/heimdal/lib/gssapi/krb5/delete_sec_context.c [moved from source4/heimdal/lib/gssapi/delete_sec_context.c with 61% similarity]
source4/heimdal/lib/gssapi/krb5/display_name.c [moved from source4/heimdal/lib/gssapi/display_name.c with 89% similarity]
source4/heimdal/lib/gssapi/krb5/display_status.c [moved from source4/heimdal/lib/gssapi/display_status.c with 88% similarity]
source4/heimdal/lib/gssapi/krb5/duplicate_name.c [moved from source4/heimdal/lib/gssapi/duplicate_name.c with 85% similarity]
source4/heimdal/lib/gssapi/krb5/encapsulate.c [moved from source4/heimdal/lib/gssapi/encapsulate.c with 87% similarity]
source4/heimdal/lib/gssapi/krb5/export_name.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/krb5/export_sec_context.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/krb5/external.c [moved from source4/heimdal/lib/gssapi/external.c with 67% similarity]
source4/heimdal/lib/gssapi/krb5/get_mic.c [moved from source4/heimdal/lib/gssapi/get_mic.c with 76% similarity]
source4/heimdal/lib/gssapi/krb5/gsskrb5-private.h [new file with mode: 0644]
source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h [new file with mode: 0644]
source4/heimdal/lib/gssapi/krb5/import_name.c [moved from source4/heimdal/lib/gssapi/import_name.c with 84% similarity]
source4/heimdal/lib/gssapi/krb5/import_sec_context.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/krb5/indicate_mechs.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/krb5/init.c [moved from source4/heimdal/lib/gssapi/init.c with 62% similarity]
source4/heimdal/lib/gssapi/krb5/init_sec_context.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/krb5/inquire_context.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/krb5/inquire_cred.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/krb5/inquire_cred_by_mech.c [moved from source4/heimdal/lib/gssapi/arcfour.h with 51% similarity]
source4/heimdal/lib/gssapi/krb5/inquire_cred_by_oid.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/krb5/inquire_mechs_for_name.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/krb5/inquire_names_for_mech.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/krb5/inquire_sec_context_by_oid.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/krb5/process_context_token.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/krb5/release_buffer.c [moved from source4/heimdal/lib/gssapi/release_buffer.c with 93% similarity]
source4/heimdal/lib/gssapi/krb5/release_cred.c [moved from source4/heimdal/lib/gssapi/release_cred.c with 66% similarity]
source4/heimdal/lib/gssapi/krb5/release_name.c [moved from source4/heimdal/lib/gssapi/release_name.c with 88% similarity]
source4/heimdal/lib/gssapi/krb5/release_oid_set.c [moved from source4/heimdal/lib/gssapi/release_oid_set.c with 93% similarity]
source4/heimdal/lib/gssapi/krb5/sequence.c [moved from source4/heimdal/lib/gssapi/sequence.c with 97% similarity]
source4/heimdal/lib/gssapi/krb5/set_cred_option.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/krb5/set_sec_context_option.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/krb5/test_oid_set_member.c [moved from source4/heimdal/lib/gssapi/test_oid_set_member.c with 82% similarity]
source4/heimdal/lib/gssapi/krb5/unwrap.c [moved from source4/heimdal/lib/gssapi/unwrap.c with 85% similarity]
source4/heimdal/lib/gssapi/krb5/verify_mic.c [moved from source4/heimdal/lib/gssapi/verify_mic.c with 82% similarity]
source4/heimdal/lib/gssapi/krb5/wrap.c [moved from source4/heimdal/lib/gssapi/wrap.c with 57% similarity]
source4/heimdal/lib/gssapi/mech/context.h [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/cred.h [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_acquire_cred.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_add_cred.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_add_oid_set_member.c [moved from source4/heimdal/lib/gssapi/ccache_name.c with 66% similarity, mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_buffer_set.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_canonicalize_name.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_compare_name.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_context_time.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_create_empty_oid_set.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_decapsulate_token.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_delete_sec_context.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_display_name.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_display_status.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_duplicate_name.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_duplicate_oid.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_encapsulate_token.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_export_name.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_export_sec_context.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_get_mic.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_import_name.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_import_sec_context.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_indicate_mechs.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_init_sec_context.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_inquire_context.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_inquire_cred.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_mech.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_oid.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_inquire_mechs_for_name.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_inquire_names_for_mech.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_inquire_sec_context_by_oid.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_krb5.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_mech_switch.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_names.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_oid_equal.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_process_context_token.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_release_buffer.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_release_cred.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_release_name.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_release_oid.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_release_oid_set.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_seal.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_set_cred_option.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_set_sec_context_option.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_sign.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_test_oid_set_member.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_unseal.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_unwrap.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_utils.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_verify.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_verify_mic.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_wrap.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_wrap_size_limit.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gssapi.asn1 [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/mech_locl.h [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/mech_switch.h [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/mechqueue.h [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/name.h [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/utils.h [new file with mode: 0644]
source4/heimdal/lib/gssapi/spnego.asn1 [deleted file]
source4/heimdal/lib/gssapi/spnego/accept_sec_context.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/spnego/compat.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/spnego/context_stubs.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/spnego/cred_stubs.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/spnego/external.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/spnego/init_sec_context.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/spnego/spnego-private.h [new file with mode: 0644]
source4/heimdal/lib/gssapi/spnego/spnego.asn1 [new file with mode: 0644]
source4/heimdal/lib/gssapi/spnego/spnego_locl.h [new file with mode: 0644]
source4/heimdal/lib/hdb/db.c
source4/heimdal/lib/hdb/ext.c
source4/heimdal/lib/hdb/hdb-protos.h
source4/heimdal/lib/hdb/hdb.asn1
source4/heimdal/lib/hdb/hdb.c
source4/heimdal/lib/hdb/hdb.h
source4/heimdal/lib/hdb/keys.c
source4/heimdal/lib/hdb/keytab.c
source4/heimdal/lib/krb5/acache.c
source4/heimdal/lib/krb5/addr_families.c
source4/heimdal/lib/krb5/asn1_glue.c
source4/heimdal/lib/krb5/cache.c
source4/heimdal/lib/krb5/context.c
source4/heimdal/lib/krb5/crypto.c
source4/heimdal/lib/krb5/data.c
source4/heimdal/lib/krb5/expand_hostname.c
source4/heimdal/lib/krb5/get_cred.c
source4/heimdal/lib/krb5/get_for_creds.c
source4/heimdal/lib/krb5/get_host_realm.c
source4/heimdal/lib/krb5/get_in_tkt.c
source4/heimdal/lib/krb5/heim_err.c [new file with mode: 0644]
source4/heimdal/lib/krb5/heim_threads.h
source4/heimdal/lib/krb5/init_creds.c
source4/heimdal/lib/krb5/init_creds_pw.c
source4/heimdal/lib/krb5/k524_err.c [new file with mode: 0644]
source4/heimdal/lib/krb5/krb5-private.h
source4/heimdal/lib/krb5/krb5-protos.h
source4/heimdal/lib/krb5/krb5.h
source4/heimdal/lib/krb5/krb5_err.c [new file with mode: 0644]
source4/heimdal/lib/krb5/krb5_locl.h
source4/heimdal/lib/krb5/krbhst.c
source4/heimdal/lib/krb5/misc.c
source4/heimdal/lib/krb5/mit_glue.c
source4/heimdal/lib/krb5/pkinit.c
source4/heimdal/lib/krb5/principal.c
source4/heimdal/lib/krb5/rd_cred.c
source4/heimdal/lib/krb5/rd_rep.c
source4/heimdal/lib/krb5/rd_req.c
source4/heimdal/lib/krb5/send_to_kdc.c
source4/heimdal/lib/krb5/set_default_realm.c
source4/heimdal/lib/krb5/store.c
source4/heimdal/lib/krb5/store_fd.c
source4/heimdal/lib/krb5/ticket.c
source4/heimdal/lib/roken/bswap.c
source4/heimdal/lib/roken/copyhostent.c
source4/heimdal/lib/roken/freeaddrinfo.c
source4/heimdal/lib/roken/freehostent.c
source4/heimdal/lib/roken/gai_strerror.c
source4/heimdal/lib/roken/getaddrinfo.c
source4/heimdal/lib/roken/getipnodebyaddr.c
source4/heimdal/lib/roken/getipnodebyname.c
source4/heimdal/lib/roken/getprogname.c
source4/heimdal/lib/roken/hex.c
source4/heimdal/lib/roken/hostent_find_fqdn.c
source4/heimdal/lib/roken/inet_aton.c
source4/heimdal/lib/roken/issuid.c
source4/heimdal/lib/roken/resolve.c
source4/heimdal/lib/roken/roken.h
source4/heimdal/lib/roken/setprogname.c
source4/heimdal/lib/roken/signal.c
source4/heimdal/lib/roken/strsep.c
source4/heimdal/lib/roken/strsep_copy.c
source4/heimdal_build/asn1_deps.pl
source4/heimdal_build/config.mk
source4/kdc/hdb-ldb.c
source4/kdc/kdc.c
source4/kdc/kdc.h
source4/kdc/kpasswdd.c
source4/kdc/pac-glue.c
source4/smbd/process_single.c
source4/smbd/process_standard.c
source4/static_deps.mk
source4/torture/auth/pac.c

index 2bd38af5c78a70fe04e782273a649d6711df1b7f..22c0f5abfeae8be28038e5860e10d8497854ba20 100644 (file)
@@ -21,9 +21,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
-struct EncryptionKey;
-
-#include "heimdal/lib/gssapi/gssapi.h"
+#include "heimdal/lib/gssapi/gssapi/gssapi.h"
 
 struct ccache_container;
 
index ed407b623bb47e5b8e2ea29687456c681dbe6072..136962d89237129538f1da5865767de643d91fad 100644 (file)
@@ -24,7 +24,7 @@
 
 #include "includes.h"
 #include "system/kerberos.h"
-#include "heimdal/lib/gssapi/gssapi.h"
+#include "heimdal/lib/gssapi/gssapi/gssapi.h"
 #include "auth/kerberos/kerberos.h"
 #include "librpc/gen_ndr/krb5pac.h"
 #include "auth/auth.h"
@@ -73,6 +73,7 @@ struct gensec_gssapi_state {
                                  * layer... */
 
        size_t max_wrap_buf_size;
+       int gss_exchange_count;
 };
 
 static size_t gensec_gssapi_max_input_size(struct gensec_security *gensec_security);
@@ -133,12 +134,14 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security)
 {
        struct gensec_gssapi_state *gensec_gssapi_state;
        krb5_error_code ret;
-       
+       struct gsskrb5_send_to_kdc send_to_kdc;
+
        gensec_gssapi_state = talloc(gensec_security, struct gensec_gssapi_state);
        if (!gensec_gssapi_state) {
                return NT_STATUS_NO_MEMORY;
        }
        
+       gensec_gssapi_state->gss_exchange_count = 0;
        gensec_gssapi_state->max_wrap_buf_size
                = lp_parm_int(-1, "gensec_gssapi", "max wrap buf size", 65536);
                
@@ -186,10 +189,18 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security)
 
        gensec_gssapi_state->gss_oid = gss_mech_krb5;
        
+       send_to_kdc.func = smb_krb5_send_and_recv_func;
+       send_to_kdc.ptr = gensec_security->event_ctx;
+
+       ret = gsskrb5_set_send_to_kdc(&send_to_kdc);
+       if (ret) {
+               DEBUG(1,("gensec_krb5_start: gsskrb5_set_send_to_kdc failed\n"));
+               return NT_STATUS_INTERNAL_ERROR;
+       }
        ret = smb_krb5_init_context(gensec_gssapi_state, 
                                    &gensec_gssapi_state->smb_krb5_context);
        if (ret) {
-               DEBUG(1,("gensec_krb5_start: krb5_init_context failed (%s)\n",                                  
+               DEBUG(1,("gensec_krb5_start: krb5_init_context failed (%s)\n",
                         error_message(ret)));
                return NT_STATUS_INTERNAL_ERROR;
        }
@@ -431,6 +442,8 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security,
                        
                }
 
+               gensec_gssapi_state->gss_exchange_count++;
+
                if (maj_stat == GSS_S_COMPLETE) {
                        *out = data_blob_talloc(out_mem_ctx, output_token.value, output_token.length);
                        gss_release_buffer(&min_stat2, &output_token);
@@ -493,12 +506,14 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security,
                                /* garbage input, possibly from the auto-mech detection */
                                return NT_STATUS_INVALID_PARAMETER;
                        default:
-                               DEBUG(1, ("GSS(krb5) Update failed: %s\n", 
+                               DEBUG(1, ("GSS Update(krb5)(%d) Update failed: %s\n", 
+                                         gensec_gssapi_state->gss_exchange_count,
                                          gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
                                return nt_status;
                        }
                } else {
-                       DEBUG(1, ("GSS Update failed: %s\n", 
+                       DEBUG(1, ("GSS Update(%d) failed: %s\n", 
+                                 gensec_gssapi_state->gss_exchange_count,
                                  gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
                        return nt_status;
                }
@@ -583,7 +598,7 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security,
                                            &conf_state,
                                            &output_token);
                        if (GSS_ERROR(maj_stat)) {
-                               DEBUG(1, ("gensec_gssapi_wrap: GSS Wrap failed: %s\n", 
+                               DEBUG(1, ("GSS Update(SSF_NEG): GSS Wrap failed: %s\n", 
                                          gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
                                return NT_STATUS_ACCESS_DENIED;
                        }
@@ -648,7 +663,7 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security,
                                            &conf_state,
                                            &output_token);
                        if (GSS_ERROR(maj_stat)) {
-                               DEBUG(1, ("gensec_gssapi_wrap: GSS Wrap failed: %s\n", 
+                               DEBUG(1, ("GSS Update(SSF_NEG): GSS Wrap failed: %s\n", 
                                          gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
                                return NT_STATUS_ACCESS_DENIED;
                        }
@@ -1185,38 +1200,57 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi
                return NT_STATUS_NO_MEMORY;
        }
 
-       maj_stat = gss_krb5_copy_service_keyblock(&min_stat, 
-                                                 gensec_gssapi_state->gssapi_context, 
-                                                 &keyblock);
-
-       if (maj_stat == 0) {
-               maj_stat = gsskrb5_extract_authtime_from_sec_context(&min_stat,
-                                                                    gensec_gssapi_state->gssapi_context, 
-                                                                    &authtime);
-       }
-
-       if (maj_stat == 0) {
-               maj_stat = gsskrb5_extract_authz_data_from_sec_context(&min_stat, 
-                                                                      gensec_gssapi_state->gssapi_context, 
-                                                                      KRB5_AUTHDATA_WIN2K_PAC,
-                                                                      &pac);
-       }
-
+       maj_stat = gsskrb5_extract_authz_data_from_sec_context(&min_stat, 
+                                                              gensec_gssapi_state->gssapi_context, 
+                                                              KRB5_AUTHDATA_WIN2K_PAC,
+                                                              &pac);
+       
+       
        if (maj_stat == 0) {
                pac_blob = data_blob_talloc(mem_ctx, pac.value, pac.length);
                gss_release_buffer(&min_stat, &pac);
+
+       } else {
+               pac_blob = data_blob(NULL, 0);
        }
        
        /* IF we have the PAC - otherwise we need to get this
         * data from elsewere - local ldb, or (TODO) lookup of some
         * kind... 
         */
-       if (maj_stat == 0) {
+       if (pac_blob.length) {
                krb5_error_code ret;
+               union netr_Validation validation;
 
-               ret = krb5_parse_name(gensec_gssapi_state->smb_krb5_context->krb5_context,
-                                     principal_string, &principal);
+               maj_stat = gsskrb5_extract_authtime_from_sec_context(&min_stat,
+                                                                    gensec_gssapi_state->gssapi_context, 
+                                                                    &authtime);
+               
+               if (GSS_ERROR(maj_stat)) {
+                       DEBUG(1, ("gsskrb5_extract_authtime_from_sec_context: %s\n", 
+                                 gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
+                       talloc_free(mem_ctx);
+                       return NT_STATUS_FOOBAR;
+               }
+
+               maj_stat = gsskrb5_extract_service_keyblock(&min_stat, 
+                                                           gensec_gssapi_state->gssapi_context, 
+                                                           &keyblock);
+               
+               if (GSS_ERROR(maj_stat)) {
+                       DEBUG(1, ("gsskrb5_copy_service_keyblock failed: %s\n", 
+                                 gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
+                       talloc_free(mem_ctx);
+                       return NT_STATUS_FOOBAR;
+               } 
+
+               ret = krb5_parse_name_flags(gensec_gssapi_state->smb_krb5_context->krb5_context,
+                                           principal_string, 
+                                           KRB5_PRINCIPAL_PARSE_MUST_REALM,
+                                           &principal);
                if (ret) {
+                       krb5_free_keyblock(gensec_gssapi_state->smb_krb5_context->krb5_context,
+                                          keyblock);
                        talloc_free(mem_ctx);
                        return NT_STATUS_INVALID_PARAMETER;
                }
@@ -1226,25 +1260,25 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi
                                                    gensec_gssapi_state->smb_krb5_context->krb5_context,
                                                    NULL, keyblock, principal, authtime, NULL);
                krb5_free_principal(gensec_gssapi_state->smb_krb5_context->krb5_context, principal);
+               krb5_free_keyblock(gensec_gssapi_state->smb_krb5_context->krb5_context,
+                                  keyblock);
 
-               if (NT_STATUS_IS_OK(nt_status)) {
-                       union netr_Validation validation;
-                       validation.sam3 = &logon_info->info3;
-                       nt_status = make_server_info_netlogon_validation(gensec_gssapi_state, 
-                                                                        NULL,
-                                                                        3, &validation,
-                                                                        &server_info); 
-                       if (!NT_STATUS_IS_OK(nt_status)) {
-                               talloc_free(mem_ctx);
-                               return nt_status;
-                       }
-               } else {
-                       maj_stat = 1;
+               if (!NT_STATUS_IS_OK(nt_status)) {
+                       talloc_free(mem_ctx);
+                       return nt_status;
                }
-       }
-       
-       if (maj_stat) {
-               DEBUG(1, ("Unable to use PAC, resorting to local user lookup!\n"));
+               validation.sam3 = &logon_info->info3;
+               nt_status = make_server_info_netlogon_validation(gensec_gssapi_state, 
+                                                                NULL,
+                                                                3, &validation,
+                                                                &server_info); 
+               if (!NT_STATUS_IS_OK(nt_status)) {
+                       talloc_free(mem_ctx);
+                       return nt_status;
+               }
+       } else if (!lp_parm_bool(-1, "gensec", "require_pac", False)) {
+               DEBUG(1, ("Unable to find PAC, resorting to local user lookup: %s\n",
+                         gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
                nt_status = sam_get_server_info_principal(mem_ctx, principal_string,
                                                          &server_info);
 
@@ -1252,6 +1286,11 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi
                        talloc_free(mem_ctx);
                        return nt_status;
                }
+       } else {
+               DEBUG(1, ("Unable to find PAC in ticket from %s, failing to allow access: %s\n",
+                         principal_string,
+                         gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
+               return NT_STATUS_ACCESS_DENIED;
        }
 
        /* references the server_info into the session_info */
index d84f3dedf579d5027a8da662792966a09d81dac0..66d280152012c5afd102b5151f102447e5b07b46 100644 (file)
@@ -527,6 +527,7 @@ static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security
        struct PAC_LOGON_INFO *logon_info;
 
        krb5_principal client_principal;
+       char *principal_string;
        
        DATA_BLOB pac;
        krb5_data pac_data;
@@ -538,30 +539,63 @@ static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security
                return NT_STATUS_NO_MEMORY;
        }
        
+       ret = krb5_ticket_get_client(context, gensec_krb5_state->ticket, &client_principal);
+       if (ret) {
+               DEBUG(5, ("krb5_ticket_get_client failed to get cleint principal: %s\n", 
+                         smb_get_krb5_error_message(context, 
+                                                    ret, mem_ctx)));
+               talloc_free(mem_ctx);
+               return NT_STATUS_NO_MEMORY;
+       }
+       
+       ret = krb5_unparse_name(gensec_krb5_state->smb_krb5_context->krb5_context, 
+                               client_principal, &principal_string);
+       if (ret) {
+               DEBUG(1, ("Unable to parse client principal: %s\n",
+                         smb_get_krb5_error_message(context, 
+                                                    ret, mem_ctx)));
+               talloc_free(mem_ctx);
+               return NT_STATUS_NO_MEMORY;
+       }
+
        ret = krb5_ticket_get_authorization_data_type(context, gensec_krb5_state->ticket, 
                                                      KRB5_AUTHDATA_WIN2K_PAC, 
                                                      &pac_data);
        
-       if (ret) {
+       if (ret && lp_parm_bool(-1, "gensec", "require_pac", False)) {
+               DEBUG(1, ("Unable to find PAC in ticket from %s, failing to allow access: %s \n",
+                         principal_string,
+                         smb_get_krb5_error_message(context, 
+                                                    ret, mem_ctx)));
+               krb5_free_principal(context, client_principal);
+               free(principal_string);
+               return NT_STATUS_ACCESS_DENIED;
+       } else if (ret) {
+               /* NO pac */
                DEBUG(5, ("krb5_ticket_get_authorization_data_type failed to find PAC: %s\n", 
                          smb_get_krb5_error_message(context, 
                                                     ret, mem_ctx)));
+               nt_status = sam_get_server_info_principal(mem_ctx, principal_string,
+                                                         &server_info);
+               krb5_free_principal(context, client_principal);
+               free(principal_string);
+               
+               if (!NT_STATUS_IS_OK(nt_status)) {
+                       talloc_free(mem_ctx);
+                       return nt_status;
+               }
        } else {
+               /* Found pac */
+               union netr_Validation validation;
+               free(principal_string);
+
                pac = data_blob_talloc(mem_ctx, pac_data.data, pac_data.length);
                if (!pac.data) {
+                       krb5_free_principal(context, client_principal);
                        talloc_free(mem_ctx);
                        return NT_STATUS_NO_MEMORY;
                }
 
-               ret = krb5_ticket_get_client(context, gensec_krb5_state->ticket, &client_principal);
-               if (ret) {
-                       DEBUG(5, ("krb5_ticket_get_client failed to get cleint principal: %s\n", 
-                                 smb_get_krb5_error_message(context, 
-                                                            ret, mem_ctx)));
-                       talloc_free(mem_ctx);
-                       return NT_STATUS_NO_MEMORY;
-               }
-               
                /* decode and verify the pac */
                nt_status = kerberos_pac_logon_info(gensec_krb5_state, &logon_info, pac,
                                                    gensec_krb5_state->smb_krb5_context->krb5_context,
@@ -570,46 +604,16 @@ static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security
                                                    gensec_krb5_state->ticket->ticket.authtime, NULL);
                krb5_free_principal(context, client_principal);
 
-               if (NT_STATUS_IS_OK(nt_status)) {
-                       union netr_Validation validation;
-                       validation.sam3 = &logon_info->info3;
-                       nt_status = make_server_info_netlogon_validation(mem_ctx, 
-                                                                        NULL,
-                                                                        3, &validation,
-                                                                        &server_info); 
-               }
-       }
-
-               
-               
-       /* IF we have the PAC - otherwise we need to get this
-        * data from elsewere - local ldb, or (TODO) lookup of some
-        * kind... 
-        */
-       if (!NT_STATUS_IS_OK(nt_status)) {
-               /* NO pac, or can't parse or verify it */
-               char *principal_string;
-               ret = krb5_ticket_get_client(context, gensec_krb5_state->ticket, &client_principal);
-               if (ret) {
-                       DEBUG(5, ("krb5_ticket_get_client failed to get cleint principal: %s\n", 
-                                 smb_get_krb5_error_message(context, 
-                                                            ret, mem_ctx)));
-                       talloc_free(mem_ctx);
-                       return NT_STATUS_NO_MEMORY;
-               }
-               
-               ret = krb5_unparse_name(gensec_krb5_state->smb_krb5_context->krb5_context, 
-                                       client_principal, &principal_string);
-               krb5_free_principal(context, client_principal);
-               if (ret) {
+               if (!NT_STATUS_IS_OK(nt_status)) {
                        talloc_free(mem_ctx);
-                       return NT_STATUS_NO_MEMORY;
+                       return nt_status;
                }
 
-               nt_status = sam_get_server_info_principal(mem_ctx, principal_string,
-                                                         &server_info);
-               free(principal_string);
-               
+               validation.sam3 = &logon_info->info3;
+               nt_status = make_server_info_netlogon_validation(mem_ctx, 
+                                                                NULL,
+                                                                3, &validation,
+                                                                &server_info); 
                if (!NT_STATUS_IS_OK(nt_status)) {
                        talloc_free(mem_ctx);
                        return nt_status;
index 06f0c186a37925a5b68399b1ccd78530bee6b876..2b4c5d4cb0e9958b0b6c0653304f95830baa85c0 100644 (file)
@@ -45,6 +45,8 @@
 
        krb5_get_init_creds_opt_init(&options);
 
+       krb5_get_init_creds_opt_set_default_flags(ctx, NULL, NULL, &options);
+
        if ((code = krb5_get_init_creds_keyblock(ctx, &my_creds, principal, keyblock,
                                                 0, NULL, &options))) {
                return code;
@@ -87,6 +89,8 @@
 
        krb5_get_init_creds_opt_init(&options);
 
+       krb5_get_init_creds_opt_set_default_flags(ctx, NULL, NULL, &options);
+
        if ((code = krb5_get_init_creds_password(ctx, &my_creds, principal, password, 
                                                 NULL, 
                                                 NULL, 0, NULL, &options))) {
index dcfe16c8965d38fe5457be451fa494c6c26b6959..8e1801f745c1ec648fb8531da7f81206ae9f34a4 100644 (file)
@@ -280,7 +280,8 @@ static krb5_error_code check_pac_checksum(TALLOC_CTX *mem_ctx,
                return NT_STATUS_ACCESS_DENIED;
        }
 
-       ret = krb5_parse_name_norealm(context, logon_name->account_name, &client_principal_pac);
+       ret = krb5_parse_name_flags(context, logon_name->account_name, KRB5_PRINCIPAL_PARSE_NO_REALM, 
+                                   &client_principal_pac);
        if (ret) {
                DEBUG(2, ("Could not parse name from incoming PAC: [%s]: %s\n", 
                          logon_name->account_name, 
@@ -591,7 +592,8 @@ static krb5_error_code make_pac_checksum(TALLOC_CTX *mem_ctx,
        u_LOGON_INFO->logon_info.info           = LOGON_INFO;
        LOGON_INFO->info3 = *sam3;
 
-       ret = krb5_unparse_name_norealm(context, client_principal, &name);
+       ret = krb5_unparse_name_flags(context, client_principal, 
+                                     KRB5_PRINCIPAL_UNPARSE_NO_REALM, &name);
        if (ret) {
                return ret;
        }
index d895d7a3369767a4773401353298de4a041111d8..a3ef895b162ff4c486f3559d2ac3346f6e11a5f2 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "includes.h"
 #include "system/kerberos.h"
+#include "heimdal/lib/krb5/krb5_locl.h"
 #include "auth/kerberos/kerberos.h"
 #include "lib/socket/socket.h"
 #include "system/network.h"
@@ -69,7 +70,7 @@ static void smb_krb5_debug_close(void *private) {
 
 static void smb_krb5_debug_wrapper(const char *timestr, const char *msg, void *private) 
 {
-       DEBUG(3, ("Kerberos: %s\n", msg));
+       DEBUG(2, ("Kerberos: %s\n", msg));
 }
 
 /*
@@ -224,11 +225,11 @@ static void smb_krb5_socket_handler(struct event_context *ev, struct fd_event *f
 }
 
 
-static krb5_error_code smb_krb5_send_and_recv_func(krb5_context context,
-                                                  void *data,
-                                                  krb5_krbhst_info *hi,
-                                                  const krb5_data *send_buf,
-                                                  krb5_data *recv_buf)
+krb5_error_code smb_krb5_send_and_recv_func(krb5_context context,
+                                           void *data,
+                                           krb5_krbhst_info *hi,
+                                           const krb5_data *send_buf,
+                                           krb5_data *recv_buf)
 {
        krb5_error_code ret;
        NTSTATUS status;
@@ -363,13 +364,6 @@ static krb5_error_code smb_krb5_send_and_recv_func(krb5_context context,
        return KRB5_KDC_UNREACH;
 }
 
-/* NO internal data, so nothing to free */
-static void smb_krb5_send_and_recv_close_func(krb5_context context, void *data) 
-{
-       return;
-}
-
-
 krb5_error_code smb_krb5_init_context(void *parent_ctx, 
                                       struct smb_krb5_context **smb_krb5_context) 
 {
@@ -437,9 +431,9 @@ krb5_error_code smb_krb5_init_context(void *parent_ctx,
 
        ev = event_context_find(*smb_krb5_context);
        /* Set use of our socket lib */
-       ret = krb5_set_send_recv_func((*smb_krb5_context)->krb5_context, 
-                                     smb_krb5_send_and_recv_func, 
-                                     smb_krb5_send_and_recv_close_func, ev);
+       ret = krb5_set_send_to_kdc_func((*smb_krb5_context)->krb5_context, 
+                                       smb_krb5_send_and_recv_func, 
+                                       ev);
        if (ret) {
                DEBUG(1,("krb5_set_send_recv_func failed (%s)\n", 
                         smb_get_krb5_error_message((*smb_krb5_context)->krb5_context, ret, tmp_ctx)));
@@ -454,12 +448,8 @@ krb5_error_code smb_krb5_init_context(void *parent_ctx,
 
        /* Set options in kerberos */
 
-       (*smb_krb5_context)->krb5_context->fdns = FALSE;
+       krb5_set_dns_canonicalize_hostname((*smb_krb5_context)->krb5_context, FALSE);
 
        return 0;
 }
 
- void smb_krb5_free_context(struct smb_krb5_context *smb_krb5_context) 
-{
-       talloc_free(smb_krb5_context);
-}
index f3ffc067faa9bf4b521d1ce160dc11a72bc85c09..7aad97e2ca58c9885f4222eb4b6048ac3eeef24c 100644 (file)
@@ -27,3 +27,8 @@ krb5_error_code smb_krb5_init_context(void *parent_ctx,
                                      struct smb_krb5_context **smb_krb5_context); 
 void smb_krb5_free_context(struct smb_krb5_context *smb_krb5_context);
 
+krb5_error_code smb_krb5_send_and_recv_func(krb5_context context,
+                                           void *data,
+                                           krb5_krbhst_info *hi,
+                                           const krb5_data *send_buf,
+                                           krb5_data *recv_buf);
index f92cf949b145e2538c2553f4daa94099bf426f15..eb051a0fb2deb56b290ff813bc37a7ff3569d427 100644 (file)
@@ -154,8 +154,8 @@ static WERROR DsCrackNameSPNAlias(struct ldb_context *sam_ctx, TALLOC_CTX *mem_c
        enum drsuapi_DsNameStatus namestatus;
        
        /* parse principal */
-       ret = krb5_parse_name_norealm(smb_krb5_context->krb5_context, 
-                                     name, &principal);
+       ret = krb5_parse_name_flags(smb_krb5_context->krb5_context, 
+                                   name, KRB5_PRINCIPAL_PARSE_NO_REALM, &principal);
        if (ret) {
                DEBUG(2, ("Could not parse principal: %s: %s",
                          name, smb_get_krb5_error_message(smb_krb5_context->krb5_context, 
@@ -196,7 +196,8 @@ static WERROR DsCrackNameSPNAlias(struct ldb_context *sam_ctx, TALLOC_CTX *mem_c
        }
        
        /* reform principal */
-       ret = krb5_unparse_name_norealm(smb_krb5_context->krb5_context, principal, &new_princ);
+       ret = krb5_unparse_name_flags(smb_krb5_context->krb5_context, principal, 
+                                     KRB5_PRINCIPAL_UNPARSE_NO_REALM, &new_princ);
 
        krb5_free_principal(smb_krb5_context->krb5_context, principal);
        
@@ -231,7 +232,8 @@ static WERROR DsCrackNameUPN(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx,
                return WERR_OK;
        }
 
-       ret = krb5_parse_name_mustrealm(smb_krb5_context->krb5_context, name, &principal);
+       ret = krb5_parse_name_flags(smb_krb5_context->krb5_context, name, 
+                                   KRB5_PRINCIPAL_PARSE_MUST_REALM, &principal);
        if (ret) {
                info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND;
                return WERR_OK;
@@ -243,7 +245,8 @@ static WERROR DsCrackNameUPN(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx,
                                        "(&(&(|(&(dnsRoot=%s)(nETBIOSName=*))(nETBIOSName=%s))(objectclass=crossRef))(ncName=*))",
                                        ldb_binary_encode_string(mem_ctx, *realm), 
                                        ldb_binary_encode_string(mem_ctx, *realm));
-       ret = krb5_unparse_name_norealm(smb_krb5_context->krb5_context, principal, &unparsed_name_short);
+       ret = krb5_unparse_name_flags(smb_krb5_context->krb5_context, principal, 
+                                     KRB5_PRINCIPAL_UNPARSE_NO_REALM, &unparsed_name_short);
        krb5_free_principal(smb_krb5_context->krb5_context, principal);
                
        if (ret) {
@@ -445,11 +448,13 @@ WERROR DsCrackNameOneName(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx,
                krb5_principal principal;
                char *unparsed_name_short;
                char *service;
-               ret = krb5_parse_name_norealm(smb_krb5_context->krb5_context, name, &principal);
+               ret = krb5_parse_name_flags(smb_krb5_context->krb5_context, name, 
+                                           KRB5_PRINCIPAL_PARSE_NO_REALM, &principal);
                if (ret) {
                        /* perhaps it's a principal with a realm, so return the right 'domain only' response */
                        char **realm;
-                       ret = krb5_parse_name_mustrealm(smb_krb5_context->krb5_context, name, &principal);
+                       ret = krb5_parse_name_flags(smb_krb5_context->krb5_context, name, 
+                                                   KRB5_PRINCIPAL_PARSE_MUST_REALM, &principal);
                        if (ret) {
                                info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND;
                                return WERR_OK;
@@ -473,7 +478,8 @@ WERROR DsCrackNameOneName(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx,
 
                domain_filter = NULL;
                
-               ret = krb5_unparse_name_norealm(smb_krb5_context->krb5_context, principal, &unparsed_name_short);
+               ret = krb5_unparse_name_flags(smb_krb5_context->krb5_context, principal, 
+                                             KRB5_PRINCIPAL_UNPARSE_NO_REALM, &unparsed_name_short);
                if (ret) {
                        krb5_free_principal(smb_krb5_context->krb5_context, principal);
                        return WERR_NOMEM;
index d61b78d9b6c592416388457319f685330afc048b..56c12efd6003641f06548da559169c27673e0cc6 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "kdc_locl.h"
 
-RCSID("$Id: 524.c,v 1.37 2006/04/27 11:33:20 lha Exp $");
+RCSID("$Id: 524.c,v 1.40 2006/10/06 17:06:30 lha Exp $");
 
 #include <krb5-v4compat.h>
 
@@ -53,7 +53,8 @@ fetch_server (krb5_context context,
     krb5_error_code ret;
     krb5_principal sprinc;
 
-    ret = _krb5_principalname2krb5_principal(context, &sprinc, t->sname, t->realm);
+    ret = _krb5_principalname2krb5_principal(context, &sprinc,
+                                            t->sname, t->realm);
     if (ret) {
        kdc_log(context, config, 0, "_krb5_principalname2krb5_principal: %s",
                krb5_get_err_text(context, ret));
@@ -66,7 +67,8 @@ fetch_server (krb5_context context,
                krb5_get_err_text(context, ret));
        return ret;
     }
-    ret = _kdc_db_fetch(context, config, sprinc, HDB_F_GET_SERVER, server);
+    ret = _kdc_db_fetch(context, config, sprinc, HDB_F_GET_SERVER, 
+                       NULL, server);
     krb5_free_principal(context, sprinc);
     if (ret) {
        kdc_log(context, config, 0,
@@ -90,7 +92,8 @@ log_524 (krb5_context context,
     char *cpn;
     krb5_error_code ret;
 
-    ret = _krb5_principalname2krb5_principal(context, &client, et->cname, et->crealm);
+    ret = _krb5_principalname2krb5_principal(context, &client, 
+                                            et->cname, et->crealm);
     if (ret) {
        kdc_log(context, config, 0, "_krb5_principalname2krb5_principal: %s",
                krb5_get_err_text (context, ret));
index 5152fe9ab1c026c8ad7a42592a79a279d46cec5f..c4d9f51fd0b2b690ea919a65eb99cabc36ba8a9a 100644 (file)
@@ -42,8 +42,9 @@
 void
 krb5_kdc_default_config(krb5_kdc_configuration *config)
 {
+    memset(config, 0, sizeof(*config));
     config->require_preauth = TRUE;
-    config->kdc_warn_pwexpire = -1;
+    config->kdc_warn_pwexpire = 0;
     config->encode_as_rep_as_tgs_rep = FALSE; /* bug compatibility */
     config->check_ticket_addresses = TRUE;
     config->allow_null_ticket_addresses = TRUE;
diff --git a/source4/heimdal/kdc/digest.c b/source4/heimdal/kdc/digest.c
new file mode 100644 (file)
index 0000000..a5517fb
--- /dev/null
@@ -0,0 +1,712 @@
+/*
+ * 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 "kdc_locl.h"
+#include <digest_asn1.h>
+#include <hex.h>
+
+RCSID("$Id: digest.c,v 1.7 2006/10/22 20:11:44 lha Exp $");
+
+krb5_error_code
+_kdc_do_digest(krb5_context context, 
+              krb5_kdc_configuration *config,
+              const DigestREQ *req, krb5_data *reply,
+              const char *from, struct sockaddr *addr)
+{
+    krb5_error_code ret = 0;
+    krb5_ticket *ticket = NULL;
+    krb5_auth_context ac = NULL;
+    krb5_keytab id = NULL;
+    krb5_crypto crypto = NULL;
+    DigestReqInner ireq;
+    DigestRepInner r;
+    DigestREP rep;
+    krb5_flags ap_req_options;
+    krb5_data buf;
+    size_t size;
+    krb5_storage *sp = NULL;
+    Checksum res;
+    hdb_entry_ex *server = NULL, *user = NULL;
+    char *password = NULL;
+    krb5_data serverNonce;
+
+    if(!config->enable_digest) {
+       kdc_log(context, config, 0, "Rejected digest request from %s", from);
+       return KRB5KDC_ERR_POLICY;
+    }
+
+    krb5_data_zero(&buf);
+    krb5_data_zero(reply);
+    krb5_data_zero(&serverNonce);
+    memset(&ireq, 0, sizeof(ireq));
+    memset(&r, 0, sizeof(r));
+    memset(&rep, 0, sizeof(rep));
+
+    kdc_log(context, config, 0, "Digest request from %s", from);
+
+    ret = krb5_kt_resolve(context, "HDB:", &id);
+    if (ret) {
+       kdc_log(context, config, 0, "Can't open database for digest");
+       goto out;
+    }
+
+    ret = krb5_rd_req(context, 
+                     &ac,
+                     &req->apReq,
+                     NULL,
+                     id,
+                     &ap_req_options,
+                     &ticket);
+    if (ret)
+       goto out;
+
+    /* check the server principal in the ticket matches digest/R@R */
+    {
+       krb5_principal principal = NULL;
+       const char *p, *r;
+
+       ret = krb5_ticket_get_server(context, ticket, &principal);
+       if (ret)
+           goto out;
+
+       ret = EINVAL;
+       krb5_set_error_string(context, "Wrong digest server principal used");
+       p = krb5_principal_get_comp_string(context, principal, 0);
+       if (p == NULL) {
+           krb5_free_principal(context, principal);
+           goto out;
+       }
+       if (strcmp(p, KRB5_DIGEST_NAME) != 0) {
+           krb5_free_principal(context, principal);
+           goto out;
+       }
+
+       p = krb5_principal_get_comp_string(context, principal, 1);
+       if (p == NULL) {
+           krb5_free_principal(context, principal);
+           goto out;
+       }
+       r = krb5_principal_get_realm(context, principal);
+       if (r == NULL) {
+           krb5_free_principal(context, principal);
+           goto out;
+       }
+       if (strcmp(p, r) != 0) {
+           krb5_free_principal(context, principal);
+           goto out;
+       }
+
+       ret = _kdc_db_fetch(context, config, principal,
+                           HDB_F_GET_SERVER, NULL, &server);
+       if (ret)
+           goto out;
+
+       krb5_free_principal(context, principal);
+    }
+
+    /* check the client is allowed to do digest auth */
+    {
+       krb5_principal principal = NULL;
+       hdb_entry_ex *client;
+
+       ret = krb5_ticket_get_client(context, ticket, &principal);
+       if (ret)
+           goto out;
+
+       ret = _kdc_db_fetch(context, config, principal,
+                           HDB_F_GET_CLIENT, NULL, &client);
+       krb5_free_principal(context, principal);
+       if (ret)
+           goto out;
+
+       if (client->entry.flags.allow_digest == 0) {
+           krb5_set_error_string(context, 
+                                 "Client is not permitted to use digest");
+           ret = KRB5KDC_ERR_POLICY;
+           _kdc_free_ent (context, client);
+           goto out;
+       }
+       _kdc_free_ent (context, client);
+    }
+
+    /* unpack request */
+    {
+       krb5_keyblock *key;
+
+       ret = krb5_auth_con_getremotesubkey(context, ac, &key);
+       if (ret)
+           goto out;
+       if (key == NULL) {
+           krb5_set_error_string(context, "digest: remote subkey not found");
+           ret = EINVAL;
+           goto out;
+       }
+
+       ret = krb5_crypto_init(context, key, 0, &crypto);
+       krb5_free_keyblock (context, key);
+       if (ret)
+           goto out;
+    }
+
+    ret = krb5_decrypt_EncryptedData(context, crypto, KRB5_KU_DIGEST_ENCRYPT,
+                                    &req->innerReq, &buf);
+    krb5_crypto_destroy(context, crypto);
+    crypto = NULL;
+    if (ret)
+       goto out;
+          
+    ret = decode_DigestReqInner(buf.data, buf.length, &ireq, NULL);
+    krb5_data_free(&buf);
+    if (ret) {
+       krb5_set_error_string(context, "Failed to decode digest inner request");
+       goto out;
+    }
+
+    /*
+     * Process the inner request
+     */
+
+    switch (ireq.element) {
+    case choice_DigestReqInner_init: {
+       unsigned char server_nonce[16], identifier;
+
+       RAND_pseudo_bytes(&identifier, sizeof(identifier));
+       RAND_pseudo_bytes(server_nonce, sizeof(server_nonce));
+
+       server_nonce[0] = kdc_time & 0xff;
+       server_nonce[1] = (kdc_time >> 8) & 0xff;
+       server_nonce[2] = (kdc_time >> 16) & 0xff;
+       server_nonce[3] = (kdc_time >> 24) & 0xff;
+
+       r.element = choice_DigestRepInner_initReply;
+
+       hex_encode(server_nonce, sizeof(server_nonce), &r.u.initReply.nonce);
+       if (r.u.initReply.nonce == NULL) {
+           krb5_set_error_string(context, "Failed to decode server nonce");
+           ret = ENOMEM;
+           goto out;
+       }
+
+       sp = krb5_storage_emem();
+       if (sp == NULL) {
+           ret = ENOMEM;
+           krb5_set_error_string(context, "out of memory");
+           goto out;
+       }
+       ret = krb5_store_stringz(sp, ireq.u.init.type);
+       if (ret) {
+           krb5_clear_error_string(context);
+           goto out;
+       }
+
+       if (ireq.u.init.channel) {
+           char *s;
+
+           asprintf(&s, "%s-%s:%s", r.u.initReply.nonce,
+                    ireq.u.init.channel->cb_type,
+                    ireq.u.init.channel->cb_binding);
+           if (s == NULL) {
+               krb5_set_error_string(context, "Failed to allocate "
+                                     "channel binding");
+               ret = ENOMEM;
+               goto out;
+           }
+           free(r.u.initReply.nonce);
+           r.u.initReply.nonce = s;
+       }
+       
+       ret = krb5_store_stringz(sp, r.u.initReply.nonce);
+       if (ret) {
+           krb5_clear_error_string(context);
+           goto out;
+       }
+
+       if (strcasecmp(ireq.u.init.type, "CHAP") == 0) {
+           r.u.initReply.identifier = 
+               malloc(sizeof(*r.u.initReply.identifier));
+           if (r.u.initReply.identifier == NULL) {
+               krb5_set_error_string(context, "out of memory");
+               ret = ENOMEM;
+               goto out;
+           }
+
+           asprintf(r.u.initReply.identifier, "%02X", identifier & 0xff);
+           if (*r.u.initReply.identifier == NULL) {
+               krb5_set_error_string(context, "out of memory");
+               ret = ENOMEM;
+               goto out;
+           }
+
+           ret = krb5_store_stringz(sp, *r.u.initReply.identifier);
+           if (ret) {
+               krb5_clear_error_string(context);
+               goto out;
+           }
+       } else
+           r.u.initReply.identifier = NULL;
+
+       if (ireq.u.init.hostname) {
+           ret = krb5_store_stringz(sp, *ireq.u.init.hostname);
+           if (ret) {
+               krb5_clear_error_string(context);
+               goto out;
+           }
+       }
+
+       ret = krb5_storage_to_data(sp, &buf);
+       if (ret) {
+           krb5_clear_error_string(context);
+           goto out;
+       }
+
+       {
+           Key *key;
+           krb5_enctype enctype;
+
+           ret = _kdc_get_preferred_key(context,
+                                        config,
+                                        server,
+                                        "digest-service",
+                                        &enctype,
+                                        &key);
+           if (ret)
+               goto out;
+           ret = krb5_crypto_init(context, &key->key, 0, &crypto);
+           if (ret)
+               goto out;
+       }
+
+       ret = krb5_create_checksum(context,
+                                  crypto,
+                                  KRB5_KU_DIGEST_OPAQUE,
+                                  0,
+                                  buf.data,
+                                  buf.length,
+                                  &res);
+       krb5_crypto_destroy(context, crypto);
+       crypto = NULL;
+       krb5_data_free(&buf);
+       if (ret)
+           goto out;
+       
+       ASN1_MALLOC_ENCODE(Checksum, buf.data, buf.length, &res, &size, ret);
+       free_Checksum(&res);
+       if (ret) {
+           krb5_set_error_string(context, "Failed to encode "
+                                 "checksum in digest request");
+           goto out;
+       }
+       if (size != buf.length)
+           krb5_abortx(context, "ASN1 internal error");
+
+       hex_encode(buf.data, buf.length, &r.u.initReply.opaque);
+       free(buf.data);
+       if (r.u.initReply.opaque == NULL) {
+           krb5_clear_error_string(context);
+           ret = ENOMEM;
+           goto out;
+       }
+
+       break;
+    }
+    case choice_DigestReqInner_digestRequest: {
+       krb5_principal clientprincipal;
+       HDB *db;
+
+       sp = krb5_storage_emem();
+       if (sp == NULL) {
+           ret = ENOMEM;
+           krb5_set_error_string(context, "out of memory");
+           goto out;
+       }
+       krb5_store_stringz(sp, ireq.u.digestRequest.type);
+
+       krb5_store_stringz(sp, ireq.u.digestRequest.serverNonce);
+       if (ireq.u.digestRequest.identifier) {
+           ret = krb5_store_stringz(sp, *ireq.u.digestRequest.identifier);
+           if (ret) {
+               krb5_clear_error_string(context);
+               goto out;
+           }
+       }
+       if (ireq.u.digestRequest.hostname) {
+           ret = krb5_store_stringz(sp, *ireq.u.digestRequest.hostname);
+           if (ret) {
+               krb5_clear_error_string(context);
+               goto out;
+           }
+       }
+
+       buf.length = strlen(ireq.u.digestRequest.opaque);
+       buf.data = malloc(buf.length);
+       if (buf.data == NULL) {
+           krb5_set_error_string(context, "out of memory");
+           ret = ENOMEM;
+           goto out;
+       }
+
+       ret = hex_decode(ireq.u.digestRequest.opaque, buf.data, buf.length);
+       if (ret <= 0) {
+           krb5_set_error_string(context, "Failed to decode opaque");
+           ret = ENOMEM;
+           goto out;
+       }
+       buf.length = ret;
+
+       ret = decode_Checksum(buf.data, buf.length, &res, NULL);
+       free(buf.data);
+       if (ret) {
+           krb5_set_error_string(context, "Failed to decode digest Checksum");
+           goto out;
+       }
+       
+       ret = krb5_storage_to_data(sp, &buf);
+       if (ret) {
+           krb5_clear_error_string(context);
+           goto out;
+       }
+
+       serverNonce.length = strlen(ireq.u.digestRequest.serverNonce);
+       serverNonce.data = malloc(serverNonce.length);
+       if (serverNonce.data == NULL) {
+           krb5_set_error_string(context, "out of memory");
+           ret = ENOMEM;
+           goto out;
+       }
+           
+       /*
+        * CHAP does the checksum of the raw nonce, but do it for all
+        * types, since we need to check the timestamp.
+        */
+       {
+           ssize_t ssize;
+           
+           ssize = hex_decode(ireq.u.digestRequest.serverNonce, 
+                              serverNonce.data, serverNonce.length);
+           if (ssize <= 0) {
+               krb5_set_error_string(context, "Failed to decode serverNonce");
+               ret = ENOMEM;
+               goto out;
+           }
+           serverNonce.length = ssize;
+       }
+
+       {
+           Key *key;
+           krb5_enctype enctype;
+
+           ret = _kdc_get_preferred_key(context,
+                                        config,
+                                        server,
+                                        "digest-service",
+                                        &enctype,
+                                        &key);
+           if (ret)
+               goto out;
+           ret = krb5_crypto_init(context, &key->key, 0, &crypto);
+           if (ret)
+               goto out;
+       }
+
+       ret = krb5_verify_checksum(context, crypto, 
+                                  KRB5_KU_DIGEST_OPAQUE,
+                                  buf.data, buf.length, &res);
+       krb5_crypto_destroy(context, crypto);
+       crypto = NULL;
+       if (ret)
+           goto out;
+
+       /* verify time */
+       {
+           unsigned char *p = serverNonce.data;
+           uint32_t t;
+           
+           if (serverNonce.length < 4) {
+               krb5_set_error_string(context, "server nonce too short");
+               ret = EINVAL;
+               goto out;
+           }
+           t = p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
+
+           if (abs((kdc_time & 0xffffffff) - t) > context->max_skew) {
+               krb5_set_error_string(context, "time screw in server nonce ");
+               ret = EINVAL;
+               goto out;
+           }
+       }
+
+       /* get username */
+       ret = krb5_parse_name(context,
+                             ireq.u.digestRequest.username,
+                             &clientprincipal);
+       if (ret)
+           goto out;
+
+       ret = _kdc_db_fetch(context, config, clientprincipal,
+                           HDB_F_GET_CLIENT, &db, &user);
+
+       krb5_free_principal(context, clientprincipal);
+       if (ret)
+           goto out;
+
+       ret = hdb_entry_get_password(context, db, &user->entry, &password);
+       if (ret || password == NULL) {
+           if (ret == 0) {
+               ret = EINVAL;
+               krb5_set_error_string(context, "password missing");
+           }
+           goto out;
+       }
+
+       if (strcasecmp(ireq.u.digestRequest.type, "CHAP") == 0) {
+           MD5_CTX ctx;
+           unsigned char md[MD5_DIGEST_LENGTH];
+           char id;
+
+           if (ireq.u.digestRequest.identifier == NULL) {
+               krb5_set_error_string(context, "Identifier missing "
+                                     "from CHAP request");
+               ret = EINVAL;
+               goto out;
+           }
+           
+           if (hex_decode(*ireq.u.digestRequest.identifier, &id, 1) != 1) {
+               krb5_set_error_string(context, "failed to decode identifier");
+               ret = EINVAL;
+               goto out;
+           }
+           
+           MD5_Init(&ctx);
+           MD5_Update(&ctx, &id, 1);
+           MD5_Update(&ctx, password, strlen(password));
+           MD5_Update(&ctx, serverNonce.data, serverNonce.length);
+           MD5_Final(md, &ctx);
+
+           r.element = choice_DigestRepInner_response;
+           hex_encode(md, sizeof(md), &r.u.response.responseData);
+           if (r.u.response.responseData == NULL) {
+               krb5_clear_error_string(context);
+               ret = ENOMEM;
+               goto out;
+           }
+       } else if (strcasecmp(ireq.u.digestRequest.type, "SASL-DIGEST-MD5") == 0) {
+           MD5_CTX ctx;
+           unsigned char md[MD5_DIGEST_LENGTH];
+           char *A1, *A2;
+
+           if (ireq.u.digestRequest.nonceCount == NULL) 
+               goto out;
+           if (ireq.u.digestRequest.clientNonce == NULL) 
+               goto out;
+           if (ireq.u.digestRequest.qop == NULL) 
+               goto out;
+           if (ireq.u.digestRequest.realm == NULL) 
+               goto out;
+           
+           MD5_Init(&ctx);
+           MD5_Update(&ctx, ireq.u.digestRequest.username,
+                      strlen(ireq.u.digestRequest.username));
+           MD5_Update(&ctx, ":", 1);
+           MD5_Update(&ctx, *ireq.u.digestRequest.realm,
+                      strlen(*ireq.u.digestRequest.realm));
+           MD5_Update(&ctx, ":", 1);
+           MD5_Update(&ctx, password, strlen(password));
+           MD5_Final(md, &ctx);
+           
+           MD5_Init(&ctx);
+           MD5_Update(&ctx, md, sizeof(md));
+           MD5_Update(&ctx, ":", 1);
+           MD5_Update(&ctx, ireq.u.digestRequest.serverNonce,
+                      strlen(ireq.u.digestRequest.serverNonce));
+           MD5_Update(&ctx, ":", 1);
+           MD5_Update(&ctx, *ireq.u.digestRequest.nonceCount,
+                      strlen(*ireq.u.digestRequest.nonceCount));
+           if (ireq.u.digestRequest.authid) {
+               MD5_Update(&ctx, ":", 1);
+               MD5_Update(&ctx, *ireq.u.digestRequest.authid,
+                          strlen(*ireq.u.digestRequest.authid));
+           }
+           MD5_Final(md, &ctx);
+           hex_encode(md, sizeof(md), &A1);
+           if (A1 == NULL) {
+               krb5_set_error_string(context, "out of memory");
+               ret = ENOMEM;
+               goto out;
+           }
+           
+           MD5_Init(&ctx);
+           MD5_Update(&ctx, "AUTHENTICATE:", sizeof("AUTHENTICATE:") - 1);
+           MD5_Update(&ctx, *ireq.u.digestRequest.uri,
+                      strlen(*ireq.u.digestRequest.uri));
+       
+           /* conf|int */
+           if (strcmp(ireq.u.digestRequest.digest, "clear") != 0) {
+               static char conf_zeros[] = ":00000000000000000000000000000000";
+               MD5_Update(&ctx, conf_zeros, sizeof(conf_zeros) - 1);
+           }
+           
+           MD5_Final(md, &ctx);
+           hex_encode(md, sizeof(md), &A2);
+           if (A2 == NULL) {
+               krb5_set_error_string(context, "out of memory");
+               ret = ENOMEM;
+               free(A1);
+               goto out;
+           }
+
+           MD5_Init(&ctx);
+           MD5_Update(&ctx, A1, strlen(A2));
+           MD5_Update(&ctx, ":", 1);
+           MD5_Update(&ctx, ireq.u.digestRequest.serverNonce,
+                      strlen(ireq.u.digestRequest.serverNonce));
+           MD5_Update(&ctx, ":", 1);
+           MD5_Update(&ctx, *ireq.u.digestRequest.nonceCount,
+                      strlen(*ireq.u.digestRequest.nonceCount));
+           MD5_Update(&ctx, ":", 1);
+           MD5_Update(&ctx, *ireq.u.digestRequest.clientNonce,
+                      strlen(*ireq.u.digestRequest.clientNonce));
+           MD5_Update(&ctx, ":", 1);
+           MD5_Update(&ctx, *ireq.u.digestRequest.qop,
+                      strlen(*ireq.u.digestRequest.qop));
+           MD5_Update(&ctx, ":", 1);
+           MD5_Update(&ctx, A2, strlen(A2));
+
+           MD5_Final(md, &ctx);
+
+           r.element = choice_DigestRepInner_response;
+           hex_encode(md, sizeof(md), &r.u.response.responseData);
+
+           free(A1);
+           free(A2);
+
+           if (r.u.response.responseData == NULL) {
+               krb5_set_error_string(context, "out of memory");
+               ret = ENOMEM;
+               goto out;
+           }
+
+       } else {
+           r.element = choice_DigestRepInner_error;
+           asprintf(&r.u.error.reason, "unsupported digest type %s", 
+                    ireq.u.digestRequest.type);
+           if (r.u.error.reason == NULL) {
+               krb5_set_error_string(context, "out of memory");
+               ret = ENOMEM;
+               goto out;
+           }
+           r.u.error.code = EINVAL;
+       }
+
+       break;
+    }
+    default:
+       r.element = choice_DigestRepInner_error;
+       r.u.error.reason = strdup("unknown operation");
+       if (r.u.error.reason == NULL) {
+           krb5_set_error_string(context, "out of memory");
+           ret = ENOMEM;
+           goto out;
+       }
+       r.u.error.code = EINVAL;
+       break;
+    }
+
+    ASN1_MALLOC_ENCODE(DigestRepInner, buf.data, buf.length, &r, &size, ret);
+    if (ret) {
+       krb5_set_error_string(context, "Failed to encode inner digest reply");
+       goto out;
+    }
+    if (size != buf.length)
+       krb5_abortx(context, "ASN1 internal error");
+
+    krb5_auth_con_addflags(context, ac, KRB5_AUTH_CONTEXT_USE_SUBKEY, NULL);
+
+    ret = krb5_mk_rep (context, ac, &rep.apRep);
+    if (ret)
+       goto out;
+
+    {
+       krb5_keyblock *key;
+
+       ret = krb5_auth_con_getlocalsubkey(context, ac, &key);
+       if (ret)
+           goto out;
+
+       ret = krb5_crypto_init(context, key, 0, &crypto);
+       krb5_free_keyblock (context, key);
+       if (ret)
+           goto out;
+    }
+
+    ret = krb5_encrypt_EncryptedData(context, crypto, KRB5_KU_DIGEST_ENCRYPT, 
+                                    buf.data, buf.length, 0,
+                                    &rep.innerRep);
+    
+    ASN1_MALLOC_ENCODE(DigestREP, reply->data, reply->length, &rep, &size, ret);
+    if (ret) {
+       krb5_set_error_string(context, "Failed to encode digest reply");
+       goto out;
+    }
+    if (size != reply->length)
+       krb5_abortx(context, "ASN1 internal error");
+
+    
+out:
+    if (ac)
+       krb5_auth_con_free(context, ac);
+    if (ret)
+       krb5_warn(context, ret, "Digest request from %s failed", from);
+    if (ticket)
+       krb5_free_ticket(context, ticket);
+    if (id)
+       krb5_kt_close(context, id);
+    if (crypto)
+       krb5_crypto_destroy(context, crypto);
+    if (sp)
+       krb5_storage_free(sp);
+    if (user)
+       _kdc_free_ent (context, user);
+    if (server)
+       _kdc_free_ent (context, server);
+    if (password) {
+       memset(password, 0, strlen(password));
+       free (password);
+    }
+    krb5_data_free(&buf);
+    krb5_data_free(&serverNonce);
+    free_DigestREP(&rep);
+    free_DigestRepInner(&r);
+    free_DigestReqInner(&ireq);
+
+    return ret;
+}
index 86f162aa94b2b8204fd8644100d340b9346417e6..87d713b076f0c0a18a8374a1f84bc0381659f130 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2006 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
  * All rights reserved. 
  *
@@ -32,7 +32,7 @@
  */
 
 /* 
- * $Id: headers.h,v 1.16 2005/04/24 13:49:00 lha Exp $ 
+ * $Id: headers.h,v 1.18 2006/10/17 02:22:17 lha Exp $ 
  */
 
 #ifndef __HEADERS_H__
 #include <parse_units.h>
 #include <krb5.h>
 #include <krb5_locl.h>
+#include <digest_asn1.h>
 #include <hdb.h>
 #include <hdb_err.h>
-#include <der.h> /* copy_octet_string */
+#include <der.h>
 
 #undef ALLOC
 #define ALLOC(X) ((X) = malloc(sizeof(*(X))))
index c08a51b9cc4073cbbb8ce7e8cf056738d91fe76a..ac282717ed0c3988e0da5010abb9a6a2ffb4b884 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "kdc_locl.h"
 
-RCSID("$Id: kaserver.c,v 1.35 2006/05/05 10:49:50 lha Exp $");
+RCSID("$Id: kaserver.c,v 1.36 2006/08/23 11:43:44 lha Exp $");
 
 #include <krb5-v4compat.h>
 #include <rx.h>
@@ -465,7 +465,8 @@ do_authenticate (krb5_context context,
            client_name, from, server_name);
 
     ret = _kdc_db_fetch4 (context, config, name, instance, 
-                         config->v4_realm, HDB_F_GET_CLIENT, &client_entry);
+                         config->v4_realm, HDB_F_GET_CLIENT,
+                         &client_entry);
     if (ret) {
        kdc_log(context, config, 0, "Client not found in database: %s: %s",
                client_name, krb5_get_err_text(context, ret));
index 251e06b14aa6a39cd947da647bb53ecefd4f5544..8c2f56002d042ba4dc4c684295c4b9f5a388a4fa 100644 (file)
@@ -4,6 +4,16 @@
 
 #include <stdarg.h>
 
+krb5_error_code
+_kdc_add_KRB5SignedPath (
+       krb5_context /*context*/,
+       krb5_kdc_configuration */*config*/,
+       hdb_entry_ex */*krbtgt*/,
+       krb5_enctype /*enctype*/,
+       krb5_const_principal /*server*/,
+       KRB5SignedPathPrincipals */*principals*/,
+       EncTicketPart */*tkt*/);
+
 krb5_error_code
 _kdc_as_rep (
        krb5_context /*context*/,
@@ -12,7 +22,15 @@ _kdc_as_rep (
        const krb5_data */*req_buffer*/,
        krb5_data */*reply*/,
        const char */*from*/,
-       struct sockaddr */*from_addr*/);
+       struct sockaddr */*from_addr*/,
+       int /*datagram_reply*/);
+
+krb5_boolean
+_kdc_check_addresses (
+       krb5_context /*context*/,
+       krb5_kdc_configuration */*config*/,
+       HostAddresses */*addresses*/,
+       const struct sockaddr */*from*/);
 
 krb5_error_code
 _kdc_check_flags (
@@ -30,6 +48,7 @@ _kdc_db_fetch (
        krb5_kdc_configuration */*config*/,
        krb5_const_principal /*principal*/,
        unsigned /*flags*/,
+       HDB **/*db*/,
        hdb_entry_ex **/*h*/);
 
 krb5_error_code
@@ -51,6 +70,15 @@ _kdc_do_524 (
        const char */*from*/,
        struct sockaddr */*addr*/);
 
+krb5_error_code
+_kdc_do_digest (
+       krb5_context /*context*/,
+       krb5_kdc_configuration */*config*/,
+       const DigestREQ */*req*/,
+       krb5_data */*reply*/,
+       const char */*from*/,
+       struct sockaddr */*addr*/);
+
 krb5_error_code
 _kdc_do_kaserver (
        krb5_context /*context*/,
@@ -71,6 +99,21 @@ _kdc_do_version4 (
        const char */*from*/,
        struct sockaddr_in */*addr*/);
 
+krb5_error_code
+_kdc_encode_reply (
+       krb5_context /*context*/,
+       krb5_kdc_configuration */*config*/,
+       KDC_REP */*rep*/,
+       const EncTicketPart */*et*/,
+       EncKDCRepPart */*ek*/,
+       krb5_enctype /*etype*/,
+       int /*skvno*/,
+       const EncryptionKey */*skey*/,
+       int /*ckvno*/,
+       const EncryptionKey */*ckey*/,
+       const char **/*e_text*/,
+       krb5_data */*reply*/);
+
 krb5_error_code
 _kdc_encode_v4_ticket (
        krb5_context /*context*/,
@@ -81,6 +124,24 @@ _kdc_encode_v4_ticket (
        const PrincipalName */*service*/,
        size_t */*size*/);
 
+krb5_error_code
+_kdc_find_etype (
+       krb5_context /*context*/,
+       const hdb_entry_ex */*princ*/,
+       krb5_enctype */*etypes*/,
+       unsigned /*len*/,
+       Key **/*ret_key*/,
+       krb5_enctype */*ret_etype*/);
+
+PA_DATA*
+_kdc_find_padata (
+       KDC_REQ */*req*/,
+       int */*start*/,
+       int /*type*/);
+
+void
+_kdc_fix_time (time_t **/*t*/);
+
 void
 _kdc_free_ent (
        krb5_context /*context*/,
@@ -94,6 +155,28 @@ _kdc_get_des_key (
        krb5_boolean /*prefer_afs_key*/,
        Key **/*ret_key*/);
 
+krb5_error_code
+_kdc_get_preferred_key (
+       krb5_context /*context*/,
+       krb5_kdc_configuration */*config*/,
+       hdb_entry_ex */*h*/,
+       const char */*name*/,
+       krb5_enctype */*enctype*/,
+       Key **/*key*/);
+
+void
+_kdc_log_timestamp (
+       krb5_context /*context*/,
+       krb5_kdc_configuration */*config*/,
+       const char */*type*/,
+       KerberosTime /*authtime*/,
+       KerberosTime */*starttime*/,
+       KerberosTime /*endtime*/,
+       KerberosTime */*renew_till*/);
+
+krb5_error_code
+_kdc_make_anonymous_principalname (PrincipalName */*pn*/);
+
 int
 _kdc_maybe_version4 (
        unsigned char */*buf*/,
@@ -120,7 +203,7 @@ _kdc_pk_initialize (
        const char */*user_id*/,
        const char */*anchors*/,
        char **/*pool*/,
-       char **/*revoke*/);
+       char **/*revoke_list*/);
 
 krb5_error_code
 _kdc_pk_mk_pa_reply (
index 5967f933f39ddeeda04ac317699087274804515c..69bc871b01dd30ebacdd5443edfeb340a6f1d290 100644 (file)
@@ -41,25 +41,27 @@ void
 krb5_kdc_default_config (krb5_kdc_configuration */*config*/);
 
 int
-krb5_kdc_process_generic_request (
+krb5_kdc_process_krb5_request (
        krb5_context /*context*/,
        krb5_kdc_configuration */*config*/,
        unsigned char */*buf*/,
        size_t /*len*/,
        krb5_data */*reply*/,
-       krb5_boolean */*prependlength*/,
        const char */*from*/,
-       struct sockaddr */*addr*/);
+       struct sockaddr */*addr*/,
+       int /*datagram_reply*/);
 
 int
-krb5_kdc_process_krb5_request (
+krb5_kdc_process_request (
        krb5_context /*context*/,
        krb5_kdc_configuration */*config*/,
        unsigned char */*buf*/,
        size_t /*len*/,
        krb5_data */*reply*/,
+       krb5_boolean */*prependlength*/,
        const char */*from*/,
-       struct sockaddr */*addr*/);
+       struct sockaddr */*addr*/,
+       int /*datagram_reply*/);
 
 #ifdef __cplusplus
 }
index 2948570e3a1f2f9906aed45834afbdb9381111bb..043b6de47d2269d96cf10eacbab32904bcb77cf3 100644 (file)
@@ -35,7 +35,7 @@
  */
 
 /* 
- * $Id: kdc.h,v 1.6 2006/05/03 12:03:29 lha Exp $ 
+ * $Id: kdc.h,v 1.9 2006/10/09 15:34:07 lha Exp $ 
  */
 
 #ifndef __KDC_H__
@@ -65,10 +65,12 @@ typedef struct krb5_kdc_configuration {
 
     char *v4_realm;
     krb5_boolean enable_v4;
+    krb5_boolean enable_v4_cross_realm;
+    krb5_boolean enable_v4_per_principal;
+
     krb5_boolean enable_kaserver;
-       
+
     krb5_boolean enable_524;
-    krb5_boolean enable_v4_cross_realm;
 
     krb5_boolean enable_pkinit;
     krb5_boolean enable_pkinit_princ_in_cert;
@@ -78,6 +80,9 @@ typedef struct krb5_kdc_configuration {
 
     int pkinit_dh_min_bits;
 
+    int enable_digest;
+    size_t max_datagram_reply_length;
+
 } krb5_kdc_configuration;
 
 #include <kdc-protos.h>
index d7a3a9cb69ac3c55332e807bf7df5dc0247cde62..97e98d86ad3ae931b7a4da7f56e66e05a4618a3a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2006 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
  * All rights reserved. 
  *
@@ -35,7 +35,7 @@
 
 #include <krb5-v4compat.h>
 
-RCSID("$Id: kerberos4.c,v 1.60 2006/05/05 10:50:44 lha Exp $");
+RCSID("$Id: kerberos4.c,v 1.63 2006/10/08 13:43:27 lha Exp $");
 
 #ifndef swap32
 static uint32_t
@@ -80,7 +80,7 @@ valid_princ(krb5_context context,
     ret = krb5_unparse_name(context, princ, &s);
     if (ret)
        return FALSE;
-    ret = _kdc_db_fetch(context, ctx->config, princ, ctx->flags, &ent);
+    ret = _kdc_db_fetch(context, ctx->config, princ, ctx->flags, NULL, &ent);
     if (ret) {
        kdc_log(context, ctx->config, 7, "Lookup %s failed: %s", s,
                krb5_get_err_text (context, ret));
@@ -111,7 +111,7 @@ _kdc_db_fetch4(krb5_context context,
                                       valid_princ, &ctx, 0, &p);
     if(ret)
        return ret;
-    ret = _kdc_db_fetch(context, config, p, flags, ent);
+    ret = _kdc_db_fetch(context, config, p, flags, NULL, ent);
     krb5_free_principal(context, p);
     return ret;
 }
@@ -221,6 +221,17 @@ _kdc_do_version4(krb5_context context,
            goto out1;
        }
 
+       if (config->enable_v4_per_principal &&
+           client->entry.flags.allow_kerberos4 == 0)
+       {
+           kdc_log(context, config, 0,
+                   "Per principal Kerberos 4 flag not turned on for %s",
+                   client_name);
+           make_err_reply(context, reply, KERB_ERR_NULL_KEY,
+                          "allow kerberos4 flag required");
+           goto out1;
+       }
+
        /*
         * There's no way to do pre-authentication in v4 and thus no
         * good error code to return if preauthentication is required.
@@ -372,7 +383,7 @@ _kdc_do_version4(krb5_context context,
        }
 
        ret = _kdc_db_fetch(context, config, tgt_princ,
-                           HDB_F_GET_KRBTGT, &tgt);
+                           HDB_F_GET_KRBTGT, NULL, &tgt);
        if(ret){
            char *s;
            s = kdc_log_msg(context, config, 0, "Ticket-granting ticket not "
@@ -668,7 +679,7 @@ _kdc_encode_v4_ticket(krb5_context context,
        if(ret)
            return ret;
 
-       _krb5_principalname2krb5_principal(context, 
+       _krb5_principalname2krb5_principal(context,
                                           &princ,
                                           et->cname,
                                           et->crealm);
index a73c2c10b3b6c6fb5c56d4ead157304dbd70a2ad..19287b31ccc4f7d44c533fb8d4daed7e05926485 100644 (file)
 
 #include "kdc_locl.h"
 
-RCSID("$Id: kerberos5.c,v 1.211 2006/04/27 12:01:09 lha Exp $");
+RCSID("$Id: kerberos5.c,v 1.223 2006/10/17 02:16:29 lha Exp $");
 
 #define MAX_TIME ((time_t)((1U << 31) - 1))
 
-static void
-fix_time(time_t **t)
+void
+_kdc_fix_time(time_t **t)
 {
     if(*t == NULL){
        ALLOC(*t);
@@ -65,13 +65,13 @@ set_salt_padata (METHOD_DATA *md, Salt *salt)
     if (salt) {
        realloc_method_data(md);
        md->val[md->len - 1].padata_type = salt->type;
-       copy_octet_string(&salt->salt,
-                         &md->val[md->len - 1].padata_value);
+       der_copy_octet_string(&salt->salt,
+                             &md->val[md->len - 1].padata_value);
     }
 }
 
-static PA_DATA*
-find_padata(KDC_REQ *req, int *start, int type)
+PA_DATA*
+_kdc_find_padata(KDC_REQ *req, int *start, int type)
 {
     while(*start < req->padata->len){
        (*start)++;
@@ -87,10 +87,10 @@ find_padata(KDC_REQ *req, int *start, int type)
  * one, but preferring one that has default salt
  */
 
-static krb5_error_code
-find_etype(krb5_context context, const hdb_entry_ex *princ,
-          krb5_enctype *etypes, unsigned len, 
-          Key **ret_key, krb5_enctype *ret_etype)
+krb5_error_code
+_kdc_find_etype(krb5_context context, const hdb_entry_ex *princ,
+               krb5_enctype *etypes, unsigned len, 
+               Key **ret_key, krb5_enctype *ret_etype)
 {
     int i;
     krb5_error_code ret = KRB5KDC_ERR_ETYPE_NOSUPP;
@@ -116,46 +116,8 @@ find_etype(krb5_context context, const hdb_entry_ex *princ,
     return ret;
 }
 
-static krb5_error_code
-find_keys(krb5_context context, 
-         krb5_kdc_configuration *config,
-         const hdb_entry_ex *client,
-         const char *client_name,
-         const hdb_entry_ex *server,
-         const char *server_name,
-         Key **ckey,
-         krb5_enctype *cetype,
-         Key **skey,
-         krb5_enctype *setype, 
-         krb5_enctype *etypes,
-         unsigned num_etypes)
-{
-    krb5_error_code ret;
-
-    if(client){
-       /* find client key */
-       ret = find_etype(context, client, etypes, num_etypes, ckey, cetype);
-       if (ret) {
-           kdc_log(context, config, 0, 
-                   "Client (%s) has no support for etypes", client_name);
-           return ret;
-       }
-    }
-
-    if(server){
-       /* find server key */
-       ret = find_etype(context, server, etypes, num_etypes, skey, setype);
-       if (ret) {
-           kdc_log(context, config, 0, 
-                   "Server (%s) has no support for etypes", server_name);
-           return ret;
-       }
-    }
-    return 0;
-}
-
-static krb5_error_code
-make_anonymous_principalname (PrincipalName *pn)
+krb5_error_code
+_kdc_make_anonymous_principalname (PrincipalName *pn)
 {
     pn->name_type = KRB5_NT_PRINCIPAL;
     pn->name_string.len = 1;
@@ -171,12 +133,12 @@ make_anonymous_principalname (PrincipalName *pn)
     return 0;
 }
 
-static void
-log_timestamp(krb5_context context, 
-             krb5_kdc_configuration *config,
-             const char *type,
-             KerberosTime authtime, KerberosTime *starttime, 
-             KerberosTime endtime, KerberosTime *renew_till)
+void
+_kdc_log_timestamp(krb5_context context, 
+                  krb5_kdc_configuration *config,
+                  const char *type,
+                  KerberosTime authtime, KerberosTime *starttime, 
+                  KerberosTime endtime, KerberosTime *renew_till)
 {
     char authtime_str[100], starttime_str[100], 
        endtime_str[100], renewtime_str[100];
@@ -248,15 +210,15 @@ log_patypes(krb5_context context,
  */
 
 
-static krb5_error_code
-encode_reply(krb5_context context,
-            krb5_kdc_configuration *config,
-            KDC_REP *rep, EncTicketPart *et, EncKDCRepPart *ek, 
-            krb5_enctype etype, 
-            int skvno, EncryptionKey *skey,
-            int ckvno, EncryptionKey *ckey,
-            const char **e_text,
-            krb5_data *reply)
+krb5_error_code
+_kdc_encode_reply(krb5_context context,
+                 krb5_kdc_configuration *config,
+                 KDC_REP *rep, const EncTicketPart *et, EncKDCRepPart *ek, 
+                 krb5_enctype etype, 
+                 int skvno, const EncryptionKey *skey,
+                 int ckvno, const EncryptionKey *ckey,
+                 const char **e_text,
+                 krb5_data *reply)
 {
     unsigned char *buf;
     size_t buf_size;
@@ -795,10 +757,10 @@ _kdc_check_flags(krb5_context context,
  * these checks
  */
 
-static krb5_boolean
-check_addresses(krb5_context context,        
-               krb5_kdc_configuration *config,
-               HostAddresses *addresses, const struct sockaddr *from)
+krb5_boolean
+_kdc_check_addresses(krb5_context context,        
+                    krb5_kdc_configuration *config,
+                    HostAddresses *addresses, const struct sockaddr *from)
 {
     krb5_error_code ret;
     krb5_address addr;
@@ -843,13 +805,14 @@ _kdc_as_rep(krb5_context context,
            const krb5_data *req_buffer, 
            krb5_data *reply,
            const char *from,
-           struct sockaddr *from_addr)
+           struct sockaddr *from_addr,
+           int datagram_reply)
 {
     KDC_REQ_BODY *b = &req->req_body;
     AS_REP rep;
     KDCOptions f = b->kdc_options;
     hdb_entry_ex *client = NULL, *server = NULL;
-    krb5_enctype cetype, setype;
+    krb5_enctype cetype, setype, sessionetype;
     EncTicketPart et;
     EncKDCRepPart ek;
     krb5_principal client_princ = NULL, server_princ = NULL;
@@ -869,12 +832,15 @@ _kdc_as_rep(krb5_context context,
        ret = KRB5KRB_ERR_GENERIC;
        e_text = "No server in request";
     } else{
-           _krb5_principalname2krb5_principal (context, &server_princ,
-                                           *(b->sname), b->realm);
+       _krb5_principalname2krb5_principal (context,
+                                           &server_princ,
+                                           *(b->sname),
+                                           b->realm);
        ret = krb5_unparse_name(context, server_princ, &server_name);
     }
     if (ret) {
-       kdc_log(context, config, 0, "AS-REQ malformed server name from %s", from);
+       kdc_log(context, config, 0, 
+               "AS-REQ malformed server name from %s", from);
        goto out;
     }
     
@@ -882,12 +848,15 @@ _kdc_as_rep(krb5_context context,
        ret = KRB5KRB_ERR_GENERIC;
        e_text = "No client in request";
     } else {
-           _krb5_principalname2krb5_principal (context, &client_princ,
-                                           *(b->cname), b->realm);
+       _krb5_principalname2krb5_principal (context,
+                                           &client_princ,
+                                           *(b->cname),
+                                           b->realm);
        ret = krb5_unparse_name(context, client_princ, &client_name);
     }
     if (ret) {
-       kdc_log(context, config, 0, "AS-REQ malformed client name from %s", from);
+       kdc_log(context, config, 0,
+               "AS-REQ malformed client name from %s", from);
        goto out;
     }
 
@@ -895,7 +864,7 @@ _kdc_as_rep(krb5_context context,
            client_name, from, server_name);
 
     ret = _kdc_db_fetch(context, config, client_princ, 
-                       HDB_F_GET_CLIENT, &client);
+                       HDB_F_GET_CLIENT, NULL, &client);
     if(ret){
        kdc_log(context, config, 0, "UNKNOWN -- %s: %s", client_name,
                krb5_get_err_text(context, ret));
@@ -904,7 +873,8 @@ _kdc_as_rep(krb5_context context,
     }
 
     ret = _kdc_db_fetch(context, config, server_princ,
-                       HDB_F_GET_SERVER|HDB_F_GET_KRBTGT, &server);
+                       HDB_F_GET_SERVER|HDB_F_GET_KRBTGT,
+                       NULL, &server);
     if(ret){
        kdc_log(context, config, 0, "UNKNOWN -- %s: %s", server_name,
                krb5_get_err_text(context, ret));
@@ -943,11 +913,11 @@ _kdc_as_rep(krb5_context context,
        e_text = "No PKINIT PA found";
 
        i = 0;
-       if ((pa = find_padata(req, &i, KRB5_PADATA_PK_AS_REQ)))
+       if ((pa = _kdc_find_padata(req, &i, KRB5_PADATA_PK_AS_REQ)))
            ;
        if (pa == NULL) {
            i = 0;
-           if((pa = find_padata(req, &i, KRB5_PADATA_PK_AS_REQ_WIN)))
+           if((pa = _kdc_find_padata(req, &i, KRB5_PADATA_PK_AS_REQ_WIN)))
                ;
        }
        if (pa) {
@@ -995,7 +965,7 @@ _kdc_as_rep(krb5_context context,
 
        i = 0;
        e_text = "No ENC-TS found";
-       while((pa = find_padata(req, &i, KRB5_PADATA_ENC_TIMESTAMP))){
+       while((pa = _kdc_find_padata(req, &i, KRB5_PADATA_ENC_TIMESTAMP))){
            krb5_data ts_data;
            PA_ENC_TS_ENC p;
            size_t len;
@@ -1056,7 +1026,7 @@ _kdc_as_rep(krb5_context context,
            if(ret){
                krb5_error_code ret2;
                ret2 = krb5_enctype_to_string(context, 
-                                            pa_key->key.keytype, &str);
+                                             pa_key->key.keytype, &str);
                if (ret2)
                    str = NULL;
                kdc_log(context, config, 5, 
@@ -1092,9 +1062,18 @@ _kdc_as_rep(krb5_context context,
            }
            free_PA_ENC_TS_ENC(&p);
            if (abs(kdc_time - p.patimestamp) > context->max_skew) {
+               char client_time[100];
+
+               krb5_format_time(context, p.patimestamp, 
+                                client_time, sizeof(client_time), TRUE); 
+
                ret = KRB5KRB_AP_ERR_SKEW;
                kdc_log(context, config, 0,
-                       "Too large time skew -- %s", client_name);
+                       "Too large time skew, client time %s is out by %u > %u seconds -- %s", 
+                       client_time, 
+                       (unsigned)abs(kdc_time - p.patimestamp), 
+                       context->max_skew,
+                       client_name);
                /* 
                 * the following is needed to make windows clients
                 * to retry using the timestamp in the error message
@@ -1162,7 +1141,7 @@ _kdc_as_rep(krb5_context context,
         *   both info replies (we send 'info' first in the list).
         * - If the client is 'modern', because it knows about 'new'
         *   enctype types, then only send the 'info2' reply.
-       */
+        */
 
        /* XXX check ret */
        if (only_older_enctype_p(req))
@@ -1197,14 +1176,54 @@ _kdc_as_rep(krb5_context context,
        goto out2;
     }
     
-    ret = find_keys(context, config, 
-                   client, client_name, 
-                   server, server_name, 
-                   &ckey, &cetype, &skey, &setype,
-                   b->etype.val, b->etype.len);
-    if(ret)
+    /*
+     * Find the client key (for preauth ENC-TS verification and reply
+     * encryption).  Then the best encryption type for the KDC and
+     * last the best session key that shared between the client and
+     * KDC runtime enctypes.
+     */
+
+    ret = _kdc_find_etype(context, client, b->etype.val, b->etype.len,
+                         &ckey, &cetype);
+    if (ret) {
+       kdc_log(context, config, 0, 
+               "Client (%s) has no support for etypes", client_name);
        goto out;
+    }
        
+    ret = _kdc_get_preferred_key(context, config,
+                                server, server_name,
+                                &setype, &skey);
+    if(ret)
+       goto out;
+
+    {
+       const krb5_enctype *p;
+       int i, j;
+
+       p = krb5_kerberos_enctypes(context);
+
+       sessionetype = ETYPE_NULL;
+
+       for (i = 0; p[i] != ETYPE_NULL && sessionetype == ETYPE_NULL; i++) {
+           if (krb5_enctype_valid(context, p[i]) != 0)
+               continue;
+           for (j = 0; j < b->etype.len; j++) {
+               if (p[i] == b->etype.val[j]) {
+                   sessionetype = p[i];
+                   break;
+               }
+           }
+       }
+       if (sessionetype == ETYPE_NULL) {
+           kdc_log(context, config, 0, 
+                   "Client (%s) from %s has no common enctypes with KDC"
+                   "to use for the session key",
+                   client_name, from);
+           goto out;
+       }
+    }
+
     {
        struct rk_strpool *p = NULL;
        char *str;
@@ -1268,9 +1287,9 @@ _kdc_as_rep(krb5_context context,
     rep.msg_type = krb_as_rep;
     copy_Realm(&client->entry.principal->realm, &rep.crealm);
     if (f.request_anonymous)
-       make_anonymous_principalname (&rep.cname);
+       _kdc_make_anonymous_principalname (&rep.cname);
     else
-           _krb5_principal2principalname(&rep.cname, 
+       _krb5_principal2principalname(&rep.cname, 
                                      client->entry.principal);
     rep.ticket.tkt_vno = 5;
     copy_Realm(&server->entry.principal->realm, &rep.ticket.realm);
@@ -1304,14 +1323,14 @@ _kdc_as_rep(krb5_context context,
     }
 
     /* check for valid set of addresses */
-    if(!check_addresses(context, config, b->addresses, from_addr)) {
+    if(!_kdc_check_addresses(context, config, b->addresses, from_addr)) {
        ret = KRB5KRB_AP_ERR_BADADDR;
        kdc_log(context, config, 0,
                "Bad address list requested -- %s", client_name);
        goto out;
     }
 
-    krb5_generate_random_keyblock(context, setype, &et.key);
+    krb5_generate_random_keyblock(context, sessionetype, &et.key);
     copy_PrincipalName(&rep.cname, &et.cname);
     copy_Realm(&rep.crealm, &et.crealm);
     
@@ -1327,7 +1346,7 @@ _kdc_as_rep(krb5_context context,
            et.flags.invalid = 1;
            et.flags.postdated = 1; /* XXX ??? */
        }
-       fix_time(&b->till);
+       _kdc_fix_time(&b->till);
        t = *b->till;
 
        /* be careful not overflowing */
@@ -1392,7 +1411,7 @@ _kdc_as_rep(krb5_context context,
     ek.last_req.len = 0;
     if (client->entry.pw_end
        && (config->kdc_warn_pwexpire == 0
-           || kdc_time + config->kdc_warn_pwexpire <= *client->entry.pw_end)) {
+           || kdc_time + config->kdc_warn_pwexpire >= *client->entry.pw_end)) {
        ek.last_req.val[ek.last_req.len].lr_type  = LR_PW_EXPTIME;
        ek.last_req.val[ek.last_req.len].lr_value = *client->entry.pw_end;
        ++ek.last_req.len;
@@ -1472,15 +1491,37 @@ _kdc_as_rep(krb5_context context,
                    goto out;
     }
 
-    log_timestamp(context, config, "AS-REQ", et.authtime, et.starttime, 
-                 et.endtime, et.renew_till);
+    _kdc_log_timestamp(context, config, "AS-REQ", et.authtime, et.starttime, 
+                      et.endtime, et.renew_till);
+
+    /* do this as the last thing since this signs the EncTicketPart */
+    ret = _kdc_add_KRB5SignedPath(context,
+                                 config,
+                                 server,
+                                 setype,
+                                 NULL,
+                                 NULL,
+                                 &et);
+    if (ret)
+       goto out;
 
-    ret = encode_reply(context, config, 
-                      &rep, &et, &ek, setype, server->entry.kvno, &skey->key,
-                      client->entry.kvno, reply_key, &e_text, reply);
+    ret = _kdc_encode_reply(context, config, 
+                           &rep, &et, &ek, setype, server->entry.kvno, 
+                           &skey->key, client->entry.kvno, 
+                           reply_key, &e_text, reply);
     free_EncTicketPart(&et);
     free_EncKDCRepPart(&ek);
- out:
+    if (ret)
+       goto out;
+
+    /* */
+    if (datagram_reply && reply->length > config->max_datagram_reply_length) {
+       krb5_data_free(reply);
+       ret = KRB5KRB_ERR_RESPONSE_TOO_BIG;
+       e_text = "Reply packet too large";
+    }
+
+out:
     free_AS_REP(&rep);
     if(ret){
        krb5_mk_error(context,
@@ -1494,7 +1535,7 @@ _kdc_as_rep(krb5_context context,
                      reply);
        ret = 0;
     }
- out2:
+out2:
 #ifdef PKINIT
     if (pkp)
        _kdc_pk_free_client_param(context, pkp);
@@ -1511,1089 +1552,3 @@ _kdc_as_rep(krb5_context context,
        _kdc_free_ent(context, server);
     return ret;
 }
-
-
-static krb5_error_code
-check_tgs_flags(krb5_context context,        
-               krb5_kdc_configuration *config,
-               KDC_REQ_BODY *b, EncTicketPart *tgt, EncTicketPart *et)
-{
-    KDCOptions f = b->kdc_options;
-       
-    if(f.validate){
-       if(!tgt->flags.invalid || tgt->starttime == NULL){
-           kdc_log(context, config, 0,
-                   "Bad request to validate ticket");
-           return KRB5KDC_ERR_BADOPTION;
-       }
-       if(*tgt->starttime > kdc_time){
-           kdc_log(context, config, 0,
-                   "Early request to validate ticket");
-           return KRB5KRB_AP_ERR_TKT_NYV;
-       }
-       /* XXX  tkt = tgt */
-       et->flags.invalid = 0;
-    }else if(tgt->flags.invalid){
-       kdc_log(context, config, 0, 
-               "Ticket-granting ticket has INVALID flag set");
-       return KRB5KRB_AP_ERR_TKT_INVALID;
-    }
-
-    if(f.forwardable){
-       if(!tgt->flags.forwardable){
-           kdc_log(context, config, 0,
-                   "Bad request for forwardable ticket");
-           return KRB5KDC_ERR_BADOPTION;
-       }
-       et->flags.forwardable = 1;
-    }
-    if(f.forwarded){
-       if(!tgt->flags.forwardable){
-           kdc_log(context, config, 0,
-                   "Request to forward non-forwardable ticket");
-           return KRB5KDC_ERR_BADOPTION;
-       }
-       et->flags.forwarded = 1;
-       et->caddr = b->addresses;
-    }
-    if(tgt->flags.forwarded)
-       et->flags.forwarded = 1;
-       
-    if(f.proxiable){
-       if(!tgt->flags.proxiable){
-           kdc_log(context, config, 0,
-                   "Bad request for proxiable ticket");
-           return KRB5KDC_ERR_BADOPTION;
-       }
-       et->flags.proxiable = 1;
-    }
-    if(f.proxy){
-       if(!tgt->flags.proxiable){
-           kdc_log(context, config, 0,
-                   "Request to proxy non-proxiable ticket");
-           return KRB5KDC_ERR_BADOPTION;
-       }
-       et->flags.proxy = 1;
-       et->caddr = b->addresses;
-    }
-    if(tgt->flags.proxy)
-       et->flags.proxy = 1;
-
-    if(f.allow_postdate){
-       if(!tgt->flags.may_postdate){
-           kdc_log(context, config, 0,
-                   "Bad request for post-datable ticket");
-           return KRB5KDC_ERR_BADOPTION;
-       }
-       et->flags.may_postdate = 1;
-    }
-    if(f.postdated){
-       if(!tgt->flags.may_postdate){
-           kdc_log(context, config, 0,
-                   "Bad request for postdated ticket");
-           return KRB5KDC_ERR_BADOPTION;
-       }
-       if(b->from)
-           *et->starttime = *b->from;
-       et->flags.postdated = 1;
-       et->flags.invalid = 1;
-    }else if(b->from && *b->from > kdc_time + context->max_skew){
-       kdc_log(context, config, 0, "Ticket cannot be postdated");
-       return KRB5KDC_ERR_CANNOT_POSTDATE;
-    }
-
-    if(f.renewable){
-       if(!tgt->flags.renewable){
-           kdc_log(context, config, 0,
-                   "Bad request for renewable ticket");
-           return KRB5KDC_ERR_BADOPTION;
-       }
-       et->flags.renewable = 1;
-       ALLOC(et->renew_till);
-       fix_time(&b->rtime);
-       *et->renew_till = *b->rtime;
-    }
-    if(f.renew){
-       time_t old_life;
-       if(!tgt->flags.renewable || tgt->renew_till == NULL){
-           kdc_log(context, config, 0,
-                   "Request to renew non-renewable ticket");
-           return KRB5KDC_ERR_BADOPTION;
-       }
-       old_life = tgt->endtime;
-       if(tgt->starttime)
-           old_life -= *tgt->starttime;
-       else
-           old_life -= tgt->authtime;
-       et->endtime = *et->starttime + old_life;
-       if (et->renew_till != NULL)
-           et->endtime = min(*et->renew_till, et->endtime);
-    }      
-    
-    /* checks for excess flags */
-    if(f.request_anonymous && !config->allow_anonymous){
-       kdc_log(context, config, 0,
-               "Request for anonymous ticket");
-       return KRB5KDC_ERR_BADOPTION;
-    }
-    return 0;
-}
-
-static krb5_error_code
-fix_transited_encoding(krb5_context context, 
-                      krb5_kdc_configuration *config,
-                      krb5_boolean check_policy,
-                      TransitedEncoding *tr, 
-                      EncTicketPart *et, 
-                      const char *client_realm, 
-                      const char *server_realm, 
-                      const char *tgt_realm)
-{
-    krb5_error_code ret = 0;
-    char **realms, **tmp;
-    int num_realms;
-    int i;
-
-    switch (tr->tr_type) {
-    case DOMAIN_X500_COMPRESS:
-       break;
-    case 0:
-       /*
-        * Allow empty content of type 0 because that is was Microsoft
-        * generates in their TGT.
-        */
-       if (tr->contents.length == 0)
-           break;
-       kdc_log(context, config, 0,
-               "Transited type 0 with non empty content");
-       return KRB5KDC_ERR_TRTYPE_NOSUPP;
-    default:
-       kdc_log(context, config, 0,
-               "Unknown transited type: %u", tr->tr_type);
-       return KRB5KDC_ERR_TRTYPE_NOSUPP;
-    }
-
-    ret = krb5_domain_x500_decode(context, 
-                                 tr->contents,
-                                 &realms, 
-                                 &num_realms,
-                                 client_realm,
-                                 server_realm);
-    if(ret){
-       krb5_warn(context, ret,
-                 "Decoding transited encoding");
-       return ret;
-    }
-    if(strcmp(client_realm, tgt_realm) && strcmp(server_realm, tgt_realm)) {
-       /* not us, so add the previous realm to transited set */
-       if (num_realms < 0 || num_realms + 1 > UINT_MAX/sizeof(*realms)) {
-           ret = ERANGE;
-           goto free_realms;
-       }
-       tmp = realloc(realms, (num_realms + 1) * sizeof(*realms));
-       if(tmp == NULL){
-           ret = ENOMEM;
-           goto free_realms;
-       }
-       realms = tmp;
-       realms[num_realms] = strdup(tgt_realm);
-       if(realms[num_realms] == NULL){
-           ret = ENOMEM;
-           goto free_realms;
-       }
-       num_realms++;
-    }
-    if(num_realms == 0) {
-       if(strcmp(client_realm, server_realm)) 
-           kdc_log(context, config, 0,
-                   "cross-realm %s -> %s", client_realm, server_realm);
-    } else {
-       size_t l = 0;
-       char *rs;
-       for(i = 0; i < num_realms; i++)
-           l += strlen(realms[i]) + 2;
-       rs = malloc(l);
-       if(rs != NULL) {
-           *rs = '\0';
-           for(i = 0; i < num_realms; i++) {
-               if(i > 0)
-                   strlcat(rs, ", ", l);
-               strlcat(rs, realms[i], l);
-           }
-           kdc_log(context, config, 0,
-                   "cross-realm %s -> %s via [%s]",
-                   client_realm, server_realm, rs);
-           free(rs);
-       }
-    }
-    if(check_policy) {
-       ret = krb5_check_transited(context, client_realm, 
-                                  server_realm, 
-                                  realms, num_realms, NULL);
-       if(ret) {
-           krb5_warn(context, ret, "cross-realm %s -> %s", 
-                     client_realm, server_realm);
-           goto free_realms;
-       }
-       et->flags.transited_policy_checked = 1;
-    }
-    et->transited.tr_type = DOMAIN_X500_COMPRESS;
-    ret = krb5_domain_x500_encode(realms, num_realms, &et->transited.contents);
-    if(ret)
-       krb5_warn(context, ret, "Encoding transited encoding");
-  free_realms:
-    for(i = 0; i < num_realms; i++)
-       free(realms[i]);
-    free(realms);
-    return ret;
-}
-
-
-static krb5_error_code
-tgs_make_reply(krb5_context context, 
-              krb5_kdc_configuration *config,
-              KDC_REQ_BODY *b, 
-              EncTicketPart *tgt, 
-              EncTicketPart *adtkt, 
-              AuthorizationData *auth_data,
-              krb5_ticket *tgs_ticket,
-              hdb_entry_ex *server, 
-              const char *server_name, 
-              hdb_entry_ex *client, 
-              krb5_principal client_principal, 
-              hdb_entry_ex *krbtgt,
-              EncryptionKey *tgtkey,
-              krb5_enctype cetype,
-              const char **e_text,
-              krb5_data *reply)
-{
-    KDC_REP rep;
-    EncKDCRepPart ek;
-    EncTicketPart et;
-    KDCOptions f = b->kdc_options;
-    krb5_error_code ret;
-    krb5_enctype etype;
-    Key *skey;
-    EncryptionKey *ekey;
-    AuthorizationData *new_auth_data = NULL;
-    
-    if(adtkt) {
-       int i;
-       ekey = &adtkt->key;
-       for(i = 0; i < b->etype.len; i++)
-           if (b->etype.val[i] == adtkt->key.keytype)
-               break;
-       if(i == b->etype.len) {
-           krb5_clear_error_string(context);
-           return KRB5KDC_ERR_ETYPE_NOSUPP;
-       }
-       etype = b->etype.val[i];
-    }else{
-       ret = find_keys(context, config, 
-                       NULL, NULL, server, server_name,
-                       NULL, NULL, &skey, &etype, 
-                       b->etype.val, b->etype.len);
-       if(ret)
-           return ret;
-       ekey = &skey->key;
-    }
-    
-    memset(&rep, 0, sizeof(rep));
-    memset(&et, 0, sizeof(et));
-    memset(&ek, 0, sizeof(ek));
-    
-    rep.pvno = 5;
-    rep.msg_type = krb_tgs_rep;
-
-    et.authtime = tgt->authtime;
-    fix_time(&b->till);
-    et.endtime = min(tgt->endtime, *b->till);
-    ALLOC(et.starttime);
-    *et.starttime = kdc_time;
-    
-    ret = check_tgs_flags(context, config, b, tgt, &et);
-    if(ret)
-       goto out;
-
-    /* We should check the transited encoding if:
-       1) the request doesn't ask not to be checked
-       2) globally enforcing a check
-       3) principal requires checking
-       4) we allow non-check per-principal, but principal isn't marked as allowing this
-       5) we don't globally allow this
-    */
-
-#define GLOBAL_FORCE_TRANSITED_CHECK           \
-       (config->trpolicy == TRPOLICY_ALWAYS_CHECK)
-#define GLOBAL_ALLOW_PER_PRINCIPAL             \
-       (config->trpolicy == TRPOLICY_ALLOW_PER_PRINCIPAL)
-#define GLOBAL_ALLOW_DISABLE_TRANSITED_CHECK   \
-       (config->trpolicy == TRPOLICY_ALWAYS_HONOUR_REQUEST)
-
-/* these will consult the database in future release */
-#define PRINCIPAL_FORCE_TRANSITED_CHECK(P)             0
-#define PRINCIPAL_ALLOW_DISABLE_TRANSITED_CHECK(P)     0
-
-    ret = fix_transited_encoding(context, config, 
-                                !f.disable_transited_check ||
-                                GLOBAL_FORCE_TRANSITED_CHECK ||
-                                PRINCIPAL_FORCE_TRANSITED_CHECK(server) ||
-                                !((GLOBAL_ALLOW_PER_PRINCIPAL && 
-                                   PRINCIPAL_ALLOW_DISABLE_TRANSITED_CHECK(server)) ||
-                                  GLOBAL_ALLOW_DISABLE_TRANSITED_CHECK),
-                                &tgt->transited, &et,
-                                *krb5_princ_realm(context, client_principal),
-                                *krb5_princ_realm(context, server->entry.principal),
-                                *krb5_princ_realm(context, krbtgt->entry.principal));
-    if(ret)
-       goto out;
-
-    copy_Realm(krb5_princ_realm(context, server->entry.principal), 
-              &rep.ticket.realm);
-    _krb5_principal2principalname(&rep.ticket.sname, server->entry.principal);
-    copy_Realm(&tgt->crealm, &rep.crealm);
-    if (f.request_anonymous)
-       make_anonymous_principalname (&tgt->cname);
-    else
-       copy_PrincipalName(&tgt->cname, &rep.cname);
-    rep.ticket.tkt_vno = 5;
-
-    ek.caddr = et.caddr;
-    if(et.caddr == NULL)
-       et.caddr = tgt->caddr;
-
-    {
-       time_t life;
-       life = et.endtime - *et.starttime;
-       if(client && client->entry.max_life)
-           life = min(life, *client->entry.max_life);
-       if(server->entry.max_life)
-           life = min(life, *server->entry.max_life);
-       et.endtime = *et.starttime + life;
-    }
-    if(f.renewable_ok && tgt->flags.renewable && 
-       et.renew_till == NULL && et.endtime < *b->till){
-       et.flags.renewable = 1;
-       ALLOC(et.renew_till);
-       *et.renew_till = *b->till;
-    }
-    if(et.renew_till){
-       time_t renew;
-       renew = *et.renew_till - et.authtime;
-       if(client && client->entry.max_renew)
-           renew = min(renew, *client->entry.max_renew);
-       if(server->entry.max_renew)
-           renew = min(renew, *server->entry.max_renew);
-       *et.renew_till = et.authtime + renew;
-    }
-           
-    if(et.renew_till){
-       *et.renew_till = min(*et.renew_till, *tgt->renew_till);
-       *et.starttime = min(*et.starttime, *et.renew_till);
-       et.endtime = min(et.endtime, *et.renew_till);
-    }
-    
-    *et.starttime = min(*et.starttime, et.endtime);
-
-    if(*et.starttime == et.endtime){
-       ret = KRB5KDC_ERR_NEVER_VALID;
-       goto out;
-    }
-    if(et.renew_till && et.endtime == *et.renew_till){
-       free(et.renew_till);
-       et.renew_till = NULL;
-       et.flags.renewable = 0;
-    }
-    
-    et.flags.pre_authent = tgt->flags.pre_authent;
-    et.flags.hw_authent  = tgt->flags.hw_authent;
-    et.flags.anonymous   = tgt->flags.anonymous;
-    et.flags.ok_as_delegate = server->entry.flags.ok_as_delegate;
-           
-    
-    krb5_generate_random_keyblock(context, etype, &et.key);
-
-    if (server->authz_data_tgs_req) {
-           ret = server->authz_data_tgs_req(context, server,
-                                            client_principal, 
-                                            tgs_ticket->ticket.authorization_data,
-                                            tgs_ticket->ticket.authtime,
-                                            tgtkey,
-                                            ekey, 
-                                            &et.key, 
-                                            &new_auth_data);
-           if (ret) {
-                   new_auth_data = NULL;
-           }
-    }
-
-    /* XXX Check enc-authorization-data */
-    et.authorization_data = new_auth_data;
-
-    et.crealm = tgt->crealm;
-    et.cname = tgt->cname;
-           
-    ek.key = et.key;
-    /* MIT must have at least one last_req */
-    ek.last_req.len = 1;
-    ek.last_req.val = calloc(1, sizeof(*ek.last_req.val));
-    ek.nonce = b->nonce;
-    ek.flags = et.flags;
-    ek.authtime = et.authtime;
-    ek.starttime = et.starttime;
-    ek.endtime = et.endtime;
-    ek.renew_till = et.renew_till;
-    ek.srealm = rep.ticket.realm;
-    ek.sname = rep.ticket.sname;
-    
-    log_timestamp(context, config, "TGS-REQ", et.authtime, et.starttime, 
-                 et.endtime, et.renew_till);
-
-    /* It is somewhat unclear where the etype in the following
-       encryption should come from. What we have is a session
-       key in the passed tgt, and a list of preferred etypes
-       *for the new ticket*. Should we pick the best possible
-       etype, given the keytype in the tgt, or should we look
-       at the etype list here as well?  What if the tgt
-       session key is DES3 and we want a ticket with a (say)
-       CAST session key. Should the DES3 etype be added to the
-       etype list, even if we don't want a session key with
-       DES3? */
-    ret = encode_reply(context, config, 
-                      &rep, &et, &ek, etype, adtkt ? 0 : server->entry.kvno, 
-                      ekey, 0, &tgt->key, e_text, reply);
-  out:
-    free_TGS_REP(&rep);
-    free_TransitedEncoding(&et.transited);
-    if(et.starttime)
-       free(et.starttime);
-    if(et.renew_till)
-       free(et.renew_till);
-    free_LastReq(&ek.last_req);
-    memset(et.key.keyvalue.data, 0, et.key.keyvalue.length);
-    free_EncryptionKey(&et.key);
-    return ret;
-}
-
-static krb5_error_code
-tgs_check_authenticator(krb5_context context, 
-                       krb5_kdc_configuration *config,
-                       krb5_auth_context ac,
-                       KDC_REQ_BODY *b, 
-                       const char **e_text,
-                       krb5_keyblock *key)
-{
-    krb5_authenticator auth;
-    size_t len;
-    unsigned char *buf;
-    size_t buf_size;
-    krb5_error_code ret;
-    krb5_crypto crypto;
-    
-    krb5_auth_con_getauthenticator(context, ac, &auth);
-    if(auth->cksum == NULL){
-       kdc_log(context, config, 0, "No authenticator in request");
-       ret = KRB5KRB_AP_ERR_INAPP_CKSUM;
-       goto out;
-    }
-    /*
-     * according to RFC1510 it doesn't need to be keyed,
-     * but according to the latest draft it needs to.
-     */
-    if (
-#if 0
-!krb5_checksum_is_keyed(context, auth->cksum->cksumtype)
-       ||
-#endif
- !krb5_checksum_is_collision_proof(context, auth->cksum->cksumtype)) {
-       kdc_log(context, config, 0, "Bad checksum type in authenticator: %d", 
-               auth->cksum->cksumtype);
-       ret =  KRB5KRB_AP_ERR_INAPP_CKSUM;
-       goto out;
-    }
-               
-    /* XXX should not re-encode this */
-    ASN1_MALLOC_ENCODE(KDC_REQ_BODY, buf, buf_size, b, &len, ret);
-    if(ret){
-       kdc_log(context, config, 0, "Failed to encode KDC-REQ-BODY: %s", 
-               krb5_get_err_text(context, ret));
-       goto out;
-    }
-    if(buf_size != len) {
-       free(buf);
-       kdc_log(context, config, 0, "Internal error in ASN.1 encoder");
-       *e_text = "KDC internal error";
-       ret = KRB5KRB_ERR_GENERIC;
-       goto out;
-    }
-    ret = krb5_crypto_init(context, key, 0, &crypto);
-    if (ret) {
-       free(buf);
-       kdc_log(context, config, 0, "krb5_crypto_init failed: %s",
-               krb5_get_err_text(context, ret));
-       goto out;
-    }
-    ret = krb5_verify_checksum(context,
-                              crypto,
-                              KRB5_KU_TGS_REQ_AUTH_CKSUM,
-                              buf, 
-                              len,
-                              auth->cksum);
-    free(buf);
-    krb5_crypto_destroy(context, crypto);
-    if(ret){
-       kdc_log(context, config, 0,
-               "Failed to verify authenticator checksum: %s", 
-               krb5_get_err_text(context, ret));
-    }
-out:
-    free_Authenticator(auth);
-    free(auth);
-    return ret;
-}
-
-/*
- * return the realm of a krbtgt-ticket or NULL
- */
-
-static Realm 
-get_krbtgt_realm(const PrincipalName *p)
-{
-    if(p->name_string.len == 2
-       && strcmp(p->name_string.val[0], KRB5_TGS_NAME) == 0)
-       return p->name_string.val[1];
-    else
-       return NULL;
-}
-
-static const char *
-find_rpath(krb5_context context, Realm crealm, Realm srealm)
-{
-    const char *new_realm = krb5_config_get_string(context,
-                                                  NULL,
-                                                  "capaths", 
-                                                  crealm,
-                                                  srealm,
-                                                  NULL);
-    return new_realm;
-}
-           
-
-static krb5_boolean
-need_referral(krb5_context context, krb5_principal server, krb5_realm **realms)
-{
-    if(server->name.name_type != KRB5_NT_SRV_INST ||
-       server->name.name_string.len != 2)
-       return FALSE;
-    return _krb5_get_host_realm_int(context, server->name.name_string.val[1],
-                                   FALSE, realms) == 0;
-}
-
-static krb5_error_code
-tgs_rep2(krb5_context context, 
-        krb5_kdc_configuration *config,
-        KDC_REQ_BODY *b,
-        PA_DATA *tgs_req,
-        krb5_data *reply,
-        const char *from,
-        const struct sockaddr *from_addr,
-        time_t **csec,
-        int **cusec)
-{
-    krb5_ap_req ap_req;
-    krb5_error_code ret;
-    krb5_principal princ;
-    krb5_auth_context ac = NULL;
-    krb5_ticket *ticket = NULL;
-    krb5_flags ap_req_options;
-    krb5_flags verify_ap_req_flags;
-    const char *e_text = NULL;
-    krb5_crypto crypto;
-
-    hdb_entry_ex *krbtgt = NULL;
-    EncTicketPart *tgt;
-    Key *tkey;
-    krb5_enctype cetype;
-    krb5_principal cp = NULL;
-    krb5_principal sp = NULL;
-    AuthorizationData *auth_data = NULL;
-
-    *csec  = NULL;
-    *cusec = NULL;
-
-    memset(&ap_req, 0, sizeof(ap_req));
-    ret = krb5_decode_ap_req(context, &tgs_req->padata_value, &ap_req);
-    if(ret){
-       kdc_log(context, config, 0, "Failed to decode AP-REQ: %s", 
-               krb5_get_err_text(context, ret));
-       goto out2;
-    }
-    
-    if(!get_krbtgt_realm(&ap_req.ticket.sname)){
-       /* XXX check for ticket.sname == req.sname */
-       kdc_log(context, config, 0, "PA-DATA is not a ticket-granting ticket");
-       ret = KRB5KDC_ERR_POLICY; /* ? */
-       goto out2;
-    }
-    
-    _krb5_principalname2krb5_principal(context, &princ,
-                                      ap_req.ticket.sname,
-                                      ap_req.ticket.realm);
-    
-    ret = _kdc_db_fetch(context, config, princ, HDB_F_GET_KRBTGT, &krbtgt);
-
-    if(ret) {
-       char *p;
-       ret = krb5_unparse_name(context, princ, &p);
-       if (ret != 0)
-           p = "<unparse_name failed>";
-       krb5_free_principal(context, princ);
-       kdc_log(context, config, 0,
-               "Ticket-granting ticket not found in database: %s: %s",
-               p, krb5_get_err_text(context, ret));
-       if (ret == 0)
-           free(p);
-       ret = KRB5KRB_AP_ERR_NOT_US;
-       goto out2;
-    }
-    
-    if(ap_req.ticket.enc_part.kvno && 
-       *ap_req.ticket.enc_part.kvno != krbtgt->entry.kvno){
-       char *p;
-
-       ret = krb5_unparse_name (context, princ, &p);
-       krb5_free_principal(context, princ);
-       if (ret != 0)
-           p = "<unparse_name failed>";
-       kdc_log(context, config, 0,
-               "Ticket kvno = %d, DB kvno = %d (%s)", 
-               *ap_req.ticket.enc_part.kvno,
-               krbtgt->entry.kvno,
-               p);
-       if (ret == 0)
-           free (p);
-       ret = KRB5KRB_AP_ERR_BADKEYVER;
-       goto out2;
-    }
-
-    ret = hdb_enctype2key(context, &krbtgt->entry, 
-                         ap_req.ticket.enc_part.etype, &tkey);
-    if(ret){
-       char *str, *p;
-       krb5_enctype_to_string(context, ap_req.ticket.enc_part.etype, &str);
-       krb5_unparse_name(context, princ, &p);
-       kdc_log(context, config, 0,
-               "No server key with enctype %s found for %s", str, p);
-       free(str);
-       free(p);
-       ret = KRB5KRB_AP_ERR_BADKEYVER;
-       goto out2;
-    }
-    
-    if (b->kdc_options.validate)
-       verify_ap_req_flags = KRB5_VERIFY_AP_REQ_IGNORE_INVALID;
-    else
-       verify_ap_req_flags = 0;
-
-    ret = krb5_verify_ap_req2(context,
-                             &ac,
-                             &ap_req,
-                             princ,
-                             &tkey->key,
-                             verify_ap_req_flags,
-                             &ap_req_options,
-                             &ticket,
-                             KRB5_KU_TGS_REQ_AUTH);
-                            
-    krb5_free_principal(context, princ);
-    if(ret) {
-       kdc_log(context, config, 0, "Failed to verify AP-REQ: %s", 
-               krb5_get_err_text(context, ret));
-       goto out2;
-    }
-
-    {
-       krb5_authenticator auth;
-
-       ret = krb5_auth_con_getauthenticator(context, ac, &auth);
-       if (ret == 0) {
-           *csec   = malloc(sizeof(**csec));
-           if (*csec == NULL) {
-               krb5_free_authenticator(context, &auth);
-               kdc_log(context, config, 0, "malloc failed");
-               goto out2;
-           }
-           **csec  = auth->ctime;
-           *cusec  = malloc(sizeof(**cusec));
-           if (*cusec == NULL) {
-               krb5_free_authenticator(context, &auth);
-               kdc_log(context, config, 0, "malloc failed");
-               goto out2;
-           }
-           **csec  = auth->cusec;
-           krb5_free_authenticator(context, &auth);
-       }
-    }
-
-    cetype = ap_req.authenticator.etype;
-
-    tgt = &ticket->ticket;
-
-    ret = tgs_check_authenticator(context, config, 
-                                 ac, b, &e_text, &tgt->key);
-    if (ret) {
-       krb5_auth_con_free(context, ac);
-       goto out2;
-    }
-
-    if (b->enc_authorization_data) {
-       krb5_keyblock *subkey;
-       krb5_data ad;
-       ret = krb5_auth_con_getremotesubkey(context,
-                                           ac,
-                                           &subkey);
-       if(ret){
-           krb5_auth_con_free(context, ac);
-           kdc_log(context, config, 0, "Failed to get remote subkey: %s", 
-                   krb5_get_err_text(context, ret));
-           goto out2;
-       }
-       if(subkey == NULL){
-           ret = krb5_auth_con_getkey(context, ac, &subkey);
-           if(ret) {
-               krb5_auth_con_free(context, ac);
-               kdc_log(context, config, 0, "Failed to get session key: %s", 
-                       krb5_get_err_text(context, ret));
-               goto out2;
-           }
-       }
-       if(subkey == NULL){
-           krb5_auth_con_free(context, ac);
-           kdc_log(context, config, 0,
-                   "Failed to get key for enc-authorization-data");
-           ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */
-           goto out2;
-       }
-       ret = krb5_crypto_init(context, subkey, 0, &crypto);
-       if (ret) {
-           krb5_auth_con_free(context, ac);
-           kdc_log(context, config, 0, "krb5_crypto_init failed: %s",
-                   krb5_get_err_text(context, ret));
-           goto out2;
-       }
-       ret = krb5_decrypt_EncryptedData (context,
-                                         crypto,
-                                         KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY,
-                                         b->enc_authorization_data,
-                                         &ad);
-       krb5_crypto_destroy(context, crypto);
-       if(ret){
-           krb5_auth_con_free(context, ac);
-           kdc_log(context, config, 0, "Failed to decrypt enc-authorization-data");
-           ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */
-           goto out2;
-       }
-       krb5_free_keyblock(context, subkey);
-       ALLOC(auth_data);
-       ret = decode_AuthorizationData(ad.data, ad.length, auth_data, NULL);
-       if(ret){
-           krb5_auth_con_free(context, ac);
-           free(auth_data);
-           auth_data = NULL;
-           kdc_log(context, config, 0, "Failed to decode authorization data");
-           ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */
-           goto out2;
-       }
-    }
-
-    krb5_auth_con_free(context, ac);
-
-    {
-       PrincipalName *s;
-       Realm r;
-       char *spn = NULL, *cpn = NULL;
-       hdb_entry_ex *server = NULL, *client = NULL;
-       int nloop = 0;
-       EncTicketPart adtkt;
-       char opt_str[128];
-
-       s = b->sname;
-       r = b->realm;
-       if(b->kdc_options.enc_tkt_in_skey){
-           Ticket *t;
-           hdb_entry_ex *uu;
-           krb5_principal p;
-           Key *uukey;
-           
-           if(b->additional_tickets == NULL || 
-              b->additional_tickets->len == 0){
-               ret = KRB5KDC_ERR_BADOPTION; /* ? */
-               kdc_log(context, config, 0,
-                       "No second ticket present in request");
-               goto out;
-           }
-           t = &b->additional_tickets->val[0];
-           if(!get_krbtgt_realm(&t->sname)){
-               kdc_log(context, config, 0,
-                       "Additional ticket is not a ticket-granting ticket");
-               ret = KRB5KDC_ERR_POLICY;
-               goto out2;
-           }
-           _krb5_principalname2krb5_principal(context, &p, t->sname, t->realm);
-           ret = _kdc_db_fetch(context, config, p, 
-                               HDB_F_GET_CLIENT|HDB_F_GET_SERVER, &uu);
-           krb5_free_principal(context, p);
-           if(ret){
-               if (ret == HDB_ERR_NOENTRY)
-                   ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
-               goto out;
-           }
-           ret = hdb_enctype2key(context, &uu->entry, 
-                                 t->enc_part.etype, &uukey);
-           if(ret){
-               _kdc_free_ent(context, uu);
-               ret = KRB5KDC_ERR_ETYPE_NOSUPP; /* XXX */
-               goto out;
-           }
-           ret = krb5_decrypt_ticket(context, t, &uukey->key, &adtkt, 0);
-           _kdc_free_ent(context, uu);
-           if(ret)
-               goto out;
-           s = &adtkt.cname;
-           r = adtkt.crealm;
-       }
-
-       _krb5_principalname2krb5_principal(context, &sp, *s, r);
-       ret = krb5_unparse_name(context, sp, &spn);     
-       if (ret)
-           goto out;
-       _krb5_principalname2krb5_principal(context, &cp, tgt->cname, tgt->crealm);
-       ret = krb5_unparse_name(context, cp, &cpn);
-       if (ret)
-           goto out;
-       unparse_flags (KDCOptions2int(b->kdc_options),
-                      asn1_KDCOptions_units(),
-                      opt_str, sizeof(opt_str));
-       if(*opt_str)
-           kdc_log(context, config, 0,
-                   "TGS-REQ %s from %s for %s [%s]", 
-                   cpn, from, spn, opt_str);
-       else
-           kdc_log(context, config, 0,
-                   "TGS-REQ %s from %s for %s", cpn, from, spn);
-    server_lookup:
-       ret = _kdc_db_fetch(context, config, sp, HDB_F_GET_SERVER, &server);
-
-       if(ret){
-           const char *new_rlm;
-           Realm req_rlm;
-           krb5_realm *realms;
-
-           if ((req_rlm = get_krbtgt_realm(&sp->name)) != NULL) {
-               if(nloop++ < 2) {
-                   new_rlm = find_rpath(context, tgt->crealm, req_rlm);
-                   if(new_rlm) {
-                       kdc_log(context, config, 5, "krbtgt for realm %s not found, trying %s", 
-                               req_rlm, new_rlm);
-                       krb5_free_principal(context, sp);
-                       free(spn);
-                       krb5_make_principal(context, &sp, r, 
-                                           KRB5_TGS_NAME, new_rlm, NULL);
-                       ret = krb5_unparse_name(context, sp, &spn);     
-                       if (ret)
-                           goto out;
-                       goto server_lookup;
-                   }
-               }
-           } else if(need_referral(context, sp, &realms)) {
-               if (strcmp(realms[0], sp->realm) != 0) {
-                   kdc_log(context, config, 5,
-                           "Returning a referral to realm %s for "
-                           "server %s that was not found",
-                           realms[0], spn);
-                   krb5_free_principal(context, sp);
-                   free(spn);
-                   krb5_make_principal(context, &sp, r, KRB5_TGS_NAME,
-                                       realms[0], NULL);
-                   ret = krb5_unparse_name(context, sp, &spn);
-                   if (ret)
-                       goto out;
-                   krb5_free_host_realm(context, realms);
-                   goto server_lookup;
-               }
-               krb5_free_host_realm(context, realms);
-           }
-           kdc_log(context, config, 0,
-                   "Server not found in database: %s: %s", spn,
-                   krb5_get_err_text(context, ret));
-           if (ret == HDB_ERR_NOENTRY)
-               ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
-           goto out;
-       }
-
-       ret = _kdc_db_fetch(context, config, cp, HDB_F_GET_CLIENT, &client);
-       if(ret)
-           kdc_log(context, config, 1, "Client not found in database: %s: %s",
-                   cpn, krb5_get_err_text(context, ret));
-
-       /*
-        * If the client belongs to the same realm as our krbtgt, it
-        * should exist in the local database.
-        *
-        * If its not the same, check the "direction" on the krbtgt,
-        * so its not a backward uni-directional trust.
-        */
-
-       if(strcmp(krb5_principal_get_realm(context, sp),
-                 krb5_principal_get_comp_string(context, 
-                                                krbtgt->entry.principal, 1)) == 0) {
-           if(ret) {
-               if (ret == HDB_ERR_NOENTRY)
-                   ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
-               goto out;
-           }
-       } else {
-           char *tpn;
-           ret = krb5_unparse_name(context, krbtgt->entry.principal, &tpn);
-           kdc_log(context, config, 0,
-                   "Request with wrong krbtgt: %s",
-                   (ret == 0) ? tpn : "<unknown>");
-           if(ret == 0)
-               free(tpn);
-           ret = KRB5KRB_AP_ERR_NOT_US;
-           goto out;
-           
-       }
-
-       ret = _kdc_check_flags(context, config, 
-                              client, cpn,
-                              server, spn,
-                              FALSE);
-       if(ret)
-           goto out;
-
-       if((b->kdc_options.validate || b->kdc_options.renew) && 
-          !krb5_principal_compare(context, 
-                                  krbtgt->entry.principal,
-                                  server->entry.principal)){
-           kdc_log(context, config, 0, "Inconsistent request.");
-           ret = KRB5KDC_ERR_SERVER_NOMATCH;
-           goto out;
-       }
-
-       /* check for valid set of addresses */
-       if(!check_addresses(context, config, tgt->caddr, from_addr)) {
-           ret = KRB5KRB_AP_ERR_BADADDR;
-           kdc_log(context, config, 0, "Request from wrong address");
-           goto out;
-       }
-       
-       ret = tgs_make_reply(context,
-                            config, 
-                            b, 
-                            tgt, 
-                            b->kdc_options.enc_tkt_in_skey ? &adtkt : NULL, 
-                            auth_data,
-                            ticket,
-                            server, 
-                            spn,
-                            client, 
-                            cp, 
-                            krbtgt, 
-                            &tkey->key,
-                            cetype, 
-                            &e_text,
-                            reply);
-       
-    out:
-       free(spn);
-       free(cpn);
-           
-       if(server)
-           _kdc_free_ent(context, server);
-       if(client)
-           _kdc_free_ent(context, client);
-    }
- out2:
-    if(ret) {
-       krb5_mk_error(context,
-                     ret,
-                     e_text,
-                     NULL,
-                     cp,
-                     sp,
-                     NULL,
-                     NULL,
-                     reply);
-       free(*csec);
-       free(*cusec);
-       *csec  = NULL;
-       *cusec = NULL;
-    }
-    krb5_free_principal(context, cp);
-    krb5_free_principal(context, sp);
-    if (ticket)
-       krb5_free_ticket(context, ticket);
-    free_AP_REQ(&ap_req);
-    if(auth_data){
-       free_AuthorizationData(auth_data);
-       free(auth_data);
-    }
-
-    if(krbtgt)
-       _kdc_free_ent(context, krbtgt);
-
-    return ret;
-}
-
-
-krb5_error_code
-_kdc_tgs_rep(krb5_context context, 
-            krb5_kdc_configuration *config,
-            KDC_REQ *req, 
-            krb5_data *data,
-            const char *from,
-            struct sockaddr *from_addr)
-{
-    krb5_error_code ret;
-    int i = 0;
-    PA_DATA *tgs_req = NULL;
-    time_t *csec = NULL;
-    int *cusec = NULL;
-
-    if(req->padata == NULL){
-       ret = KRB5KDC_ERR_PREAUTH_REQUIRED; /* XXX ??? */
-       kdc_log(context, config, 0,
-               "TGS-REQ from %s without PA-DATA", from);
-       goto out;
-    }
-    
-    tgs_req = find_padata(req, &i, KRB5_PADATA_TGS_REQ);
-
-    if(tgs_req == NULL){
-       ret = KRB5KDC_ERR_PADATA_TYPE_NOSUPP;
-       
-       kdc_log(context, config, 0, 
-               "TGS-REQ from %s without PA-TGS-REQ", from);
-       goto out;
-    }
-    ret = tgs_rep2(context, config, 
-                  &req->req_body, tgs_req, data, from, from_addr,
-                  &csec, &cusec);
-out:
-    if(ret && data->data == NULL){
-       krb5_mk_error(context,
-                     ret,
-                     NULL,
-                     NULL,
-                     NULL,
-                     NULL,
-                     csec,
-                     cusec,
-                     data);
-    }
-    free(csec);
-    free(cusec);
-    return 0;
-}
diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c
new file mode 100644 (file)
index 0000000..dcf29eb
--- /dev/null
@@ -0,0 +1,1781 @@
+/*
+ * 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 "kdc_locl.h"
+
+RCSID("$Id: krb5tgs.c,v 1.16 2006/10/22 15:54:37 lha Exp $");
+
+/*
+ * return the realm of a krbtgt-ticket or NULL
+ */
+
+static Realm 
+get_krbtgt_realm(const PrincipalName *p)
+{
+    if(p->name_string.len == 2
+       && strcmp(p->name_string.val[0], KRB5_TGS_NAME) == 0)
+       return p->name_string.val[1];
+    else
+       return NULL;
+}
+
+/*
+ * The KDC might add a signed path to the ticket authorization data
+ * field. This is to avoid server impersonating clients and the
+ * request constrained delegation.
+ *
+ * This is done by storing a KRB5_AUTHDATA_IF_RELEVANT with a single
+ * entry of type KRB5SignedPath.
+ */
+
+static krb5_error_code
+find_KRB5SignedPath(krb5_context context,
+                   const AuthorizationData *ad,
+                   krb5_data *data)
+{
+    AuthorizationData child;
+    krb5_error_code ret;
+    int pos;
+       
+    if (ad == NULL || ad->len == 0)
+       return KRB5KDC_ERR_PADATA_TYPE_NOSUPP;
+
+    pos = ad->len - 1;
+
+    if (ad->val[pos].ad_type != KRB5_AUTHDATA_IF_RELEVANT)
+       return KRB5KDC_ERR_PADATA_TYPE_NOSUPP;
+
+    ret = decode_AuthorizationData(ad->val[pos].ad_data.data,
+                                  ad->val[pos].ad_data.length,
+                                  &child,
+                                  NULL);
+    if (ret) {
+       krb5_set_error_string(context, "Failed to decode "
+                             "IF_RELEVANT with %d", ret);
+       return ret;
+    }
+
+    if (child.len != 1) {
+       free_AuthorizationData(&child);
+       return KRB5KDC_ERR_PADATA_TYPE_NOSUPP;
+    }
+
+    if (child.val[0].ad_type != KRB5_AUTHDATA_SIGNTICKET) {
+       free_AuthorizationData(&child);
+       return KRB5KDC_ERR_PADATA_TYPE_NOSUPP;
+    }
+
+    if (data)
+       ret = der_copy_octet_string(&child.val[0].ad_data, data);
+    free_AuthorizationData(&child);
+    return ret;
+}
+
+krb5_error_code
+_kdc_add_KRB5SignedPath(krb5_context context,
+                       krb5_kdc_configuration *config,
+                       hdb_entry_ex *krbtgt,
+                       krb5_enctype enctype,
+                       krb5_const_principal server,
+                       KRB5SignedPathPrincipals *principals,
+                       EncTicketPart *tkt)
+{
+    krb5_error_code ret;
+    KRB5SignedPath sp;
+    krb5_data data;
+    krb5_crypto crypto = NULL;
+    size_t size;
+
+    if (server && principals) {
+       ret = add_KRB5SignedPathPrincipals(principals, server);
+       if (ret)
+           goto out;
+    }
+
+    {
+       KRB5SignedPathData spd;
+       
+       spd.encticket = *tkt;
+       spd.delegated = principals;
+       
+       ASN1_MALLOC_ENCODE(KRB5SignedPathData, data.data, data.length,
+                          &spd, &size, ret);
+       if (ret)
+           goto out;
+       if (data.length != size)
+           krb5_abortx(context, "internal asn.1 encoder error");
+    }
+
+    {
+       Key *key;
+       ret = hdb_enctype2key(context, &krbtgt->entry, enctype, &key);
+       if (ret == 0)
+           ret = krb5_crypto_init(context, &key->key, 0, &crypto);
+       if (ret) {
+           free(data.data);
+           return ret;
+       }
+    }
+
+    /*
+     * Fill in KRB5SignedPath
+     */
+
+    sp.etype = enctype;
+    sp.delegated = principals;
+
+    ret = krb5_create_checksum(context, crypto, KRB5_KU_KRB5SIGNEDPATH, 0,
+                              data.data, data.length, &sp.cksum);
+    krb5_crypto_destroy(context, crypto);
+    free(data.data);
+    if (ret)
+       goto out;
+
+    ASN1_MALLOC_ENCODE(KRB5SignedPath, data.data, data.length, &sp, &size, ret);
+    free_Checksum(&sp.cksum);
+    if (ret)
+       goto out;
+    if (data.length != size)
+       krb5_abortx(context, "internal asn.1 encoder error");
+
+    
+    /*
+     * Add IF-RELEVANT(KRB5SignedPath) to the last slot in
+     * authorization data field.
+     */
+
+    if (tkt->authorization_data == NULL) {
+       tkt->authorization_data = calloc(1, sizeof(*tkt->authorization_data));
+       if (tkt->authorization_data == NULL) {
+           ret = ENOMEM;
+           goto out;
+       }
+    }
+
+    /* add the entry to the last element */
+    {
+       AuthorizationData ad = { 0, NULL };
+       AuthorizationDataElement ade;
+
+       ade.ad_type = KRB5_AUTHDATA_SIGNTICKET;
+       ade.ad_data = data;
+
+       ret = add_AuthorizationData(&ad, &ade);
+       krb5_data_free(&data);
+       if (ret)
+           return ret;
+
+       ASN1_MALLOC_ENCODE(AuthorizationData, data.data, data.length, 
+                          &ad, &size, ret);
+       free_AuthorizationData(&ad);
+       if (ret)
+           return ret;
+       if (data.length != size)
+           krb5_abortx(context, "internal asn.1 encoder error");
+       
+       ade.ad_type = KRB5_AUTHDATA_IF_RELEVANT;
+       ade.ad_data = data;
+
+       ret = add_AuthorizationData(tkt->authorization_data, &ade);
+       krb5_data_free(&data);
+       if (ret)
+           return ret;
+    }
+
+out:
+    return 0;
+}
+
+static krb5_error_code
+check_KRB5SignedPath(krb5_context context,
+                    krb5_kdc_configuration *config,
+                    hdb_entry_ex *krbtgt,
+                    EncTicketPart *tkt,
+                    KRB5SignedPathPrincipals **delegated,
+                    int require_signedpath)
+{
+    krb5_error_code ret;
+    krb5_data data;
+    krb5_crypto crypto = NULL;
+
+    *delegated = NULL;
+
+    ret = find_KRB5SignedPath(context, tkt->authorization_data, &data);
+    if (ret == 0) {
+       KRB5SignedPathData spd;
+       KRB5SignedPath sp;
+       AuthorizationData *ad;
+       size_t size;
+
+       ret = decode_KRB5SignedPath(data.data, data.length, &sp, NULL);
+       krb5_data_free(&data);
+       if (ret)
+           return ret;
+
+       spd.encticket = *tkt;
+       /* the KRB5SignedPath is the last entry */
+       ad = spd.encticket.authorization_data;
+       if (--ad->len == 0)
+           spd.encticket.authorization_data = NULL;
+       spd.delegated = sp.delegated;
+
+       ASN1_MALLOC_ENCODE(KRB5SignedPathData, data.data, data.length,
+                          &spd, &size, ret);
+       ad->len++;
+       spd.encticket.authorization_data = ad;
+       if (ret) {
+           free_KRB5SignedPath(&sp);
+           return ret;
+       }
+       if (data.length != size)
+           krb5_abortx(context, "internal asn.1 encoder error");
+
+       {
+           Key *key;
+           ret = hdb_enctype2key(context, &krbtgt->entry, sp.etype, &key);
+           if (ret == 0)
+               ret = krb5_crypto_init(context, &key->key, 0, &crypto);
+           if (ret) {
+               free(data.data);
+               free_KRB5SignedPath(&sp);
+               return ret;
+           }
+       }
+       ret = krb5_verify_checksum(context, crypto, KRB5_KU_KRB5SIGNEDPATH, 
+                                  data.data, data.length, 
+                                  &sp.cksum);
+       krb5_crypto_destroy(context, crypto);
+       free(data.data);
+       if (ret) {
+           free_KRB5SignedPath(&sp);
+           return ret;
+       }
+
+       if (sp.delegated) {
+
+           *delegated = malloc(sizeof(*sp.delegated));
+           if (*delegated == NULL) {
+               free_KRB5SignedPath(&sp);
+               return ENOMEM;
+           }
+
+           ret = copy_KRB5SignedPathPrincipals(*delegated, sp.delegated);
+           if (ret) {
+               free_KRB5SignedPath(&sp);
+               free(*delegated);
+               *delegated = NULL;
+               return ret;
+           }
+       }
+       free_KRB5SignedPath(&sp);
+       
+    } else {
+       if (require_signedpath)
+           return KRB5KDC_ERR_BADOPTION;
+    }
+
+    return 0;
+}
+
+
+/*
+ *
+ */
+
+static krb5_error_code
+check_tgs_flags(krb5_context context,        
+               krb5_kdc_configuration *config,
+               KDC_REQ_BODY *b, const EncTicketPart *tgt, EncTicketPart *et)
+{
+    KDCOptions f = b->kdc_options;
+       
+    if(f.validate){
+       if(!tgt->flags.invalid || tgt->starttime == NULL){
+           kdc_log(context, config, 0,
+                   "Bad request to validate ticket");
+           return KRB5KDC_ERR_BADOPTION;
+       }
+       if(*tgt->starttime > kdc_time){
+           kdc_log(context, config, 0,
+                   "Early request to validate ticket");
+           return KRB5KRB_AP_ERR_TKT_NYV;
+       }
+       /* XXX  tkt = tgt */
+       et->flags.invalid = 0;
+    }else if(tgt->flags.invalid){
+       kdc_log(context, config, 0, 
+               "Ticket-granting ticket has INVALID flag set");
+       return KRB5KRB_AP_ERR_TKT_INVALID;
+    }
+
+    if(f.forwardable){
+       if(!tgt->flags.forwardable){
+           kdc_log(context, config, 0,
+                   "Bad request for forwardable ticket");
+           return KRB5KDC_ERR_BADOPTION;
+       }
+       et->flags.forwardable = 1;
+    }
+    if(f.forwarded){
+       if(!tgt->flags.forwardable){
+           kdc_log(context, config, 0,
+                   "Request to forward non-forwardable ticket");
+           return KRB5KDC_ERR_BADOPTION;
+       }
+       et->flags.forwarded = 1;
+       et->caddr = b->addresses;
+    }
+    if(tgt->flags.forwarded)
+       et->flags.forwarded = 1;
+       
+    if(f.proxiable){
+       if(!tgt->flags.proxiable){
+           kdc_log(context, config, 0,
+                   "Bad request for proxiable ticket");
+           return KRB5KDC_ERR_BADOPTION;
+       }
+       et->flags.proxiable = 1;
+    }
+    if(f.proxy){
+       if(!tgt->flags.proxiable){
+           kdc_log(context, config, 0,
+                   "Request to proxy non-proxiable ticket");
+           return KRB5KDC_ERR_BADOPTION;
+       }
+       et->flags.proxy = 1;
+       et->caddr = b->addresses;
+    }
+    if(tgt->flags.proxy)
+       et->flags.proxy = 1;
+
+    if(f.allow_postdate){
+       if(!tgt->flags.may_postdate){
+           kdc_log(context, config, 0,
+                   "Bad request for post-datable ticket");
+           return KRB5KDC_ERR_BADOPTION;
+       }
+       et->flags.may_postdate = 1;
+    }
+    if(f.postdated){
+       if(!tgt->flags.may_postdate){
+           kdc_log(context, config, 0,
+                   "Bad request for postdated ticket");
+           return KRB5KDC_ERR_BADOPTION;
+       }
+       if(b->from)
+           *et->starttime = *b->from;
+       et->flags.postdated = 1;
+       et->flags.invalid = 1;
+    }else if(b->from && *b->from > kdc_time + context->max_skew){
+       kdc_log(context, config, 0, "Ticket cannot be postdated");
+       return KRB5KDC_ERR_CANNOT_POSTDATE;
+    }
+
+    if(f.renewable){
+       if(!tgt->flags.renewable){
+           kdc_log(context, config, 0,
+                   "Bad request for renewable ticket");
+           return KRB5KDC_ERR_BADOPTION;
+       }
+       et->flags.renewable = 1;
+       ALLOC(et->renew_till);
+       _kdc_fix_time(&b->rtime);
+       *et->renew_till = *b->rtime;
+    }
+    if(f.renew){
+       time_t old_life;
+       if(!tgt->flags.renewable || tgt->renew_till == NULL){
+           kdc_log(context, config, 0,
+                   "Request to renew non-renewable ticket");
+           return KRB5KDC_ERR_BADOPTION;
+       }
+       old_life = tgt->endtime;
+       if(tgt->starttime)
+           old_life -= *tgt->starttime;
+       else
+           old_life -= tgt->authtime;
+       et->endtime = *et->starttime + old_life;
+       if (et->renew_till != NULL)
+           et->endtime = min(*et->renew_till, et->endtime);
+    }      
+    
+    /* checks for excess flags */
+    if(f.request_anonymous && !config->allow_anonymous){
+       kdc_log(context, config, 0,
+               "Request for anonymous ticket");
+       return KRB5KDC_ERR_BADOPTION;
+    }
+    return 0;
+}
+
+/*
+ *
+ */
+
+static krb5_error_code
+check_constrained_delegation(krb5_context context, 
+                            krb5_kdc_configuration *config,
+                            hdb_entry_ex *client,
+                            krb5_const_principal server)
+{
+    const HDB_Ext_Constrained_delegation_acl *acl;
+    krb5_error_code ret;
+    int i;
+
+    ret = hdb_entry_get_ConstrainedDelegACL(&client->entry, &acl);
+    if (ret) {
+       krb5_clear_error_string(context);
+       return ret;
+    }
+
+    if (acl) {
+       for (i = 0; i < acl->len; i++) {
+           if (krb5_principal_compare(context, server, &acl->val[i]) == TRUE)
+               return 0;
+       }
+    }
+    kdc_log(context, config, 0,
+           "Bad request for constrained delegation");
+    return KRB5KDC_ERR_BADOPTION;
+}
+
+/*
+ *
+ */
+
+static krb5_error_code
+verify_flags (krb5_context context, 
+             krb5_kdc_configuration *config,
+             const EncTicketPart *et,
+             const char *pstr)
+{
+    if(et->endtime < kdc_time){
+       kdc_log(context, config, 0, "Ticket expired (%s)", pstr);
+       return KRB5KRB_AP_ERR_TKT_EXPIRED;
+    }
+    if(et->flags.invalid){
+       kdc_log(context, config, 0, "Ticket not valid (%s)", pstr);
+       return KRB5KRB_AP_ERR_TKT_NYV;
+    }
+    return 0;
+}
+
+/*
+ *
+ */
+
+static krb5_error_code
+fix_transited_encoding(krb5_context context, 
+                      krb5_kdc_configuration *config,
+                      krb5_boolean check_policy,
+                      const TransitedEncoding *tr, 
+                      EncTicketPart *et, 
+                      const char *client_realm, 
+                      const char *server_realm, 
+                      const char *tgt_realm)
+{
+    krb5_error_code ret = 0;
+    char **realms, **tmp;
+    int num_realms;
+    int i;
+
+    switch (tr->tr_type) {
+    case DOMAIN_X500_COMPRESS:
+       break;
+    case 0:
+       /*
+        * Allow empty content of type 0 because that is was Microsoft
+        * generates in their TGT.
+        */
+       if (tr->contents.length == 0)
+           break;
+       kdc_log(context, config, 0,
+               "Transited type 0 with non empty content");
+       return KRB5KDC_ERR_TRTYPE_NOSUPP;
+    default:
+       kdc_log(context, config, 0,
+               "Unknown transited type: %u", tr->tr_type);
+       return KRB5KDC_ERR_TRTYPE_NOSUPP;
+    }
+
+    ret = krb5_domain_x500_decode(context, 
+                                 tr->contents,
+                                 &realms, 
+                                 &num_realms,
+                                 client_realm,
+                                 server_realm);
+    if(ret){
+       krb5_warn(context, ret,
+                 "Decoding transited encoding");
+       return ret;
+    }
+    if(strcmp(client_realm, tgt_realm) && strcmp(server_realm, tgt_realm)) {
+       /* not us, so add the previous realm to transited set */
+       if (num_realms < 0 || num_realms + 1 > UINT_MAX/sizeof(*realms)) {
+           ret = ERANGE;
+           goto free_realms;
+       }
+       tmp = realloc(realms, (num_realms + 1) * sizeof(*realms));
+       if(tmp == NULL){
+           ret = ENOMEM;
+           goto free_realms;
+       }
+       realms = tmp;
+       realms[num_realms] = strdup(tgt_realm);
+       if(realms[num_realms] == NULL){
+           ret = ENOMEM;
+           goto free_realms;
+       }
+       num_realms++;
+    }
+    if(num_realms == 0) {
+       if(strcmp(client_realm, server_realm)) 
+           kdc_log(context, config, 0,
+                   "cross-realm %s -> %s", client_realm, server_realm);
+    } else {
+       size_t l = 0;
+       char *rs;
+       for(i = 0; i < num_realms; i++)
+           l += strlen(realms[i]) + 2;
+       rs = malloc(l);
+       if(rs != NULL) {
+           *rs = '\0';
+           for(i = 0; i < num_realms; i++) {
+               if(i > 0)
+                   strlcat(rs, ", ", l);
+               strlcat(rs, realms[i], l);
+           }
+           kdc_log(context, config, 0,
+                   "cross-realm %s -> %s via [%s]",
+                   client_realm, server_realm, rs);
+           free(rs);
+       }
+    }
+    if(check_policy) {
+       ret = krb5_check_transited(context, client_realm, 
+                                  server_realm, 
+                                  realms, num_realms, NULL);
+       if(ret) {
+           krb5_warn(context, ret, "cross-realm %s -> %s", 
+                     client_realm, server_realm);
+           goto free_realms;
+       }
+       et->flags.transited_policy_checked = 1;
+    }
+    et->transited.tr_type = DOMAIN_X500_COMPRESS;
+    ret = krb5_domain_x500_encode(realms, num_realms, &et->transited.contents);
+    if(ret)
+       krb5_warn(context, ret, "Encoding transited encoding");
+  free_realms:
+    for(i = 0; i < num_realms; i++)
+       free(realms[i]);
+    free(realms);
+    return ret;
+}
+
+
+static krb5_error_code
+tgs_make_reply(krb5_context context, 
+              krb5_kdc_configuration *config,
+              KDC_REQ_BODY *b, 
+              krb5_const_principal tgt_name,
+              const EncTicketPart *tgt, 
+              const EncTicketPart *adtkt, 
+              AuthorizationData *auth_data,
+              krb5_ticket *tgs_ticket,
+              hdb_entry_ex *server, 
+              const char *server_name, 
+              hdb_entry_ex *client, 
+              krb5_principal client_principal, 
+              hdb_entry_ex *krbtgt,
+              krb5_enctype krbtgt_etype,
+              KRB5SignedPathPrincipals *spp,
+              EncryptionKey *tgtkey,
+              const char **e_text,
+              krb5_data *reply)
+{
+    KDC_REP rep;
+    EncKDCRepPart ek;
+    EncTicketPart et;
+    KDCOptions f = b->kdc_options;
+    krb5_error_code ret;
+    krb5_enctype etype;
+    Key *skey;
+    const EncryptionKey *ekey;
+    AuthorizationData *new_auth_data = NULL;
+    
+    if(adtkt) {
+       int i;
+       ekey = &adtkt->key;
+       for(i = 0; i < b->etype.len; i++)
+           if (b->etype.val[i] == adtkt->key.keytype)
+               break;
+       if(i == b->etype.len) {
+           krb5_clear_error_string(context);
+           return KRB5KDC_ERR_ETYPE_NOSUPP;
+       }
+       etype = b->etype.val[i];
+    }else{
+       ret = _kdc_find_etype(context, server, b->etype.val, b->etype.len,
+                             &skey, &etype);
+       if(ret) {
+           kdc_log(context, config, 0, 
+                   "Server (%s) has no support for etypes", server_name);
+           return ret;
+       }
+       ekey = &skey->key;
+    }
+    
+    memset(&rep, 0, sizeof(rep));
+    memset(&et, 0, sizeof(et));
+    memset(&ek, 0, sizeof(ek));
+    
+    rep.pvno = 5;
+    rep.msg_type = krb_tgs_rep;
+
+    et.authtime = tgt->authtime;
+    _kdc_fix_time(&b->till);
+    et.endtime = min(tgt->endtime, *b->till);
+    ALLOC(et.starttime);
+    *et.starttime = kdc_time;
+    
+    ret = check_tgs_flags(context, config, b, tgt, &et);
+    if(ret)
+       goto out;
+
+    /* We should check the transited encoding if:
+       1) the request doesn't ask not to be checked
+       2) globally enforcing a check
+       3) principal requires checking
+       4) we allow non-check per-principal, but principal isn't marked as allowing this
+       5) we don't globally allow this
+    */
+
+#define GLOBAL_FORCE_TRANSITED_CHECK           \
+    (config->trpolicy == TRPOLICY_ALWAYS_CHECK)
+#define GLOBAL_ALLOW_PER_PRINCIPAL                     \
+    (config->trpolicy == TRPOLICY_ALLOW_PER_PRINCIPAL)
+#define GLOBAL_ALLOW_DISABLE_TRANSITED_CHECK                   \
+    (config->trpolicy == TRPOLICY_ALWAYS_HONOUR_REQUEST)
+
+/* these will consult the database in future release */
+#define PRINCIPAL_FORCE_TRANSITED_CHECK(P)             0
+#define PRINCIPAL_ALLOW_DISABLE_TRANSITED_CHECK(P)     0
+
+    ret = fix_transited_encoding(context, config, 
+                                !f.disable_transited_check ||
+                                GLOBAL_FORCE_TRANSITED_CHECK ||
+                                PRINCIPAL_FORCE_TRANSITED_CHECK(server) ||
+                                !((GLOBAL_ALLOW_PER_PRINCIPAL && 
+                                   PRINCIPAL_ALLOW_DISABLE_TRANSITED_CHECK(server)) ||
+                                  GLOBAL_ALLOW_DISABLE_TRANSITED_CHECK),
+                                &tgt->transited, &et,
+                                *krb5_princ_realm(context, client_principal),
+                                *krb5_princ_realm(context, server->entry.principal),
+                                *krb5_princ_realm(context, krbtgt->entry.principal));
+    if(ret)
+       goto out;
+
+    copy_Realm(krb5_princ_realm(context, server->entry.principal), 
+              &rep.ticket.realm);
+    _krb5_principal2principalname(&rep.ticket.sname, server->entry.principal);
+    copy_Realm(&tgt_name->realm, &rep.crealm);
+    if (f.request_anonymous)
+       _kdc_make_anonymous_principalname (&rep.cname);
+    else
+       copy_PrincipalName(&tgt_name->name, &rep.cname);
+    rep.ticket.tkt_vno = 5;
+
+    ek.caddr = et.caddr;
+    if(et.caddr == NULL)
+       et.caddr = tgt->caddr;
+
+    {
+       time_t life;
+       life = et.endtime - *et.starttime;
+       if(client && client->entry.max_life)
+           life = min(life, *client->entry.max_life);
+       if(server->entry.max_life)
+           life = min(life, *server->entry.max_life);
+       et.endtime = *et.starttime + life;
+    }
+    if(f.renewable_ok && tgt->flags.renewable && 
+       et.renew_till == NULL && et.endtime < *b->till){
+       et.flags.renewable = 1;
+       ALLOC(et.renew_till);
+       *et.renew_till = *b->till;
+    }
+    if(et.renew_till){
+       time_t renew;
+       renew = *et.renew_till - et.authtime;
+       if(client && client->entry.max_renew)
+           renew = min(renew, *client->entry.max_renew);
+       if(server->entry.max_renew)
+           renew = min(renew, *server->entry.max_renew);
+       *et.renew_till = et.authtime + renew;
+    }
+           
+    if(et.renew_till){
+       *et.renew_till = min(*et.renew_till, *tgt->renew_till);
+       *et.starttime = min(*et.starttime, *et.renew_till);
+       et.endtime = min(et.endtime, *et.renew_till);
+    }
+    
+    *et.starttime = min(*et.starttime, et.endtime);
+
+    if(*et.starttime == et.endtime){
+       ret = KRB5KDC_ERR_NEVER_VALID;
+       goto out;
+    }
+    if(et.renew_till && et.endtime == *et.renew_till){
+       free(et.renew_till);
+       et.renew_till = NULL;
+       et.flags.renewable = 0;
+    }
+    
+    et.flags.pre_authent = tgt->flags.pre_authent;
+    et.flags.hw_authent  = tgt->flags.hw_authent;
+    et.flags.anonymous   = tgt->flags.anonymous;
+    et.flags.ok_as_delegate = server->entry.flags.ok_as_delegate;
+           
+    
+    krb5_generate_random_keyblock(context, etype, &et.key);
+
+    if (server->authz_data_tgs_req) {
+           ret = server->authz_data_tgs_req(context, server,
+                                            client_principal, 
+                                            tgs_ticket->ticket.authorization_data,
+                                            tgs_ticket->ticket.authtime,
+                                            tgtkey,
+                                            ekey, 
+                                            &et.key, 
+                                            &new_auth_data);
+           if (ret) {
+                   new_auth_data = NULL;
+           }
+    }
+
+    /* XXX Check enc-authorization-data */
+    et.authorization_data = new_auth_data;
+
+    et.crealm = tgt->crealm;
+    et.cname = tgt_name->name;
+           
+    ek.key = et.key;
+    /* MIT must have at least one last_req */
+    ek.last_req.len = 1;
+    ek.last_req.val = calloc(1, sizeof(*ek.last_req.val));
+    ek.nonce = b->nonce;
+    ek.flags = et.flags;
+    ek.authtime = et.authtime;
+    ek.starttime = et.starttime;
+    ek.endtime = et.endtime;
+    ek.renew_till = et.renew_till;
+    ek.srealm = rep.ticket.realm;
+    ek.sname = rep.ticket.sname;
+    
+    _kdc_log_timestamp(context, config, "TGS-REQ", et.authtime, et.starttime, 
+                      et.endtime, et.renew_till);
+
+    /* Don't sign cross realm tickets, they can't be checked anyway */
+    {
+       char *r = get_krbtgt_realm(&ek.sname);
+
+       if (r == NULL || strcmp(r, ek.srealm) == 0) {
+           ret = _kdc_add_KRB5SignedPath(context,
+                                         config,
+                                         krbtgt,
+                                         krbtgt_etype,
+                                         NULL,
+                                         NULL,
+                                         &et);
+           if (ret)
+               goto out;
+       }
+    }
+
+    /* It is somewhat unclear where the etype in the following
+       encryption should come from. What we have is a session
+       key in the passed tgt, and a list of preferred etypes
+       *for the new ticket*. Should we pick the best possible
+       etype, given the keytype in the tgt, or should we look
+       at the etype list here as well?  What if the tgt
+       session key is DES3 and we want a ticket with a (say)
+       CAST session key. Should the DES3 etype be added to the
+       etype list, even if we don't want a session key with
+       DES3? */
+    ret = _kdc_encode_reply(context, config, 
+                           &rep, &et, &ek, etype,
+                           adtkt ? 0 : server->entry.kvno, 
+                           ekey, 0, &tgt->key, e_text, reply);
+out:
+    free_TGS_REP(&rep);
+    free_TransitedEncoding(&et.transited);
+    if(et.starttime)
+       free(et.starttime);
+    if(et.renew_till)
+       free(et.renew_till);
+    if(et.authorization_data) {
+       free_AuthorizationData(et.authorization_data);
+       free(et.authorization_data);
+    }
+    free_LastReq(&ek.last_req);
+    memset(et.key.keyvalue.data, 0, et.key.keyvalue.length);
+    free_EncryptionKey(&et.key);
+    return ret;
+}
+
+static krb5_error_code
+tgs_check_authenticator(krb5_context context, 
+                       krb5_kdc_configuration *config,
+                       krb5_auth_context ac,
+                       KDC_REQ_BODY *b, 
+                       const char **e_text,
+                       krb5_keyblock *key)
+{
+    krb5_authenticator auth;
+    size_t len;
+    unsigned char *buf;
+    size_t buf_size;
+    krb5_error_code ret;
+    krb5_crypto crypto;
+    
+    krb5_auth_con_getauthenticator(context, ac, &auth);
+    if(auth->cksum == NULL){
+       kdc_log(context, config, 0, "No authenticator in request");
+       ret = KRB5KRB_AP_ERR_INAPP_CKSUM;
+       goto out;
+    }
+    /*
+     * according to RFC1510 it doesn't need to be keyed,
+     * but according to the latest draft it needs to.
+     */
+    if (
+#if 0
+!krb5_checksum_is_keyed(context, auth->cksum->cksumtype)
+       ||
+#endif
+ !krb5_checksum_is_collision_proof(context, auth->cksum->cksumtype)) {
+       kdc_log(context, config, 0, "Bad checksum type in authenticator: %d", 
+               auth->cksum->cksumtype);
+       ret =  KRB5KRB_AP_ERR_INAPP_CKSUM;
+       goto out;
+    }
+               
+    /* XXX should not re-encode this */
+    ASN1_MALLOC_ENCODE(KDC_REQ_BODY, buf, buf_size, b, &len, ret);
+    if(ret){
+       kdc_log(context, config, 0, "Failed to encode KDC-REQ-BODY: %s", 
+               krb5_get_err_text(context, ret));
+       goto out;
+    }
+    if(buf_size != len) {
+       free(buf);
+       kdc_log(context, config, 0, "Internal error in ASN.1 encoder");
+       *e_text = "KDC internal error";
+       ret = KRB5KRB_ERR_GENERIC;
+       goto out;
+    }
+    ret = krb5_crypto_init(context, key, 0, &crypto);
+    if (ret) {
+       free(buf);
+       kdc_log(context, config, 0, "krb5_crypto_init failed: %s",
+               krb5_get_err_text(context, ret));
+       goto out;
+    }
+    ret = krb5_verify_checksum(context,
+                              crypto,
+                              KRB5_KU_TGS_REQ_AUTH_CKSUM,
+                              buf, 
+                              len,
+                              auth->cksum);
+    free(buf);
+    krb5_crypto_destroy(context, crypto);
+    if(ret){
+       kdc_log(context, config, 0,
+               "Failed to verify authenticator checksum: %s", 
+               krb5_get_err_text(context, ret));
+    }
+out:
+    free_Authenticator(auth);
+    free(auth);
+    return ret;
+}
+
+/*
+ *
+ */
+
+static const char *
+find_rpath(krb5_context context, Realm crealm, Realm srealm)
+{
+    const char *new_realm = krb5_config_get_string(context,
+                                                  NULL,
+                                                  "capaths", 
+                                                  crealm,
+                                                  srealm,
+                                                  NULL);
+    return new_realm;
+}
+           
+
+static krb5_boolean
+need_referral(krb5_context context, krb5_principal server, krb5_realm **realms)
+{
+    if(server->name.name_type != KRB5_NT_SRV_INST ||
+       server->name.name_string.len != 2)
+       return FALSE;
+    return _krb5_get_host_realm_int(context, server->name.name_string.val[1],
+                                   FALSE, realms) == 0;
+}
+
+static krb5_error_code
+tgs_parse_request(krb5_context context, 
+                 krb5_kdc_configuration *config,
+                 KDC_REQ_BODY *b,
+                 PA_DATA *tgs_req,
+                 hdb_entry_ex **krbtgt,
+                 krb5_enctype *krbtgt_etype,
+                 krb5_ticket **ticket,
+                 const char **e_text,
+                 const char *from,
+                 const struct sockaddr *from_addr,
+                 time_t **csec,
+                 int **cusec,
+                 AuthorizationData **auth_data,
+                 EncryptionKey **tgtkey)
+{
+    krb5_ap_req ap_req;
+    krb5_error_code ret;
+    krb5_principal princ;
+    krb5_auth_context ac = NULL;
+    krb5_flags ap_req_options;
+    krb5_flags verify_ap_req_flags;
+    krb5_crypto crypto;
+    Key *tkey;
+
+    *auth_data = NULL;
+    *csec  = NULL;
+    *cusec = NULL;
+
+    memset(&ap_req, 0, sizeof(ap_req));
+    ret = krb5_decode_ap_req(context, &tgs_req->padata_value, &ap_req);
+    if(ret){
+       kdc_log(context, config, 0, "Failed to decode AP-REQ: %s", 
+               krb5_get_err_text(context, ret));
+       goto out;
+    }
+
+    if(!get_krbtgt_realm(&ap_req.ticket.sname)){
+       /* XXX check for ticket.sname == req.sname */
+       kdc_log(context, config, 0, "PA-DATA is not a ticket-granting ticket");
+       ret = KRB5KDC_ERR_POLICY; /* ? */
+       goto out;
+    }
+    
+    _krb5_principalname2krb5_principal(context,
+                                      &princ,
+                                      ap_req.ticket.sname,
+                                      ap_req.ticket.realm);
+    
+    ret = _kdc_db_fetch(context, config, princ, HDB_F_GET_KRBTGT, NULL, krbtgt);
+
+    if(ret) {
+       char *p;
+       ret = krb5_unparse_name(context, princ, &p);
+       if (ret != 0)
+           p = "<unparse_name failed>";
+       krb5_free_principal(context, princ);
+       kdc_log(context, config, 0,
+               "Ticket-granting ticket not found in database: %s: %s",
+               p, krb5_get_err_text(context, ret));
+       if (ret == 0)
+           free(p);
+       ret = KRB5KRB_AP_ERR_NOT_US;
+       goto out;
+    }
+    
+    if(ap_req.ticket.enc_part.kvno && 
+       *ap_req.ticket.enc_part.kvno != (*krbtgt)->entry.kvno){
+       char *p;
+
+       ret = krb5_unparse_name (context, princ, &p);
+       krb5_free_principal(context, princ);
+       if (ret != 0)
+           p = "<unparse_name failed>";
+       kdc_log(context, config, 0,
+               "Ticket kvno = %d, DB kvno = %d (%s)", 
+               *ap_req.ticket.enc_part.kvno,
+               (*krbtgt)->entry.kvno,
+               p);
+       if (ret == 0)
+           free (p);
+       ret = KRB5KRB_AP_ERR_BADKEYVER;
+       goto out;
+    }
+
+    *krbtgt_etype = ap_req.ticket.enc_part.etype;
+
+    ret = hdb_enctype2key(context, &(*krbtgt)->entry, 
+                         ap_req.ticket.enc_part.etype, &tkey);
+    if(ret){
+       char *str, *p;
+       krb5_enctype_to_string(context, ap_req.ticket.enc_part.etype, &str);
+       krb5_unparse_name(context, princ, &p);
+       kdc_log(context, config, 0,
+               "No server key with enctype %s found for %s", str, p);
+       free(str);
+       free(p);
+       ret = KRB5KRB_AP_ERR_BADKEYVER;
+       goto out;
+    }
+
+    *tgtkey = &tkey->key;
+    
+    if (b->kdc_options.validate)
+       verify_ap_req_flags = KRB5_VERIFY_AP_REQ_IGNORE_INVALID;
+    else
+       verify_ap_req_flags = 0;
+
+    ret = krb5_verify_ap_req2(context,
+                             &ac,
+                             &ap_req,
+                             princ,
+                             &tkey->key,
+                             verify_ap_req_flags,
+                             &ap_req_options,
+                             ticket,
+                             KRB5_KU_TGS_REQ_AUTH);
+                            
+    krb5_free_principal(context, princ);
+    if(ret) {
+       kdc_log(context, config, 0, "Failed to verify AP-REQ: %s", 
+               krb5_get_err_text(context, ret));
+       goto out;
+    }
+
+    {
+       krb5_authenticator auth;
+
+       ret = krb5_auth_con_getauthenticator(context, ac, &auth);
+       if (ret == 0) {
+           *csec   = malloc(sizeof(**csec));
+           if (*csec == NULL) {
+               krb5_free_authenticator(context, &auth);
+               kdc_log(context, config, 0, "malloc failed");
+               goto out;
+           }
+           **csec  = auth->ctime;
+           *cusec  = malloc(sizeof(**cusec));
+           if (*cusec == NULL) {
+               krb5_free_authenticator(context, &auth);
+               kdc_log(context, config, 0, "malloc failed");
+               goto out;
+           }
+           **cusec  = auth->cusec;
+           krb5_free_authenticator(context, &auth);
+       }
+    }
+
+    ret = tgs_check_authenticator(context, config, 
+                                 ac, b, e_text, &(*ticket)->ticket.key);
+    if (ret) {
+       krb5_auth_con_free(context, ac);
+       goto out;
+    }
+
+    if (b->enc_authorization_data) {
+       krb5_keyblock *subkey;
+       krb5_data ad;
+       ret = krb5_auth_con_getremotesubkey(context,
+                                           ac,
+                                           &subkey);
+       if(ret){
+           krb5_auth_con_free(context, ac);
+           kdc_log(context, config, 0, "Failed to get remote subkey: %s", 
+                   krb5_get_err_text(context, ret));
+           goto out;
+       }
+       if(subkey == NULL){
+           ret = krb5_auth_con_getkey(context, ac, &subkey);
+           if(ret) {
+               krb5_auth_con_free(context, ac);
+               kdc_log(context, config, 0, "Failed to get session key: %s", 
+                       krb5_get_err_text(context, ret));
+               goto out;
+           }
+       }
+       if(subkey == NULL){
+           krb5_auth_con_free(context, ac);
+           kdc_log(context, config, 0,
+                   "Failed to get key for enc-authorization-data");
+           ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */
+           goto out;
+       }
+       ret = krb5_crypto_init(context, subkey, 0, &crypto);
+       if (ret) {
+           krb5_auth_con_free(context, ac);
+           kdc_log(context, config, 0, "krb5_crypto_init failed: %s",
+                   krb5_get_err_text(context, ret));
+           goto out;
+       }
+       ret = krb5_decrypt_EncryptedData (context,
+                                         crypto,
+                                         KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY,
+                                         b->enc_authorization_data,
+                                         &ad);
+       krb5_crypto_destroy(context, crypto);
+       if(ret){
+           krb5_auth_con_free(context, ac);
+           kdc_log(context, config, 0, 
+                   "Failed to decrypt enc-authorization-data");
+           ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */
+           goto out;
+       }
+       krb5_free_keyblock(context, subkey);
+       ALLOC(*auth_data);
+       if (*auth_data == NULL) {
+           krb5_auth_con_free(context, ac);
+           ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */
+           goto out;
+       }
+       ret = decode_AuthorizationData(ad.data, ad.length, *auth_data, NULL);
+       if(ret){
+           krb5_auth_con_free(context, ac);
+           free(*auth_data);
+           *auth_data = NULL;
+           kdc_log(context, config, 0, "Failed to decode authorization data");
+           ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */
+           goto out;
+       }
+    }
+
+    krb5_auth_con_free(context, ac);
+    
+out:
+    free_AP_REQ(&ap_req);
+    
+    return ret;
+}
+
+static krb5_error_code
+tgs_build_reply(krb5_context context, 
+               krb5_kdc_configuration *config,
+               KDC_REQ *req, 
+               KDC_REQ_BODY *b,
+               hdb_entry_ex *krbtgt,
+               krb5_enctype krbtgt_etype,
+               krb5_ticket *ticket,
+               krb5_data *reply,
+               const char *from,
+               const char **e_text,
+               AuthorizationData *auth_data,
+               EncryptionKey *tgtkey,
+       const struct sockaddr *from_addr)
+{
+    krb5_error_code ret;
+    krb5_principal cp = NULL, sp = NULL;
+    krb5_principal client_principal = NULL;
+    char *spn = NULL, *cpn = NULL;
+    hdb_entry_ex *server = NULL, *client = NULL;
+    EncTicketPart *tgt = &ticket->ticket;
+    KRB5SignedPathPrincipals *spp = NULL;
+
+    PrincipalName *s;
+    Realm r;
+    int nloop = 0;
+    EncTicketPart adtkt;
+    char opt_str[128];
+    int require_signedpath = 0;
+
+    memset(&adtkt, 0, sizeof(adtkt));
+
+    s = b->sname;
+    r = b->realm;
+
+    if(b->kdc_options.enc_tkt_in_skey){
+       Ticket *t;
+       hdb_entry_ex *uu;
+       krb5_principal p;
+       Key *uukey;
+           
+       if(b->additional_tickets == NULL || 
+          b->additional_tickets->len == 0){
+           ret = KRB5KDC_ERR_BADOPTION; /* ? */
+           kdc_log(context, config, 0,
+                   "No second ticket present in request");
+           goto out;
+       }
+       t = &b->additional_tickets->val[0];
+       if(!get_krbtgt_realm(&t->sname)){
+           kdc_log(context, config, 0,
+                   "Additional ticket is not a ticket-granting ticket");
+           ret = KRB5KDC_ERR_POLICY;
+           goto out;
+       }
+       _krb5_principalname2krb5_principal(context, &p, t->sname, t->realm);
+       ret = _kdc_db_fetch(context, config, p, 
+                           HDB_F_GET_CLIENT|HDB_F_GET_SERVER, 
+                           NULL, &uu);
+       krb5_free_principal(context, p);
+       if(ret){
+           if (ret == HDB_ERR_NOENTRY)
+               ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
+           goto out;
+       }
+       ret = hdb_enctype2key(context, &uu->entry, 
+                             t->enc_part.etype, &uukey);
+       if(ret){
+           _kdc_free_ent(context, uu);
+           ret = KRB5KDC_ERR_ETYPE_NOSUPP; /* XXX */
+           goto out;
+       }
+       ret = krb5_decrypt_ticket(context, t, &uukey->key, &adtkt, 0);
+       _kdc_free_ent(context, uu);
+       if(ret)
+           goto out;
+
+       ret = verify_flags(context, config, &adtkt, spn);
+       if (ret)
+           goto out;
+
+       s = &adtkt.cname;
+       r = adtkt.crealm;
+    }
+
+    _krb5_principalname2krb5_principal(context, &sp, *s, r);
+    ret = krb5_unparse_name(context, sp, &spn);        
+    if (ret)
+       goto out;
+    _krb5_principalname2krb5_principal(context, &cp, tgt->cname, tgt->crealm);
+    ret = krb5_unparse_name(context, cp, &cpn);
+    if (ret)
+       goto out;
+    unparse_flags (KDCOptions2int(b->kdc_options),
+                  asn1_KDCOptions_units(),
+                  opt_str, sizeof(opt_str));
+    if(*opt_str)
+       kdc_log(context, config, 0,
+               "TGS-REQ %s from %s for %s [%s]", 
+               cpn, from, spn, opt_str);
+    else
+       kdc_log(context, config, 0,
+               "TGS-REQ %s from %s for %s", cpn, from, spn);
+
+    /*
+     * Fetch server
+     */
+
+server_lookup:
+    ret = _kdc_db_fetch(context, config, sp, HDB_F_GET_SERVER, NULL, &server);
+
+    if(ret){
+       const char *new_rlm;
+       Realm req_rlm;
+       krb5_realm *realms;
+
+       if ((req_rlm = get_krbtgt_realm(&sp->name)) != NULL) {
+           if(nloop++ < 2) {
+               new_rlm = find_rpath(context, tgt->crealm, req_rlm);
+               if(new_rlm) {
+                   kdc_log(context, config, 5, "krbtgt for realm %s "
+                           "not found, trying %s", 
+                           req_rlm, new_rlm);
+                   krb5_free_principal(context, sp);
+                   free(spn);
+                   krb5_make_principal(context, &sp, r, 
+                                       KRB5_TGS_NAME, new_rlm, NULL);
+                   ret = krb5_unparse_name(context, sp, &spn); 
+                   if (ret)
+                       goto out;
+                   goto server_lookup;
+               }
+           }
+       } else if(need_referral(context, sp, &realms)) {
+           if (strcmp(realms[0], sp->realm) != 0) {
+               kdc_log(context, config, 5,
+                       "Returning a referral to realm %s for "
+                       "server %s that was not found",
+                       realms[0], spn);
+               krb5_free_principal(context, sp);
+               free(spn);
+               krb5_make_principal(context, &sp, r, KRB5_TGS_NAME,
+                                   realms[0], NULL);
+               ret = krb5_unparse_name(context, sp, &spn);
+               if (ret)
+                   goto out;
+               krb5_free_host_realm(context, realms);
+               goto server_lookup;
+           }
+           krb5_free_host_realm(context, realms);
+       }
+       kdc_log(context, config, 0,
+               "Server not found in database: %s: %s", spn,
+               krb5_get_err_text(context, ret));
+       if (ret == HDB_ERR_NOENTRY)
+           ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
+       goto out;
+    }
+
+    ret = _kdc_db_fetch(context, config, cp, HDB_F_GET_CLIENT, NULL, &client);
+    if(ret) {
+       const char *krbtgt_realm; 
+
+       /*
+        * If the client belongs to the same realm as our krbtgt, it
+        * should exist in the local database.
+        *
+        */
+
+       krbtgt_realm = 
+           krb5_principal_get_comp_string(context, 
+                                          krbtgt->entry.principal, 1);
+
+       if(strcmp(krb5_principal_get_realm(context, cp), krbtgt_realm) == 0) {
+           if (ret == HDB_ERR_NOENTRY)
+               ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
+           kdc_log(context, config, 1, "Client no longer in database: %s",
+                   cpn);
+           goto out;
+       }
+       
+       kdc_log(context, config, 1, "Client not found in database: %s: %s",
+               cpn, krb5_get_err_text(context, ret));
+    }
+    
+    /*
+     * Check that service is in the same realm as the krbtgt. If its
+     * not the same, its someone that is using a uni-directional trust
+     * backward.
+     */
+    
+    if (strcmp(krb5_principal_get_realm(context, sp),
+              krb5_principal_get_comp_string(context, 
+                                             krbtgt->entry.principal, 
+                                             1)) != 0) {
+       char *tpn;
+       ret = krb5_unparse_name(context, krbtgt->entry.principal, &tpn);
+       kdc_log(context, config, 0,
+               "Request with wrong krbtgt: %s",
+               (ret == 0) ? tpn : "<unknown>");
+       if(ret == 0)
+           free(tpn);
+       ret = KRB5KRB_AP_ERR_NOT_US;
+       goto out;
+    }
+
+    /*
+     *
+     */
+
+    client_principal = cp;
+
+    if (client) {
+       const PA_DATA *sdata;
+       int i = 0;
+
+       sdata = _kdc_find_padata(req, &i, KRB5_PADATA_S4U2SELF);
+       if (sdata) {
+           krb5_crypto crypto;
+           krb5_data datack;
+           PA_S4U2Self self;
+           char *selfcpn = NULL;
+           const char *str;
+
+           ret = decode_PA_S4U2Self(sdata->padata_value.data, 
+                                    sdata->padata_value.length,
+                                    &self, NULL);
+           if (ret) {
+               kdc_log(context, config, 0, "Failed to decode PA-S4U2Self");
+               goto out;
+           }
+
+           ret = _krb5_s4u2self_to_checksumdata(context, &self, &datack);
+           if (ret)
+               goto out;
+
+           ret = krb5_crypto_init(context, &tgt->key, 0, &crypto);
+           if (ret) {
+               free_PA_S4U2Self(&self);
+               krb5_data_free(&datack);
+               kdc_log(context, config, 0, "krb5_crypto_init failed: %s",
+                       krb5_get_err_text(context, ret));
+               goto out;
+           }
+
+           ret = krb5_verify_checksum(context,
+                                      crypto,
+                                      KRB5_KU_TGS_IMPERSONATE,
+                                      datack.data, 
+                                      datack.length, 
+                                      &self.cksum);
+           krb5_data_free(&datack);
+           krb5_crypto_destroy(context, crypto);
+           if (ret) {
+               free_PA_S4U2Self(&self);
+               kdc_log(context, config, 0, 
+                       "krb5_verify_checksum failed for S4U2Self: %s",
+                       krb5_get_err_text(context, ret));
+               goto out;
+           }
+
+           ret = _krb5_principalname2krb5_principal(context,
+                                                    &client_principal,
+                                                    self.name,
+                                                    self.realm);
+           free_PA_S4U2Self(&self);
+           if (ret)
+               goto out;
+
+           ret = krb5_unparse_name(context, client_principal, &selfcpn);       
+           if (ret)
+               goto out;
+
+           /*
+            * Check that service doing the impersonating is
+            * requesting a ticket to it-self.
+            */
+           if (krb5_principal_compare(context, cp, sp) != TRUE) {
+               kdc_log(context, config, 0, "S4U2Self: %s is not allowed "
+                       "to impersonate some other user "
+                       "(tried for user %s to service %s)",
+                       cpn, selfcpn, spn);
+               free(selfcpn);
+               ret = KRB5KDC_ERR_BADOPTION; /* ? */
+               goto out;
+           }
+
+           /*
+            * If the service isn't trusted for authentication to
+            * delegation, remove the forward flag.
+            */
+
+           if (client->entry.flags.trusted_for_delegation) {
+               str = "[forwardable]";
+           } else {
+               b->kdc_options.forwardable = 0;
+               str = "";
+           }
+           kdc_log(context, config, 0, "s4u2self %s impersonating %s to "
+                   "service %s %s", cpn, selfcpn, spn, str);
+           free(selfcpn);
+       }
+    }
+
+    /*
+     * Constrained delegation
+     */
+
+    if (client != NULL
+       && b->additional_tickets != NULL
+       && b->additional_tickets->len != 0
+       && b->kdc_options.enc_tkt_in_skey == 0)
+    {
+       Key *clientkey;
+       Ticket *t;
+       char *str;
+
+       t = &b->additional_tickets->val[0];
+
+       ret = hdb_enctype2key(context, &client->entry, 
+                             t->enc_part.etype, &clientkey);
+       if(ret){
+           ret = KRB5KDC_ERR_ETYPE_NOSUPP; /* XXX */
+           goto out;
+       }
+
+       ret = krb5_decrypt_ticket(context, t, &clientkey->key, &adtkt, 0);
+       if (ret) {
+           kdc_log(context, config, 0,
+                   "failed to decrypt ticket for "
+                   "constrained delegation from %s to %s ", spn, cpn);
+           goto out;
+       }
+
+       /* check that ticket is valid */
+
+       if (adtkt.flags.forwardable == 0) {
+           kdc_log(context, config, 0,
+                   "Missing forwardable flag on ticket for "
+                   "constrained delegation from %s to %s ", spn, cpn);
+           ret = KRB5KDC_ERR_ETYPE_NOSUPP; /* XXX */
+           goto out;
+       }
+
+       ret = check_constrained_delegation(context, config, client, sp);
+       if (ret) {
+           kdc_log(context, config, 0,
+                   "constrained delegation from %s to %s not allowed", 
+                   spn, cpn);
+           goto out;
+       }
+
+       ret = _krb5_principalname2krb5_principal(context,
+                                                &client_principal,
+                                                adtkt.cname,
+                                                adtkt.crealm);
+       if (ret)
+           goto out;
+
+       ret = krb5_unparse_name(context, client_principal, &str);
+       if (ret)
+           goto out;
+
+       ret = verify_flags(context, config, &adtkt, str);
+       if (ret) {
+           free(str);
+           goto out;
+       }
+
+       /*
+        * Check KRB5SignedPath in authorization data and add new entry to
+        * make sure servers can't fake a ticket to us.
+        */
+
+       ret = check_KRB5SignedPath(context,
+                                  config,
+                                  krbtgt,
+                                  &adtkt,
+                                  &spp,
+                                  1);
+       if (ret) {
+           kdc_log(context, config, 0,
+                   "KRB5SignedPath check from service %s failed "
+                   "for delegation to %s for client %s "
+                   "from %s failed with %s",
+                   spn, str, cpn, from, krb5_get_err_text(context, ret));
+           free(str);
+           goto out;
+       }
+
+       kdc_log(context, config, 0, "constrained delegation for %s "
+               "from %s to %s", str, cpn, spn);
+       free(str);
+
+       /* 
+        * Also require that the KDC have issue the service's krbtgt
+        * used to do the request. 
+        */
+       require_signedpath = 1;
+    }
+
+    /*
+     * Check flags
+     */
+
+    ret = _kdc_check_flags(context, config, 
+                          client, cpn,
+                          server, spn,
+                          FALSE);
+    if(ret)
+       goto out;
+
+    if((b->kdc_options.validate || b->kdc_options.renew) && 
+       !krb5_principal_compare(context, 
+                              krbtgt->entry.principal,
+                              server->entry.principal)){
+       kdc_log(context, config, 0, "Inconsistent request.");
+       ret = KRB5KDC_ERR_SERVER_NOMATCH;
+       goto out;
+    }
+
+    /* check for valid set of addresses */
+    if(!_kdc_check_addresses(context, config, tgt->caddr, from_addr)) {
+       ret = KRB5KRB_AP_ERR_BADADDR;
+       kdc_log(context, config, 0, "Request from wrong address");
+       goto out;
+    }
+       
+    /* also check the krbtgt for signature */
+    ret = check_KRB5SignedPath(context,
+                              config,
+                              krbtgt,
+                              tgt,
+                              &spp,
+                              require_signedpath);
+    if (ret) {
+       kdc_log(context, config, 0,
+               "KRB5SignedPath check failed for %s (%s) from %s with %s",
+               spn, cpn, from, krb5_get_err_text(context, ret));
+       goto out;
+    }
+
+    /*
+     *
+     */
+
+    ret = tgs_make_reply(context,
+                        config, 
+                        b, 
+                        client_principal,
+                        tgt, 
+                        b->kdc_options.enc_tkt_in_skey ? &adtkt : NULL, 
+                        auth_data,
+                        ticket,
+                        server, 
+                        spn,
+                        client, 
+                        cp, 
+                        krbtgt, 
+                        krbtgt_etype,
+                        spp,
+                        tgtkey,
+                        e_text,
+                        reply);
+       
+out:
+    free(spn);
+    free(cpn);
+           
+    if(server)
+       _kdc_free_ent(context, server);
+    if(client)
+       _kdc_free_ent(context, client);
+
+    if (client_principal && client_principal != cp)
+       krb5_free_principal(context, client_principal);
+    if (cp)
+       krb5_free_principal(context, cp);
+    if (sp)
+       krb5_free_principal(context, sp);
+
+    free_EncTicketPart(&adtkt);
+
+    return ret;
+}
+
+/*
+ *
+ */
+
+krb5_error_code
+_kdc_tgs_rep(krb5_context context, 
+            krb5_kdc_configuration *config,
+            KDC_REQ *req, 
+            krb5_data *data,
+            const char *from,
+            struct sockaddr *from_addr)
+{
+    AuthorizationData *auth_data = NULL;
+    krb5_error_code ret;
+    int i = 0;
+    PA_DATA *tgs_req = NULL;
+
+    hdb_entry_ex *krbtgt = NULL;
+    krb5_ticket *ticket = NULL;
+    const char *e_text = NULL;
+    krb5_enctype krbtgt_etype = ETYPE_NULL;
+    EncryptionKey *tgtkey = NULL;
+
+
+    time_t *csec = NULL;
+    int *cusec = NULL;
+
+    if(req->padata == NULL){
+       ret = KRB5KDC_ERR_PREAUTH_REQUIRED; /* XXX ??? */
+       kdc_log(context, config, 0,
+               "TGS-REQ from %s without PA-DATA", from);
+       goto out;
+    }
+    
+    tgs_req = _kdc_find_padata(req, &i, KRB5_PADATA_TGS_REQ);
+
+    if(tgs_req == NULL){
+       ret = KRB5KDC_ERR_PADATA_TYPE_NOSUPP;
+       
+       kdc_log(context, config, 0, 
+               "TGS-REQ from %s without PA-TGS-REQ", from);
+       goto out;
+    }
+    ret = tgs_parse_request(context, config, 
+                           &req->req_body, tgs_req,
+                           &krbtgt,
+                           &krbtgt_etype,
+                           &ticket,
+                           &e_text,
+                           from, from_addr,
+                           &csec, &cusec,
+                           &auth_data,                           
+                           &tgtkey);
+    if (ret) {
+       kdc_log(context, config, 0, 
+               "Failed parsing TGS-REQ from %s", from);
+       goto out;
+    }
+
+    ret = tgs_build_reply(context,
+                         config,
+                         req,
+                         &req->req_body,
+                         krbtgt,
+                         krbtgt_etype,
+                         ticket,
+                         data,
+                         from,
+                         &e_text,
+                         auth_data,
+                         tgtkey,
+                         from_addr);
+    if (ret) {
+       kdc_log(context, config, 0, 
+               "Failed building TGS-REP to %s", from);
+       goto out;
+    }
+
+out:
+    if(ret && data->data == NULL){
+       krb5_mk_error(context,
+                     ret,
+                     NULL,
+                     NULL,
+                     NULL,
+                     NULL,
+                     csec,
+                     cusec,
+                     data);
+    }
+    free(csec);
+    free(cusec);
+    if (ticket)
+       krb5_free_ticket(context, ticket);
+    if(krbtgt)
+       _kdc_free_ent(context, krbtgt);
+
+    if (auth_data) {
+       free_AuthorizationData(auth_data);
+       free(auth_data);
+    }
+
+    return 0;
+}
index a61c647f719fc956be7b6b7ae75f9f19cc5f26c6..b511e1a7a8d39a575ff8abec7ebad541bb0ae14a 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "kdc_locl.h"
 
-RCSID("$Id: misc.c,v 1.29 2006/04/27 11:33:21 lha Exp $");
+RCSID("$Id: misc.c,v 1.32 2006/08/28 14:41:49 lha Exp $");
 
 struct timeval _kdc_now;
 
@@ -42,6 +42,7 @@ _kdc_db_fetch(krb5_context context,
              krb5_kdc_configuration *config,
              krb5_const_principal principal,
              unsigned flags,
+             HDB **db,
              hdb_entry_ex **h)
 {
     hdb_entry_ex *ent;
@@ -66,6 +67,8 @@ _kdc_db_fetch(krb5_context context,
                                       ent);
        config->db[i]->hdb_close(context, config->db[i]);
        if(ret == 0) {
+           if (db)
+               *db = config->db[i];
            *h = ent;
            return 0;
        }
@@ -81,3 +84,36 @@ _kdc_free_ent(krb5_context context, hdb_entry_ex *ent)
     free (ent);
 }
 
+/*
+ * Use the order list of preferred encryption types and sort the
+ * available keys and return the most preferred key.
+ */
+
+krb5_error_code
+_kdc_get_preferred_key(krb5_context context,
+                      krb5_kdc_configuration *config,
+                      hdb_entry_ex *h,
+                      const char *name,
+                      krb5_enctype *enctype,
+                      Key **key)
+{
+    const krb5_enctype *p;
+    krb5_error_code ret;
+    int i;
+
+    p = krb5_kerberos_enctypes(context);
+
+    for (i = 0; p[i] != ETYPE_NULL; i++) {
+       if (krb5_enctype_valid(context, p[i]) != 0)
+           continue;
+       ret = hdb_enctype2key(context, &h->entry, p[i], key);
+       if (ret == 0) {
+           *enctype = p[i];
+           return 0;
+       }
+    }
+
+    krb5_set_error_string(context, "No valid kerberos key found for %s", name);
+    return EINVAL;
+}
+
index c220e70dddb77ca32605eeddcbb5d3ea231ab5a2..e3d77c06219f76e16668619c4947346d6b54a025 100755 (executable)
@@ -33,7 +33,7 @@
 
 #include "kdc_locl.h"
 
-RCSID("$Id: pkinit.c,v 1.65 2006/05/06 13:22:33 lha Exp $");
+RCSID("$Id: pkinit.c,v 1.72 2006/10/24 17:51:33 lha Exp $");
 
 #ifdef PKINIT
 
@@ -156,7 +156,7 @@ pk_check_pkauthenticator(krb5_context context,
        goto out;
     }
 
-    if (heim_octet_string_cmp(a->paChecksum, &checksum.checksum) != 0) {
+    if (der_heim_octet_string_cmp(a->paChecksum, &checksum.checksum) != 0) {
        krb5_clear_error_string(context);
        ret = KRB5KRB_ERR_GENERIC;
     }
@@ -269,7 +269,7 @@ get_dh_param(krb5_context context,
 
     memset(&dhparam, 0, sizeof(dhparam));
 
-    if (heim_oid_cmp(&dh_key_info->algorithm.algorithm, oid_id_dhpublicnumber())) {
+    if (der_heim_oid_cmp(&dh_key_info->algorithm.algorithm, oid_id_dhpublicnumber())) {
        krb5_set_error_string(context,
                              "PKINIT invalid oid in clientPublicValue");
        return KRB5_BADMSGTYPE;
@@ -338,7 +338,7 @@ get_dh_param(krb5_context context,
        client_params->dh_public_key = integer_to_BN(context,
                                                     "subjectPublicKey",
                                                     &glue);
-       free_heim_integer(&glue);
+       der_free_heim_integer(&glue);
        if (client_params->dh_public_key == NULL)
            goto out;
     }
@@ -426,7 +426,7 @@ _kdc_pk_rd_padata(krb5_context context,
     krb5_data signed_content = { 0, NULL };
     const char *type = "unknown type";
     const heim_oid *pa_contentType;
-    int have_data;
+    int have_data = 0;
 
     *ret_params = NULL;
     
@@ -444,7 +444,6 @@ _kdc_pk_rd_padata(krb5_context context,
 
     if (pa->padata_type == KRB5_PADATA_PK_AS_REQ_WIN) {
        PA_PK_AS_REQ_Win2k r;
-       int have_data;
 
        type = "PK-INIT-Win2k";
        pa_contentType = oid_id_pkcs7_data();
@@ -502,7 +501,7 @@ _kdc_pk_rd_padata(krb5_context context,
        goto out;
     }
 
-    ret = heim_oid_cmp(&contentInfoOid, oid_id_pkcs7_signedData());
+    ret = der_heim_oid_cmp(&contentInfoOid, oid_id_pkcs7_signedData());
     if (ret != 0) {
        krb5_set_error_string(context, "PK-AS-REQ-Win2k invalid content "
                              "type oid");
@@ -542,7 +541,7 @@ _kdc_pk_rd_padata(krb5_context context,
     }
 
     /* Signature is correct, now verify the signed message */
-    if (heim_oid_cmp(&eContentType, pa_contentType)) {
+    if (der_heim_oid_cmp(&eContentType, pa_contentType)) {
        krb5_set_error_string(context, "got wrong oid for pkauthdata");
        ret = KRB5_BADMSGTYPE;
        goto out;
@@ -621,8 +620,8 @@ out:
     if (signed_content.data)
        free(signed_content.data);
     krb5_data_free(&eContent);
-    free_oid(&eContentType);
-    free_oid(&contentInfoOid);
+    der_free_oid(&eContentType);
+    der_free_oid(&contentInfoOid);
     if (ret)
        _kdc_pk_free_client_param(context, client_params);
     else
@@ -657,10 +656,11 @@ pk_mk_pa_reply_enckey(krb5_context context,
                      ContentInfo *content_info)
 {
     krb5_error_code ret;
-    krb5_data buf, o;
+    krb5_data buf, signed_data;
     size_t size;
 
     krb5_data_zero(&buf);
+    krb5_data_zero(&signed_data);
 
     switch (client_params->type) {
     case PKINIT_COMPAT_WIN2K: {
@@ -678,6 +678,7 @@ pk_mk_pa_reply_enckey(krb5_context context,
                           buf.data, buf.length,
                           &kp, &size,ret);
        free_ReplyKeyPack_Win2k(&kp);
+       break;
     }
     case PKINIT_COMPAT_27: {
        krb5_crypto ascrypto;
@@ -724,21 +725,55 @@ pk_mk_pa_reply_enckey(krb5_context context,
     if (buf.length != size)
        krb5_abortx(context, "Internal ASN.1 encoder error");
 
+    {
+       hx509_query *q;
+       hx509_cert cert;
+       
+       ret = hx509_query_alloc(kdc_identity->hx509ctx, &q);
+       if (ret)
+           goto out;
+       
+       hx509_query_match_option(q, HX509_QUERY_OPTION_PRIVATE_KEY);
+       hx509_query_match_option(q, HX509_QUERY_OPTION_KU_DIGITALSIGNATURE);
+       
+       ret = hx509_certs_find(kdc_identity->hx509ctx, 
+                              kdc_identity->certs, 
+                              q, 
+                              &cert);
+       hx509_query_free(kdc_identity->hx509ctx, q);
+       if (ret)
+           goto out;
+       
+       ret = hx509_cms_create_signed_1(kdc_identity->hx509ctx,
+                                       oid_id_pkrkeydata(),
+                                       buf.data,
+                                       buf.length,
+                                       NULL,
+                                       cert,
+                                       kdc_identity->anchors,
+                                       kdc_identity->certpool,
+                                       &signed_data);
+       hx509_cert_free(cert);
+    }
+
+    krb5_data_free(&buf);
+    if (ret) 
+       goto out;
+
     ret = hx509_cms_envelope_1(kdc_identity->hx509ctx,
                               client_params->cert,
-                              buf.data, buf.length, NULL,
-                              oid_id_pkcs7_signedData(), &o);
+                              signed_data.data, signed_data.length, NULL,
+                              oid_id_pkcs7_signedData(), &buf);
     if (ret)
        goto out;
     
     ret = _krb5_pk_mk_ContentInfo(context,
-                                 &o,
+                                 &buf,
                                  oid_id_pkcs7_envelopedData(),
                                  content_info);
-    free_octet_string(&o);
-
- out:
+out:
     krb5_data_free(&buf);
+    krb5_data_free(&signed_data);
     return ret;
 }
 
@@ -1195,6 +1230,7 @@ _kdc_pk_check_client(krb5_context context,
                     pk_client_params *client_params,
                     char **subject_name)
 {
+    const HDB_Ext_PKINIT_acl *acl;
     krb5_error_code ret;
     hx509_name name;
     int i;
@@ -1210,8 +1246,8 @@ _kdc_pk_check_client(krb5_context context,
     if (ret)
        return ret;
 
-    kdc_log(context, config, 5,
-           "Trying to authorize subject DN %s", 
+    kdc_log(context, config, 0,
+           "Trying to authorize PK-INIT subject DN %s", 
            *subject_name);
 
     if (config->enable_pkinit_princ_in_cert) {
@@ -1225,6 +1261,28 @@ _kdc_pk_check_client(krb5_context context,
        }
     }
 
+    ret = hdb_entry_get_pkinit_acl(&client->entry, &acl);
+    if (ret == 0 && acl != NULL) {
+       /*
+        * Cheat here and compare the generated name with the string
+        * and not the reverse.
+        */
+       for (i = 0; i < acl->len; i++) {
+           if (strcmp(*subject_name, acl->val[0].subject) != 0)
+               continue;
+
+           /* Don't support isser and anchor checking right now */
+           if (acl->val[0].issuer)
+               continue;
+           if (acl->val[0].anchor)
+               continue;
+
+           kdc_log(context, config, 5,
+                   "Found matching PK-INIT database ACL");
+           return 0;
+       }
+    }
+
     for (i = 0; i < principal_mappings.len; i++) {
        krb5_boolean b;
 
@@ -1235,11 +1293,14 @@ _kdc_pk_check_client(krb5_context context,
            continue;
        if (strcmp(principal_mappings.val[i].subject, *subject_name) != 0)
            continue;
+       kdc_log(context, config, 5,
+               "Found matching PK-INIT FILE ACL");
        return 0;
     }
-    free(*subject_name);
 
+    free(*subject_name);
     *subject_name = NULL;
+
     krb5_set_error_string(context, "PKINIT no matching principals");
     return KRB5_KDC_ERR_CLIENT_NAME_MISMATCH;
 }
@@ -1282,7 +1343,7 @@ _kdc_pk_initialize(krb5_context context,
                   const char *user_id,
                   const char *anchors,
                   char **pool,
-                  char **revoke)
+                  char **revoke_list)
 {
     const char *file; 
     krb5_error_code ret;
@@ -1305,7 +1366,7 @@ _kdc_pk_initialize(krb5_context context,
                           user_id,
                           anchors,
                           pool,
-                          revoke,
+                          revoke_list,
                           NULL,
                           NULL,
                           NULL);
index d0f8245bf9101a3b02c4c407b72136577821908a..ed5cb3d651330c046fad37e7fb1059260770f247 100644 (file)
@@ -34,7 +34,7 @@
 
 #include "kdc_locl.h"
 
-RCSID("$Id: process.c,v 1.3 2005/08/12 08:25:48 lha Exp $");
+RCSID("$Id: process.c,v 1.5 2006/10/09 15:37:39 lha Exp $");
 
 /*
  * handle the request in `buf, len', from `addr' (or `from' as a string),
@@ -42,17 +42,19 @@ RCSID("$Id: process.c,v 1.3 2005/08/12 08:25:48 lha Exp $");
  */
 
 int
-krb5_kdc_process_generic_request(krb5_context context, 
-                                krb5_kdc_configuration *config,
-                                unsigned char *buf, 
-                                size_t len, 
-                                krb5_data *reply,
-                                krb5_boolean *prependlength,
-                                const char *from,
-                                struct sockaddr *addr)
+krb5_kdc_process_request(krb5_context context, 
+                        krb5_kdc_configuration *config,
+                        unsigned char *buf, 
+                        size_t len, 
+                        krb5_data *reply,
+                        krb5_boolean *prependlength,
+                        const char *from,
+                        struct sockaddr *addr,
+                        int datagram_reply)
 {
     KDC_REQ req;
     Ticket ticket;
+    DigestREQ digestreq;
     krb5_error_code ret;
     size_t i;
 
@@ -64,7 +66,7 @@ krb5_kdc_process_generic_request(krb5_context context,
        req_buffer.length = len;
 
        ret = _kdc_as_rep(context, config, &req, &req_buffer, 
-                         reply, from, addr);
+                         reply, from, addr, datagram_reply);
        free_AS_REQ(&req);
        return ret;
     }else if(decode_TGS_REQ(buf, len, &req, &i) == 0){
@@ -75,6 +77,10 @@ krb5_kdc_process_generic_request(krb5_context context,
        ret = _kdc_do_524(context, config, &ticket, reply, from, addr);
        free_Ticket(&ticket);
        return ret;
+    }else if(decode_DigestREQ(buf, len, &digestreq, &i) == 0){
+       ret = _kdc_do_digest(context, config, &digestreq, reply, from, addr);
+       free_DigestREQ(&digestreq);
+       return ret;
     } else if(_kdc_maybe_version4(buf, len)){
        *prependlength = FALSE; /* elbitapmoc sdrawkcab XXX */
        _kdc_do_version4(context, config, buf, len, reply, from, 
@@ -103,7 +109,8 @@ krb5_kdc_process_krb5_request(krb5_context context,
                              size_t len, 
                              krb5_data *reply,
                              const char *from,
-                             struct sockaddr *addr)
+                             struct sockaddr *addr,
+                             int datagram_reply)
 {
     KDC_REQ req;
     krb5_error_code ret;
@@ -117,7 +124,7 @@ krb5_kdc_process_krb5_request(krb5_context context,
        req_buffer.length = len;
 
        ret = _kdc_as_rep(context, config, &req, &req_buffer,
-                         reply, from, addr);
+                         reply, from, addr, datagram_reply);
        free_AS_REQ(&req);
        return ret;
     }else if(decode_TGS_REQ(buf, len, &req, &i) == 0){
index 78873761b6eeb8b26c140315fce9708a84bb3103..ce43c2cd02f944f1941c93e4f4a2c2f5c303276e 100644 (file)
@@ -1,5 +1,5 @@
 -- From RFC 3369 --
--- $Id: CMS.asn1,v 1.4 2006/04/15 10:53:25 lha Exp $ --
+-- $Id: CMS.asn1,v 1.5 2006/09/07 12:20:42 lha Exp $ --
 
 CMS DEFINITIONS ::= BEGIN
 
@@ -17,7 +17,13 @@ id-pkcs7-signedAndEnvelopedData OBJECT IDENTIFIER ::=        { id-pkcs7 4 }
 id-pkcs7-digestedData OBJECT IDENTIFIER ::=            { id-pkcs7 5 }
 id-pkcs7-encryptedData OBJECT IDENTIFIER ::=           { id-pkcs7 6 }
 
-CMSVersion ::= INTEGER { v0(0), v1(1), v2(2), v3(3), v4(4) }
+CMSVersion ::= INTEGER {
+          CMSVersion_v0(0), 
+          CMSVersion_v1(1), 
+          CMSVersion_v2(2),
+          CMSVersion_v3(3),
+          CMSVersion_v4(4)
+}
 
 DigestAlgorithmIdentifier ::= AlgorithmIdentifier
 DigestAlgorithmIdentifiers ::= SET OF DigestAlgorithmIdentifier
index 01411b384a288ddf2c3cf31c13df0b984f62290d..ab06ae79dd630d02670386744f71d584c906fe4b 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: asn1-common.h,v 1.5 2005/07/12 06:27:14 lha Exp $ */
+/* $Id: asn1-common.h,v 1.6 2006/10/14 05:09:47 lha Exp $ */
 
 #include <stddef.h>
 #include <time.h>
@@ -43,6 +43,9 @@ typedef struct heim_bit_string {
     void *data;
 } heim_bit_string;
 
+typedef struct heim_octet_string heim_any;
+typedef struct heim_octet_string heim_any_set;
+
 #define ASN1_MALLOC_ENCODE(T, B, BL, S, L, R)                  \
   do {                                                         \
     (BL) = length_##T((S));                                    \
diff --git a/source4/heimdal/lib/asn1/der-protos.h b/source4/heimdal/lib/asn1/der-protos.h
new file mode 100644 (file)
index 0000000..3aee392
--- /dev/null
@@ -0,0 +1,542 @@
+/* This is a generated file */
+#ifndef __der_protos_h__
+#define __der_protos_h__
+
+#include <stdarg.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int
+copy_heim_any (
+       const heim_any */*from*/,
+       heim_any */*to*/);
+
+int
+copy_heim_any_set (
+       const heim_any_set */*from*/,
+       heim_any_set */*to*/);
+
+int
+decode_heim_any (
+       const unsigned char */*p*/,
+       size_t /*len*/,
+       heim_any */*data*/,
+       size_t */*size*/);
+
+int
+decode_heim_any_set (
+       const unsigned char */*p*/,
+       size_t /*len*/,
+       heim_any_set */*data*/,
+       size_t */*size*/);
+
+int
+der_copy_bit_string (
+       const heim_bit_string */*from*/,
+       heim_bit_string */*to*/);
+
+int
+der_copy_bmp_string (
+       const heim_bmp_string */*from*/,
+       heim_bmp_string */*to*/);
+
+int
+der_copy_general_string (
+       const heim_general_string */*from*/,
+       heim_general_string */*to*/);
+
+int
+der_copy_heim_integer (
+       const heim_integer */*from*/,
+       heim_integer */*to*/);
+
+int
+der_copy_ia5_string (
+       const heim_printable_string */*from*/,
+       heim_printable_string */*to*/);
+
+int
+der_copy_octet_string (
+       const heim_octet_string */*from*/,
+       heim_octet_string */*to*/);
+
+int
+der_copy_oid (
+       const heim_oid */*from*/,
+       heim_oid */*to*/);
+
+int
+der_copy_printable_string (
+       const heim_printable_string */*from*/,
+       heim_printable_string */*to*/);
+
+int
+der_copy_universal_string (
+       const heim_universal_string */*from*/,
+       heim_universal_string */*to*/);
+
+int
+der_copy_utf8string (
+       const heim_utf8_string */*from*/,
+       heim_utf8_string */*to*/);
+
+void
+der_free_bit_string (heim_bit_string */*k*/);
+
+void
+der_free_bmp_string (heim_bmp_string */*k*/);
+
+void
+der_free_general_string (heim_general_string */*str*/);
+
+void
+der_free_heim_integer (heim_integer */*k*/);
+
+void
+der_free_ia5_string (heim_ia5_string */*str*/);
+
+void
+der_free_octet_string (heim_octet_string */*k*/);
+
+void
+der_free_oid (heim_oid */*k*/);
+
+void
+der_free_printable_string (heim_printable_string */*str*/);
+
+void
+der_free_universal_string (heim_universal_string */*k*/);
+
+void
+der_free_utf8string (heim_utf8_string */*str*/);
+
+int
+der_get_bit_string (
+       const unsigned char */*p*/,
+       size_t /*len*/,
+       heim_bit_string */*data*/,
+       size_t */*size*/);
+
+int
+der_get_bmp_string (
+       const unsigned char */*p*/,
+       size_t /*len*/,
+       heim_bmp_string */*data*/,
+       size_t */*size*/);
+
+int
+der_get_boolean (
+       const unsigned char */*p*/,
+       size_t /*len*/,
+       int */*data*/,
+       size_t */*size*/);
+
+const char *
+der_get_class_name (unsigned /*num*/);
+
+int
+der_get_class_num (const char */*name*/);
+
+int
+der_get_general_string (
+       const unsigned char */*p*/,
+       size_t /*len*/,
+       heim_general_string */*str*/,
+       size_t */*size*/);
+
+int
+der_get_generalized_time (
+       const unsigned char */*p*/,
+       size_t /*len*/,
+       time_t */*data*/,
+       size_t */*size*/);
+
+int
+der_get_heim_integer (
+       const unsigned char */*p*/,
+       size_t /*len*/,
+       heim_integer */*data*/,
+       size_t */*size*/);
+
+int
+der_get_ia5_string (
+       const unsigned char */*p*/,
+       size_t /*len*/,
+       heim_ia5_string */*str*/,
+       size_t */*size*/);
+
+int
+der_get_integer (
+       const unsigned char */*p*/,
+       size_t /*len*/,
+       int */*ret*/,
+       size_t */*size*/);
+
+int
+der_get_length (
+       const unsigned char */*p*/,
+       size_t /*len*/,
+       size_t */*val*/,
+       size_t */*size*/);
+
+int
+der_get_octet_string (
+       const unsigned char */*p*/,
+       size_t /*len*/,
+       heim_octet_string */*data*/,
+       size_t */*size*/);
+
+int
+der_get_oid (
+       const unsigned char */*p*/,
+       size_t /*len*/,
+       heim_oid */*data*/,
+       size_t */*size*/);
+
+int
+der_get_printable_string (
+       const unsigned char */*p*/,
+       size_t /*len*/,
+       heim_printable_string */*str*/,
+       size_t */*size*/);
+
+int
+der_get_tag (
+       const unsigned char */*p*/,
+       size_t /*len*/,
+       Der_class */*class*/,
+       Der_type */*type*/,
+       unsigned int */*tag*/,
+       size_t */*size*/);
+
+const char *
+der_get_tag_name (unsigned /*num*/);
+
+int
+der_get_tag_num (const char */*name*/);
+
+const char *
+der_get_type_name (unsigned /*num*/);
+
+int
+der_get_type_num (const char */*name*/);
+
+int
+der_get_universal_string (
+       const unsigned char */*p*/,
+       size_t /*len*/,
+       heim_universal_string */*data*/,
+       size_t */*size*/);
+
+int
+der_get_unsigned (
+       const unsigned char */*p*/,
+       size_t /*len*/,
+       unsigned */*ret*/,
+       size_t */*size*/);
+
+int
+der_get_utctime (
+       const unsigned char */*p*/,
+       size_t /*len*/,
+       time_t */*data*/,
+       size_t */*size*/);
+
+int
+der_get_utf8string (
+       const unsigned char */*p*/,
+       size_t /*len*/,
+       heim_utf8_string */*str*/,
+       size_t */*size*/);
+
+int
+der_heim_bit_string_cmp (
+       const heim_bit_string */*p*/,
+       const heim_bit_string */*q*/);
+
+int
+der_heim_bmp_string_cmp (
+       const heim_bmp_string */*p*/,
+       const heim_bmp_string */*q*/);
+
+int
+der_heim_integer_cmp (
+       const heim_integer */*p*/,
+       const heim_integer */*q*/);
+
+int
+der_heim_octet_string_cmp (
+       const heim_octet_string */*p*/,
+       const heim_octet_string */*q*/);
+
+int
+der_heim_oid_cmp (
+       const heim_oid */*p*/,
+       const heim_oid */*q*/);
+
+int
+der_heim_universal_string_cmp (
+       const heim_universal_string */*p*/,
+       const heim_universal_string */*q*/);
+
+size_t
+der_length_bit_string (const heim_bit_string */*k*/);
+
+size_t
+der_length_bmp_string (const heim_bmp_string */*data*/);
+
+size_t
+der_length_boolean (const int */*k*/);
+
+size_t
+der_length_enumerated (const unsigned */*data*/);
+
+size_t
+der_length_general_string (const heim_general_string */*data*/);
+
+size_t
+der_length_generalized_time (const time_t */*t*/);
+
+size_t
+der_length_heim_integer (const heim_integer */*k*/);
+
+size_t
+der_length_ia5_string (const heim_ia5_string */*data*/);
+
+size_t
+der_length_integer (const int */*data*/);
+
+size_t
+der_length_len (size_t /*len*/);
+
+size_t
+der_length_octet_string (const heim_octet_string */*k*/);
+
+size_t
+der_length_oid (const heim_oid */*k*/);
+
+size_t
+der_length_printable_string (const heim_printable_string */*data*/);
+
+size_t
+der_length_universal_string (const heim_universal_string */*data*/);
+
+size_t
+der_length_unsigned (const unsigned */*data*/);
+
+size_t
+der_length_utctime (const time_t */*t*/);
+
+size_t
+der_length_utf8string (const heim_utf8_string */*data*/);
+
+int
+der_match_tag (
+       const unsigned char */*p*/,
+       size_t /*len*/,
+       Der_class /*class*/,
+       Der_type /*type*/,
+       unsigned int /*tag*/,
+       size_t */*size*/);
+
+int
+der_match_tag_and_length (
+       const unsigned char */*p*/,
+       size_t /*len*/,
+       Der_class /*class*/,
+       Der_type /*type*/,
+       unsigned int /*tag*/,
+       size_t */*length_ret*/,
+       size_t */*size*/);
+
+int
+der_parse_heim_oid (
+       const char */*str*/,
+       const char */*sep*/,
+       heim_oid */*data*/);
+
+int
+der_parse_hex_heim_integer (
+       const char */*p*/,
+       heim_integer */*data*/);
+
+int
+der_print_heim_oid (
+       const heim_oid */*oid*/,
+       char /*delim*/,
+       char **/*str*/);
+
+int
+der_print_hex_heim_integer (
+       const heim_integer */*data*/,
+       char **/*p*/);
+
+int
+der_put_bit_string (
+       unsigned char */*p*/,
+       size_t /*len*/,
+       const heim_bit_string */*data*/,
+       size_t */*size*/);
+
+int
+der_put_bmp_string (
+       unsigned char */*p*/,
+       size_t /*len*/,
+       const heim_bmp_string */*data*/,
+       size_t */*size*/);
+
+int
+der_put_boolean (
+       unsigned char */*p*/,
+       size_t /*len*/,
+       const int */*data*/,
+       size_t */*size*/);
+
+int
+der_put_general_string (
+       unsigned char */*p*/,
+       size_t /*len*/,
+       const heim_general_string */*str*/,
+       size_t */*size*/);
+
+int
+der_put_generalized_time (
+       unsigned char */*p*/,
+       size_t /*len*/,
+       const time_t */*data*/,
+       size_t */*size*/);
+
+int
+der_put_heim_integer (
+       unsigned char */*p*/,
+       size_t /*len*/,
+       const heim_integer */*data*/,
+       size_t */*size*/);
+
+int
+der_put_ia5_string (
+       unsigned char */*p*/,
+       size_t /*len*/,
+       const heim_ia5_string */*str*/,
+       size_t */*size*/);
+
+int
+der_put_integer (
+       unsigned char */*p*/,
+       size_t /*len*/,
+       const int */*v*/,
+       size_t */*size*/);
+
+int
+der_put_length (
+       unsigned char */*p*/,
+       size_t /*len*/,
+       size_t /*val*/,
+       size_t */*size*/);
+
+int
+der_put_length_and_tag (
+       unsigned char */*p*/,
+       size_t /*len*/,
+       size_t /*len_val*/,
+       Der_class /*class*/,
+       Der_type /*type*/,
+       unsigned int /*tag*/,
+       size_t */*size*/);
+
+int
+der_put_octet_string (
+       unsigned char */*p*/,
+       size_t /*len*/,
+       const heim_octet_string */*data*/,
+       size_t */*size*/);
+
+int
+der_put_oid (
+       unsigned char */*p*/,
+       size_t /*len*/,
+       const heim_oid */*data*/,
+       size_t */*size*/);
+
+int
+der_put_printable_string (
+       unsigned char */*p*/,
+       size_t /*len*/,
+       const heim_printable_string */*str*/,
+       size_t */*size*/);
+
+int
+der_put_tag (
+       unsigned char */*p*/,
+       size_t /*len*/,
+       Der_class /*class*/,
+       Der_type /*type*/,
+       unsigned int /*tag*/,
+       size_t */*size*/);
+
+int
+der_put_universal_string (
+       unsigned char */*p*/,
+       size_t /*len*/,
+       const heim_universal_string */*data*/,
+       size_t */*size*/);
+
+int
+der_put_unsigned (
+       unsigned char */*p*/,
+       size_t /*len*/,
+       const unsigned */*v*/,
+       size_t */*size*/);
+
+int
+der_put_utctime (
+       unsigned char */*p*/,
+       size_t /*len*/,
+       const time_t */*data*/,
+       size_t */*size*/);
+
+int
+der_put_utf8string (
+       unsigned char */*p*/,
+       size_t /*len*/,
+       const heim_utf8_string */*str*/,
+       size_t */*size*/);
+
+int
+encode_heim_any (
+       unsigned char */*p*/,
+       size_t /*len*/,
+       const heim_any */*data*/,
+       size_t */*size*/);
+
+int
+encode_heim_any_set (
+       unsigned char */*p*/,
+       size_t /*len*/,
+       const heim_any_set */*data*/,
+       size_t */*size*/);
+
+void
+free_heim_any (heim_any */*data*/);
+
+void
+free_heim_any_set (heim_any_set */*data*/);
+
+int
+heim_any_cmp (
+       const heim_any_set */*p*/,
+       const heim_any_set */*q*/);
+
+size_t
+length_heim_any (const heim_any */*data*/);
+
+size_t
+length_heim_any_set (const heim_any */*data*/);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __der_protos_h__ */
index b9c2b470792d7fbcefe3e2c78884ec9fb0412ddd..b0170e35fe534bc1a5f76ae48c41deb81216e299 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2006 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
  * All rights reserved. 
  *
@@ -31,7 +31,7 @@
  * SUCH DAMAGE. 
  */
 
-/* $Id: der.h,v 1.32 2006/01/30 15:25:25 lha Exp $ */
+/* $Id: der.h,v 1.36 2006/10/14 05:16:08 lha Exp $ */
 
 #ifndef __DER_H__
 #define __DER_H__
@@ -83,164 +83,21 @@ enum {
 
 #define ASN1_INDEFINITE 0xdce0deed
 
-typedef struct asn1_der_time_t {
+typedef struct heim_der_time_t {
     time_t dt_sec;
     unsigned long dt_nsec;
-} asn1_der_time_t;
+} heim_der_time_t;
 
-typedef struct asn1_ber_time_t {
+typedef struct heim_ber_time_t {
     time_t bt_sec;
     unsigned bt_nsec;
     int bt_zone;
-} asn1_ber_time_t;
+} heim_ber_time_t;
 
-int der_get_unsigned (const unsigned char *p, size_t len,
-                     unsigned *ret, size_t *size);
-int der_get_integer (const unsigned char *p, size_t len,
-                    int *ret, size_t *size);
-int der_get_heim_integer (const unsigned char *p, size_t len,
-                         heim_integer *ret, size_t *size);
-int der_get_boolean(const unsigned char *p, size_t len,
-                   int *data, size_t *size);
-int der_get_length (const unsigned char *p, size_t len,
-                   size_t *val, size_t *size);
-int der_get_general_string (const unsigned char *p, size_t len, 
-                           heim_general_string *str, size_t *size);
-int der_get_utf8string (const unsigned char *p, size_t len, 
-                           heim_utf8_string *str, size_t *size);
-int der_get_universal_string (const unsigned char *p, size_t len, 
-                            heim_universal_string *str, size_t *size);
-int der_get_bmp_string (const unsigned char *p, size_t len, 
-                       heim_bmp_string *str, size_t *size);
-int der_get_printable_string (const unsigned char *p, size_t len, 
-                           heim_printable_string *str, size_t *size);
-int der_get_ia5_string (const unsigned char *p, size_t len,
-                       heim_ia5_string *str, size_t *size);
-int der_get_octet_string (const unsigned char *p, size_t len, 
-                         heim_octet_string *data, size_t *size);
-int der_get_generalized_time (const unsigned char *p, size_t len, 
-                             time_t *data, size_t *size);
-int der_get_generalized_time_der (const unsigned char *p, size_t len, 
-                                 asn1_der_time_t *data, size_t *size);
-int der_get_generalized_time_ber (const unsigned char *p, size_t len, 
-                                 asn1_ber_time_t *data, size_t *size);
-int der_get_utctime (const unsigned char *p, size_t len, 
-                    time_t *data, size_t *size);
-int der_get_oid (const unsigned char *p, size_t len,
-                heim_oid *data, size_t *size);
-int der_get_bit_string (const unsigned char *p, size_t len,
-                       heim_bit_string *data, size_t *size);
-int der_get_tag (const unsigned char *p, size_t len, 
-                Der_class *class, Der_type *type,
-                unsigned int *tag, size_t *size);
-
-int der_match_tag (const unsigned char *p, size_t len, 
-                  Der_class class, Der_type type,
-                  unsigned int tag, size_t *size);
-int der_match_tag_and_length (const unsigned char *p, size_t len,
-                             Der_class class, Der_type type, unsigned int tag,
-                             size_t *length_ret, size_t *size);
-
-int der_put_unsigned (unsigned char *p, size_t len, const unsigned *val, size_t*);
-int der_put_integer (unsigned char *p, size_t len, const int *val, size_t*);
-int der_put_heim_integer (unsigned char *p, size_t len, 
-                         const heim_integer *val, size_t*);
-int der_put_boolean (unsigned char *p, size_t len, const int *val, size_t*);
-
-int der_put_length (unsigned char *p, size_t len, size_t val, size_t*);
-int der_put_general_string (unsigned char *p, size_t len,
-                           const heim_general_string *str, size_t*);
-int der_put_utf8string (unsigned char *p, size_t len,
-                       const heim_utf8_string *str, size_t*);
-int der_put_universal_string (unsigned char *p, size_t len,
-                             const heim_universal_string *str, size_t*);
-int der_put_bmp_string (unsigned char *p, size_t len,
-                           const heim_bmp_string *str, size_t*);
-int der_put_printable_string (unsigned char *p, size_t len,
-                           const heim_printable_string *str, size_t*);
-int der_put_ia5_string (unsigned char *p, size_t len,
-                       const heim_ia5_string *str, size_t*);
-int der_put_octet_string (unsigned char *p, size_t len,
-                         const heim_octet_string *data, size_t*);
-int der_put_generalized_time (unsigned char *p, size_t len, 
-                             const time_t *data, size_t *size);
-int der_put_utctime (unsigned char *p, size_t len, 
-                    const time_t *data, size_t *size);
-int der_put_oid (unsigned char *p, size_t len,
-                const heim_oid *data, size_t *size);
-int der_put_bit_string (unsigned char *p, size_t len,
-                       const heim_bit_string *data, size_t *size);
-int der_put_tag (unsigned char *p, size_t len, Der_class class, Der_type type,
-                unsigned int tag, size_t*);
-int der_put_length_and_tag (unsigned char*, size_t, size_t, 
-                           Der_class, Der_type, unsigned int, size_t*);
-
-void free_integer (int *num);
-void free_heim_integer (heim_integer *num);
-void free_octet_string (heim_octet_string *k);
-void free_general_string (heim_general_string *str);
-void free_octet_string (heim_octet_string *k);
-void free_oid (heim_oid *k);
-void free_bit_string (heim_bit_string *k);
-void free_generalized_time (time_t *t);
-void free_utctime (time_t *t);
-void free_utf8string (heim_utf8_string*);
-void free_printable_string (heim_printable_string*);
-void free_ia5_string (heim_ia5_string*);
-void free_universal_string (heim_universal_string*);
-void free_bmp_string (heim_bmp_string*);
-
-size_t length_len (size_t len);
-size_t length_integer (const int *data);
-size_t length_heim_integer (const heim_integer *data);
-size_t length_unsigned (const unsigned *data);
-size_t length_enumerated (const unsigned *data);
-size_t length_general_string (const heim_general_string *data);
-size_t length_octet_string (const heim_octet_string *k);
-size_t length_oid (const heim_oid *k);
-size_t length_bit_string (const heim_bit_string *k);
-size_t length_generalized_time (const time_t *t);
-size_t length_utctime (const time_t *t);
-size_t length_utf8string (const heim_utf8_string*);
-size_t length_printable_string (const heim_printable_string*);
-size_t length_ia5_string (const heim_ia5_string*);
-size_t length_bmp_string (const heim_bmp_string*);
-size_t length_universal_string (const heim_universal_string*);
-size_t length_boolean (const int*);
-
-int copy_heim_integer (const heim_integer *, heim_integer *);
-int copy_general_string (const heim_general_string *, heim_general_string *);
-int copy_octet_string (const heim_octet_string *, heim_octet_string *);
-int copy_oid (const heim_oid *from, heim_oid *to);
-int copy_bit_string (const heim_bit_string *from, heim_bit_string *to);
-int copy_utf8string (const heim_utf8_string*, heim_utf8_string*);
-int copy_printable_string (const heim_printable_string*,heim_printable_string*);
-int copy_ia5_string (const heim_ia5_string*,heim_ia5_string*);
-int copy_universal_string(const heim_universal_string*,heim_universal_string*);
-int copy_bmp_string (const heim_bmp_string*,heim_bmp_string*);
-
-int heim_oid_cmp(const heim_oid *, const heim_oid *);
-int heim_octet_string_cmp(const heim_octet_string *,const heim_octet_string *);
-int heim_bit_string_cmp(const heim_bit_string *, const heim_bit_string *);
-int heim_integer_cmp(const heim_integer *, const heim_integer *);
-int heim_bmp_string_cmp(const heim_bmp_string *, const heim_bmp_string *);
-int heim_universal_string_cmp(const heim_universal_string *, 
-                             const heim_universal_string *);
-
-int der_parse_oid(const char *, heim_oid *);
+#include <der-protos.h>
 
 int _heim_fix_dce(size_t reallen, size_t *len);
 int _heim_der_set_sort(const void *, const void *);
 int _heim_time2generalizedtime (time_t, heim_octet_string *, int);
 
-const char *   der_get_class_name(unsigned);
-int            der_get_class_num(const char *);
-const char *   der_get_type_name(unsigned);
-int            der_get_type_num(const char *);
-const char *   der_get_tag_name(unsigned);
-int            der_get_tag_num(const char *);
-
-int            der_parse_hex_heim_integer(const char *, heim_integer *);
-int            der_print_hex_heim_integer(const heim_integer *, char **);
-
 #endif /* __DER_H__ */
index 2471312ba81a70fd52e367a5d062ae27ae8775be..f27f03c02bd3a0c3ca734fa913ef526f8d5ec459 100755 (executable)
@@ -34,7 +34,7 @@
 #include "der_locl.h"
 
 int
-heim_oid_cmp(const heim_oid *p, const heim_oid *q)
+der_heim_oid_cmp(const heim_oid *p, const heim_oid *q)
 {
     if (p->length != q->length)
        return p->length - q->length;
@@ -44,7 +44,8 @@ heim_oid_cmp(const heim_oid *p, const heim_oid *q)
 }
 
 int
-heim_octet_string_cmp(const heim_octet_string *p, const heim_octet_string *q)
+der_heim_octet_string_cmp(const heim_octet_string *p, 
+                         const heim_octet_string *q)
 {
     if (p->length != q->length)
        return p->length - q->length;
@@ -52,7 +53,8 @@ heim_octet_string_cmp(const heim_octet_string *p, const heim_octet_string *q)
 }
 
 int
-heim_bit_string_cmp(const heim_bit_string *p, const heim_bit_string *q)
+der_heim_bit_string_cmp(const heim_bit_string *p,
+                       const heim_bit_string *q)
 {
     int i, r1, r2;
     if (p->length != q->length)
@@ -72,7 +74,8 @@ heim_bit_string_cmp(const heim_bit_string *p, const heim_bit_string *q)
 }
 
 int
-heim_integer_cmp(const heim_integer *p, const heim_integer *q)
+der_heim_integer_cmp(const heim_integer *p,
+                    const heim_integer *q)
 {
     if (p->negative != q->negative)
        return q->negative - p->negative;
@@ -82,7 +85,7 @@ heim_integer_cmp(const heim_integer *p, const heim_integer *q)
 }
 
 int
-heim_bmp_string_cmp(const heim_bmp_string *p, const heim_bmp_string *q)
+der_heim_bmp_string_cmp(const heim_bmp_string *p, const heim_bmp_string *q)
 {
     if (p->length != q->length)
        return p->length - q->length;
@@ -90,8 +93,8 @@ heim_bmp_string_cmp(const heim_bmp_string *p, const heim_bmp_string *q)
 }
 
 int
-heim_universal_string_cmp(const heim_universal_string *p, 
-                         const heim_universal_string *q)
+der_heim_universal_string_cmp(const heim_universal_string *p, 
+                             const heim_universal_string *q)
 {
     if (p->length != q->length)
        return p->length - q->length;
index e0443eed39cc412c0b93b079af28b9e0d7b62b27..96eea9c6d7c99416346417624b6223c3d04ecdce 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2006 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
  * All rights reserved. 
  *
 
 #include "der_locl.h"
 
-RCSID("$Id: der_copy.c,v 1.14 2006/01/04 23:41:29 lha Exp $");
+RCSID("$Id: der_copy.c,v 1.16 2006/10/14 05:30:02 lha Exp $");
 
 int
-copy_general_string (const heim_general_string *from, heim_general_string *to)
+der_copy_general_string (const heim_general_string *from, 
+                        heim_general_string *to)
 {
     *to = strdup(*from);
     if(*to == NULL)
@@ -45,27 +46,27 @@ copy_general_string (const heim_general_string *from, heim_general_string *to)
 }
 
 int
-copy_utf8string (const heim_utf8_string *from, heim_utf8_string *to)
+der_copy_utf8string (const heim_utf8_string *from, heim_utf8_string *to)
 {
-    return copy_general_string(from, to);
+    return der_copy_general_string(from, to);
 }
 
 int
-copy_printable_string (const heim_printable_string *from, 
+der_copy_printable_string (const heim_printable_string *from, 
                       heim_printable_string *to)
 {
-    return copy_general_string(from, to);
+    return der_copy_general_string(from, to);
 }
 
 int
-copy_ia5_string (const heim_printable_string *from, 
-                      heim_printable_string *to)
+der_copy_ia5_string (const heim_printable_string *from, 
+                    heim_printable_string *to)
 {
-    return copy_general_string(from, to);
+    return der_copy_general_string(from, to);
 }
 
 int
-copy_bmp_string (const heim_bmp_string *from, heim_bmp_string *to)
+der_copy_bmp_string (const heim_bmp_string *from, heim_bmp_string *to)
 {
     to->length = from->length;
     to->data   = malloc(to->length * sizeof(to->data[0]));
@@ -76,8 +77,8 @@ copy_bmp_string (const heim_bmp_string *from, heim_bmp_string *to)
 }
 
 int
-copy_universal_string (const heim_universal_string *from,
-                      heim_universal_string *to)
+der_copy_universal_string (const heim_universal_string *from,
+                          heim_universal_string *to)
 {
     to->length = from->length;
     to->data   = malloc(to->length * sizeof(to->data[0]));
@@ -88,7 +89,7 @@ copy_universal_string (const heim_universal_string *from,
 }
 
 int
-copy_octet_string (const heim_octet_string *from, heim_octet_string *to)
+der_copy_octet_string (const heim_octet_string *from, heim_octet_string *to)
 {
     to->length = from->length;
     to->data   = malloc(to->length);
@@ -99,7 +100,7 @@ copy_octet_string (const heim_octet_string *from, heim_octet_string *to)
 }
 
 int
-copy_heim_integer (const heim_integer *from, heim_integer *to)
+der_copy_heim_integer (const heim_integer *from, heim_integer *to)
 {
     to->length = from->length;
     to->data   = malloc(to->length);
@@ -111,7 +112,7 @@ copy_heim_integer (const heim_integer *from, heim_integer *to)
 }
 
 int
-copy_oid (const heim_oid *from, heim_oid *to)
+der_copy_oid (const heim_oid *from, heim_oid *to)
 {
     to->length     = from->length;
     to->components = malloc(to->length * sizeof(*to->components));
@@ -123,7 +124,7 @@ copy_oid (const heim_oid *from, heim_oid *to)
 }
 
 int
-copy_bit_string (const heim_bit_string *from, heim_bit_string *to)
+der_copy_bit_string (const heim_bit_string *from, heim_bit_string *to)
 {
     size_t len;
 
index 44e39b46c590354b817b7de7c0b2edd4cccfa709..9655269356d6a7716aa9ff21fd2ef97d004906cd 100644 (file)
@@ -34,7 +34,7 @@
 #include "der_locl.h"
 #include <hex.h>
 
-RCSID("$Id: der_format.c,v 1.2 2006/01/16 23:01:11 lha Exp $");
+RCSID("$Id: der_format.c,v 1.6 2006/10/21 18:24:15 lha Exp $");
 
 int
 der_parse_hex_heim_integer (const char *p, heim_integer *data)
@@ -73,13 +73,13 @@ der_parse_hex_heim_integer (const char *p, heim_integer *data)
     }
 
     {
-       unsigned char *p = data->data;
-       while(*p == 0 && len > 0) {
-           p++;
+       unsigned char *q = data->data;
+       while(*q == 0 && len > 0) {
+           q++;
            len--;
        }
        data->length = len;
-       memmove(data->data, p, len);
+       memmove(data->data, q, len);
     }
     return 0;
 }
@@ -103,3 +103,65 @@ der_print_hex_heim_integer (const heim_integer *data, char **p)
     }
     return 0;
 }
+
+int
+der_print_heim_oid (const heim_oid *oid, char delim, char **str)
+{
+    struct rk_strpool *p = NULL;
+    int i;
+
+    for (i = 0; i < oid->length ; i++) {
+       p = rk_strpoolprintf(p, "%d%s", 
+                            oid->components[i],
+                            i < oid->length - 1 ? " " : "");
+       if (p == NULL) {
+           *str = NULL;
+           return ENOMEM;
+       }
+    }
+
+    *str = rk_strpoolcollect(p);
+    if (*str == NULL)
+       return ENOMEM;
+    return 0;
+}
+
+int
+der_parse_heim_oid (const char *str, const char *sep, heim_oid *data)
+{
+    char *s, *w, *brkt, *endptr;
+    unsigned int *c;
+    long l;
+
+    data->length = 0;
+    data->components = NULL;
+
+    if (sep == NULL)
+       sep = ".";
+
+    s = strdup(str);
+
+    for (w = strtok_r(s, sep, &brkt); 
+        w != NULL; 
+        w = strtok_r(NULL, sep, &brkt)) {
+
+       c = realloc(data->components,
+                   (data->length + 1) * sizeof(data->components[0]));
+       if (c == NULL) {
+           der_free_oid(data);
+           free(s);
+           return ENOMEM;
+       }
+       data->components = c;
+
+       l = strtol(w, &endptr, 10);
+       if (*endptr != '\0' || l < 0 || l > INT_MAX) {
+           der_free_oid(data);
+           free(s);
+           return EINVAL;
+       }
+       data->components[data->length++] = l;
+    }
+    free(s);
+    return 0;
+}
index 8959c3b1c3b9521bdb799af3cfe45b118b6122a9..c3a6a17fff730923cee5c3f0d4f34d196ea101b0 100644 (file)
 
 #include "der_locl.h"
 
-RCSID("$Id: der_free.c,v 1.11 2005/07/12 06:27:21 lha Exp $");
+RCSID("$Id: der_free.c,v 1.13 2006/10/14 05:30:47 lha Exp $");
 
 void
-free_general_string (heim_general_string *str)
+der_free_general_string (heim_general_string *str)
 {
     free(*str);
     *str = NULL;
 }
 
 void
-free_utf8string (heim_utf8_string *str)
+der_free_utf8string (heim_utf8_string *str)
 {
     free(*str);
     *str = NULL;
 }
 
 void
-free_printable_string (heim_printable_string *str)
+der_free_printable_string (heim_printable_string *str)
 {
     free(*str);
     *str = NULL;
 }
 
 void
-free_ia5_string (heim_ia5_string *str)
+der_free_ia5_string (heim_ia5_string *str)
 {
-    free_general_string(str);
+    free(*str);
+    *str = NULL;
 }
 
 void
-free_bmp_string (heim_bmp_string *k)
+der_free_bmp_string (heim_bmp_string *k)
 {
     free(k->data);
     k->data = NULL;
@@ -71,7 +72,7 @@ free_bmp_string (heim_bmp_string *k)
 }
 
 void
-free_universal_string (heim_universal_string *k)
+der_free_universal_string (heim_universal_string *k)
 {
     free(k->data);
     k->data = NULL;
@@ -79,7 +80,7 @@ free_universal_string (heim_universal_string *k)
 }
 
 void
-free_octet_string (heim_octet_string *k)
+der_free_octet_string (heim_octet_string *k)
 {
     free(k->data);
     k->data = NULL;
@@ -87,7 +88,7 @@ free_octet_string (heim_octet_string *k)
 }
 
 void
-free_heim_integer (heim_integer *k)
+der_free_heim_integer (heim_integer *k)
 {
     free(k->data);
     k->data = NULL;
@@ -95,7 +96,7 @@ free_heim_integer (heim_integer *k)
 }
 
 void
-free_oid (heim_oid *k)
+der_free_oid (heim_oid *k)
 {
     free(k->components);
     k->components = NULL;
@@ -103,7 +104,7 @@ free_oid (heim_oid *k)
 }
 
 void
-free_bit_string (heim_bit_string *k)
+der_free_bit_string (heim_bit_string *k)
 {
     free(k->data);
     k->data = NULL;
index a75ab15c09f808a403f82878dd4cc66ff2e9d850..7808fa81651d7099bf6d633aeef41336d5e8b482 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "der_locl.h"
 
-RCSID("$Id: der_get.c,v 1.45 2006/01/20 10:03:50 lha Exp $");
+RCSID("$Id: der_get.c,v 1.50 2006/10/19 16:27:44 lha Exp $");
 
 #include <version.h>
 
@@ -254,6 +254,8 @@ der_get_heim_integer (const unsigned char *p, size_t len,
        data->data = malloc(data->length);
        if (data->data == NULL) {
            data->length = 0;
+           if (size)
+               *size = 0;
            return ENOMEM;
        }
        q = &((unsigned char*)data->data)[data->length - 1];
@@ -276,6 +278,8 @@ der_get_heim_integer (const unsigned char *p, size_t len,
        data->data = malloc(data->length);
        if (data->data == NULL && data->length != 0) {
            data->length = 0;
+           if (size)
+               *size = 0;
            return ENOMEM;
        }
        memcpy(data->data, p, data->length);
@@ -305,9 +309,10 @@ generalizedtime2time (const char *s, time_t *t)
     }
     tm.tm_year -= 1900;
     tm.tm_mon -= 1;
-    *t = timegm (&tm);
+    *t = _der_timegm (&tm);
     return 0;
 }
+#undef timegm
 
 static int
 der_get_time (const unsigned char *p, size_t len, 
@@ -378,7 +383,7 @@ der_get_oid (const unsigned char *p, size_t len,
            u1 = u * 128 + (*p++ % 128);
            /* check that we don't overflow the element */
            if (u1 < u) {
-               free_oid(data);
+               der_free_oid(data);
                return ASN1_OVERRUN;
            }
            u = u1;
@@ -386,7 +391,7 @@ der_get_oid (const unsigned char *p, size_t len,
        data->components[n] = u;
     }
     if (n > 2 && p[-1] & 0x80) {
-       free_oid (data);
+       der_free_oid (data);
        return ASN1_OVERRUN;
     }
     data->length = n;
index 2c017ad84e77128fabbc36587d921717adb844eb..9b2e9f09981c981feddfd215e5017feccc3809fc 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "der_locl.h"
 
-RCSID("$Id: der_length.c,v 1.18 2006/01/20 10:04:46 lha Exp $");
+RCSID("$Id: der_length.c,v 1.19 2006/10/14 05:26:06 lha Exp $");
 
 size_t
 _heim_len_unsigned (unsigned val)
@@ -98,7 +98,7 @@ len_oid (const heim_oid *oid)
 }
 
 size_t
-length_len (size_t len)
+der_length_len (size_t len)
 {
     if (len < 128)
        return 1;
@@ -113,67 +113,67 @@ length_len (size_t len)
 }
 
 size_t
-length_integer (const int *data)
+der_length_integer (const int *data)
 {
     return _heim_len_int (*data);
 }
 
 size_t
-length_unsigned (const unsigned *data)
+der_length_unsigned (const unsigned *data)
 {
     return _heim_len_unsigned(*data);
 }
 
 size_t
-length_enumerated (const unsigned *data)
+der_length_enumerated (const unsigned *data)
 {
   return _heim_len_int (*data);
 }
 
 size_t
-length_general_string (const heim_general_string *data)
+der_length_general_string (const heim_general_string *data)
 {
     return strlen(*data);
 }
 
 size_t
-length_utf8string (const heim_utf8_string *data)
+der_length_utf8string (const heim_utf8_string *data)
 {
     return strlen(*data);
 }
 
 size_t
-length_printable_string (const heim_printable_string *data)
+der_length_printable_string (const heim_printable_string *data)
 {
     return strlen(*data);
 }
 
 size_t
-length_ia5_string (const heim_ia5_string *data)
+der_length_ia5_string (const heim_ia5_string *data)
 {
     return strlen(*data);
 }
 
 size_t
-length_bmp_string (const heim_bmp_string *data)
+der_length_bmp_string (const heim_bmp_string *data)
 {
     return data->length * 2;
 }
 
 size_t
-length_universal_string (const heim_universal_string *data)
+der_length_universal_string (const heim_universal_string *data)
 {
     return data->length * 4;
 }
 
 size_t
-length_octet_string (const heim_octet_string *k)
+der_length_octet_string (const heim_octet_string *k)
 {
     return k->length;
 }
 
 size_t
-length_heim_integer (const heim_integer *k)
+der_length_heim_integer (const heim_integer *k)
 {
     if (k->length == 0)
        return 1;
@@ -184,13 +184,13 @@ length_heim_integer (const heim_integer *k)
 }
 
 size_t
-length_oid (const heim_oid *k)
+der_length_oid (const heim_oid *k)
 {
     return len_oid (k);
 }
 
 size_t
-length_generalized_time (const time_t *t)
+der_length_generalized_time (const time_t *t)
 {
     heim_octet_string k;
     size_t ret;
@@ -202,7 +202,7 @@ length_generalized_time (const time_t *t)
 }
 
 size_t
-length_utctime (const time_t *t)
+der_length_utctime (const time_t *t)
 {
     heim_octet_string k;
     size_t ret;
@@ -214,13 +214,13 @@ length_utctime (const time_t *t)
 }
 
 size_t
-length_boolean (const int *k)
+der_length_boolean (const int *k)
 {
     return 1;
 }
 
 size_t
-length_bit_string (const heim_bit_string *k)
+der_length_bit_string (const heim_bit_string *k)
 {
     return (k->length + 7) / 8 + 1;
 }
index 1127383e6caceda666e3b884d83979088ae21264..1a87aaaee996e1b61fa259858fca54b3d3e07c0e 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE. 
  */
 
-/* $Id: der_locl.h,v 1.6 2005/07/12 06:27:22 lha Exp $ */
+/* $Id: der_locl.h,v 1.8 2006/10/19 16:24:02 lha Exp $ */
 
 #ifndef __DER_LOCL_H__
 #define __DER_LOCL_H__
 #include <asn1_err.h>
 #include <der.h>
 
-#ifndef HAVE_TIMEGM
-time_t timegm (struct tm *);
-#endif
-
+time_t _der_timegm (struct tm *);
 size_t _heim_len_unsigned (unsigned);
 size_t _heim_len_int (int);
 
index b006f233ca62ab8ab9395fc74c8bf61837501782..2fe90df9a9300c319509e6fa7929e2b55bcfcf56 100644 (file)
@@ -335,6 +335,9 @@ der_put_utctime (unsigned char *p, size_t len,
     return 0;
 }
 
+/* This API is not what you might expect.  p is a pointer to the *end*
+ * (last byte) of the buffer, of length len */
+
 int
 der_put_oid (unsigned char *p, size_t len,
             const heim_oid *data, size_t *size)
diff --git a/source4/heimdal/lib/asn1/digest.asn1 b/source4/heimdal/lib/asn1/digest.asn1
new file mode 100644 (file)
index 0000000..1f8f18b
--- /dev/null
@@ -0,0 +1,115 @@
+-- $Id: digest.asn1,v 1.9 2006/08/25 11:57:54 lha Exp $
+
+DIGEST DEFINITIONS ::=
+BEGIN
+
+IMPORTS EncryptedData, Principal FROM krb5;
+
+DigestInit ::= SEQUENCE {
+    type               UTF8String, -- http, sasl, chap, cram-md5 --
+    channel            [0] SEQUENCE {
+       cb-type         UTF8String,
+       cb-binding      UTF8String
+    } OPTIONAL,
+    hostname           [1] UTF8String OPTIONAL -- for chap/cram-md5
+}
+
+DigestInitReply ::= SEQUENCE {
+    nonce              UTF8String,     -- service nonce/challange
+    opaque             UTF8String,     -- server state
+    identifier         [0] UTF8String OPTIONAL
+}
+
+
+DigestRequest ::= SEQUENCE  {
+    type               UTF8String, -- http, sasl-md5, chap, cram-md5 --
+    digest             UTF8String, -- http:md5/md5-sess sasl:clear/int/conf --
+    username           UTF8String, -- username user used
+    authid             [0] UTF8String OPTIONAL,
+    authentication-user        [1] Principal OPTIONAL, -- principal to get key from
+    realm              [2] UTF8String OPTIONAL,
+    method             [3] UTF8String OPTIONAL,
+    uri                        [4] UTF8String OPTIONAL,
+    serverNonce                UTF8String, -- same as "DigestInitReply.nonce"
+    clientNonce                [5] UTF8String OPTIONAL,
+    nonceCount         [6] UTF8String OPTIONAL,
+    qop                        [7] UTF8String OPTIONAL,
+    identifier         [8] UTF8String OPTIONAL,
+    hostname           [9] UTF8String OPTIONAL,
+    opaque             UTF8String -- same as "DigestInitReply.opaque"
+}
+-- opaque = hex(cksum(type|serverNonce|identifier|hostname,digest-key))
+-- serverNonce = hex(time[4bytes]random[12bytes])(-cbType:cbBinding)
+
+
+DigestError ::= SEQUENCE {
+    reason             UTF8String,
+    code               INTEGER (-2147483648..2147483647)
+}
+
+DigestResponse ::= SEQUENCE  {
+    responseData       UTF8String,
+    rsp                        [0] UTF8String OPTIONAL,
+    tickets            [1] SEQUENCE OF OCTET STRING OPTIONAL,
+    channel            [2] SEQUENCE {
+       cb-type         UTF8String,
+       cb-binding      UTF8String
+    } OPTIONAL,
+    hash-a1            [3] OCTET STRING OPTIONAL
+}
+
+DigestReqInner ::= CHOICE {
+    init               [0] DigestInit,
+    digestRequest      [1] DigestRequest
+}
+
+DigestREQ ::= [APPLICATION 128] SEQUENCE {
+    apReq              [0] OCTET STRING,
+    innerReq           [1] EncryptedData
+}
+
+DigestRepInner ::= CHOICE {
+    error              [0] DigestError,
+    initReply          [1] DigestInitReply,
+    response           [2] DigestResponse
+}
+
+DigestREP ::= [APPLICATION 129] SEQUENCE {
+    apRep              [0] OCTET STRING,
+    innerRep           [1] EncryptedData
+}
+
+
+-- HTTP
+
+-- md5
+-- A1 = unq(username-value) ":" unq(realm-value) ":" passwd
+-- md5-sess
+-- A1 = HEX(H(unq(username-value) ":" unq(realm-value) ":" passwd ) ":" unq(nonce-value) ":" unq(cnonce-value))
+
+-- qop == auth
+-- A2 = Method ":" digest-uri-value
+-- qop == auth-int
+-- A2 = Method ":" digest-uri-value ":" H(entity-body) 
+
+-- request-digest  = HEX(KD(HEX(H(A1)),
+--    unq(nonce-value) ":" nc-value ":" unq(cnonce-value) ":" unq(qop-value) ":" HEX(H(A2))))
+-- no "qop"
+-- request-digest  = HEX(KD(HEX(H(A1)), unq(nonce-value) ":" HEX(H(A2))))
+
+
+-- SASL:
+-- SS = H( { unq(username-value), ":", unq(realm-value), ":", password } )
+-- A1 = { SS, ":", unq(nonce-value), ":", unq(cnonce-value) }
+-- A1 = { SS, ":", unq(nonce-value), ":", unq(cnonce-value), ":", unq(authzid-value) }
+
+-- A2 = "AUTHENTICATE:", ":", digest-uri-value
+-- qop == auth-int,auth-conf
+-- A2 = "AUTHENTICATE:", ":", digest-uri-value, ":00000000000000000000000000000000"
+
+-- response-value = HEX( KD ( HEX(H(A1)),
+--                 { unq(nonce-value), ":" nc-value, ":",
+--                   unq(cnonce-value), ":", qop-value, ":",
+--                   HEX(H(A2)) }))
+
+END
index 3d7c3983ac2e4da64a7e8f74279617d55eb22b4e..c3af316c888aaa4c14ba8e82316ed016f48d3c45 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "gen_locl.h"
 
-RCSID("$Id: gen.c,v 1.67 2006/03/31 02:52:21 lha Exp $");
+RCSID("$Id: gen.c,v 1.69 2006/10/14 05:11:52 lha Exp $");
 
 FILE *headerfile, *codefile, *logfile;
 
@@ -145,6 +145,9 @@ init_generate (const char *filename, const char *base)
             "  size_t length;\n"
             "  void *data;\n"
             "} heim_bit_string;\n\n");
+    fprintf (headerfile,
+            "typedef struct heim_octet_string heim_any;\n"
+            "typedef struct heim_octet_string heim_any_set;\n\n");
     fputs("#define ASN1_MALLOC_ENCODE(T, B, BL, S, L, R)                  \\\n"
          "  do {                                                         \\\n"
          "    (BL) = length_##T((S));                                    \\\n"
@@ -774,6 +777,7 @@ generate_type (const Symbol *s)
     generate_type_free (s);
     generate_type_length (s);
     generate_type_copy (s);
+    generate_type_seq (s);
     generate_glue (s->type, s->gen_name);
     fprintf(headerfile, "\n\n");
     close_codefile();
index 07b7efba2c833d9860de4518efec473131384efc..9455f33c6f360a7ca1c88baae9da92bef3010a97 100644 (file)
 
 #include "gen_locl.h"
 
-RCSID("$Id: gen_copy.c,v 1.16 2005/07/12 06:27:26 lha Exp $");
+RCSID("$Id: gen_copy.c,v 1.18 2006/10/14 05:34:19 lha Exp $");
 
 static int used_fail;
 
 static void
 copy_primitive (const char *typename, const char *from, const char *to)
 {
-    fprintf (codefile, "if(copy_%s(%s, %s)) goto fail;\n", 
+    fprintf (codefile, "if(der_copy_%s(%s, %s)) goto fail;\n", 
             typename, from, to);
     used_fail++;
 }
@@ -86,7 +86,7 @@ copy_type (const char *from, const char *to, const Type *t, int preserve)
        if ((t->type == TSequence || t->type == TChoice) && preserve) {
            fprintf(codefile,
                    "{ int ret;\n"
-                   "ret = copy_octet_string(&(%s)->_save, &(%s)->_save);\n"
+                   "ret = der_copy_octet_string(&(%s)->_save, &(%s)->_save);\n"
                    "if (ret) goto fail;\n"
                    "}\n",
                    from, to);
@@ -140,7 +140,7 @@ copy_type (const char *from, const char *to, const Type *t, int preserve)
            if (have_ellipsis) {
                fprintf(codefile, "case %s: {\n"
                        "int ret;\n"
-                       "ret = copy_octet_string(&(%s)->u.%s, &(%s)->u.%s);\n"
+                       "ret=der_copy_octet_string(&(%s)->u.%s, &(%s)->u.%s);\n"
                        "if (ret) goto fail;\n"
                        "break;\n"
                        "}\n",
index 6461a0ada9fdc0b4d8588d571f6f69b7b1ba839b..193dab40e1a4e5ced8b1ec5ef35b69a3cd79e155 100644 (file)
@@ -34,7 +34,7 @@
 #include "gen_locl.h"
 #include "lex.h"
 
-RCSID("$Id: gen_decode.c,v 1.29 2005/09/21 00:30:37 lha Exp $");
+RCSID("$Id: gen_decode.c,v 1.30 2006/09/24 09:13:12 lha Exp $");
 
 static void
 decode_primitive (const char *typename, const char *name, const char *forwstr)
@@ -307,7 +307,7 @@ decode_type (const char *name, const Type *t, int optional,
            decode_type (s, m->type, m->optional, forwstr, m->gen_name);
            free (s);
        }
-
+       
        break;
     }
     case TSet: {
@@ -632,7 +632,7 @@ generate_type_decode (const Symbol *s)
     case TType:
     case TChoice:
        fprintf (codefile,
-                "size_t ret = 0, reallen;\n"
+                "size_t ret = 0;\n"
                 "size_t l;\n"
                 "int e;\n");
        if (preserve)
@@ -640,7 +640,6 @@ generate_type_decode (const Symbol *s)
 
        fprintf (codefile, "\n");
        fprintf (codefile, "memset(data, 0, sizeof(*data));\n"); /* hack to avoid `unused variable' */
-       fprintf (codefile, "reallen = 0;\n"); 
 
        decode_type ("data", s->type, 0, "goto fail", "Top");
        if (preserve)
index 36c7474a03abe5122ee7ab5a84897e3bbf2b262c..2b143bf81898250057f7a622c00f427a9a8ac112 100644 (file)
 
 #include "gen_locl.h"
 
-RCSID("$Id: gen_free.c,v 1.14 2005/07/25 21:28:29 lha Exp $");
+RCSID("$Id: gen_free.c,v 1.16 2006/10/14 05:33:58 lha Exp $");
 
 static void
 free_primitive (const char *typename, const char *name)
 {
-    fprintf (codefile, "free_%s(%s);\n", typename, name);
+    fprintf (codefile, "der_free_%s(%s);\n", typename, name);
 }
 
 static void
@@ -78,7 +78,7 @@ free_type (const char *name, const Type *t, int preserve)
            break;
 
        if ((t->type == TSequence || t->type == TChoice) && preserve)
-           fprintf(codefile, "free_octet_string(&data->_save);\n");
+           fprintf(codefile, "der_free_octet_string(&data->_save);\n");
 
        if(t->type == TChoice)
            fprintf(codefile, "switch((%s)->element) {\n", name);
@@ -115,7 +115,7 @@ free_type (const char *name, const Type *t, int preserve)
            if (have_ellipsis)
                fprintf(codefile,
                        "case %s:\n"
-                       "free_octet_string(&(%s)->u.%s);\n"
+                       "der_free_octet_string(&(%s)->u.%s);\n"
                        "break;",
                        have_ellipsis->label,
                        name, have_ellipsis->gen_name);
index f3869fa5f2c6d4992443a1865df48a2c5e6a7d42..0c92225b9248a17ac376ff8df2bf444f6f91db1f 100644 (file)
 
 #include "gen_locl.h"
 
-RCSID("$Id: gen_length.c,v 1.19 2005/08/23 11:51:41 lha Exp $");
+RCSID("$Id: gen_length.c,v 1.21 2006/10/14 05:28:28 lha Exp $");
 
 static void
 length_primitive (const char *typename,
                  const char *name,
                  const char *variable)
 {
-    fprintf (codefile, "%s += length_%s(%s);\n", variable, typename, name);
+    fprintf (codefile, "%s += der_length_%s(%s);\n", variable, typename, name);
 }
 
 static size_t
@@ -247,7 +247,7 @@ length_type (const char *name, const Type *t,
        if (tname == NULL)
            errx(1, "malloc");
        length_type (name, t->subtype, variable, tname);
-       fprintf (codefile, "ret += %lu + length_len (ret);\n", 
+       fprintf (codefile, "ret += %lu + der_length_len (ret);\n", 
                 (unsigned long)length_tag(t->tag.tagvalue));
        free(tname);
        break;
index 5a2ba85c7a97226ec6f8147b4392edf6d757d0e9..c9ea714c5f7f0a3f8e4213869891c2b1ad5c0d27 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE. 
  */
 
-/* $Id: gen_locl.h,v 1.13 2005/08/23 10:48:15 lha Exp $ */
+/* $Id: gen_locl.h,v 1.14 2006/09/05 12:29:18 lha Exp $ */
 
 #ifndef __GEN_LOCL_H__
 #define __GEN_LOCL_H__
@@ -58,11 +58,10 @@ void generate_type (const Symbol *);
 void generate_constant (const Symbol *);
 void generate_type_encode (const Symbol *);
 void generate_type_decode (const Symbol *);
-void generate_seq_type_decode (const Symbol *);
 void generate_type_free (const Symbol *);
 void generate_type_length (const Symbol *);
 void generate_type_copy (const Symbol *);
-void generate_type_maybe (const Symbol *);
+void generate_type_seq (const Symbol *);
 void generate_glue (const Type *, const char*);
 
 const char *classname(Der_class);
@@ -79,6 +78,7 @@ void add_import(const char *);
 int yyparse(void);
 
 int preserve_type(const char *);
+int seq_type(const char *);
 
 extern FILE *headerfile, *codefile, *logfile;
 extern int dce_fix;
diff --git a/source4/heimdal/lib/asn1/gen_seq.c b/source4/heimdal/lib/asn1/gen_seq.c
new file mode 100644 (file)
index 0000000..fa3813f
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * 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 "gen_locl.h"
+
+RCSID("$Id: gen_seq.c,v 1.4 2006/10/04 10:18:10 lha Exp $");
+
+void
+generate_type_seq (const Symbol *s)
+{
+    char *subname;
+    Type *type;
+
+    if (!seq_type(s->name))
+       return;
+    type = s->type;
+    while(type->type == TTag)
+       type = type->subtype;
+
+    if (type->type != TSequenceOf) {
+       printf("%s not seq of %d\n", s->name, (int)type->type);
+       return;
+    }
+
+    /*
+     * Require the subtype to be a type so we can name it and use
+     * copy_/free_
+     */
+    
+    if (type->subtype->type != TType) {
+       fprintf(stderr, "%s subtype is not a type, can't generate "
+              "sequence code for this case: %d\n",
+               s->name, (int)type->subtype->type);
+       exit(1);
+    }
+
+    subname = type->subtype->symbol->gen_name;
+
+    fprintf (headerfile,
+            "int   add_%s  (%s *, const %s *);\n"
+            "int   remove_%s  (%s *, unsigned int);\n",
+            s->gen_name, s->gen_name, subname,
+            s->gen_name, s->gen_name);
+
+    fprintf (codefile, "int\n"
+            "add_%s(%s *data, const %s *element)\n"
+            "{\n",
+            s->gen_name, s->gen_name, subname);
+
+    fprintf (codefile, 
+            "int ret;\n"
+            "void *ptr;\n"
+            "\n"
+            "ptr = realloc(data->val, \n"
+            "\t(data->len + 1) * sizeof(data->val[0]));\n"
+            "if (ptr == NULL) return ENOMEM;\n"
+            "data->val = ptr;\n\n"
+            "ret = copy_%s(element, &data->val[data->len]);\n"
+            "if (ret) return ret;\n"
+            "data->len++;\n"
+            "return 0;\n",
+            subname);
+
+    fprintf (codefile, "}\n\n");
+    
+    fprintf (codefile, "int\n"
+            "remove_%s(%s *data, unsigned int element)\n"
+            "{\n",
+            s->gen_name, s->gen_name);
+
+    fprintf (codefile, 
+            "void *ptr;\n"
+            "\n"
+            "if (data->len == 0 || element >= data->len)\n"
+            "\treturn ASN1_OVERRUN;\n"
+            "free_%s(&data->val[element]);\n"
+            "data->len--;\n"
+            /* don't move if its the last element */
+            "if (element < data->len)\n"
+            "\tmemmove(&data->val[element], &data->val[element + 1], \n"
+            "\t\tsizeof(data->val[0]) * data->len);\n"
+            /* resize but don't care about failures since it doesn't matter */
+            "ptr = realloc(data->val, data->len * sizeof(data->val[0]));\n"
+            "if (ptr) data->val = ptr;\n"
+            "return 0;\n",
+            subname);
+
+    fprintf (codefile, "}\n\n");
+}
index 99f8e9514a424f93790596b0ab2efa7ea963bf22..afee6f421886cfdf1e9cfce18c0a91acd75f5030 100644 (file)
@@ -34,9 +34,6 @@
 #ifndef __HEIM_ANY_H__
 #define __HEIM_ANY_H__ 1
 
-typedef struct heim_octet_string heim_any;
-typedef struct heim_octet_string heim_any_set;
-
 int    encode_heim_any(unsigned char *, size_t, const heim_any *, size_t *);
 int    decode_heim_any(const unsigned char *, size_t, heim_any *, size_t *);
 void   free_heim_any(heim_any *);
index e314adee0e55e79e3dbc44c7b9de8f468bb04d17..3f501f0592c2e6e63610f2d5394ec39feb505726 100644 (file)
@@ -1,4 +1,4 @@
--- $Id: k5.asn1,v 1.47 2006/03/27 22:52:11 lha Exp $
+-- $Id: k5.asn1,v 1.50 2006/09/11 13:28:59 lha Exp $
 
 KERBEROS5 DEFINITIONS ::=
 BEGIN
@@ -70,10 +70,11 @@ PADATA-TYPE ::= INTEGER {
        KRB5-PADATA-TD-REQ-NONCE(107),          -- INTEGER
        KRB5-PADATA-TD-REQ-SEQ(108),            -- INTEGER
        KRB5-PADATA-PA-PAC-REQUEST(128),        -- jbrezak@exchange.microsoft.com
-       KRB5-PADATA-PK-AS-09-BINDING(132)       -- client send this to 
+       KRB5-PADATA-PK-AS-09-BINDING(132),      -- client send this to 
                                                -- tell KDC that is supports 
                                                -- the asCheckSum in the
                                                --  PK-AS-REP
+       KRB5-PADATA-S4U2SELF(-17)
 }
 
 AUTHDATA-TYPE ::= INTEGER {
@@ -89,7 +90,8 @@ AUTHDATA-TYPE ::= INTEGER {
        KRB5-AUTHDATA-SESAME(65),
        KRB5-AUTHDATA-OSF-DCE-PKI-CERTID(66),
        KRB5-AUTHDATA-WIN2K-PAC(128),
-       KRB5-AUTHDATA-GSS-API-ETYPE-NEGOTIATION(129) -- Authenticator only
+       KRB5-AUTHDATA-GSS-API-ETYPE-NEGOTIATION(129), -- Authenticator only
+       KRB5-AUTHDATA-SIGNTICKET(-17)
 }
 
 -- checksumtypes
@@ -138,12 +140,7 @@ ENCTYPE ::= INTEGER {
        ETYPE_DES_CFB64_NONE(-0x1002),
        ETYPE_DES_PCBC_NONE(-0x1003),
        ETYPE_DIGEST_MD5_NONE(-0x1004),         -- private use, lukeh@padl.com
-       ETYPE_CRAM_MD5_NONE(-0x1005),           -- private use, lukeh@padl.com
-       ETYPE_RC2_CBC_NONE(-0x1006),
-       ETYPE_AES128_CBC_NONE(-0x1007),
-       ETYPE_AES192_CBC_NONE(-0x1008),
-       ETYPE_AES256_CBC_NONE(-0x1009),
-       ETYPE_DES3_CBC_NONE_CMS(-0x100a)
+       ETYPE_CRAM_MD5_NONE(-0x1005)            -- private use, lukeh@padl.com
 }
 
 
@@ -186,11 +183,13 @@ HostAddresses ::= SEQUENCE OF HostAddress
 
 KerberosTime ::= GeneralizedTime -- Specifying UTC time zone (Z)
 
-AuthorizationData ::= SEQUENCE OF SEQUENCE {
+AuthorizationDataElement ::= SEQUENCE {
        ad-type[0]              krb5int32,
        ad-data[1]              OCTET STRING
 }
 
+AuthorizationData ::= SEQUENCE OF AuthorizationDataElement
+
 APOptions ::= BIT STRING {
        reserved(0),
        use-session-key(1),
@@ -307,7 +306,7 @@ Authenticator ::= [APPLICATION 2] SEQUENCE    {
        subkey[6]               EncryptionKey OPTIONAL,
        seq-number[7]           krb5uint32 OPTIONAL,
        authorization-data[8]   AuthorizationData OPTIONAL
-       }
+}
 
 PA-DATA ::= SEQUENCE {
        -- might be encoded AP-REQ
@@ -601,16 +600,29 @@ PA-ENC-SAM-RESPONSE-ENC ::= SEQUENCE {
        ...
 }
 
--- This is really part of CMS, but its here because KCRYPTO provides
--- the crypto framework for CMS glue in heimdal.
-
-RC2CBCParameter ::= SEQUENCE {
-       rc2ParameterVersion     krb5int32,
-       iv                      OCTET STRING -- exactly 8 octets
+PA-S4U2Self ::= SEQUENCE {
+       name[0]         PrincipalName,
+        realm[1]       Realm,
+        cksum[2]       Checksum,
+        auth[3]                GeneralString
 }
 
-CBCParameter ::= OCTET STRING
+KRB5SignedPathPrincipals ::= SEQUENCE OF Principal
 
+-- never encoded on the wire, just used to checksum over
+KRB5SignedPathData ::= SEQUENCE {
+       encticket[0]    EncTicketPart,
+       delegated[1]    KRB5SignedPathPrincipals OPTIONAL
+}
+
+KRB5SignedPath ::= SEQUENCE {
+       -- DERcoded KRB5SignedPathData
+       -- krbtgt key (etype), KeyUsage = XXX 
+       etype[0]        ENCTYPE,
+       cksum[1]        Checksum,
+       -- srvs delegated though
+       delegated[2]    KRB5SignedPathPrincipals OPTIONAL
+}
 
 END
 
index 70e893197d930a8faa7d059fea10a01c67386627..10b4d65a7e3655b965847af870d53696ad86200a 100644 (file)
@@ -1,94 +1,32 @@
-#include "config.h"
+/* A lexical scanner generated by flex*/
 
-#line 3 "lex.yy.c"
-
-#define  YY_INT_ALIGNED short int
-
-/* A lexical scanner generated by flex */
+/* Scanner skeleton version:
+ * $Header: /home/daffy/u0/vern/flex/RCS/flex.skl,v 2.91 96/09/10 16:58:48 vern Exp $
+ */
 
 #define FLEX_SCANNER
 #define YY_FLEX_MAJOR_VERSION 2
 #define YY_FLEX_MINOR_VERSION 5
-#define YY_FLEX_SUBMINOR_VERSION 33
-#if YY_FLEX_SUBMINOR_VERSION > 0
-#define FLEX_BETA
-#endif
 
-/* First, we deal with  platform-specific or compiler-specific issues. */
-
-/* begin standard C headers. */
 #include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-
-/* end standard C headers. */
-
-/* flex integer type definitions */
-
-#ifndef FLEXINT_H
-#define FLEXINT_H
-
-/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
-
-#if __STDC_VERSION__ >= 199901L
-
-/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
- * if you want the limit (max/min) macros for int types. 
- */
-#ifndef __STDC_LIMIT_MACROS
-#define __STDC_LIMIT_MACROS 1
-#endif
+#include <unistd.h>
 
-#include <inttypes.h>
-typedef int8_t flex_int8_t;
-typedef uint8_t flex_uint8_t;
-typedef int16_t flex_int16_t;
-typedef uint16_t flex_uint16_t;
-typedef int32_t flex_int32_t;
-typedef uint32_t flex_uint32_t;
-#else
-typedef signed char flex_int8_t;
-typedef short int flex_int16_t;
-typedef int flex_int32_t;
-typedef unsigned char flex_uint8_t; 
-typedef unsigned short int flex_uint16_t;
-typedef unsigned int flex_uint32_t;
-#endif /* ! C99 */
 
-/* Limits of integral types. */
-#ifndef INT8_MIN
-#define INT8_MIN               (-128)
-#endif
-#ifndef INT16_MIN
-#define INT16_MIN              (-32767-1)
-#endif
-#ifndef INT32_MIN
-#define INT32_MIN              (-2147483647-1)
-#endif
-#ifndef INT8_MAX
-#define INT8_MAX               (127)
-#endif
-#ifndef INT16_MAX
-#define INT16_MAX              (32767)
-#endif
-#ifndef INT32_MAX
-#define INT32_MAX              (2147483647)
-#endif
-#ifndef UINT8_MAX
-#define UINT8_MAX              (255U)
-#endif
-#ifndef UINT16_MAX
-#define UINT16_MAX             (65535U)
+/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
+#ifdef c_plusplus
+#ifndef __cplusplus
+#define __cplusplus
 #endif
-#ifndef UINT32_MAX
-#define UINT32_MAX             (4294967295U)
 #endif
 
-#endif /* ! FLEXINT_H */
 
 #ifdef __cplusplus
 
+#include <stdlib.h>
+
+/* Use prototypes in function declarations. */
+#define YY_USE_PROTOS
+
 /* The "const" storage-class-modifier is valid. */
 #define YY_USE_CONST
 
@@ -96,17 +34,34 @@ typedef unsigned int flex_uint32_t;
 
 #if __STDC__
 
+#define YY_USE_PROTOS
 #define YY_USE_CONST
 
 #endif /* __STDC__ */
 #endif /* ! __cplusplus */
 
+#ifdef __TURBOC__
+ #pragma warn -rch
+ #pragma warn -use
+#include <io.h>
+#include <stdlib.h>
+#define YY_USE_CONST
+#define YY_USE_PROTOS
+#endif
+
 #ifdef YY_USE_CONST
 #define yyconst const
 #else
 #define yyconst
 #endif
 
+
+#ifdef YY_USE_PROTOS
+#define YY_PROTO(proto) proto
+#else
+#define YY_PROTO(proto) ()
+#endif
+
 /* Returned upon end-of-file. */
 #define YY_NULL 0
 
@@ -121,75 +76,80 @@ typedef unsigned int flex_uint32_t;
  * but we do it the disgusting crufty way forced on us by the ()-less
  * definition of BEGIN.
  */
-#define BEGIN (yy_start) = 1 + 2 *
+#define BEGIN yy_start = 1 + 2 *
 
 /* Translate the current start state into a value that can be later handed
  * to BEGIN to return to the state.  The YYSTATE alias is for lex
  * compatibility.
  */
-#define YY_START (((yy_start) - 1) / 2)
+#define YY_START ((yy_start - 1) / 2)
 #define YYSTATE YY_START
 
 /* Action number for EOF rule of a given start state. */
 #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
 
 /* Special action meaning "start processing a new file". */
-#define YY_NEW_FILE yyrestart(yyin  )
+#define YY_NEW_FILE yyrestart( yyin )
 
 #define YY_END_OF_BUFFER_CHAR 0
 
 /* Size of default input buffer. */
-#ifndef YY_BUF_SIZE
 #define YY_BUF_SIZE 16384
-#endif
-
-/* The state buf must be large enough to hold one state per character in the main buffer.
- */
-#define YY_STATE_BUF_SIZE   ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
 
-#ifndef YY_TYPEDEF_YY_BUFFER_STATE
-#define YY_TYPEDEF_YY_BUFFER_STATE
 typedef struct yy_buffer_state *YY_BUFFER_STATE;
-#endif
 
 extern int yyleng;
-
 extern FILE *yyin, *yyout;
 
 #define EOB_ACT_CONTINUE_SCAN 0
 #define EOB_ACT_END_OF_FILE 1
 #define EOB_ACT_LAST_MATCH 2
 
-    #define YY_LESS_LINENO(n)
-    
-/* Return all but the first "n" matched characters back to the input stream. */
+/* The funky do-while in the following #define is used to turn the definition
+ * int a single C statement (which needs a semi-colon terminator).  This
+ * avoids problems with code like:
+ *
+ *     if ( condition_holds )
+ *             yyless( 5 );
+ *     else
+ *             do_something_else();
+ *
+ * Prior to using the do-while the compiler would get upset at the
+ * "else" because it interpreted the "if" statement as being all
+ * done when it reached the ';' after the yyless() call.
+ */
+
+/* Return all but the first 'n' matched characters back to the input stream. */
+
 #define yyless(n) \
        do \
                { \
                /* Undo effects of setting up yytext. */ \
-        int yyless_macro_arg = (n); \
-        YY_LESS_LINENO(yyless_macro_arg);\
-               *yy_cp = (yy_hold_char); \
+               *yy_cp = yy_hold_char; \
                YY_RESTORE_YY_MORE_OFFSET \
-               (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+               yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \
                YY_DO_BEFORE_ACTION; /* set up yytext again */ \
                } \
        while ( 0 )
 
-#define unput(c) yyunput( c, (yytext_ptr)  )
+#define unput(c) yyunput( c, yytext_ptr )
+
+/* Some routines like yy_flex_realloc() are emitted as static but are
+   not called by all lexers. This generates warnings in some compilers,
+   notably GCC. Arrange to suppress these. */
+#ifdef __GNUC__
+#define YY_MAY_BE_UNUSED __attribute__((unused))
+#else
+#define YY_MAY_BE_UNUSED
+#endif
 
 /* The following is because we cannot portably get our hands on size_t
  * (without autoconf's help, which isn't available because we want
  * flex-generated scanners to compile on their own).
  */
-
-#ifndef YY_TYPEDEF_YY_SIZE_T
-#define YY_TYPEDEF_YY_SIZE_T
 typedef unsigned int yy_size_t;
-#endif
 
-#ifndef YY_STRUCT_YY_BUFFER_STATE
-#define YY_STRUCT_YY_BUFFER_STATE
+
 struct yy_buffer_state
        {
        FILE *yy_input_file;
@@ -226,16 +186,12 @@ struct yy_buffer_state
         */
        int yy_at_bol;
 
-    int yy_bs_lineno; /**< The line count. */
-    int yy_bs_column; /**< The column count. */
-    
        /* Whether to try to fill the input buffer when we reach the
         * end of it.
         */
        int yy_fill_buffer;
 
        int yy_buffer_status;
-
 #define YY_BUFFER_NEW 0
 #define YY_BUFFER_NORMAL 1
        /* When an EOF's been seen but there's still some text to process
@@ -249,38 +205,28 @@ struct yy_buffer_state
         * just pointing yyin at a new input file.
         */
 #define YY_BUFFER_EOF_PENDING 2
-
        };
-#endif /* !YY_STRUCT_YY_BUFFER_STATE */
 
-/* Stack of input buffers. */
-static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
-static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
-static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
+static YY_BUFFER_STATE yy_current_buffer = 0;
 
 /* We provide macros for accessing buffer states in case in the
  * future we want to put the buffer states in a more general
  * "scanner state".
- *
- * Returns the top of the stack, or NULL.
  */
-#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
-                          ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
-                          : NULL)
+#define YY_CURRENT_BUFFER yy_current_buffer
 
-/* Same as previous macro, but useful when we know that the buffer stack is not
- * NULL or when we need an lvalue. For internal use only.
- */
-#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
 
 /* yy_hold_char holds the character lost when yytext is formed. */
 static char yy_hold_char;
+
 static int yy_n_chars;         /* number of characters read into yy_ch_buf */
+
+
 int yyleng;
 
 /* Points to current character in buffer. */
 static char *yy_c_buf_p = (char *) 0;
-static int yy_init = 0;                /* whether we need to initialize */
+static int yy_init = 1;                /* whether we need to initialize */
 static int yy_start = 0;       /* start state number */
 
 /* Flag which is used to allow yywrap()'s to do buffer switches
@@ -288,92 +234,66 @@ static int yy_start = 0;  /* start state number */
  */
 static int yy_did_buffer_switch_on_eof;
 
-void yyrestart (FILE *input_file  );
-void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer  );
-YY_BUFFER_STATE yy_create_buffer (FILE *file,int size  );
-void yy_delete_buffer (YY_BUFFER_STATE b  );
-void yy_flush_buffer (YY_BUFFER_STATE b  );
-void yypush_buffer_state (YY_BUFFER_STATE new_buffer  );
-void yypop_buffer_state (void );
-
-static void yyensure_buffer_stack (void );
-static void yy_load_buffer_state (void );
-static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file  );
+void yyrestart YY_PROTO(( FILE *input_file ));
 
-#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER )
+void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer ));
+void yy_load_buffer_state YY_PROTO(( void ));
+YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size ));
+void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file ));
+void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer )
 
-YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size  );
-YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str  );
-YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len  );
+YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size ));
+YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str ));
+YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len ));
 
-void *yyalloc (yy_size_t  );
-void *yyrealloc (void *,yy_size_t  );
-void yyfree (void *  );
+static void *yy_flex_alloc YY_PROTO(( yy_size_t ));
+static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t )) YY_MAY_BE_UNUSED;
+static void yy_flex_free YY_PROTO(( void * ));
 
 #define yy_new_buffer yy_create_buffer
 
 #define yy_set_interactive(is_interactive) \
        { \
-       if ( ! YY_CURRENT_BUFFER ){ \
-        yyensure_buffer_stack (); \
-               YY_CURRENT_BUFFER_LVALUE =    \
-            yy_create_buffer(yyin,YY_BUF_SIZE ); \
-       } \
-       YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+       if ( ! yy_current_buffer ) \
+               yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+       yy_current_buffer->yy_is_interactive = is_interactive; \
        }
 
 #define yy_set_bol(at_bol) \
        { \
-       if ( ! YY_CURRENT_BUFFER ){\
-        yyensure_buffer_stack (); \
-               YY_CURRENT_BUFFER_LVALUE =    \
-            yy_create_buffer(yyin,YY_BUF_SIZE ); \
-       } \
-       YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+       if ( ! yy_current_buffer ) \
+               yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+       yy_current_buffer->yy_at_bol = at_bol; \
        }
 
-#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
-
-/* Begin user sect3 */
+#define YY_AT_BOL() (yy_current_buffer->yy_at_bol)
 
 typedef unsigned char YY_CHAR;
-
 FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
-
 typedef int yy_state_type;
-
-extern int yylineno;
-
-int yylineno = 1;
-
 extern char *yytext;
 #define yytext_ptr yytext
 
-static yy_state_type yy_get_previous_state (void );
-static yy_state_type yy_try_NUL_trans (yy_state_type current_state  );
-static int yy_get_next_buffer (void );
-static void yy_fatal_error (yyconst char msg[]  );
+static yy_state_type yy_get_previous_state YY_PROTO(( void ));
+static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state ));
+static int yy_get_next_buffer YY_PROTO(( void ));
+static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
 
 /* Done after the current pattern has been matched and before the
  * corresponding action - sets up yytext.
  */
 #define YY_DO_BEFORE_ACTION \
-       (yytext_ptr) = yy_bp; \
-       yyleng = (size_t) (yy_cp - yy_bp); \
-       (yy_hold_char) = *yy_cp; \
+       yytext_ptr = yy_bp; \
+       yyleng = (int) (yy_cp - yy_bp); \
+       yy_hold_char = *yy_cp; \
        *yy_cp = '\0'; \
-       (yy_c_buf_p) = yy_cp;
+       yy_c_buf_p = yy_cp;
 
 #define YY_NUM_RULES 95
 #define YY_END_OF_BUFFER 96
-/* This struct is not used in this scanner,
-   but its presence is necessary. */
-struct yy_trans_info
-       {
-       flex_int32_t yy_verify;
-       flex_int32_t yy_nxt;
-       };
-static yyconst flex_int16_t yy_accept[568] =
+static yyconst short int yy_accept[568] =
     {   0,
         0,    0,   96,   94,   90,   91,   87,   81,   81,   94,
        94,   88,   88,   94,   89,   89,   89,   89,   89,   89,
@@ -439,7 +359,7 @@ static yyconst flex_int16_t yy_accept[568] =
        32,   89,   59,   70,   77,   53,    0
     } ;
 
-static yyconst flex_int32_t yy_ec[256] =
+static yyconst int yy_ec[256] =
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
@@ -471,7 +391,7 @@ static yyconst flex_int32_t yy_ec[256] =
         1,    1,    1,    1,    1
     } ;
 
-static yyconst flex_int32_t yy_meta[70] =
+static yyconst int yy_meta[70] =
     {   0,
         1,    1,    1,    1,    1,    1,    2,    1,    1,    3,
         3,    3,    3,    3,    3,    3,    1,    1,    3,    3,
@@ -482,7 +402,7 @@ static yyconst flex_int32_t yy_meta[70] =
         2,    2,    2,    2,    2,    2,    2,    2,    2
     } ;
 
-static yyconst flex_int16_t yy_base[570] =
+static yyconst short int yy_base[570] =
     {   0,
         0,    0,  636,  637,  637,  637,  637,  637,   63,  627,
       628,   70,   77,  616,   74,   72,   76,  609,   65,   81,
@@ -548,7 +468,7 @@ static yyconst flex_int16_t yy_base[570] =
         0,  101,    0,    0,    0,    0,  637,  223,   69
     } ;
 
-static yyconst flex_int16_t yy_def[570] =
+static yyconst short int yy_def[570] =
     {   0,
       567,    1,  567,  567,  567,  567,  567,  567,  567,  567,
       567,  567,  567,  567,  568,  568,  568,  568,  568,  568,
@@ -614,7 +534,7 @@ static yyconst flex_int16_t yy_def[570] =
       568,  568,  568,  568,  568,  568,    0,  567,  567
     } ;
 
-static yyconst flex_int16_t yy_nxt[707] =
+static yyconst short int yy_nxt[707] =
     {   0,
         4,    5,    6,    7,    8,    4,    9,   10,   11,   12,
        13,   13,   13,   13,   13,   13,   14,    4,   15,   16,
@@ -696,7 +616,7 @@ static yyconst flex_int16_t yy_nxt[707] =
       567,  567,  567,  567,  567,  567
     } ;
 
-static yyconst flex_int16_t yy_chk[707] =
+static yyconst short int yy_chk[707] =
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
@@ -781,9 +701,6 @@ static yyconst flex_int16_t yy_chk[707] =
 static yy_state_type yy_last_accepting_state;
 static char *yy_last_accepting_cpos;
 
-extern int yy_flex_debug;
-int yy_flex_debug = 0;
-
 /* The intent behind this definition is that it'll catch
  * any uses of REJECT which flex missed.
  */
@@ -793,6 +710,7 @@ int yy_flex_debug = 0;
 #define YY_RESTORE_YY_MORE_OFFSET
 char *yytext;
 #line 1 "lex.l"
+#define INITIAL 0
 #line 2 "lex.l"
 /*
  * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
@@ -827,7 +745,7 @@ char *yytext;
  * SUCH DAMAGE. 
  */
 
-/* $Id: lex.l,v 1.27 2005/09/13 18:17:16 lha Exp $ */
+/* $Id: lex.l,v 1.31 2006/10/21 11:57:22 lha Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
@@ -851,23 +769,8 @@ static unsigned lineno = 1;
 
 static void unterminated(const char *, unsigned);
 
-#line 854 "lex.yy.c"
-
-#define INITIAL 0
-
-#ifndef YY_NO_UNISTD_H
-/* Special case for "unistd.h", since it is non-ANSI. We include it way
- * down here because we want the user's section 1 to have been scanned first.
- * The user has a chance to override it with an option.
- */
-#include <unistd.h>
-#endif
-
-#ifndef YY_EXTRA_TYPE
-#define YY_EXTRA_TYPE void *
-#endif
-
-static int yy_init_globals (void );
+/* This is for broken old lexes (solaris 10 and hpux) */
+#line 774 "lex.c"
 
 /* Macros after this point can all be overridden by user definitions in
  * section 1.
@@ -875,30 +778,65 @@ static int yy_init_globals (void );
 
 #ifndef YY_SKIP_YYWRAP
 #ifdef __cplusplus
-extern "C" int yywrap (void );
+extern "C" int yywrap YY_PROTO(( void ));
 #else
-extern int yywrap (void );
+extern int yywrap YY_PROTO(( void ));
+#endif
 #endif
+
+#ifndef YY_NO_UNPUT
+static void yyunput YY_PROTO(( int c, char *buf_ptr ));
 #endif
 
-    static void yyunput (int c,char *buf_ptr  );
-    
 #ifndef yytext_ptr
-static void yy_flex_strncpy (char *,yyconst char *,int );
+static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int ));
 #endif
 
 #ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * );
+static int yy_flex_strlen YY_PROTO(( yyconst char * ));
 #endif
 
 #ifndef YY_NO_INPUT
-
 #ifdef __cplusplus
-static int yyinput (void );
+static int yyinput YY_PROTO(( void ));
+#else
+static int input YY_PROTO(( void ));
+#endif
+#endif
+
+#if YY_STACK_USED
+static int yy_start_stack_ptr = 0;
+static int yy_start_stack_depth = 0;
+static int *yy_start_stack = 0;
+#ifndef YY_NO_PUSH_STATE
+static void yy_push_state YY_PROTO(( int new_state ));
+#endif
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state YY_PROTO(( void ));
+#endif
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state YY_PROTO(( void ));
+#endif
+
 #else
-static int input (void );
+#define YY_NO_PUSH_STATE 1
+#define YY_NO_POP_STATE 1
+#define YY_NO_TOP_STATE 1
 #endif
 
+#ifdef YY_MALLOC_DECL
+YY_MALLOC_DECL
+#else
+#if __STDC__
+#ifndef __cplusplus
+#include <stdlib.h>
+#endif
+#else
+/* Just try to get by without declaring the routines.  This will fail
+ * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int)
+ * or sizeof(void*) != sizeof(int).
+ */
+#endif
 #endif
 
 /* Amount of stuff to slurp up with each read. */
@@ -907,6 +845,7 @@ static int input (void );
 #endif
 
 /* Copy whatever the last rule matched to the standard output. */
+
 #ifndef ECHO
 /* This used to be an fputs(), but since the string might contain NUL's,
  * we now use fwrite().
@@ -919,10 +858,9 @@ static int input (void );
  */
 #ifndef YY_INPUT
 #define YY_INPUT(buf,result,max_size) \
-       if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+       if ( yy_current_buffer->yy_is_interactive ) \
                { \
-               int c = '*'; \
-               size_t n; \
+               int c = '*', n; \
                for ( n = 0; n < max_size && \
                             (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
                        buf[n] = (char) c; \
@@ -932,22 +870,9 @@ static int input (void );
                        YY_FATAL_ERROR( "input in flex scanner failed" ); \
                result = n; \
                } \
-       else \
-               { \
-               errno=0; \
-               while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
-                       { \
-                       if( errno != EINTR) \
-                               { \
-                               YY_FATAL_ERROR( "input in flex scanner failed" ); \
-                               break; \
-                               } \
-                       errno=0; \
-                       clearerr(yyin); \
-                       } \
-               }\
-\
-
+       else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \
+                 && ferror( yyin ) ) \
+               YY_FATAL_ERROR( "input in flex scanner failed" );
 #endif
 
 /* No semi-colon after return; correct usage is to write "yyterminate();" -
@@ -968,18 +893,12 @@ static int input (void );
 #define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
 #endif
 
-/* end tables serialization structures and prototypes */
-
 /* Default declaration of generated scanner - a define so the user can
  * easily add parameters.
  */
 #ifndef YY_DECL
-#define YY_DECL_IS_OURS 1
-
-extern int yylex (void);
-
-#define YY_DECL int yylex (void)
-#endif /* !YY_DECL */
+#define YY_DECL int yylex YY_PROTO(( void ))
+#endif
 
 /* Code executed at the beginning of each rule, after yytext and yyleng
  * have been set up.
@@ -996,28 +915,26 @@ extern int yylex (void);
 #define YY_RULE_SETUP \
        YY_USER_ACTION
 
-/** The main scanner function which does all the work.
- */
 YY_DECL
-{
+       {
        register yy_state_type yy_current_state;
-       register char *yy_cp, *yy_bp;
+       register char *yy_cp = NULL, *yy_bp = NULL;
        register int yy_act;
-    
-#line 62 "lex.l"
 
-#line 1009 "lex.yy.c"
+#line 68 "lex.l"
+
+#line 927 "lex.c"
 
-       if ( !(yy_init) )
+       if ( yy_init )
                {
-               (yy_init) = 1;
+               yy_init = 0;
 
 #ifdef YY_USER_INIT
                YY_USER_INIT;
 #endif
 
-               if ( ! (yy_start) )
-                       (yy_start) = 1; /* first start state */
+               if ( ! yy_start )
+                       yy_start = 1;   /* first start state */
 
                if ( ! yyin )
                        yyin = stdin;
@@ -1025,36 +942,34 @@ YY_DECL
                if ( ! yyout )
                        yyout = stdout;
 
-               if ( ! YY_CURRENT_BUFFER ) {
-                       yyensure_buffer_stack ();
-                       YY_CURRENT_BUFFER_LVALUE =
-                               yy_create_buffer(yyin,YY_BUF_SIZE );
-               }
+               if ( ! yy_current_buffer )
+                       yy_current_buffer =
+                               yy_create_buffer( yyin, YY_BUF_SIZE );
 
-               yy_load_buffer_state( );
+               yy_load_buffer_state();
                }
 
        while ( 1 )             /* loops until end-of-file is reached */
                {
-               yy_cp = (yy_c_buf_p);
+               yy_cp = yy_c_buf_p;
 
                /* Support of yytext. */
-               *yy_cp = (yy_hold_char);
+               *yy_cp = yy_hold_char;
 
                /* yy_bp points to the position in yy_ch_buf of the start of
                 * the current run.
                 */
                yy_bp = yy_cp;
 
-               yy_current_state = (yy_start);
+               yy_current_state = yy_start;
 yy_match:
                do
                        {
                        register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
                        if ( yy_accept[yy_current_state] )
                                {
-                               (yy_last_accepting_state) = yy_current_state;
-                               (yy_last_accepting_cpos) = yy_cp;
+                               yy_last_accepting_state = yy_current_state;
+                               yy_last_accepting_cpos = yy_cp;
                                }
                        while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                                {
@@ -1071,447 +986,449 @@ yy_find_action:
                yy_act = yy_accept[yy_current_state];
                if ( yy_act == 0 )
                        { /* have to back up */
-                       yy_cp = (yy_last_accepting_cpos);
-                       yy_current_state = (yy_last_accepting_state);
+                       yy_cp = yy_last_accepting_cpos;
+                       yy_current_state = yy_last_accepting_state;
                        yy_act = yy_accept[yy_current_state];
                        }
 
                YY_DO_BEFORE_ACTION;
 
+
 do_action:     /* This label is used only to access EOF actions. */
 
+
                switch ( yy_act )
        { /* beginning of action switch */
                        case 0: /* must back up */
                        /* undo the effects of YY_DO_BEFORE_ACTION */
-                       *yy_cp = (yy_hold_char);
-                       yy_cp = (yy_last_accepting_cpos);
-                       yy_current_state = (yy_last_accepting_state);
+                       *yy_cp = yy_hold_char;
+                       yy_cp = yy_last_accepting_cpos;
+                       yy_current_state = yy_last_accepting_state;
                        goto yy_find_action;
 
 case 1:
 YY_RULE_SETUP
-#line 63 "lex.l"
+#line 69 "lex.l"
 { return kw_ABSENT; }
        YY_BREAK
 case 2:
 YY_RULE_SETUP
-#line 64 "lex.l"
+#line 70 "lex.l"
 { return kw_ABSTRACT_SYNTAX; }
        YY_BREAK
 case 3:
 YY_RULE_SETUP
-#line 65 "lex.l"
+#line 71 "lex.l"
 { return kw_ALL; }
        YY_BREAK
 case 4:
 YY_RULE_SETUP
-#line 66 "lex.l"
+#line 72 "lex.l"
 { return kw_APPLICATION; }
        YY_BREAK
 case 5:
 YY_RULE_SETUP
-#line 67 "lex.l"
+#line 73 "lex.l"
 { return kw_AUTOMATIC; }
        YY_BREAK
 case 6:
 YY_RULE_SETUP
-#line 68 "lex.l"
+#line 74 "lex.l"
 { return kw_BEGIN; }
        YY_BREAK
 case 7:
 YY_RULE_SETUP
-#line 69 "lex.l"
+#line 75 "lex.l"
 { return kw_BIT; }
        YY_BREAK
 case 8:
 YY_RULE_SETUP
-#line 70 "lex.l"
+#line 76 "lex.l"
 { return kw_BMPString; }
        YY_BREAK
 case 9:
 YY_RULE_SETUP
-#line 71 "lex.l"
+#line 77 "lex.l"
 { return kw_BOOLEAN; }
        YY_BREAK
 case 10:
 YY_RULE_SETUP
-#line 72 "lex.l"
+#line 78 "lex.l"
 { return kw_BY; }
        YY_BREAK
 case 11:
 YY_RULE_SETUP
-#line 73 "lex.l"
+#line 79 "lex.l"
 { return kw_CHARACTER; }
        YY_BREAK
 case 12:
 YY_RULE_SETUP
-#line 74 "lex.l"
+#line 80 "lex.l"
 { return kw_CHOICE; }
        YY_BREAK
 case 13:
 YY_RULE_SETUP
-#line 75 "lex.l"
+#line 81 "lex.l"
 { return kw_CLASS; }
        YY_BREAK
 case 14:
 YY_RULE_SETUP
-#line 76 "lex.l"
+#line 82 "lex.l"
 { return kw_COMPONENT; }
        YY_BREAK
 case 15:
 YY_RULE_SETUP
-#line 77 "lex.l"
+#line 83 "lex.l"
 { return kw_COMPONENTS; }
        YY_BREAK
 case 16:
 YY_RULE_SETUP
-#line 78 "lex.l"
+#line 84 "lex.l"
 { return kw_CONSTRAINED; }
        YY_BREAK
 case 17:
 YY_RULE_SETUP
-#line 79 "lex.l"
+#line 85 "lex.l"
 { return kw_CONTAINING; }
        YY_BREAK
 case 18:
 YY_RULE_SETUP
-#line 80 "lex.l"
+#line 86 "lex.l"
 { return kw_DEFAULT; }
        YY_BREAK
 case 19:
 YY_RULE_SETUP
-#line 81 "lex.l"
+#line 87 "lex.l"
 { return kw_DEFINITIONS; }
        YY_BREAK
 case 20:
 YY_RULE_SETUP
-#line 82 "lex.l"
+#line 88 "lex.l"
 { return kw_EMBEDDED; }
        YY_BREAK
 case 21:
 YY_RULE_SETUP
-#line 83 "lex.l"
+#line 89 "lex.l"
 { return kw_ENCODED; }
        YY_BREAK
 case 22:
 YY_RULE_SETUP
-#line 84 "lex.l"
+#line 90 "lex.l"
 { return kw_END; }
        YY_BREAK
 case 23:
 YY_RULE_SETUP
-#line 85 "lex.l"
+#line 91 "lex.l"
 { return kw_ENUMERATED; }
        YY_BREAK
 case 24:
 YY_RULE_SETUP
-#line 86 "lex.l"
+#line 92 "lex.l"
 { return kw_EXCEPT; }
        YY_BREAK
 case 25:
 YY_RULE_SETUP
-#line 87 "lex.l"
+#line 93 "lex.l"
 { return kw_EXPLICIT; }
        YY_BREAK
 case 26:
 YY_RULE_SETUP
-#line 88 "lex.l"
+#line 94 "lex.l"
 { return kw_EXPORTS; }
        YY_BREAK
 case 27:
 YY_RULE_SETUP
-#line 89 "lex.l"
+#line 95 "lex.l"
 { return kw_EXTENSIBILITY; }
        YY_BREAK
 case 28:
 YY_RULE_SETUP
-#line 90 "lex.l"
+#line 96 "lex.l"
 { return kw_EXTERNAL; }
        YY_BREAK
 case 29:
 YY_RULE_SETUP
-#line 91 "lex.l"
+#line 97 "lex.l"
 { return kw_FALSE; }
        YY_BREAK
 case 30:
 YY_RULE_SETUP
-#line 92 "lex.l"
+#line 98 "lex.l"
 { return kw_FROM; }
        YY_BREAK
 case 31:
 YY_RULE_SETUP
-#line 93 "lex.l"
+#line 99 "lex.l"
 { return kw_GeneralString; }
        YY_BREAK
 case 32:
 YY_RULE_SETUP
-#line 94 "lex.l"
+#line 100 "lex.l"
 { return kw_GeneralizedTime; }
        YY_BREAK
 case 33:
 YY_RULE_SETUP
-#line 95 "lex.l"
+#line 101 "lex.l"
 { return kw_GraphicString; }
        YY_BREAK
 case 34:
 YY_RULE_SETUP
-#line 96 "lex.l"
+#line 102 "lex.l"
 { return kw_IA5String; }
        YY_BREAK
 case 35:
 YY_RULE_SETUP
-#line 97 "lex.l"
+#line 103 "lex.l"
 { return kw_IDENTIFIER; }
        YY_BREAK
 case 36:
 YY_RULE_SETUP
-#line 98 "lex.l"
+#line 104 "lex.l"
 { return kw_IMPLICIT; }
        YY_BREAK
 case 37:
 YY_RULE_SETUP
-#line 99 "lex.l"
+#line 105 "lex.l"
 { return kw_IMPLIED; }
        YY_BREAK
 case 38:
 YY_RULE_SETUP
-#line 100 "lex.l"
+#line 106 "lex.l"
 { return kw_IMPORTS; }
        YY_BREAK
 case 39:
 YY_RULE_SETUP
-#line 101 "lex.l"
+#line 107 "lex.l"
 { return kw_INCLUDES; }
        YY_BREAK
 case 40:
 YY_RULE_SETUP
-#line 102 "lex.l"
+#line 108 "lex.l"
 { return kw_INSTANCE; }
        YY_BREAK
 case 41:
 YY_RULE_SETUP
-#line 103 "lex.l"
+#line 109 "lex.l"
 { return kw_INTEGER; }
        YY_BREAK
 case 42:
 YY_RULE_SETUP
-#line 104 "lex.l"
+#line 110 "lex.l"
 { return kw_INTERSECTION; }
        YY_BREAK
 case 43:
 YY_RULE_SETUP
-#line 105 "lex.l"
+#line 111 "lex.l"
 { return kw_ISO646String; }
        YY_BREAK
 case 44:
 YY_RULE_SETUP
-#line 106 "lex.l"
+#line 112 "lex.l"
 { return kw_MAX; }
        YY_BREAK
 case 45:
 YY_RULE_SETUP
-#line 107 "lex.l"
+#line 113 "lex.l"
 { return kw_MIN; }
        YY_BREAK
 case 46:
 YY_RULE_SETUP
-#line 108 "lex.l"
+#line 114 "lex.l"
 { return kw_MINUS_INFINITY; }
        YY_BREAK
 case 47:
 YY_RULE_SETUP
-#line 109 "lex.l"
+#line 115 "lex.l"
 { return kw_NULL; }
        YY_BREAK
 case 48:
 YY_RULE_SETUP
-#line 110 "lex.l"
+#line 116 "lex.l"
 { return kw_NumericString; }
        YY_BREAK
 case 49:
 YY_RULE_SETUP
-#line 111 "lex.l"
+#line 117 "lex.l"
 { return kw_OBJECT; }
        YY_BREAK
 case 50:
 YY_RULE_SETUP
-#line 112 "lex.l"
+#line 118 "lex.l"
 { return kw_OCTET; }
        YY_BREAK
 case 51:
 YY_RULE_SETUP
-#line 113 "lex.l"
+#line 119 "lex.l"
 { return kw_OF; }
        YY_BREAK
 case 52:
 YY_RULE_SETUP
-#line 114 "lex.l"
+#line 120 "lex.l"
 { return kw_OPTIONAL; }
        YY_BREAK
 case 53:
 YY_RULE_SETUP
-#line 115 "lex.l"
+#line 121 "lex.l"
 { return kw_ObjectDescriptor; }
        YY_BREAK
 case 54:
 YY_RULE_SETUP
-#line 116 "lex.l"
+#line 122 "lex.l"
 { return kw_PATTERN; }
        YY_BREAK
 case 55:
 YY_RULE_SETUP
-#line 117 "lex.l"
+#line 123 "lex.l"
 { return kw_PDV; }
        YY_BREAK
 case 56:
 YY_RULE_SETUP
-#line 118 "lex.l"
+#line 124 "lex.l"
 { return kw_PLUS_INFINITY; }
        YY_BREAK
 case 57:
 YY_RULE_SETUP
-#line 119 "lex.l"
+#line 125 "lex.l"
 { return kw_PRESENT; }
        YY_BREAK
 case 58:
 YY_RULE_SETUP
-#line 120 "lex.l"
+#line 126 "lex.l"
 { return kw_PRIVATE; }
        YY_BREAK
 case 59:
 YY_RULE_SETUP
-#line 121 "lex.l"
+#line 127 "lex.l"
 { return kw_PrintableString; }
        YY_BREAK
 case 60:
 YY_RULE_SETUP
-#line 122 "lex.l"
+#line 128 "lex.l"
 { return kw_REAL; }
        YY_BREAK
 case 61:
 YY_RULE_SETUP
-#line 123 "lex.l"
+#line 129 "lex.l"
 { return kw_RELATIVE_OID; }
        YY_BREAK
 case 62:
 YY_RULE_SETUP
-#line 124 "lex.l"
+#line 130 "lex.l"
 { return kw_SEQUENCE; }
        YY_BREAK
 case 63:
 YY_RULE_SETUP
-#line 125 "lex.l"
+#line 131 "lex.l"
 { return kw_SET; }
        YY_BREAK
 case 64:
 YY_RULE_SETUP
-#line 126 "lex.l"
+#line 132 "lex.l"
 { return kw_SIZE; }
        YY_BREAK
 case 65:
 YY_RULE_SETUP
-#line 127 "lex.l"
+#line 133 "lex.l"
 { return kw_STRING; }
        YY_BREAK
 case 66:
 YY_RULE_SETUP
-#line 128 "lex.l"
+#line 134 "lex.l"
 { return kw_SYNTAX; }
        YY_BREAK
 case 67:
 YY_RULE_SETUP
-#line 129 "lex.l"
+#line 135 "lex.l"
 { return kw_T61String; }
        YY_BREAK
 case 68:
 YY_RULE_SETUP
-#line 130 "lex.l"
+#line 136 "lex.l"
 { return kw_TAGS; }
        YY_BREAK
 case 69:
 YY_RULE_SETUP
-#line 131 "lex.l"
+#line 137 "lex.l"
 { return kw_TRUE; }
        YY_BREAK
 case 70:
 YY_RULE_SETUP
-#line 132 "lex.l"
+#line 138 "lex.l"
 { return kw_TYPE_IDENTIFIER; }
        YY_BREAK
 case 71:
 YY_RULE_SETUP
-#line 133 "lex.l"
+#line 139 "lex.l"
 { return kw_TeletexString; }
        YY_BREAK
 case 72:
 YY_RULE_SETUP
-#line 134 "lex.l"
+#line 140 "lex.l"
 { return kw_UNION; }
        YY_BREAK
 case 73:
 YY_RULE_SETUP
-#line 135 "lex.l"
+#line 141 "lex.l"
 { return kw_UNIQUE; }
        YY_BREAK
 case 74:
 YY_RULE_SETUP
-#line 136 "lex.l"
+#line 142 "lex.l"
 { return kw_UNIVERSAL; }
        YY_BREAK
 case 75:
 YY_RULE_SETUP
-#line 137 "lex.l"
+#line 143 "lex.l"
 { return kw_UTCTime; }
        YY_BREAK
 case 76:
 YY_RULE_SETUP
-#line 138 "lex.l"
+#line 144 "lex.l"
 { return kw_UTF8String; }
        YY_BREAK
 case 77:
 YY_RULE_SETUP
-#line 139 "lex.l"
+#line 145 "lex.l"
 { return kw_UniversalString; }
        YY_BREAK
 case 78:
 YY_RULE_SETUP
-#line 140 "lex.l"
+#line 146 "lex.l"
 { return kw_VideotexString; }
        YY_BREAK
 case 79:
 YY_RULE_SETUP
-#line 141 "lex.l"
+#line 147 "lex.l"
 { return kw_VisibleString; }
        YY_BREAK
 case 80:
 YY_RULE_SETUP
-#line 142 "lex.l"
+#line 148 "lex.l"
 { return kw_WITH; }
        YY_BREAK
 case 81:
 YY_RULE_SETUP
-#line 143 "lex.l"
+#line 149 "lex.l"
 { return *yytext; }
        YY_BREAK
 case 82:
 YY_RULE_SETUP
-#line 144 "lex.l"
+#line 150 "lex.l"
 { return *yytext; }
        YY_BREAK
 case 83:
 YY_RULE_SETUP
-#line 145 "lex.l"
+#line 151 "lex.l"
 { return *yytext; }
        YY_BREAK
 case 84:
 YY_RULE_SETUP
-#line 146 "lex.l"
+#line 152 "lex.l"
 { return EEQUAL; }
        YY_BREAK
 case 85:
 YY_RULE_SETUP
-#line 147 "lex.l"
+#line 153 "lex.l"
 { 
                            int c, start_lineno = lineno;
                            int f = 0;
@@ -1534,7 +1451,7 @@ YY_RULE_SETUP
        YY_BREAK
 case 86:
 YY_RULE_SETUP
-#line 166 "lex.l"
+#line 172 "lex.l"
 { 
                            int c, start_lineno = lineno;
                            int level = 1;
@@ -1578,7 +1495,7 @@ YY_RULE_SETUP
        YY_BREAK
 case 87:
 YY_RULE_SETUP
-#line 206 "lex.l"
+#line 212 "lex.l"
 { 
                            int start_lineno = lineno;
                            int c;
@@ -1626,7 +1543,7 @@ YY_RULE_SETUP
        YY_BREAK
 case 88:
 YY_RULE_SETUP
-#line 251 "lex.l"
+#line 257 "lex.l"
 { char *e, *y = yytext;
                          yylval.constant = strtol((const char *)yytext,
                                                   &e, 0);
@@ -1638,7 +1555,7 @@ YY_RULE_SETUP
        YY_BREAK
 case 89:
 YY_RULE_SETUP
-#line 259 "lex.l"
+#line 265 "lex.l"
 {
                          yylval.name =  estrdup ((const char *)yytext);
                          return IDENTIFIER;
@@ -1646,62 +1563,61 @@ YY_RULE_SETUP
        YY_BREAK
 case 90:
 YY_RULE_SETUP
-#line 263 "lex.l"
+#line 269 "lex.l"
 ;
        YY_BREAK
 case 91:
-/* rule 91 can match eol */
 YY_RULE_SETUP
-#line 264 "lex.l"
+#line 270 "lex.l"
 { ++lineno; }
        YY_BREAK
 case 92:
 YY_RULE_SETUP
-#line 265 "lex.l"
+#line 271 "lex.l"
 { return ELLIPSIS; }
        YY_BREAK
 case 93:
 YY_RULE_SETUP
-#line 266 "lex.l"
+#line 272 "lex.l"
 { return RANGE; }
        YY_BREAK
 case 94:
 YY_RULE_SETUP
-#line 267 "lex.l"
+#line 273 "lex.l"
 { error_message("Ignoring char(%c)\n", *yytext); }
        YY_BREAK
 case 95:
 YY_RULE_SETUP
-#line 268 "lex.l"
+#line 274 "lex.l"
 ECHO;
        YY_BREAK
-#line 1678 "lex.yy.c"
+#line 1595 "lex.c"
 case YY_STATE_EOF(INITIAL):
        yyterminate();
 
        case YY_END_OF_BUFFER:
                {
                /* Amount of text matched not including the EOB char. */
-               int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
+               int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1;
 
                /* Undo the effects of YY_DO_BEFORE_ACTION. */
-               *yy_cp = (yy_hold_char);
+               *yy_cp = yy_hold_char;
                YY_RESTORE_YY_MORE_OFFSET
 
-               if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+               if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW )
                        {
                        /* We're scanning a new file or input source.  It's
                         * possible that this happened because the user
                         * just pointed yyin at a new source and called
                         * yylex().  If so, then we have to assure
-                        * consistency between YY_CURRENT_BUFFER and our
+                        * consistency between yy_current_buffer and our
                         * globals.  Here is the right place to do so, because
                         * this is the first action (other than possibly a
                         * back-up) that will match for the new input source.
                         */
-                       (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
-                       YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
-                       YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+                       yy_n_chars = yy_current_buffer->yy_n_chars;
+                       yy_current_buffer->yy_input_file = yyin;
+                       yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL;
                        }
 
                /* Note that here we test for yy_c_buf_p "<=" to the position
@@ -1711,13 +1627,13 @@ case YY_STATE_EOF(INITIAL):
                 * end-of-buffer state).  Contrast this with the test
                 * in input().
                 */
-               if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+               if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] )
                        { /* This was really a NUL. */
                        yy_state_type yy_next_state;
 
-                       (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
+                       yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text;
 
-                       yy_current_state = yy_get_previous_state(  );
+                       yy_current_state = yy_get_previous_state();
 
                        /* Okay, we're now positioned to make the NUL
                         * transition.  We couldn't have
@@ -1730,30 +1646,30 @@ case YY_STATE_EOF(INITIAL):
 
                        yy_next_state = yy_try_NUL_trans( yy_current_state );
 
-                       yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+                       yy_bp = yytext_ptr + YY_MORE_ADJ;
 
                        if ( yy_next_state )
                                {
                                /* Consume the NUL. */
-                               yy_cp = ++(yy_c_buf_p);
+                               yy_cp = ++yy_c_buf_p;
                                yy_current_state = yy_next_state;
                                goto yy_match;
                                }
 
                        else
                                {
-                               yy_cp = (yy_c_buf_p);
+                               yy_cp = yy_c_buf_p;
                                goto yy_find_action;
                                }
                        }
 
-               else switch ( yy_get_next_buffer(  ) )
+               else switch ( yy_get_next_buffer() )
                        {
                        case EOB_ACT_END_OF_FILE:
                                {
-                               (yy_did_buffer_switch_on_eof) = 0;
+                               yy_did_buffer_switch_on_eof = 0;
 
-                               if ( yywrap( ) )
+                               if ( yywrap() )
                                        {
                                        /* Note: because we've taken care in
                                         * yy_get_next_buffer() to have set up
@@ -1764,7 +1680,7 @@ case YY_STATE_EOF(INITIAL):
                                         * YY_NULL, it'll still work - another
                                         * YY_NULL will get returned.
                                         */
-                                       (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
+                                       yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;
 
                                        yy_act = YY_STATE_EOF(YY_START);
                                        goto do_action;
@@ -1772,30 +1688,30 @@ case YY_STATE_EOF(INITIAL):
 
                                else
                                        {
-                                       if ( ! (yy_did_buffer_switch_on_eof) )
+                                       if ( ! yy_did_buffer_switch_on_eof )
                                                YY_NEW_FILE;
                                        }
                                break;
                                }
 
                        case EOB_ACT_CONTINUE_SCAN:
-                               (yy_c_buf_p) =
-                                       (yytext_ptr) + yy_amount_of_matched_text;
+                               yy_c_buf_p =
+                                       yytext_ptr + yy_amount_of_matched_text;
 
-                               yy_current_state = yy_get_previous_state(  );
+                               yy_current_state = yy_get_previous_state();
 
-                               yy_cp = (yy_c_buf_p);
-                               yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+                               yy_cp = yy_c_buf_p;
+                               yy_bp = yytext_ptr + YY_MORE_ADJ;
                                goto yy_match;
 
                        case EOB_ACT_LAST_MATCH:
-                               (yy_c_buf_p) =
-                               &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
+                               yy_c_buf_p =
+                               &yy_current_buffer->yy_ch_buf[yy_n_chars];
 
-                               yy_current_state = yy_get_previous_state(  );
+                               yy_current_state = yy_get_previous_state();
 
-                               yy_cp = (yy_c_buf_p);
-                               yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+                               yy_cp = yy_c_buf_p;
+                               yy_bp = yytext_ptr + YY_MORE_ADJ;
                                goto yy_find_action;
                        }
                break;
@@ -1806,7 +1722,8 @@ case YY_STATE_EOF(INITIAL):
                        "fatal flex scanner internal error--no action found" );
        } /* end of action switch */
                } /* end of scanning one token */
-} /* end of yylex */
+       } /* end of yylex */
+
 
 /* yy_get_next_buffer - try to read in a new buffer
  *
@@ -1815,20 +1732,21 @@ case YY_STATE_EOF(INITIAL):
  *     EOB_ACT_CONTINUE_SCAN - continue scanning from current position
  *     EOB_ACT_END_OF_FILE - end of file
  */
-static int yy_get_next_buffer (void)
-{
-       register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
-       register char *source = (yytext_ptr);
+
+static int yy_get_next_buffer()
+       {
+       register char *dest = yy_current_buffer->yy_ch_buf;
+       register char *source = yytext_ptr;
        register int number_to_move, i;
        int ret_val;
 
-       if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
+       if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] )
                YY_FATAL_ERROR(
                "fatal flex scanner internal error--end of buffer missed" );
 
-       if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+       if ( yy_current_buffer->yy_fill_buffer == 0 )
                { /* Don't try to fill the buffer, so this is an EOF. */
-               if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
+               if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 )
                        {
                        /* We matched a single character, the EOB, so
                         * treat this as a final EOF.
@@ -1848,30 +1766,34 @@ static int yy_get_next_buffer (void)
        /* Try to read more data. */
 
        /* First move last chars to start of buffer. */
-       number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
+       number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1;
 
        for ( i = 0; i < number_to_move; ++i )
                *(dest++) = *(source++);
 
-       if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+       if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING )
                /* don't do the read, it's not guaranteed to return an EOF,
                 * just force an EOF
                 */
-               YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
+               yy_current_buffer->yy_n_chars = yy_n_chars = 0;
 
        else
                {
-                       int num_to_read =
-                       YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+               int num_to_read =
+                       yy_current_buffer->yy_buf_size - number_to_move - 1;
 
                while ( num_to_read <= 0 )
                        { /* Not enough room in the buffer - grow it. */
+#ifdef YY_USES_REJECT
+                       YY_FATAL_ERROR(
+"input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
+#else
 
                        /* just a shorter name for the current buffer */
-                       YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
+                       YY_BUFFER_STATE b = yy_current_buffer;
 
                        int yy_c_buf_p_offset =
-                               (int) ((yy_c_buf_p) - b->yy_ch_buf);
+                               (int) (yy_c_buf_p - b->yy_ch_buf);
 
                        if ( b->yy_is_our_buffer )
                                {
@@ -1884,7 +1806,8 @@ static int yy_get_next_buffer (void)
 
                                b->yy_ch_buf = (char *)
                                        /* Include room in for 2 EOB chars. */
-                                       yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2  );
+                                       yy_flex_realloc( (void *) b->yy_ch_buf,
+                                                        b->yy_buf_size + 2 );
                                }
                        else
                                /* Can't grow it, we don't own it. */
@@ -1894,35 +1817,35 @@ static int yy_get_next_buffer (void)
                                YY_FATAL_ERROR(
                                "fatal error - scanner input buffer overflow" );
 
-                       (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
+                       yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
 
-                       num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+                       num_to_read = yy_current_buffer->yy_buf_size -
                                                number_to_move - 1;
-
+#endif
                        }
 
                if ( num_to_read > YY_READ_BUF_SIZE )
                        num_to_read = YY_READ_BUF_SIZE;
 
                /* Read in more data. */
-               YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
-                       (yy_n_chars), (size_t) num_to_read );
+               YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]),
+                       yy_n_chars, num_to_read );
 
-               YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+               yy_current_buffer->yy_n_chars = yy_n_chars;
                }
 
-       if ( (yy_n_chars) == 0 )
+       if ( yy_n_chars == 0 )
                {
                if ( number_to_move == YY_MORE_ADJ )
                        {
                        ret_val = EOB_ACT_END_OF_FILE;
-                       yyrestart(yyin  );
+                       yyrestart( yyin );
                        }
 
                else
                        {
                        ret_val = EOB_ACT_LAST_MATCH;
-                       YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+                       yy_current_buffer->yy_buffer_status =
                                YY_BUFFER_EOF_PENDING;
                        }
                }
@@ -1930,31 +1853,32 @@ static int yy_get_next_buffer (void)
        else
                ret_val = EOB_ACT_CONTINUE_SCAN;
 
-       (yy_n_chars) += number_to_move;
-       YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
-       YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
+       yy_n_chars += number_to_move;
+       yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+       yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
 
-       (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+       yytext_ptr = &yy_current_buffer->yy_ch_buf[0];
 
        return ret_val;
-}
+       }
+
 
 /* yy_get_previous_state - get the state just before the EOB char was reached */
 
-    static yy_state_type yy_get_previous_state (void)
-{
+static yy_state_type yy_get_previous_state()
+       {
        register yy_state_type yy_current_state;
        register char *yy_cp;
-    
-       yy_current_state = (yy_start);
 
-       for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
+       yy_current_state = yy_start;
+
+       for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp )
                {
                register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
                if ( yy_accept[yy_current_state] )
                        {
-                       (yy_last_accepting_state) = yy_current_state;
-                       (yy_last_accepting_cpos) = yy_cp;
+                       yy_last_accepting_state = yy_current_state;
+                       yy_last_accepting_cpos = yy_cp;
                        }
                while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                        {
@@ -1966,23 +1890,30 @@ static int yy_get_next_buffer (void)
                }
 
        return yy_current_state;
-}
+       }
+
 
 /* yy_try_NUL_trans - try to make a transition on the NUL character
  *
  * synopsis
  *     next_state = yy_try_NUL_trans( current_state );
  */
-    static yy_state_type yy_try_NUL_trans  (yy_state_type yy_current_state )
-{
+
+#ifdef YY_USE_PROTOS
+static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state )
+#else
+static yy_state_type yy_try_NUL_trans( yy_current_state )
+yy_state_type yy_current_state;
+#endif
+       {
        register int yy_is_jam;
-       register char *yy_cp = (yy_c_buf_p);
+       register char *yy_cp = yy_c_buf_p;
 
        register YY_CHAR yy_c = 1;
        if ( yy_accept[yy_current_state] )
                {
-               (yy_last_accepting_state) = yy_current_state;
-               (yy_last_accepting_cpos) = yy_cp;
+               yy_last_accepting_state = yy_current_state;
+               yy_last_accepting_cpos = yy_cp;
                }
        while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                {
@@ -1994,73 +1925,81 @@ static int yy_get_next_buffer (void)
        yy_is_jam = (yy_current_state == 567);
 
        return yy_is_jam ? 0 : yy_current_state;
-}
+       }
 
-    static void yyunput (int c, register char * yy_bp )
-{
-       register char *yy_cp;
-    
-    yy_cp = (yy_c_buf_p);
+
+#ifndef YY_NO_UNPUT
+#ifdef YY_USE_PROTOS
+static void yyunput( int c, register char *yy_bp )
+#else
+static void yyunput( c, yy_bp )
+int c;
+register char *yy_bp;
+#endif
+       {
+       register char *yy_cp = yy_c_buf_p;
 
        /* undo effects of setting up yytext */
-       *yy_cp = (yy_hold_char);
+       *yy_cp = yy_hold_char;
 
-       if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+       if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
                { /* need to shift things up to make room */
                /* +2 for EOB chars. */
-               register int number_to_move = (yy_n_chars) + 2;
-               register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
-                                       YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
+               register int number_to_move = yy_n_chars + 2;
+               register char *dest = &yy_current_buffer->yy_ch_buf[
+                                       yy_current_buffer->yy_buf_size + 2];
                register char *source =
-                               &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
+                               &yy_current_buffer->yy_ch_buf[number_to_move];
 
-               while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+               while ( source > yy_current_buffer->yy_ch_buf )
                        *--dest = *--source;
 
                yy_cp += (int) (dest - source);
                yy_bp += (int) (dest - source);
-               YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
-                       (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
+               yy_current_buffer->yy_n_chars =
+                       yy_n_chars = yy_current_buffer->yy_buf_size;
 
-               if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+               if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
                        YY_FATAL_ERROR( "flex scanner push-back overflow" );
                }
 
        *--yy_cp = (char) c;
 
-       (yytext_ptr) = yy_bp;
-       (yy_hold_char) = *yy_cp;
-       (yy_c_buf_p) = yy_cp;
-}
+
+       yytext_ptr = yy_bp;
+       yy_hold_char = *yy_cp;
+       yy_c_buf_p = yy_cp;
+       }
+#endif /* ifndef YY_NO_UNPUT */
+
 
 #ifndef YY_NO_INPUT
 #ifdef __cplusplus
-    static int yyinput (void)
+static int yyinput()
 #else
-    static int input  (void)
+static int input()
 #endif
-
-{
+       {
        int c;
-    
-       *(yy_c_buf_p) = (yy_hold_char);
 
-       if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
+       *yy_c_buf_p = yy_hold_char;
+
+       if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
                {
                /* yy_c_buf_p now points to the character we want to return.
                 * If this occurs *before* the EOB characters, then it's a
                 * valid NUL; if not, then we've hit the end of the buffer.
                 */
-               if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+               if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] )
                        /* This was really a NUL. */
-                       *(yy_c_buf_p) = '\0';
+                       *yy_c_buf_p = '\0';
 
                else
                        { /* need more input */
-                       int offset = (yy_c_buf_p) - (yytext_ptr);
-                       ++(yy_c_buf_p);
+                       int offset = yy_c_buf_p - yytext_ptr;
+                       ++yy_c_buf_p;
 
-                       switch ( yy_get_next_buffer(  ) )
+                       switch ( yy_get_next_buffer() )
                                {
                                case EOB_ACT_LAST_MATCH:
                                        /* This happens because yy_g_n_b()
@@ -2074,16 +2013,16 @@ static int yy_get_next_buffer (void)
                                         */
 
                                        /* Reset buffer status. */
-                                       yyrestart(yyin );
+                                       yyrestart( yyin );
 
-                                       /*FALLTHROUGH*/
+                                       /* fall through */
 
                                case EOB_ACT_END_OF_FILE:
                                        {
-                                       if ( yywrap( ) )
+                                       if ( yywrap() )
                                                return EOF;
 
-                                       if ( ! (yy_did_buffer_switch_on_eof) )
+                                       if ( ! yy_did_buffer_switch_on_eof )
                                                YY_NEW_FILE;
 #ifdef __cplusplus
                                        return yyinput();
@@ -2093,92 +2032,90 @@ static int yy_get_next_buffer (void)
                                        }
 
                                case EOB_ACT_CONTINUE_SCAN:
-                                       (yy_c_buf_p) = (yytext_ptr) + offset;
+                                       yy_c_buf_p = yytext_ptr + offset;
                                        break;
                                }
                        }
                }
 
-       c = *(unsigned char *) (yy_c_buf_p);    /* cast for 8-bit char's */
-       *(yy_c_buf_p) = '\0';   /* preserve yytext */
-       (yy_hold_char) = *++(yy_c_buf_p);
+       c = *(unsigned char *) yy_c_buf_p;      /* cast for 8-bit char's */
+       *yy_c_buf_p = '\0';     /* preserve yytext */
+       yy_hold_char = *++yy_c_buf_p;
+
 
        return c;
-}
-#endif /* ifndef YY_NO_INPUT */
+       }
+#endif /* YY_NO_INPUT */
 
-/** Immediately switch to a different input stream.
- * @param input_file A readable stream.
- * 
- * @note This function does not reset the start condition to @c INITIAL .
- */
-    void yyrestart  (FILE * input_file )
-{
-    
-       if ( ! YY_CURRENT_BUFFER ){
-        yyensure_buffer_stack ();
-               YY_CURRENT_BUFFER_LVALUE =
-            yy_create_buffer(yyin,YY_BUF_SIZE );
+#ifdef YY_USE_PROTOS
+void yyrestart( FILE *input_file )
+#else
+void yyrestart( input_file )
+FILE *input_file;
+#endif
+       {
+       if ( ! yy_current_buffer )
+               yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE );
+
+       yy_init_buffer( yy_current_buffer, input_file );
+       yy_load_buffer_state();
        }
 
-       yy_init_buffer(YY_CURRENT_BUFFER,input_file );
-       yy_load_buffer_state( );
-}
 
-/** Switch to a different input buffer.
- * @param new_buffer The new input buffer.
- * 
- */
-    void yy_switch_to_buffer  (YY_BUFFER_STATE  new_buffer )
-{
-    
-       /* TODO. We should be able to replace this entire function body
-        * with
-        *              yypop_buffer_state();
-        *              yypush_buffer_state(new_buffer);
-     */
-       yyensure_buffer_stack ();
-       if ( YY_CURRENT_BUFFER == new_buffer )
+#ifdef YY_USE_PROTOS
+void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
+#else
+void yy_switch_to_buffer( new_buffer )
+YY_BUFFER_STATE new_buffer;
+#endif
+       {
+       if ( yy_current_buffer == new_buffer )
                return;
 
-       if ( YY_CURRENT_BUFFER )
+       if ( yy_current_buffer )
                {
                /* Flush out information for old buffer. */
-               *(yy_c_buf_p) = (yy_hold_char);
-               YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
-               YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+               *yy_c_buf_p = yy_hold_char;
+               yy_current_buffer->yy_buf_pos = yy_c_buf_p;
+               yy_current_buffer->yy_n_chars = yy_n_chars;
                }
 
-       YY_CURRENT_BUFFER_LVALUE = new_buffer;
-       yy_load_buffer_state( );
+       yy_current_buffer = new_buffer;
+       yy_load_buffer_state();
 
        /* We don't actually know whether we did this switch during
         * EOF (yywrap()) processing, but the only time this flag
         * is looked at is after yywrap() is called, so it's safe
         * to go ahead and always set it.
         */
-       (yy_did_buffer_switch_on_eof) = 1;
-}
+       yy_did_buffer_switch_on_eof = 1;
+       }
 
-static void yy_load_buffer_state  (void)
-{
-       (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
-       (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
-       yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
-       (yy_hold_char) = *(yy_c_buf_p);
-}
 
-/** Allocate and initialize an input buffer state.
- * @param file A readable stream.
- * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
- * 
- * @return the allocated buffer state.
- */
-    YY_BUFFER_STATE yy_create_buffer  (FILE * file, int  size )
-{
+#ifdef YY_USE_PROTOS
+void yy_load_buffer_state( void )
+#else
+void yy_load_buffer_state()
+#endif
+       {
+       yy_n_chars = yy_current_buffer->yy_n_chars;
+       yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos;
+       yyin = yy_current_buffer->yy_input_file;
+       yy_hold_char = *yy_c_buf_p;
+       }
+
+
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_create_buffer( FILE *file, int size )
+#else
+YY_BUFFER_STATE yy_create_buffer( file, size )
+FILE *file;
+int size;
+#endif
+       {
        YY_BUFFER_STATE b;
-    
-       b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state )  );
+
+       b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
        if ( ! b )
                YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
 
@@ -2187,75 +2124,75 @@ static void yy_load_buffer_state  (void)
        /* yy_ch_buf has to be 2 characters longer than the size given because
         * we need to put in 2 end-of-buffer characters.
         */
-       b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2  );
+       b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 );
        if ( ! b->yy_ch_buf )
                YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
 
        b->yy_is_our_buffer = 1;
 
-       yy_init_buffer(b,file );
+       yy_init_buffer( b, file );
 
        return b;
-}
+       }
 
-/** Destroy the buffer.
- * @param b a buffer created with yy_create_buffer()
- * 
- */
-    void yy_delete_buffer (YY_BUFFER_STATE  b )
-{
-    
+
+#ifdef YY_USE_PROTOS
+void yy_delete_buffer( YY_BUFFER_STATE b )
+#else
+void yy_delete_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+       {
        if ( ! b )
                return;
 
-       if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
-               YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+       if ( b == yy_current_buffer )
+               yy_current_buffer = (YY_BUFFER_STATE) 0;
 
        if ( b->yy_is_our_buffer )
-               yyfree((void *) b->yy_ch_buf  );
+               yy_flex_free( (void *) b->yy_ch_buf );
 
-       yyfree((void *) b  );
-}
+       yy_flex_free( (void *) b );
+       }
 
-#ifndef __cplusplus
-extern int isatty (int );
-#endif /* __cplusplus */
-    
-/* Initializes or reinitializes a buffer.
- * This function is sometimes called more than once on the same buffer,
- * such as during a yyrestart() or at EOF.
- */
-    static void yy_init_buffer  (YY_BUFFER_STATE  b, FILE * file )
 
-{
-       int oerrno = errno;
-    
-       yy_flush_buffer(b );
+
+#ifdef YY_USE_PROTOS
+void yy_init_buffer( YY_BUFFER_STATE b, FILE *file )
+#else
+void yy_init_buffer( b, file )
+YY_BUFFER_STATE b;
+FILE *file;
+#endif
+
+
+       {
+       yy_flush_buffer( b );
 
        b->yy_input_file = file;
        b->yy_fill_buffer = 1;
 
-    /* If b is the current buffer, then yy_init_buffer was _probably_
-     * called from yyrestart() or through yy_get_next_buffer.
-     * In that case, we don't want to reset the lineno or column.
-     */
-    if (b != YY_CURRENT_BUFFER){
-        b->yy_bs_lineno = 1;
-        b->yy_bs_column = 0;
-    }
-
-        b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
-    
-       errno = oerrno;
-}
+#if YY_ALWAYS_INTERACTIVE
+       b->yy_is_interactive = 1;
+#else
+#if YY_NEVER_INTERACTIVE
+       b->yy_is_interactive = 0;
+#else
+       b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+#endif
+#endif
+       }
 
-/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
- * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
- * 
- */
-    void yy_flush_buffer (YY_BUFFER_STATE  b )
-{
-       if ( ! b )
+
+#ifdef YY_USE_PROTOS
+void yy_flush_buffer( YY_BUFFER_STATE b )
+#else
+void yy_flush_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+
+       {
+       if ( ! b )
                return;
 
        b->yy_n_chars = 0;
@@ -2272,121 +2209,29 @@ extern int isatty (int );
        b->yy_at_bol = 1;
        b->yy_buffer_status = YY_BUFFER_NEW;
 
-       if ( b == YY_CURRENT_BUFFER )
-               yy_load_buffer_state( );
-}
-
-/** Pushes the new state onto the stack. The new state becomes
- *  the current state. This function will allocate the stack
- *  if necessary.
- *  @param new_buffer The new state.
- *  
- */
-void yypush_buffer_state (YY_BUFFER_STATE new_buffer )
-{
-       if (new_buffer == NULL)
-               return;
-
-       yyensure_buffer_stack();
-
-       /* This block is copied from yy_switch_to_buffer. */
-       if ( YY_CURRENT_BUFFER )
-               {
-               /* Flush out information for old buffer. */
-               *(yy_c_buf_p) = (yy_hold_char);
-               YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
-               YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
-               }
-
-       /* Only push if top exists. Otherwise, replace top. */
-       if (YY_CURRENT_BUFFER)
-               (yy_buffer_stack_top)++;
-       YY_CURRENT_BUFFER_LVALUE = new_buffer;
-
-       /* copied from yy_switch_to_buffer. */
-       yy_load_buffer_state( );
-       (yy_did_buffer_switch_on_eof) = 1;
-}
-
-/** Removes and deletes the top of the stack, if present.
- *  The next element becomes the new top.
- *  
- */
-void yypop_buffer_state (void)
-{
-       if (!YY_CURRENT_BUFFER)
-               return;
-
-       yy_delete_buffer(YY_CURRENT_BUFFER );
-       YY_CURRENT_BUFFER_LVALUE = NULL;
-       if ((yy_buffer_stack_top) > 0)
-               --(yy_buffer_stack_top);
-
-       if (YY_CURRENT_BUFFER) {
-               yy_load_buffer_state( );
-               (yy_did_buffer_switch_on_eof) = 1;
+       if ( b == yy_current_buffer )
+               yy_load_buffer_state();
        }
-}
-
-/* Allocates the stack if it does not exist.
- *  Guarantees space for at least one push.
- */
-static void yyensure_buffer_stack (void)
-{
-       int num_to_alloc;
-    
-       if (!(yy_buffer_stack)) {
-
-               /* First allocation is just for 2 elements, since we don't know if this
-                * scanner will even need a stack. We use 2 instead of 1 to avoid an
-                * immediate realloc on the next call.
-         */
-               num_to_alloc = 1;
-               (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
-                                                               (num_to_alloc * sizeof(struct yy_buffer_state*)
-                                                               );
-               
-               memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
-                               
-               (yy_buffer_stack_max) = num_to_alloc;
-               (yy_buffer_stack_top) = 0;
-               return;
-       }
-
-       if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
 
-               /* Increase the buffer to prepare for a possible push. */
-               int grow_size = 8 /* arbitrary grow size */;
 
-               num_to_alloc = (yy_buffer_stack_max) + grow_size;
-               (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc
-                                                               ((yy_buffer_stack),
-                                                               num_to_alloc * sizeof(struct yy_buffer_state*)
-                                                               );
-
-               /* zero only the new slots.*/
-               memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
-               (yy_buffer_stack_max) = num_to_alloc;
-       }
-}
-
-/** Setup the input buffer state to scan directly from a user-specified character buffer.
- * @param base the character buffer
- * @param size the size in bytes of the character buffer
- * 
- * @return the newly allocated buffer state object. 
- */
-YY_BUFFER_STATE yy_scan_buffer  (char * base, yy_size_t  size )
-{
+#ifndef YY_NO_SCAN_BUFFER
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size )
+#else
+YY_BUFFER_STATE yy_scan_buffer( base, size )
+char *base;
+yy_size_t size;
+#endif
+       {
        YY_BUFFER_STATE b;
-    
+
        if ( size < 2 ||
             base[size-2] != YY_END_OF_BUFFER_CHAR ||
             base[size-1] != YY_END_OF_BUFFER_CHAR )
                /* They forgot to leave room for the EOB's. */
                return 0;
 
-       b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state )  );
+       b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
        if ( ! b )
                YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
 
@@ -2400,51 +2245,56 @@ YY_BUFFER_STATE yy_scan_buffer  (char * base, yy_size_t  size )
        b->yy_fill_buffer = 0;
        b->yy_buffer_status = YY_BUFFER_NEW;
 
-       yy_switch_to_buffer( );
+       yy_switch_to_buffer( b );
 
        return b;
-}
+       }
+#endif
 
-/** Setup the input buffer state to scan a string. The next call to yylex() will
- * scan from a @e copy of @a str.
- * @param yystr a NUL-terminated string to scan
- * 
- * @return the newly allocated buffer state object.
- * @note If you want to scan bytes that may contain NUL values, then use
- *       yy_scan_bytes() instead.
- */
-YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
-{
-    
-       return yy_scan_bytes(yystr,strlen(yystr) );
-}
 
-/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
- * scan from a @e copy of @a bytes.
- * @param bytes the byte buffer to scan
- * @param len the number of bytes in the buffer pointed to by @a bytes.
- * 
- * @return the newly allocated buffer state object.
- */
-YY_BUFFER_STATE yy_scan_bytes  (yyconst char * yybytes, int  _yybytes_len )
-{
+#ifndef YY_NO_SCAN_STRING
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str )
+#else
+YY_BUFFER_STATE yy_scan_string( yy_str )
+yyconst char *yy_str;
+#endif
+       {
+       int len;
+       for ( len = 0; yy_str[len]; ++len )
+               ;
+
+       return yy_scan_bytes( yy_str, len );
+       }
+#endif
+
+
+#ifndef YY_NO_SCAN_BYTES
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len )
+#else
+YY_BUFFER_STATE yy_scan_bytes( bytes, len )
+yyconst char *bytes;
+int len;
+#endif
+       {
        YY_BUFFER_STATE b;
        char *buf;
        yy_size_t n;
        int i;
-    
+
        /* Get memory for full buffer, including space for trailing EOB's. */
-       n = _yybytes_len + 2;
-       buf = (char *) yyalloc(n  );
+       n = len + 2;
+       buf = (char *) yy_flex_alloc( n );
        if ( ! buf )
                YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
 
-       for ( i = 0; i < _yybytes_len; ++i )
-               buf[i] = yybytes[i];
+       for ( i = 0; i < len; ++i )
+               buf[i] = bytes[i];
 
-       buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+       buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
 
-       b = yy_scan_buffer(buf,n );
+       b = yy_scan_buffer( buf, n );
        if ( ! b )
                YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
 
@@ -2454,196 +2304,148 @@ YY_BUFFER_STATE yy_scan_bytes  (yyconst char * yybytes, int  _yybytes_len )
        b->yy_is_our_buffer = 1;
 
        return b;
-}
-
-#ifndef YY_EXIT_FAILURE
-#define YY_EXIT_FAILURE 2
+       }
 #endif
 
-static void yy_fatal_error (yyconst char* msg )
-{
-       (void) fprintf( stderr, "%s\n", msg );
-       exit( YY_EXIT_FAILURE );
-}
-
-/* Redefine yyless() so it works in section 3 code. */
 
-#undef yyless
-#define yyless(n) \
-       do \
-               { \
-               /* Undo effects of setting up yytext. */ \
-        int yyless_macro_arg = (n); \
-        YY_LESS_LINENO(yyless_macro_arg);\
-               yytext[yyleng] = (yy_hold_char); \
-               (yy_c_buf_p) = yytext + yyless_macro_arg; \
-               (yy_hold_char) = *(yy_c_buf_p); \
-               *(yy_c_buf_p) = '\0'; \
-               yyleng = yyless_macro_arg; \
-               } \
-       while ( 0 )
+#ifndef YY_NO_PUSH_STATE
+#ifdef YY_USE_PROTOS
+static void yy_push_state( int new_state )
+#else
+static void yy_push_state( new_state )
+int new_state;
+#endif
+       {
+       if ( yy_start_stack_ptr >= yy_start_stack_depth )
+               {
+               yy_size_t new_size;
 
-/* Accessor  methods (get/set functions) to struct members. */
+               yy_start_stack_depth += YY_START_STACK_INCR;
+               new_size = yy_start_stack_depth * sizeof( int );
 
-/** Get the current line number.
- * 
- */
-int yyget_lineno  (void)
-{
-        
-    return yylineno;
-}
+               if ( ! yy_start_stack )
+                       yy_start_stack = (int *) yy_flex_alloc( new_size );
 
-/** Get the input stream.
- * 
- */
-FILE *yyget_in  (void)
-{
-        return yyin;
-}
+               else
+                       yy_start_stack = (int *) yy_flex_realloc(
+                                       (void *) yy_start_stack, new_size );
 
-/** Get the output stream.
- * 
- */
-FILE *yyget_out  (void)
-{
-        return yyout;
-}
+               if ( ! yy_start_stack )
+                       YY_FATAL_ERROR(
+                       "out of memory expanding start-condition stack" );
+               }
 
-/** Get the length of the current token.
- * 
- */
-int yyget_leng  (void)
-{
-        return yyleng;
-}
+       yy_start_stack[yy_start_stack_ptr++] = YY_START;
 
-/** Get the current token.
- * 
- */
+       BEGIN(new_state);
+       }
+#endif
 
-char *yyget_text  (void)
-{
-        return yytext;
-}
 
-/** Set the current line number.
- * @param line_number
- * 
- */
-void yyset_lineno (int  line_number )
-{
-    
-    yylineno = line_number;
-}
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state()
+       {
+       if ( --yy_start_stack_ptr < 0 )
+               YY_FATAL_ERROR( "start-condition stack underflow" );
 
-/** Set the input stream. This does not discard the current
- * input buffer.
- * @param in_str A readable stream.
- * 
- * @see yy_switch_to_buffer
- */
-void yyset_in (FILE *  in_str )
-{
-        yyin = in_str ;
-}
+       BEGIN(yy_start_stack[yy_start_stack_ptr]);
+       }
+#endif
 
-void yyset_out (FILE *  out_str )
-{
-        yyout = out_str ;
-}
 
-int yyget_debug  (void)
-{
-        return yy_flex_debug;
-}
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state()
+       {
+       return yy_start_stack[yy_start_stack_ptr - 1];
+       }
+#endif
 
-void yyset_debug (int  bdebug )
-{
-        yy_flex_debug = bdebug ;
-}
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
 
-static int yy_init_globals (void)
-{
-        /* Initialization is the same as for the non-reentrant scanner.
-     * This function is called from yylex_destroy(), so don't allocate here.
-     */
-
-    (yy_buffer_stack) = 0;
-    (yy_buffer_stack_top) = 0;
-    (yy_buffer_stack_max) = 0;
-    (yy_c_buf_p) = (char *) 0;
-    (yy_init) = 0;
-    (yy_start) = 0;
-
-/* Defined in main.c */
-#ifdef YY_STDINIT
-    yyin = stdin;
-    yyout = stdout;
+#ifdef YY_USE_PROTOS
+static void yy_fatal_error( yyconst char msg[] )
 #else
-    yyin = (FILE *) 0;
-    yyout = (FILE *) 0;
+static void yy_fatal_error( msg )
+char msg[];
 #endif
+       {
+       (void) fprintf( stderr, "%s\n", msg );
+       exit( YY_EXIT_FAILURE );
+       }
 
-    /* For future reference: Set errno on error, since we are called by
-     * yylex_init()
-     */
-    return 0;
-}
 
-/* yylex_destroy is for both reentrant and non-reentrant scanners. */
-int yylex_destroy  (void)
-{
-    
-    /* Pop the buffer stack, destroying each element. */
-       while(YY_CURRENT_BUFFER){
-               yy_delete_buffer(YY_CURRENT_BUFFER  );
-               YY_CURRENT_BUFFER_LVALUE = NULL;
-               yypop_buffer_state();
-       }
 
-       /* Destroy the stack itself. */
-       yyfree((yy_buffer_stack) );
-       (yy_buffer_stack) = NULL;
+/* Redefine yyless() so it works in section 3 code. */
 
-    /* Reset the globals. This is important in a non-reentrant scanner so the next time
-     * yylex() is called, initialization will occur. */
-    yy_init_globals( );
+#undef yyless
+#define yyless(n) \
+       do \
+               { \
+               /* Undo effects of setting up yytext. */ \
+               yytext[yyleng] = yy_hold_char; \
+               yy_c_buf_p = yytext + n; \
+               yy_hold_char = *yy_c_buf_p; \
+               *yy_c_buf_p = '\0'; \
+               yyleng = n; \
+               } \
+       while ( 0 )
 
-    return 0;
-}
 
-/*
- * Internal utility routines.
- */
+/* Internal utility routines. */
 
 #ifndef yytext_ptr
-static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
-{
+#ifdef YY_USE_PROTOS
+static void yy_flex_strncpy( char *s1, yyconst char *s2, int n )
+#else
+static void yy_flex_strncpy( s1, s2, n )
+char *s1;
+yyconst char *s2;
+int n;
+#endif
+       {
        register int i;
        for ( i = 0; i < n; ++i )
                s1[i] = s2[i];
-}
+       }
 #endif
 
 #ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * s )
-{
+#ifdef YY_USE_PROTOS
+static int yy_flex_strlen( yyconst char *s )
+#else
+static int yy_flex_strlen( s )
+yyconst char *s;
+#endif
+       {
        register int n;
        for ( n = 0; s[n]; ++n )
                ;
 
        return n;
-}
+       }
 #endif
 
-void *yyalloc (yy_size_t  size )
-{
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_alloc( yy_size_t size )
+#else
+static void *yy_flex_alloc( size )
+yy_size_t size;
+#endif
+       {
        return (void *) malloc( size );
-}
+       }
 
-void *yyrealloc  (void * ptr, yy_size_t  size )
-{
+#ifdef YY_USE_PROTOS
+static void *yy_flex_realloc( void *ptr, yy_size_t size )
+#else
+static void *yy_flex_realloc( ptr, size )
+void *ptr;
+yy_size_t size;
+#endif
+       {
        /* The cast to (char *) in the following accommodates both
         * implementations that use char* generic pointers, and those
         * that use void* generic pointers.  It works with the latter
@@ -2652,17 +2454,26 @@ void *yyrealloc  (void * ptr, yy_size_t  size )
         * as though doing an assignment.
         */
        return (void *) realloc( (char *) ptr, size );
-}
-
-void yyfree (void * ptr )
-{
-       free( (char *) ptr );   /* see yyrealloc() for (char *) cast */
-}
-
-#define YYTABLES_NAME "yytables"
+       }
 
-#line 268 "lex.l"
+#ifdef YY_USE_PROTOS
+static void yy_flex_free( void *ptr )
+#else
+static void yy_flex_free( ptr )
+void *ptr;
+#endif
+       {
+       free( ptr );
+       }
 
+#if YY_MAIN
+int main()
+       {
+       yylex();
+       return 0;
+       }
+#endif
+#line 274 "lex.l"
 
 
 #ifndef yywrap /* XXX */
@@ -2690,4 +2501,3 @@ unterminated(const char *type, unsigned start_lineno)
 {
     error_message("unterminated %s, possibly started on line %d\n", type, start_lineno);
 }
-
index eec775f3baa94b90244059e0b0b5c8f89349d855..bba79b1e4e2f4c3ff3aa5b75be5cba532636debe 100644 (file)
 #include <getarg.h>
 #include "lex.h"
 
-RCSID("$Id: main.c,v 1.15 2005/08/23 10:50:12 lha Exp $");
+RCSID("$Id: main.c,v 1.16 2006/09/05 12:27:29 lha Exp $");
 
 extern FILE *yyin;
 
 static getarg_strings preserve;
+static getarg_strings seq;
 
 int
 preserve_type(const char *p)
@@ -51,6 +52,16 @@ preserve_type(const char *p)
     return 0;
 }
 
+int
+seq_type(const char *p)
+{
+    int i;
+    for (i = 0; i < seq.num_strings; i++)
+       if (strcmp(seq.strings[i], p) == 0)
+           return 1;
+    return 0;
+}
+
 int dce_fix;
 int rfc1510_bitstring;
 int version_flag;
@@ -59,6 +70,7 @@ struct getargs args[] = {
     { "encode-rfc1510-bit-string", 0, arg_flag, &rfc1510_bitstring },
     { "decode-dce-ber", 0, arg_flag, &dce_fix },
     { "preserve-binary", 0, arg_strings, &preserve },
+    { "sequence", 0, arg_strings, &seq },
     { "version", 0, arg_flag, &version_flag },
     { "help", 0, arg_flag, &help_flag }
 };
index e498d8f9656668368c98eb5782744f14304db4ef..29d13ed68d2341c215c9c34697e0d3cd223874bc 100644 (file)
@@ -1,7 +1,7 @@
-/* A Bison parser, made by GNU Bison 2.0.  */
+/* A Bison parser, made by GNU Bison 2.1.  */
 
 /* Skeleton parser for Yacc-like parsing with Bison,
-   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -15,8 +15,8 @@
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
 
 /* As a special exception, when this file is copied by Bison into a
    Bison output file, you may use that output file without restriction.
@@ -36,6 +36,9 @@
 /* Identify Bison output.  */
 #define YYBISON 1
 
+/* Bison version.  */
+#define YYBISON_VERSION "2.1"
+
 /* Skeleton name.  */
 #define YYSKELETON_NAME "yacc.c"
 
      NUMBER = 344
    };
 #endif
+/* Tokens.  */
 #define kw_ABSENT 258
 #define kw_ABSTRACT_SYNTAX 259
 #define kw_ALL 260
@@ -277,6 +281,11 @@ struct string_list {
 # define YYERROR_VERBOSE 0
 #endif
 
+/* Enabling the token table.  */
+#ifndef YYTOKEN_TABLE
+# define YYTOKEN_TABLE 0
+#endif
+
 #if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
 #line 65 "parse.y"
 typedef union YYSTYPE {
@@ -293,8 +302,8 @@ typedef union YYSTYPE {
     struct memhead *members;
     struct constraint_spec *constraint_spec;
 } YYSTYPE;
-/* Line 190 of yacc.c.  */
-#line 298 "parse.c"
+/* Line 196 of yacc.c.  */
+#line 307 "parse.c"
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
 # define YYSTYPE_IS_TRIVIAL 1
@@ -305,17 +314,36 @@ typedef union YYSTYPE {
 /* Copy the second part of user declarations.  */
 
 
-/* Line 213 of yacc.c.  */
-#line 310 "parse.c"
+/* Line 219 of yacc.c.  */
+#line 319 "parse.c"
 
-#if ! defined (yyoverflow) || YYERROR_VERBOSE
+#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
+# define YYSIZE_T __SIZE_TYPE__
+#endif
+#if ! defined (YYSIZE_T) && defined (size_t)
+# define YYSIZE_T size_t
+#endif
+#if ! defined (YYSIZE_T) && (defined (__STDC__) || defined (__cplusplus))
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+#endif
+#if ! defined (YYSIZE_T)
+# define YYSIZE_T unsigned int
+#endif
 
-# ifndef YYFREE
-#  define YYFREE free
+#ifndef YY_
+# if YYENABLE_NLS
+#  if ENABLE_NLS
+#   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+#   define YY_(msgid) dgettext ("bison-runtime", msgid)
+#  endif
 # endif
-# ifndef YYMALLOC
-#  define YYMALLOC malloc
+# ifndef YY_
+#  define YY_(msgid) msgid
 # endif
+#endif
+
+#if ! defined (yyoverflow) || YYERROR_VERBOSE
 
 /* The parser invokes alloca or malloc; define the necessary symbols.  */
 
@@ -325,6 +353,10 @@ typedef union YYSTYPE {
 #    define YYSTACK_ALLOC __builtin_alloca
 #   else
 #    define YYSTACK_ALLOC alloca
+#    if defined (__STDC__) || defined (__cplusplus)
+#     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+#     define YYINCLUDED_STDLIB_H
+#    endif
 #   endif
 #  endif
 # endif
@@ -332,13 +364,39 @@ typedef union YYSTYPE {
 # ifdef YYSTACK_ALLOC
    /* Pacify GCC's `empty if-body' warning. */
 #  define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
-# else
-#  if defined (__STDC__) || defined (__cplusplus)
-#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-#   define YYSIZE_T size_t
+#  ifndef YYSTACK_ALLOC_MAXIMUM
+    /* The OS might guarantee only one guard page at the bottom of the stack,
+       and a page size can be as small as 4096 bytes.  So we cannot safely
+       invoke alloca (N) if N exceeds 4096.  Use a slightly smaller number
+       to allow for a few compiler-allocated temporary stack slots.  */
+#   define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2005 */
 #  endif
+# else
 #  define YYSTACK_ALLOC YYMALLOC
 #  define YYSTACK_FREE YYFREE
+#  ifndef YYSTACK_ALLOC_MAXIMUM
+#   define YYSTACK_ALLOC_MAXIMUM ((YYSIZE_T) -1)
+#  endif
+#  ifdef __cplusplus
+extern "C" {
+#  endif
+#  ifndef YYMALLOC
+#   define YYMALLOC malloc
+#   if (! defined (malloc) && ! defined (YYINCLUDED_STDLIB_H) \
+       && (defined (__STDC__) || defined (__cplusplus)))
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+#   endif
+#  endif
+#  ifndef YYFREE
+#   define YYFREE free
+#   if (! defined (free) && ! defined (YYINCLUDED_STDLIB_H) \
+       && (defined (__STDC__) || defined (__cplusplus)))
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+#   endif
+#  endif
+#  ifdef __cplusplus
+}
+#  endif
 # endif
 #endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
 
@@ -373,7 +431,7 @@ union yyalloc
 #   define YYCOPY(To, From, Count)             \
       do                                       \
        {                                       \
-         register YYSIZE_T yyi;                \
+         YYSIZE_T yyi;                         \
          for (yyi = 0; yyi < (Count); yyi++)   \
            (To)[yyi] = (From)[yyi];            \
        }                                       \
@@ -423,7 +481,7 @@ union yyalloc
 #define YYUNDEFTOK  2
 #define YYMAXUTOK   344
 
-#define YYTRANSLATE(YYX)                                               \
+#define YYTRANSLATE(YYX)                                               \
   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
 
 /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
@@ -548,8 +606,8 @@ static const unsigned short int yyrline[] =
 };
 #endif
 
-#if YYDEBUG || YYERROR_VERBOSE
-/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
    First, the terminals, then, starting at YYNTOKENS, nonterminals. */
 static const char *const yytname[] =
 {
@@ -804,22 +862,6 @@ static const unsigned char yystos[] =
      154
 };
 
-#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
-# define YYSIZE_T __SIZE_TYPE__
-#endif
-#if ! defined (YYSIZE_T) && defined (size_t)
-# define YYSIZE_T size_t
-#endif
-#if ! defined (YYSIZE_T)
-# if defined (__STDC__) || defined (__cplusplus)
-#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
-#  define YYSIZE_T size_t
-# endif
-#endif
-#if ! defined (YYSIZE_T)
-# define YYSIZE_T unsigned int
-#endif
-
 #define yyerrok                (yyerrstatus = 0)
 #define yyclearin      (yychar = YYEMPTY)
 #define YYEMPTY                (-2)
@@ -849,8 +891,8 @@ do                                                          \
       goto yybackup;                                           \
     }                                                          \
   else                                                         \
-    {                                                          \
-      yyerror ("syntax error: cannot back up");\
+    {                                                          \
+      yyerror (YY_("syntax error: cannot back up")); \
       YYERROR;                                                 \
     }                                                          \
 while (0)
@@ -929,7 +971,7 @@ do {                                                                \
   if (yydebug)                                                 \
     {                                                          \
       YYFPRINTF (stderr, "%s ", Title);                                \
-      yysymprint (stderr,                                      \
+      yysymprint (stderr,                                      \
                   Type, Value);        \
       YYFPRINTF (stderr, "\n");                                        \
     }                                                          \
@@ -977,13 +1019,13 @@ yy_reduce_print (yyrule)
 #endif
 {
   int yyi;
-  unsigned int yylno = yyrline[yyrule];
-  YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ",
+  unsigned long int yylno = yyrline[yyrule];
+  YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu), ",
              yyrule - 1, yylno);
   /* Print the symbols being reduced, and their result.  */
   for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
-    YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]);
-  YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]);
+    YYFPRINTF (stderr, "%s ", yytname[yyrhs[yyi]]);
+  YYFPRINTF (stderr, "-> %s\n", yytname[yyr1[yyrule]]);
 }
 
 # define YY_REDUCE_PRINT(Rule)         \
@@ -1012,7 +1054,7 @@ int yydebug;
    if the built-in stack extension method is used).
 
    Do not make this value too large; the results are undefined if
-   SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
+   YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
    evaluated with infinite-precision integer arithmetic.  */
 
 #ifndef YYMAXDEPTH
@@ -1036,7 +1078,7 @@ yystrlen (yystr)
      const char *yystr;
 #   endif
 {
-  register const char *yys = yystr;
+  const char *yys = yystr;
 
   while (*yys++ != '\0')
     continue;
@@ -1061,8 +1103,8 @@ yystpcpy (yydest, yysrc)
      const char *yysrc;
 #   endif
 {
-  register char *yyd = yydest;
-  register const char *yys = yysrc;
+  char *yyd = yydest;
+  const char *yys = yysrc;
 
   while ((*yyd++ = *yys++) != '\0')
     continue;
@@ -1072,7 +1114,55 @@ yystpcpy (yydest, yysrc)
 #  endif
 # endif
 
-#endif /* !YYERROR_VERBOSE */
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+   quotes and backslashes, so that it's suitable for yyerror.  The
+   heuristic is that double-quoting is unnecessary unless the string
+   contains an apostrophe, a comma, or backslash (other than
+   backslash-backslash).  YYSTR is taken from yytname.  If YYRES is
+   null, do not copy; instead, return the length of what the result
+   would have been.  */
+static YYSIZE_T
+yytnamerr (char *yyres, const char *yystr)
+{
+  if (*yystr == '"')
+    {
+      size_t yyn = 0;
+      char const *yyp = yystr;
+
+      for (;;)
+       switch (*++yyp)
+         {
+         case '\'':
+         case ',':
+           goto do_not_strip_quotes;
+
+         case '\\':
+           if (*++yyp != '\\')
+             goto do_not_strip_quotes;
+           /* Fall through.  */
+         default:
+           if (yyres)
+             yyres[yyn] = *yyp;
+           yyn++;
+           break;
+
+         case '"':
+           if (yyres)
+             yyres[yyn] = '\0';
+           return yyn;
+         }
+    do_not_strip_quotes: ;
+    }
+
+  if (! yyres)
+    return yystrlen (yystr);
+
+  return yystpcpy (yyres, yystr) - yyres;
+}
+# endif
+
+#endif /* YYERROR_VERBOSE */
 
 \f
 
@@ -1197,8 +1287,8 @@ yyparse ()
 #endif
 {
   
-  register int yystate;
-  register int yyn;
+  int yystate;
+  int yyn;
   int yyresult;
   /* Number of tokens to shift before error messages enabled.  */
   int yyerrstatus;
@@ -1216,12 +1306,12 @@ yyparse ()
   /* The state stack.  */
   short int yyssa[YYINITDEPTH];
   short int *yyss = yyssa;
-  register short int *yyssp;
+  short int *yyssp;
 
   /* The semantic value stack.  */
   YYSTYPE yyvsa[YYINITDEPTH];
   YYSTYPE *yyvs = yyvsa;
-  register YYSTYPE *yyvsp;
+  YYSTYPE *yyvsp;
 
 
 
@@ -1253,9 +1343,6 @@ yyparse ()
   yyssp = yyss;
   yyvsp = yyvs;
 
-
-  yyvsp[0] = yylval;
-
   goto yysetstate;
 
 /*------------------------------------------------------------.
@@ -1288,7 +1375,7 @@ yyparse ()
           data in use in that stack, in bytes.  This used to be a
           conditional around just the two extra args, but that might
           be undefined if yyoverflow is a macro.  */
-       yyoverflow ("parser stack overflow",
+       yyoverflow (YY_("memory exhausted"),
                    &yyss1, yysize * sizeof (*yyssp),
                    &yyvs1, yysize * sizeof (*yyvsp),
 
@@ -1299,11 +1386,11 @@ yyparse ()
       }
 #else /* no yyoverflow */
 # ifndef YYSTACK_RELOCATE
-      goto yyoverflowlab;
+      goto yyexhaustedlab;
 # else
       /* Extend the stack our own way.  */
       if (YYMAXDEPTH <= yystacksize)
-       goto yyoverflowlab;
+       goto yyexhaustedlab;
       yystacksize *= 2;
       if (YYMAXDEPTH < yystacksize)
        yystacksize = YYMAXDEPTH;
@@ -1313,7 +1400,7 @@ yyparse ()
        union yyalloc *yyptr =
          (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
        if (! yyptr)
-         goto yyoverflowlab;
+         goto yyexhaustedlab;
        YYSTACK_RELOCATE (yyss);
        YYSTACK_RELOCATE (yyvs);
 
@@ -2143,10 +2230,11 @@ yyreduce:
     break;
 
 
+      default: break;
     }
 
-/* Line 1037 of yacc.c.  */
-#line 2150 "parse.c"
+/* Line 1126 of yacc.c.  */
+#line 2238 "parse.c"
 \f
   yyvsp -= yylen;
   yyssp -= yylen;
@@ -2185,12 +2273,36 @@ yyerrlab:
 
       if (YYPACT_NINF < yyn && yyn < YYLAST)
        {
-         YYSIZE_T yysize = 0;
          int yytype = YYTRANSLATE (yychar);
-         const char* yyprefix;
-         char *yymsg;
+         YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
+         YYSIZE_T yysize = yysize0;
+         YYSIZE_T yysize1;
+         int yysize_overflow = 0;
+         char *yymsg = 0;
+#        define YYERROR_VERBOSE_ARGS_MAXIMUM 5
+         char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
          int yyx;
 
+#if 0
+         /* This is so xgettext sees the translatable formats that are
+            constructed on the fly.  */
+         YY_("syntax error, unexpected %s");
+         YY_("syntax error, unexpected %s, expecting %s");
+         YY_("syntax error, unexpected %s, expecting %s or %s");
+         YY_("syntax error, unexpected %s, expecting %s or %s or %s");
+         YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+#endif
+         char *yyfmt;
+         char const *yyf;
+         static char const yyunexpected[] = "syntax error, unexpected %s";
+         static char const yyexpecting[] = ", expecting %s";
+         static char const yyor[] = " or %s";
+         char yyformat[sizeof yyunexpected
+                       + sizeof yyexpecting - 1
+                       + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
+                          * (sizeof yyor - 1))];
+         char const *yyprefix = yyexpecting;
+
          /* Start YYX at -YYN if negative to avoid negative indexes in
             YYCHECK.  */
          int yyxbegin = yyn < 0 ? -yyn : 0;
@@ -2198,48 +2310,68 @@ yyerrlab:
          /* Stay within bounds of both yycheck and yytname.  */
          int yychecklim = YYLAST - yyn;
          int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
-         int yycount = 0;
+         int yycount = 1;
+
+         yyarg[0] = yytname[yytype];
+         yyfmt = yystpcpy (yyformat, yyunexpected);
 
-         yyprefix = ", expecting ";
          for (yyx = yyxbegin; yyx < yyxend; ++yyx)
            if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
              {
-               yysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]);
-               yycount += 1;
-               if (yycount == 5)
+               if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
                  {
-                   yysize = 0;
+                   yycount = 1;
+                   yysize = yysize0;
+                   yyformat[sizeof yyunexpected - 1] = '\0';
                    break;
                  }
+               yyarg[yycount++] = yytname[yyx];
+               yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+               yysize_overflow |= yysize1 < yysize;
+               yysize = yysize1;
+               yyfmt = yystpcpy (yyfmt, yyprefix);
+               yyprefix = yyor;
              }
-         yysize += (sizeof ("syntax error, unexpected ")
-                    + yystrlen (yytname[yytype]));
-         yymsg = (char *) YYSTACK_ALLOC (yysize);
-         if (yymsg != 0)
-           {
-             char *yyp = yystpcpy (yymsg, "syntax error, unexpected ");
-             yyp = yystpcpy (yyp, yytname[yytype]);
 
-             if (yycount < 5)
+         yyf = YY_(yyformat);
+         yysize1 = yysize + yystrlen (yyf);
+         yysize_overflow |= yysize1 < yysize;
+         yysize = yysize1;
+
+         if (!yysize_overflow && yysize <= YYSTACK_ALLOC_MAXIMUM)
+           yymsg = (char *) YYSTACK_ALLOC (yysize);
+         if (yymsg)
+           {
+             /* Avoid sprintf, as that infringes on the user's name space.
+                Don't have undefined behavior even if the translation
+                produced a string with the wrong number of "%s"s.  */
+             char *yyp = yymsg;
+             int yyi = 0;
+             while ((*yyp = *yyf))
                {
-                 yyprefix = ", expecting ";
-                 for (yyx = yyxbegin; yyx < yyxend; ++yyx)
-                   if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
-                     {
-                       yyp = yystpcpy (yyp, yyprefix);
-                       yyp = yystpcpy (yyp, yytname[yyx]);
-                       yyprefix = " or ";
-                     }
+                 if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
+                   {
+                     yyp += yytnamerr (yyp, yyarg[yyi++]);
+                     yyf += 2;
+                   }
+                 else
+                   {
+                     yyp++;
+                     yyf++;
+                   }
                }
              yyerror (yymsg);
              YYSTACK_FREE (yymsg);
            }
          else
-           yyerror ("syntax error; also virtual memory exhausted");
+           {
+             yyerror (YY_("syntax error"));
+             goto yyexhaustedlab;
+           }
        }
       else
 #endif /* YYERROR_VERBOSE */
-       yyerror ("syntax error");
+       yyerror (YY_("syntax error"));
     }
 
 
@@ -2251,18 +2383,9 @@ yyerrlab:
 
       if (yychar <= YYEOF)
         {
-          /* If at end of input, pop the error token,
-            then the rest of the stack, then return failure.  */
+         /* Return failure if at end of input.  */
          if (yychar == YYEOF)
-            for (;;)
-              {
-
-                YYPOPSTACK;
-                if (yyssp == yyss)
-                  YYABORT;
-                yydestruct ("Error: popping",
-                             yystos[*yyssp], yyvsp);
-              }
+           YYABORT;
         }
       else
        {
@@ -2281,12 +2404,11 @@ yyerrlab:
 `---------------------------------------------------*/
 yyerrorlab:
 
-#ifdef __GNUC__
-  /* Pacify GCC when the user code never invokes YYERROR and the label
-     yyerrorlab therefore never appears in user code.  */
+  /* Pacify compilers like GCC when the user code never invokes
+     YYERROR and the label yyerrorlab therefore never appears in user
+     code.  */
   if (0)
      goto yyerrorlab;
-#endif
 
 yyvsp -= yylen;
   yyssp -= yylen;
@@ -2349,23 +2471,29 @@ yyacceptlab:
 | yyabortlab -- YYABORT comes here.  |
 `-----------------------------------*/
 yyabortlab:
-  yydestruct ("Error: discarding lookahead",
-              yytoken, &yylval);
-  yychar = YYEMPTY;
   yyresult = 1;
   goto yyreturn;
 
 #ifndef yyoverflow
-/*----------------------------------------------.
-| yyoverflowlab -- parser overflow comes here.  |
-`----------------------------------------------*/
-yyoverflowlab:
-  yyerror ("parser stack overflow");
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here.  |
+`-------------------------------------------------*/
+yyexhaustedlab:
+  yyerror (YY_("memory exhausted"));
   yyresult = 2;
   /* Fall through.  */
 #endif
 
 yyreturn:
+  if (yychar != YYEOF && yychar != YYEMPTY)
+     yydestruct ("Cleanup: discarding lookahead",
+                yytoken, &yylval);
+  while (yyssp != yyss)
+    {
+      yydestruct ("Cleanup: popping",
+                 yystos[*yyssp], yyvsp);
+      YYPOPSTACK;
+    }
 #ifndef yyoverflow
   if (yyss != yyssa)
     YYSTACK_FREE (yyss);
index 5cc13426185634d70250ffe6b6e584a4ef355597..df4587501e672d949c4993baed0d1f0a0239391a 100644 (file)
@@ -1,7 +1,7 @@
-/* A Bison parser, made by GNU Bison 2.0.  */
+/* A Bison parser, made by GNU Bison 2.1.  */
 
 /* Skeleton parser for Yacc-like parsing with Bison,
-   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -15,8 +15,8 @@
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
 
 /* As a special exception, when this file is copied by Bison into a
    Bison output file, you may use that output file without restriction.
      NUMBER = 344
    };
 #endif
+/* Tokens.  */
 #define kw_ABSENT 258
 #define kw_ABSTRACT_SYNTAX 259
 #define kw_ALL 260
@@ -225,8 +226,8 @@ typedef union YYSTYPE {
     struct memhead *members;
     struct constraint_spec *constraint_spec;
 } YYSTYPE;
-/* Line 1318 of yacc.c.  */
-#line 230 "parse.h"
+/* Line 1447 of yacc.c.  */
+#line 231 "parse.h"
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
 # define YYSTYPE_IS_TRIVIAL 1
diff --git a/source4/heimdal/lib/asn1/pkinit.asn1 b/source4/heimdal/lib/asn1/pkinit.asn1
new file mode 100644 (file)
index 0000000..56d6611
--- /dev/null
@@ -0,0 +1,161 @@
+-- $Id$ --
+
+PKINIT DEFINITIONS ::= BEGIN
+
+IMPORTS EncryptionKey, PrincipalName, Realm, KerberosTime, Checksum FROM krb5
+       IssuerAndSerialNumber, ContentInfo FROM cms
+       SubjectPublicKeyInfo, AlgorithmIdentifier FROM rfc2459
+       heim_any FROM heim;
+
+id-pkinit OBJECT IDENTIFIER ::=
+  { iso (1) org (3) dod (6) internet (1) security (5)
+    kerberosv5 (2) pkinit (3) }
+
+id-pkauthdata  OBJECT IDENTIFIER  ::= { id-pkinit 1 }
+id-pkdhkeydata OBJECT IDENTIFIER  ::= { id-pkinit 2 }
+id-pkrkeydata  OBJECT IDENTIFIER  ::= { id-pkinit 3 }
+id-pkekuoid    OBJECT IDENTIFIER  ::= { id-pkinit 4 }
+id-pkkdcekuoid OBJECT IDENTIFIER  ::= { id-pkinit 5 }
+
+id-pkinit-san  OBJECT IDENTIFIER ::=
+  { iso(1) org(3) dod(6) internet(1) security(5) kerberosv5(2)
+    x509-sanan(2) }
+
+id-pkinit-ms-san OBJECT IDENTIFIER ::=
+  { iso(1) org(3) dod(6) internet(1) foo1(4) 
+    foo2(1) foo3(311) foo4(20) foo5(2) foo6(3) }
+
+pa-pk-as-req INTEGER ::=                  16
+pa-pk-as-rep INTEGER ::=                  17
+
+ad-initial-verified-cas INTEGER ::=        9
+
+td-trusted-certifiers INTEGER ::=        104
+td-invalid-certificates INTEGER ::=      105
+td-dh-parameters INTEGER ::=             109
+
+DHNonce ::= OCTET STRING
+
+TrustedCA ::= SEQUENCE {
+       caName                  [0] IMPLICIT OCTET STRING,
+       certificateSerialNumber [1] INTEGER OPTIONAL,
+       subjectKeyIdentifier    [2] OCTET STRING OPTIONAL,
+       ...
+}
+
+ExternalPrincipalIdentifier ::= SEQUENCE {
+       subjectName             [0] IMPLICIT OCTET STRING OPTIONAL,
+       issuerAndSerialNumber   [1] IMPLICIT OCTET STRING OPTIONAL,
+       subjectKeyIdentifier    [2] IMPLICIT OCTET STRING OPTIONAL,
+       ...
+}
+
+ExternalPrincipalIdentifiers ::= SEQUENCE OF ExternalPrincipalIdentifier
+
+PA-PK-AS-REQ ::= SEQUENCE {
+        signedAuthPack          [0] IMPLICIT OCTET STRING,
+        trustedCertifiers       [1] ExternalPrincipalIdentifiers OPTIONAL,
+       kdcPkId                 [2] IMPLICIT OCTET STRING OPTIONAL,
+       ...
+}
+
+PKAuthenticator ::= SEQUENCE {
+       cusec                   [0] INTEGER -- (0..999999) --,
+       ctime                   [1] KerberosTime,
+       nonce                   [2] INTEGER (0..4294967295),
+       paChecksum              [3] OCTET STRING OPTIONAL,
+       ...
+}
+
+AuthPack ::= SEQUENCE {
+       pkAuthenticator         [0] PKAuthenticator,
+       clientPublicValue       [1] SubjectPublicKeyInfo OPTIONAL,
+       supportedCMSTypes       [2] SEQUENCE OF AlgorithmIdentifier OPTIONAL,
+       clientDHNonce           [3] DHNonce OPTIONAL,
+       ...
+}
+
+TD-TRUSTED-CERTIFIERS ::= ExternalPrincipalIdentifiers
+TD-INVALID-CERTIFICATES ::= ExternalPrincipalIdentifiers
+
+KRB5PrincipalName ::= SEQUENCE {
+       realm                   [0] Realm,
+       principalName           [1] PrincipalName
+}
+
+AD-INITIAL-VERIFIED-CAS ::= SEQUENCE OF ExternalPrincipalIdentifier
+
+
+DHRepInfo ::= SEQUENCE {
+       dhSignedData            [0] IMPLICIT OCTET STRING,
+       serverDHNonce           [1] DHNonce OPTIONAL
+}
+
+PA-PK-AS-REP ::= CHOICE {
+       dhInfo                  [0] DHRepInfo,
+       encKeyPack              [1] IMPLICIT OCTET STRING,
+       ...
+}
+
+KDCDHKeyInfo ::= SEQUENCE {
+       subjectPublicKey        [0] BIT STRING,
+       nonce                   [1] INTEGER (0..4294967295),
+       dhKeyExpiration         [2] KerberosTime OPTIONAL,
+       ...
+}
+
+ReplyKeyPack ::= SEQUENCE {
+       replyKey                [0] EncryptionKey,
+       asChecksum              [1] Checksum,
+       ...
+}
+
+TD-DH-PARAMETERS ::= SEQUENCE OF AlgorithmIdentifier
+
+
+-- Windows compat glue --
+
+PKAuthenticator-Win2k ::= SEQUENCE {
+       kdcName                 [0] PrincipalName,
+       kdcRealm                [1] Realm,
+       cusec                   [2] INTEGER (0..4294967295),
+       ctime                   [3] KerberosTime,
+       nonce                   [4] INTEGER (-2147483648..2147483647)
+}
+
+AuthPack-Win2k ::= SEQUENCE {
+       pkAuthenticator         [0] PKAuthenticator-Win2k,
+       clientPublicValue       [1] SubjectPublicKeyInfo OPTIONAL
+}
+
+
+TrustedCA-Win2k ::= CHOICE {
+       caName                  [1] heim_any,
+       issuerAndSerial         [2] IssuerAndSerialNumber
+}
+
+PA-PK-AS-REQ-Win2k ::= SEQUENCE { 
+       signed-auth-pack        [0] IMPLICIT OCTET STRING, 
+       trusted-certifiers      [2] SEQUENCE OF TrustedCA-Win2k OPTIONAL, 
+       kdc-cert                [3] IMPLICIT OCTET STRING OPTIONAL, 
+       encryption-cert         [4] IMPLICIT OCTET STRING OPTIONAL
+}
+
+PA-PK-AS-REP-Win2k ::= CHOICE {
+       dhSignedData            [0] IMPLICIT OCTET STRING, 
+       encKeyPack              [1] IMPLICIT OCTET STRING
+}
+
+
+KDCDHKeyInfo-Win2k ::= SEQUENCE {
+       nonce                   [0] INTEGER (-2147483648..2147483647),
+       subjectPublicKey        [2] BIT STRING
+}
+
+ReplyKeyPack-Win2k ::= SEQUENCE {
+        replyKey                [0] EncryptionKey,
+        nonce                   [1] INTEGER (0..4294967295),
+       ...
+}
+
+END
diff --git a/source4/heimdal/lib/asn1/rfc2459.asn1 b/source4/heimdal/lib/asn1/rfc2459.asn1
new file mode 100644 (file)
index 0000000..eebbc32
--- /dev/null
@@ -0,0 +1,426 @@
+-- $Id$ --
+-- Definitions from rfc2459/rfc3280
+
+RFC2459 DEFINITIONS ::= BEGIN
+
+IMPORTS heim_any FROM heim;
+
+Version ::=  INTEGER {
+       rfc3280_version_1(0), 
+       rfc3280_version_2(1),
+       rfc3280_version_3(2)
+}
+
+id-pkcs-1 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840)
+       rsadsi(113549) pkcs(1) 1 }
+id-pkcs1-rsaEncryption OBJECT IDENTIFIER ::=           { id-pkcs-1 1 }
+id-pkcs1-md2WithRSAEncryption OBJECT IDENTIFIER ::=    { id-pkcs-1 2 }
+id-pkcs1-md5WithRSAEncryption OBJECT IDENTIFIER ::=    { id-pkcs-1 4 }
+id-pkcs1-sha1WithRSAEncryption OBJECT IDENTIFIER ::=   { id-pkcs-1 5 }
+id-pkcs1-sha256WithRSAEncryption OBJECT IDENTIFIER ::= { id-pkcs-1 11 }
+id-pkcs1-sha384WithRSAEncryption OBJECT IDENTIFIER ::= { id-pkcs-1 12 }
+id-pkcs1-sha512WithRSAEncryption OBJECT IDENTIFIER ::= { id-pkcs-1 13 }
+
+id-pkcs-2 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840)
+       rsadsi(113549) pkcs(1) 2 }
+id-pkcs2-md2 OBJECT IDENTIFIER ::=             { id-pkcs-2 2 }
+id-pkcs2-md4 OBJECT IDENTIFIER ::=             { id-pkcs-2 4 }
+id-pkcs2-md5 OBJECT IDENTIFIER ::=             { id-pkcs-2 5 }
+
+id-rsa-digestAlgorithm OBJECT IDENTIFIER ::= 
+{ iso(1) member-body(2) us(840) rsadsi(113549) 2 }
+
+id-rsa-digest-md2 OBJECT IDENTIFIER ::= { id-rsa-digestAlgorithm 2 }
+id-rsa-digest-md4 OBJECT IDENTIFIER ::= { id-rsa-digestAlgorithm 4 }
+id-rsa-digest-md5 OBJECT IDENTIFIER ::= { id-rsa-digestAlgorithm 5 }
+
+id-pkcs-3 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840)
+       rsadsi(113549) pkcs(1) 3 }
+
+id-pkcs3-rc2-cbc OBJECT IDENTIFIER ::=         { id-pkcs-3 2 }
+id-pkcs3-rc4     OBJECT IDENTIFIER ::=         { id-pkcs-3 4 }
+id-pkcs3-des-ede3-cbc OBJECT IDENTIFIER ::=    { id-pkcs-3 7 }
+
+id-rsadsi-encalg OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840)
+       rsadsi(113549) 3 }
+
+id-rsadsi-rc2-cbc OBJECT IDENTIFIER ::=                { id-rsadsi-encalg 2 }
+id-rsadsi-des-ede3-cbc OBJECT IDENTIFIER ::=   { id-rsadsi-encalg 7 }
+
+id-secsig-sha-1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3)
+       oiw(14) secsig(3) algorithm(2) 26 }
+
+id-nistAlgorithm OBJECT IDENTIFIER ::= {
+   joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) 4 }
+   
+id-nist-aes-algs OBJECT IDENTIFIER ::= { id-nistAlgorithm 1 }
+
+id-aes-128-cbc OBJECT IDENTIFIER ::=           { id-nist-aes-algs 2 }
+id-aes-192-cbc OBJECT IDENTIFIER ::=           { id-nist-aes-algs 22 }
+id-aes-256-cbc OBJECT IDENTIFIER ::=           { id-nist-aes-algs 42 }
+
+id-nist-sha-algs OBJECT IDENTIFIER ::=         { id-nistAlgorithm 2 }
+
+id-sha256 OBJECT IDENTIFIER ::=                        { id-nist-sha-algs 1 }
+id-sha224 OBJECT IDENTIFIER ::=                        { id-nist-sha-algs 4 }
+id-sha384 OBJECT IDENTIFIER ::=                        { id-nist-sha-algs 2 }
+id-sha512 OBJECT IDENTIFIER ::=                        { id-nist-sha-algs 3 }
+
+id-dhpublicnumber OBJECT IDENTIFIER ::= {
+        iso(1) member-body(2) us(840) ansi-x942(10046)
+        number-type(2) 1 }
+
+id-x9-57 OBJECT IDENTIFIER ::= {
+        iso(1) member-body(2) us(840) ansi-x942(10046)
+       4 }
+
+id-dsa OBJECT IDENTIFIER ::=           { id-x9-57 1 }
+id-dsa-with-sha1 OBJECT IDENTIFIER ::=         { id-x9-57 3 }
+
+-- x.520 names types
+
+id-x520-at     OBJECT IDENTIFIER ::= { joint-iso-ccitt(2) ds(5) 4 }
+
+id-at-commonName               OBJECT IDENTIFIER ::= { id-x520-at 3 }
+id-at-surname                  OBJECT IDENTIFIER ::= { id-x520-at 4 }
+id-at-serialNumber             OBJECT IDENTIFIER ::= { id-x520-at 5 }
+id-at-countryName              OBJECT IDENTIFIER ::= { id-x520-at 6 }
+id-at-localityName             OBJECT IDENTIFIER ::= { id-x520-at 7 }
+id-at-stateOrProvinceName      OBJECT IDENTIFIER ::= { id-x520-at 8 }
+id-at-organizationName         OBJECT IDENTIFIER ::= { id-x520-at 10 }
+id-at-organizationalUnitName   OBJECT IDENTIFIER ::= { id-x520-at 11 }
+id-at-name                     OBJECT IDENTIFIER ::= { id-x520-at 41 }
+id-at-givenName                        OBJECT IDENTIFIER ::= { id-x520-at 42 }
+id-at-initials                 OBJECT IDENTIFIER ::= { id-x520-at 43 }
+id-at-generationQualifier      OBJECT IDENTIFIER ::= { id-x520-at 44 }
+id-at-pseudonym                        OBJECT IDENTIFIER ::= { id-x520-at 65 }
+-- RFC 2247
+id-Userid                      OBJECT IDENTIFIER ::=
+                          { 0 9 2342 19200300 100 1 1 }
+id-domainComponent             OBJECT IDENTIFIER ::=
+                          { 0 9 2342 19200300 100 1 25 }
+
+
+-- rfc3280
+
+id-x509-ce OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 29}
+
+AlgorithmIdentifier ::= SEQUENCE {
+       algorithm       OBJECT IDENTIFIER,
+       parameters      heim_any OPTIONAL
+}
+
+AttributeType ::=   OBJECT IDENTIFIER
+
+AttributeValue ::=   heim_any
+
+TeletexStringx ::= [UNIVERSAL 20] IMPLICIT OCTET STRING
+
+DirectoryString ::= CHOICE {
+       ia5String       IA5String,
+       teletexString   TeletexStringx,
+       printableString PrintableString,
+       universalString UniversalString,
+       utf8String      UTF8String,
+       bmpString       BMPString
+}
+
+Attribute ::= SEQUENCE {
+        type    AttributeType,
+        value   SET OF -- AttributeValue -- heim_any
+}
+
+AttributeTypeAndValue ::= SEQUENCE {
+        type    AttributeType,
+        value   DirectoryString
+}
+
+RelativeDistinguishedName ::= SET OF AttributeTypeAndValue
+
+RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
+
+Name ::= CHOICE {
+       rdnSequence  RDNSequence
+}
+
+CertificateSerialNumber ::= INTEGER
+
+Time ::= CHOICE {
+     utcTime        UTCTime,
+     generalTime    GeneralizedTime
+}
+
+Validity ::= SEQUENCE {
+     notBefore      Time,
+     notAfter       Time
+}
+
+UniqueIdentifier  ::=  BIT STRING
+
+SubjectPublicKeyInfo  ::=  SEQUENCE  {
+     algorithm            AlgorithmIdentifier,
+     subjectPublicKey     BIT STRING
+}
+
+Extension  ::=  SEQUENCE  {
+     extnID      OBJECT IDENTIFIER,
+     critical    BOOLEAN OPTIONAL, -- DEFAULT FALSE XXX
+     extnValue   OCTET STRING
+}
+
+Extensions  ::=  SEQUENCE OF Extension --  SIZE (1..MAX) 
+
+TBSCertificate  ::=  SEQUENCE  {
+     version         [0]  Version OPTIONAL, -- EXPLICIT nnn DEFAULT 1,
+     serialNumber         CertificateSerialNumber,
+     signature            AlgorithmIdentifier,
+     issuer               Name,
+     validity             Validity,
+     subject              Name,
+     subjectPublicKeyInfo SubjectPublicKeyInfo,
+     issuerUniqueID  [1]  IMPLICIT BIT STRING -- UniqueIdentifier -- OPTIONAL,
+                          -- If present, version shall be v2 or v3
+     subjectUniqueID [2]  IMPLICIT BIT STRING -- UniqueIdentifier -- OPTIONAL,
+                          -- If present, version shall be v2 or v3
+     extensions      [3]  EXPLICIT Extensions OPTIONAL
+                          -- If present, version shall be v3
+}
+
+Certificate  ::=  SEQUENCE  {
+     tbsCertificate       TBSCertificate,
+     signatureAlgorithm   AlgorithmIdentifier,
+     signatureValue       BIT STRING
+}
+
+Certificates ::= SEQUENCE OF Certificate
+
+ValidationParms ::= SEQUENCE {
+       seed            BIT STRING,
+       pgenCounter     INTEGER
+}
+
+DomainParameters ::= SEQUENCE {
+       p               INTEGER, -- odd prime, p=jq +1
+       g               INTEGER, -- generator, g
+       q               INTEGER, -- factor of p-1
+       j               INTEGER OPTIONAL, -- subgroup factor
+       validationParms ValidationParms OPTIONAL -- ValidationParms
+}
+
+DHPublicKey ::= INTEGER
+
+OtherName ::= SEQUENCE {
+       type-id    OBJECT IDENTIFIER,
+       value      [0] EXPLICIT heim_any
+}
+
+GeneralName ::= CHOICE {
+       otherName                       [0]     IMPLICIT -- OtherName -- SEQUENCE {
+               type-id    OBJECT IDENTIFIER,
+               value      [0] EXPLICIT heim_any
+       },
+       rfc822Name                      [1]     IMPLICIT IA5String,
+       dNSName                         [2]     IMPLICIT IA5String,
+--     x400Address                     [3]     IMPLICIT ORAddress,--
+       directoryName                   [4]     IMPLICIT -- Name -- CHOICE {
+               rdnSequence  RDNSequence
+       },
+--     ediPartyName                    [5]     IMPLICIT EDIPartyName, --
+       uniformResourceIdentifier       [6]     IMPLICIT IA5String,
+       iPAddress                       [7]     IMPLICIT OCTET STRING,
+       registeredID                    [8]     IMPLICIT OBJECT IDENTIFIER
+}
+
+GeneralNames ::= SEQUENCE -- SIZE (1..MAX) -- OF GeneralName
+
+id-x509-ce-keyUsage OBJECT IDENTIFIER ::=  { id-x509-ce 15 }
+
+KeyUsage ::= BIT STRING {
+       digitalSignature        (0),
+       nonRepudiation          (1),
+       keyEncipherment         (2),
+       dataEncipherment        (3),
+       keyAgreement            (4),
+       keyCertSign             (5),
+       cRLSign                 (6),
+       encipherOnly            (7),
+       decipherOnly            (8)
+}
+
+id-x509-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::=  { id-x509-ce 35 }
+
+KeyIdentifier ::= OCTET STRING
+
+AuthorityKeyIdentifier ::= SEQUENCE {
+       keyIdentifier             [0] IMPLICIT OCTET STRING OPTIONAL,
+       authorityCertIssuer       [1] IMPLICIT -- GeneralName -- 
+               SEQUENCE -- SIZE (1..MAX) -- OF GeneralName OPTIONAL, 
+       authorityCertSerialNumber [2] IMPLICIT INTEGER OPTIONAL
+}
+
+id-x509-ce-subjectKeyIdentifier OBJECT IDENTIFIER ::=  { id-x509-ce 14 }
+
+SubjectKeyIdentifier ::= KeyIdentifier
+
+id-x509-ce-basicConstraints OBJECT IDENTIFIER ::=  { id-x509-ce 19 }
+
+BasicConstraints ::= SEQUENCE {
+       cA                      BOOLEAN OPTIONAL -- DEFAULT FALSE --,
+       pathLenConstraint       INTEGER (0..4294967295) OPTIONAL 
+}
+
+id-x509-ce-nameConstraints OBJECT IDENTIFIER ::=  { id-x509-ce 30 }
+
+BaseDistance ::= INTEGER -- (0..MAX) --
+
+GeneralSubtree ::= SEQUENCE {
+       base                    GeneralName,
+       minimum         [0]     IMPLICIT -- BaseDistance -- INTEGER OPTIONAL -- DEFAULT 0 --,
+       maximum         [1]     IMPLICIT -- BaseDistance -- INTEGER OPTIONAL
+}
+
+GeneralSubtrees ::= SEQUENCE -- SIZE (1..MAX) -- OF GeneralSubtree
+
+NameConstraints ::= SEQUENCE {
+       permittedSubtrees       [0]     IMPLICIT -- GeneralSubtrees -- SEQUENCE OF GeneralSubtree OPTIONAL,
+       excludedSubtrees        [1]     IMPLICIT -- GeneralSubtrees -- SEQUENCE OF GeneralSubtree OPTIONAL
+}
+
+id-x509-ce-privateKeyUsagePeriod OBJECT IDENTIFIER ::=  { id-x509-ce 16 }
+id-x509-ce-certificatePolicies OBJECT IDENTIFIER ::=  { id-x509-ce 32 }
+id-x509-ce-policyMappings OBJECT IDENTIFIER ::=  { id-x509-ce 33 }
+id-x509-ce-subjectAltName OBJECT IDENTIFIER ::=  { id-x509-ce 17 }
+id-x509-ce-issuerAltName OBJECT IDENTIFIER ::=  { id-x509-ce 18 }
+id-x509-ce-subjectDirectoryAttributes OBJECT IDENTIFIER ::=  { id-x509-ce 9 }
+id-x509-ce-policyConstraints OBJECT IDENTIFIER ::=  { id-x509-ce 36 }
+
+id-x509-ce-extKeyUsage OBJECT IDENTIFIER ::= { id-x509-ce 37}
+
+ExtKeyUsage ::= SEQUENCE OF OBJECT IDENTIFIER
+
+id-x509-ce-cRLDistributionPoints OBJECT IDENTIFIER ::=  { id-x509-ce 31 }
+id-x509-ce-deltaCRLIndicator OBJECT IDENTIFIER ::= { id-x509-ce 27 }
+id-x509-ce-issuingDistributionPoint OBJECT IDENTIFIER ::= { id-x509-ce 28 }
+id-x509-ce-holdInstructionCode OBJECT IDENTIFIER ::= { id-x509-ce 23 }
+id-x509-ce-invalidityDate OBJECT IDENTIFIER ::= { id-x509-ce 24 }
+id-x509-ce-certificateIssuer   OBJECT IDENTIFIER ::= { id-x509-ce 29 }
+id-x509-ce-inhibitAnyPolicy OBJECT IDENTIFIER ::=  { id-x509-ce 54 }
+
+-- rfc3279
+
+DSASigValue  ::=  SEQUENCE {
+       r       INTEGER,
+       s       INTEGER
+}
+
+DSAPublicKey ::= INTEGER
+
+DSAParams  ::=  SEQUENCE {
+       p       INTEGER,
+       q       INTEGER,
+       g       INTEGER
+}
+
+-- really pkcs1
+
+RSAPublicKey ::= SEQUENCE {
+       modulus INTEGER, -- n
+       publicExponent INTEGER -- e
+}
+
+RSAPrivateKey ::= SEQUENCE {
+       version INTEGER (0..4294967295),
+       modulus INTEGER, -- n
+       publicExponent INTEGER, -- e
+       privateExponent INTEGER, -- d
+       prime1 INTEGER, -- p
+       prime2 INTEGER, -- q
+       exponent1 INTEGER, -- d mod (p-1)
+       exponent2 INTEGER, -- d mod (q-1)
+       coefficient INTEGER -- (inverse of q) mod p
+}
+
+DigestInfo ::= SEQUENCE {
+       digestAlgorithm AlgorithmIdentifier,
+       digest OCTET STRING
+}
+
+-- some ms ext
+
+-- szOID_ENROLL_CERTTYPE_EXTENSION "1.3.6.1.4.1.311.20.2" is Encoded as a
+
+-- UNICODESTRING (0x1E tag)
+
+-- szOID_CERTIFICATE_TEMPLATE "1.3.6.1.4.1.311.21.7" is Encoded as:
+
+-- TemplateVersion ::= INTEGER (0..4294967295) 
+
+-- CertificateTemplate ::= SEQUENCE {
+--     templateID OBJECT IDENTIFIER,
+--     templateMajorVersion TemplateVersion,
+--     templateMinorVersion TemplateVersion OPTIONAL
+-- }
+
+
+--
+-- CRL
+-- 
+
+TBSCRLCertList ::=  SEQUENCE  {
+       version                 Version OPTIONAL, -- if present, MUST be v2
+       signature               AlgorithmIdentifier,
+       issuer                  Name,
+       thisUpdate              Time,
+       nextUpdate              Time OPTIONAL,
+       revokedCertificates     SEQUENCE OF SEQUENCE  {
+               userCertificate         CertificateSerialNumber,
+               revocationDate          Time,
+               crlEntryExtensions      Extensions OPTIONAL
+                                               -- if present, MUST be v2
+       } OPTIONAL,
+       crlExtensions           [0] EXPLICIT Extensions OPTIONAL
+                                               -- if present, MUST be v2
+}
+
+
+CRLCertificateList ::=  SEQUENCE  {
+       tbsCertList          TBSCRLCertList,
+       signatureAlgorithm   AlgorithmIdentifier,
+       signatureValue       BIT STRING
+}
+
+id-x509-ce-cRLNumber OBJECT IDENTIFIER ::= { id-x509-ce 20 }
+id-x509-ce-freshestCRL OBJECT IDENTIFIER ::=  { id-x509-ce 46 }
+id-x509-ce-cRLReason OBJECT IDENTIFIER ::= { id-x509-ce 21 }
+
+CRLReason ::= ENUMERATED {
+       unspecified             (0),
+       keyCompromise           (1),
+       cACompromise            (2),
+       affiliationChanged      (3),
+       superseded              (4),
+       cessationOfOperation    (5),
+       certificateHold         (6),
+       removeFromCRL           (8),
+       privilegeWithdrawn      (9),
+       aACompromise           (10)
+}
+
+-- RFC 3820 Proxy Certificate Profile
+
+id-pkix-pe OBJECT IDENTIFIER ::= { iso(1) identified-organization(3)
+            dod(6) internet(1) security(5) mechanisms(5) pkix(7) 1 }
+
+id-pe-proxyCertInfo OBJECT IDENTIFIER ::= { id-pkix-pe 14 }
+
+ProxyPolicy ::= SEQUENCE {
+       policyLanguage          OBJECT IDENTIFIER,
+       policy                  OCTET STRING OPTIONAL
+}
+
+ProxyCertInfo ::= SEQUENCE {
+       pCPathLenConstraint     INTEGER (0..4294967295) OPTIONAL, -- really MAX
+       proxyPolicy             ProxyPolicy
+}
+
+END
index 22fcc0b0036bb412ffc10aa1aa5c7f02f10dc84f..1a1179bc301f22655545312519ce9b4085076377 100644 (file)
@@ -1,4 +1,4 @@
--- $Id: test.asn1,v 1.8 2006/01/31 09:42:04 lha Exp $ --
+-- $Id: test.asn1,v 1.9 2006/09/05 14:00:44 lha Exp $ --
 
 TEST DEFINITIONS ::=
 
@@ -83,4 +83,6 @@ TESTUSERCONSTRAINED ::= OCTET STRING (CONSTRAINED BY { -- meh -- })
 -- TESTUSERCONSTRAINED3 ::= OCTET STRING (CONSTRAINED BY { INTEGER })
 -- TESTUSERCONSTRAINED4 ::= OCTET STRING (CONSTRAINED BY { INTEGER : 1 })
 
+TESTSeqOf ::= SEQUENCE OF TESTInteger
+
 END
diff --git a/source4/heimdal/lib/asn1/timegm.c b/source4/heimdal/lib/asn1/timegm.c
new file mode 100644 (file)
index 0000000..86df58d
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * 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 "der_locl.h"
+
+RCSID("$Id: timegm.c,v 1.11 2006/10/19 16:19:32 lha Exp $");
+
+static int
+is_leap(unsigned y)
+{
+    y += 1900;
+    return (y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0);
+}
+
+/* 
+ * This is a simplifed version of _der_timegm that doesn't accept out
+ * of bound values that timegm(3) normally accepts but those are not
+ * valid in asn1 encodings.
+ */
+
+time_t
+_der_timegm (struct tm *tm)
+{
+  static const unsigned ndays[2][12] ={
+    {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
+    {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
+  time_t res = 0;
+  unsigned i;
+
+  if (tm->tm_year < 0) 
+      return -1;
+  if (tm->tm_mon < 0 || tm->tm_mon > 11) 
+      return -1;
+  if (tm->tm_mday < 1 || tm->tm_mday > ndays[is_leap(tm->tm_year)][tm->tm_mon])
+      return -1;
+  if (tm->tm_hour < 0 || tm->tm_hour > 23) 
+      return -1;
+  if (tm->tm_min < 0 || tm->tm_min > 59) 
+      return -1;
+  if (tm->tm_sec < 0 || tm->tm_sec > 59) 
+      return -1;
+
+  for (i = 70; i < tm->tm_year; ++i)
+    res += is_leap(i) ? 366 : 365;
+
+  for (i = 0; i < tm->tm_mon; ++i)
+    res += ndays[is_leap(tm->tm_year)][i];
+  res += tm->tm_mday - 1;
+  res *= 24;
+  res += tm->tm_hour;
+  res *= 60;
+  res += tm->tm_min;
+  res *= 60;
+  res += tm->tm_sec;
+  return res;
+}
index 4697d0a3fd64c23110eddb561dee22f07e84e351..30b44d0c192d2268279151ddc2c9ee4cf1832916 100644 (file)
@@ -1,94 +1,32 @@
-#include "config.h"
-
-#line 3 "lex.yy.c"
-
-#define  YY_INT_ALIGNED short int
-
 /* A lexical scanner generated by flex */
 
+/* Scanner skeleton version:
+ * $Header: /cvs/root/flex/flex/skel.c,v 1.2 2004/05/07 00:28:17 jkh Exp $
+ */
+
 #define FLEX_SCANNER
 #define YY_FLEX_MAJOR_VERSION 2
 #define YY_FLEX_MINOR_VERSION 5
-#define YY_FLEX_SUBMINOR_VERSION 33
-#if YY_FLEX_SUBMINOR_VERSION > 0
-#define FLEX_BETA
-#endif
-
-/* First, we deal with  platform-specific or compiler-specific issues. */
 
-/* begin standard C headers. */
 #include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-
-/* end standard C headers. */
-
-/* flex integer type definitions */
 
-#ifndef FLEXINT_H
-#define FLEXINT_H
 
-/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
-
-#if __STDC_VERSION__ >= 199901L
-
-/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
- * if you want the limit (max/min) macros for int types. 
- */
-#ifndef __STDC_LIMIT_MACROS
-#define __STDC_LIMIT_MACROS 1
-#endif
-
-#include <inttypes.h>
-typedef int8_t flex_int8_t;
-typedef uint8_t flex_uint8_t;
-typedef int16_t flex_int16_t;
-typedef uint16_t flex_uint16_t;
-typedef int32_t flex_int32_t;
-typedef uint32_t flex_uint32_t;
-#else
-typedef signed char flex_int8_t;
-typedef short int flex_int16_t;
-typedef int flex_int32_t;
-typedef unsigned char flex_uint8_t; 
-typedef unsigned short int flex_uint16_t;
-typedef unsigned int flex_uint32_t;
-#endif /* ! C99 */
-
-/* Limits of integral types. */
-#ifndef INT8_MIN
-#define INT8_MIN               (-128)
-#endif
-#ifndef INT16_MIN
-#define INT16_MIN              (-32767-1)
-#endif
-#ifndef INT32_MIN
-#define INT32_MIN              (-2147483647-1)
-#endif
-#ifndef INT8_MAX
-#define INT8_MAX               (127)
-#endif
-#ifndef INT16_MAX
-#define INT16_MAX              (32767)
-#endif
-#ifndef INT32_MAX
-#define INT32_MAX              (2147483647)
-#endif
-#ifndef UINT8_MAX
-#define UINT8_MAX              (255U)
-#endif
-#ifndef UINT16_MAX
-#define UINT16_MAX             (65535U)
+/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
+#ifdef c_plusplus
+#ifndef __cplusplus
+#define __cplusplus
 #endif
-#ifndef UINT32_MAX
-#define UINT32_MAX             (4294967295U)
 #endif
 
-#endif /* ! FLEXINT_H */
 
 #ifdef __cplusplus
 
+#include <stdlib.h>
+#include <unistd.h>
+
+/* Use prototypes in function declarations. */
+#define YY_USE_PROTOS
+
 /* The "const" storage-class-modifier is valid. */
 #define YY_USE_CONST
 
@@ -96,17 +34,34 @@ typedef unsigned int flex_uint32_t;
 
 #if __STDC__
 
+#define YY_USE_PROTOS
 #define YY_USE_CONST
 
 #endif /* __STDC__ */
 #endif /* ! __cplusplus */
 
+#ifdef __TURBOC__
+ #pragma warn -rch
+ #pragma warn -use
+#include <io.h>
+#include <stdlib.h>
+#define YY_USE_CONST
+#define YY_USE_PROTOS
+#endif
+
 #ifdef YY_USE_CONST
 #define yyconst const
 #else
 #define yyconst
 #endif
 
+
+#ifdef YY_USE_PROTOS
+#define YY_PROTO(proto) proto
+#else
+#define YY_PROTO(proto) ()
+#endif
+
 /* Returned upon end-of-file. */
 #define YY_NULL 0
 
@@ -121,75 +76,71 @@ typedef unsigned int flex_uint32_t;
  * but we do it the disgusting crufty way forced on us by the ()-less
  * definition of BEGIN.
  */
-#define BEGIN (yy_start) = 1 + 2 *
+#define BEGIN yy_start = 1 + 2 *
 
 /* Translate the current start state into a value that can be later handed
  * to BEGIN to return to the state.  The YYSTATE alias is for lex
  * compatibility.
  */
-#define YY_START (((yy_start) - 1) / 2)
+#define YY_START ((yy_start - 1) / 2)
 #define YYSTATE YY_START
 
 /* Action number for EOF rule of a given start state. */
 #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
 
 /* Special action meaning "start processing a new file". */
-#define YY_NEW_FILE yyrestart(yyin  )
+#define YY_NEW_FILE yyrestart( yyin )
 
 #define YY_END_OF_BUFFER_CHAR 0
 
 /* Size of default input buffer. */
-#ifndef YY_BUF_SIZE
 #define YY_BUF_SIZE 16384
-#endif
-
-/* The state buf must be large enough to hold one state per character in the main buffer.
- */
-#define YY_STATE_BUF_SIZE   ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
 
-#ifndef YY_TYPEDEF_YY_BUFFER_STATE
-#define YY_TYPEDEF_YY_BUFFER_STATE
 typedef struct yy_buffer_state *YY_BUFFER_STATE;
-#endif
 
 extern int yyleng;
-
 extern FILE *yyin, *yyout;
 
 #define EOB_ACT_CONTINUE_SCAN 0
 #define EOB_ACT_END_OF_FILE 1
 #define EOB_ACT_LAST_MATCH 2
 
-    #define YY_LESS_LINENO(n)
-    
-/* Return all but the first "n" matched characters back to the input stream. */
+/* The funky do-while in the following #define is used to turn the definition
+ * int a single C statement (which needs a semi-colon terminator).  This
+ * avoids problems with code like:
+ *
+ *     if ( condition_holds )
+ *             yyless( 5 );
+ *     else
+ *             do_something_else();
+ *
+ * Prior to using the do-while the compiler would get upset at the
+ * "else" because it interpreted the "if" statement as being all
+ * done when it reached the ';' after the yyless() call.
+ */
+
+/* Return all but the first 'n' matched characters back to the input stream. */
+
 #define yyless(n) \
        do \
                { \
                /* Undo effects of setting up yytext. */ \
-        int yyless_macro_arg = (n); \
-        YY_LESS_LINENO(yyless_macro_arg);\
-               *yy_cp = (yy_hold_char); \
+               *yy_cp = yy_hold_char; \
                YY_RESTORE_YY_MORE_OFFSET \
-               (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+               yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \
                YY_DO_BEFORE_ACTION; /* set up yytext again */ \
                } \
        while ( 0 )
 
-#define unput(c) yyunput( c, (yytext_ptr)  )
+#define unput(c) yyunput( c, yytext_ptr )
 
 /* The following is because we cannot portably get our hands on size_t
  * (without autoconf's help, which isn't available because we want
  * flex-generated scanners to compile on their own).
  */
-
-#ifndef YY_TYPEDEF_YY_SIZE_T
-#define YY_TYPEDEF_YY_SIZE_T
 typedef unsigned int yy_size_t;
-#endif
 
-#ifndef YY_STRUCT_YY_BUFFER_STATE
-#define YY_STRUCT_YY_BUFFER_STATE
+
 struct yy_buffer_state
        {
        FILE *yy_input_file;
@@ -226,16 +177,12 @@ struct yy_buffer_state
         */
        int yy_at_bol;
 
-    int yy_bs_lineno; /**< The line count. */
-    int yy_bs_column; /**< The column count. */
-    
        /* Whether to try to fill the input buffer when we reach the
         * end of it.
         */
        int yy_fill_buffer;
 
        int yy_buffer_status;
-
 #define YY_BUFFER_NEW 0
 #define YY_BUFFER_NORMAL 1
        /* When an EOF's been seen but there's still some text to process
@@ -249,38 +196,28 @@ struct yy_buffer_state
         * just pointing yyin at a new input file.
         */
 #define YY_BUFFER_EOF_PENDING 2
-
        };
-#endif /* !YY_STRUCT_YY_BUFFER_STATE */
 
-/* Stack of input buffers. */
-static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
-static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
-static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
+static YY_BUFFER_STATE yy_current_buffer = 0;
 
 /* We provide macros for accessing buffer states in case in the
  * future we want to put the buffer states in a more general
  * "scanner state".
- *
- * Returns the top of the stack, or NULL.
  */
-#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
-                          ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
-                          : NULL)
+#define YY_CURRENT_BUFFER yy_current_buffer
 
-/* Same as previous macro, but useful when we know that the buffer stack is not
- * NULL or when we need an lvalue. For internal use only.
- */
-#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
 
 /* yy_hold_char holds the character lost when yytext is formed. */
 static char yy_hold_char;
+
 static int yy_n_chars;         /* number of characters read into yy_ch_buf */
+
+
 int yyleng;
 
 /* Points to current character in buffer. */
 static char *yy_c_buf_p = (char *) 0;
-static int yy_init = 0;                /* whether we need to initialize */
+static int yy_init = 1;                /* whether we need to initialize */
 static int yy_start = 0;       /* start state number */
 
 /* Flag which is used to allow yywrap()'s to do buffer switches
@@ -288,92 +225,66 @@ static int yy_start = 0;  /* start state number */
  */
 static int yy_did_buffer_switch_on_eof;
 
-void yyrestart (FILE *input_file  );
-void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer  );
-YY_BUFFER_STATE yy_create_buffer (FILE *file,int size  );
-void yy_delete_buffer (YY_BUFFER_STATE b  );
-void yy_flush_buffer (YY_BUFFER_STATE b  );
-void yypush_buffer_state (YY_BUFFER_STATE new_buffer  );
-void yypop_buffer_state (void );
-
-static void yyensure_buffer_stack (void );
-static void yy_load_buffer_state (void );
-static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file  );
+void yyrestart YY_PROTO(( FILE *input_file ));
 
-#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER )
+void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer ));
+void yy_load_buffer_state YY_PROTO(( void ));
+YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size ));
+void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file ));
+void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer )
 
-YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size  );
-YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str  );
-YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len  );
+YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size ));
+YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str ));
+YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len ));
 
-void *yyalloc (yy_size_t  );
-void *yyrealloc (void *,yy_size_t  );
-void yyfree (void *  );
+static void *yy_flex_alloc YY_PROTO(( yy_size_t ));
+static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t ));
+static void yy_flex_free YY_PROTO(( void * ));
 
 #define yy_new_buffer yy_create_buffer
 
 #define yy_set_interactive(is_interactive) \
        { \
-       if ( ! YY_CURRENT_BUFFER ){ \
-        yyensure_buffer_stack (); \
-               YY_CURRENT_BUFFER_LVALUE =    \
-            yy_create_buffer(yyin,YY_BUF_SIZE ); \
-       } \
-       YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+       if ( ! yy_current_buffer ) \
+               yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+       yy_current_buffer->yy_is_interactive = is_interactive; \
        }
 
 #define yy_set_bol(at_bol) \
        { \
-       if ( ! YY_CURRENT_BUFFER ){\
-        yyensure_buffer_stack (); \
-               YY_CURRENT_BUFFER_LVALUE =    \
-            yy_create_buffer(yyin,YY_BUF_SIZE ); \
-       } \
-       YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+       if ( ! yy_current_buffer ) \
+               yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+       yy_current_buffer->yy_at_bol = at_bol; \
        }
 
-#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
-
-/* Begin user sect3 */
+#define YY_AT_BOL() (yy_current_buffer->yy_at_bol)
 
 typedef unsigned char YY_CHAR;
-
 FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
-
 typedef int yy_state_type;
-
-extern int yylineno;
-
-int yylineno = 1;
-
 extern char *yytext;
 #define yytext_ptr yytext
 
-static yy_state_type yy_get_previous_state (void );
-static yy_state_type yy_try_NUL_trans (yy_state_type current_state  );
-static int yy_get_next_buffer (void );
-static void yy_fatal_error (yyconst char msg[]  );
+static yy_state_type yy_get_previous_state YY_PROTO(( void ));
+static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state ));
+static int yy_get_next_buffer YY_PROTO(( void ));
+static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
 
 /* Done after the current pattern has been matched and before the
  * corresponding action - sets up yytext.
  */
 #define YY_DO_BEFORE_ACTION \
-       (yytext_ptr) = yy_bp; \
-       yyleng = (size_t) (yy_cp - yy_bp); \
-       (yy_hold_char) = *yy_cp; \
+       yytext_ptr = yy_bp; \
+       yyleng = (int) (yy_cp - yy_bp); \
+       yy_hold_char = *yy_cp; \
        *yy_cp = '\0'; \
-       (yy_c_buf_p) = yy_cp;
+       yy_c_buf_p = yy_cp;
 
 #define YY_NUM_RULES 16
 #define YY_END_OF_BUFFER 17
-/* This struct is not used in this scanner,
-   but its presence is necessary. */
-struct yy_trans_info
-       {
-       flex_int32_t yy_verify;
-       flex_int32_t yy_nxt;
-       };
-static yyconst flex_int16_t yy_accept[46] =
+static yyconst short int yy_accept[46] =
     {   0,
         0,    0,   17,   15,   11,   12,   13,   10,    9,   14,
        14,   14,   14,   10,    9,   14,    3,   14,   14,    1,
@@ -382,7 +293,7 @@ static yyconst flex_int16_t yy_accept[46] =
        14,    4,   14,    2,    0
     } ;
 
-static yyconst flex_int32_t yy_ec[256] =
+static yyconst int yy_ec[256] =
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
@@ -414,14 +325,14 @@ static yyconst flex_int32_t yy_ec[256] =
         1,    1,    1,    1,    1
     } ;
 
-static yyconst flex_int32_t yy_meta[23] =
+static yyconst int yy_meta[23] =
     {   0,
         1,    1,    2,    1,    1,    3,    3,    3,    3,    3,
         3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
         3,    3
     } ;
 
-static yyconst flex_int16_t yy_base[48] =
+static yyconst short int yy_base[48] =
     {   0,
         0,    0,   56,   57,   57,   57,   57,    0,   49,    0,
        12,   13,   34,    0,   47,    0,    0,   40,   31,    0,
@@ -430,7 +341,7 @@ static yyconst flex_int16_t yy_base[48] =
        12,    0,   14,    0,   57,   34,   23
     } ;
 
-static yyconst flex_int16_t yy_def[48] =
+static yyconst short int yy_def[48] =
     {   0,
        45,    1,   45,   45,   45,   45,   45,   46,   47,   47,
        47,   47,   47,   46,   47,   47,   47,   47,   47,   47,
@@ -439,7 +350,7 @@ static yyconst flex_int16_t yy_def[48] =
        47,   47,   47,   47,    0,   45,   45
     } ;
 
-static yyconst flex_int16_t yy_nxt[80] =
+static yyconst short int yy_nxt[80] =
     {   0,
         4,    5,    6,    7,    8,    9,   10,   10,   10,   10,
        10,   10,   11,   10,   12,   10,   10,   10,   13,   10,
@@ -451,7 +362,7 @@ static yyconst flex_int16_t yy_nxt[80] =
        45,   45,   45,   45,   45,   45,   45,   45,   45
     } ;
 
-static yyconst flex_int16_t yy_chk[80] =
+static yyconst short int yy_chk[80] =
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
@@ -466,9 +377,6 @@ static yyconst flex_int16_t yy_chk[80] =
 static yy_state_type yy_last_accepting_state;
 static char *yy_last_accepting_cpos;
 
-extern int yy_flex_debug;
-int yy_flex_debug = 0;
-
 /* The intent behind this definition is that it'll catch
  * any uses of REJECT which flex missed.
  */
@@ -477,8 +385,9 @@ int yy_flex_debug = 0;
 #define YY_MORE_ADJ 0
 #define YY_RESTORE_YY_MORE_OFFSET
 char *yytext;
-#line 1 "lex.l"
-#line 2 "lex.l"
+#line 1 "../../../lib/com_err/lex.l"
+#define INITIAL 0
+#line 2 "../../../lib/com_err/lex.l"
 /*
  * Copyright (c) 1998 - 2000 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
@@ -533,23 +442,7 @@ static int getstring(void);
 
 #undef ECHO
 
-#line 536 "lex.yy.c"
-
-#define INITIAL 0
-
-#ifndef YY_NO_UNISTD_H
-/* Special case for "unistd.h", since it is non-ANSI. We include it way
- * down here because we want the user's section 1 to have been scanned first.
- * The user has a chance to override it with an option.
- */
-#include <unistd.h>
-#endif
-
-#ifndef YY_EXTRA_TYPE
-#define YY_EXTRA_TYPE void *
-#endif
-
-static int yy_init_globals (void );
+#line 446 "lex.c"
 
 /* Macros after this point can all be overridden by user definitions in
  * section 1.
@@ -557,30 +450,65 @@ static int yy_init_globals (void );
 
 #ifndef YY_SKIP_YYWRAP
 #ifdef __cplusplus
-extern "C" int yywrap (void );
+extern "C" int yywrap YY_PROTO(( void ));
 #else
-extern int yywrap (void );
+extern int yywrap YY_PROTO(( void ));
 #endif
 #endif
 
-    static void yyunput (int c,char *buf_ptr  );
-    
+#ifndef YY_NO_UNPUT
+static void yyunput YY_PROTO(( int c, char *buf_ptr ));
+#endif
+
 #ifndef yytext_ptr
-static void yy_flex_strncpy (char *,yyconst char *,int );
+static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int ));
 #endif
 
 #ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * );
+static int yy_flex_strlen YY_PROTO(( yyconst char * ));
 #endif
 
 #ifndef YY_NO_INPUT
-
 #ifdef __cplusplus
-static int yyinput (void );
+static int yyinput YY_PROTO(( void ));
+#else
+static int input YY_PROTO(( void ));
+#endif
+#endif
+
+#if YY_STACK_USED
+static int yy_start_stack_ptr = 0;
+static int yy_start_stack_depth = 0;
+static int *yy_start_stack = 0;
+#ifndef YY_NO_PUSH_STATE
+static void yy_push_state YY_PROTO(( int new_state ));
+#endif
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state YY_PROTO(( void ));
+#endif
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state YY_PROTO(( void ));
+#endif
+
 #else
-static int input (void );
+#define YY_NO_PUSH_STATE 1
+#define YY_NO_POP_STATE 1
+#define YY_NO_TOP_STATE 1
 #endif
 
+#ifdef YY_MALLOC_DECL
+YY_MALLOC_DECL
+#else
+#if __STDC__
+#ifndef __cplusplus
+#include <stdlib.h>
+#endif
+#else
+/* Just try to get by without declaring the routines.  This will fail
+ * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int)
+ * or sizeof(void*) != sizeof(int).
+ */
+#endif
 #endif
 
 /* Amount of stuff to slurp up with each read. */
@@ -589,6 +517,7 @@ static int input (void );
 #endif
 
 /* Copy whatever the last rule matched to the standard output. */
+
 #ifndef ECHO
 /* This used to be an fputs(), but since the string might contain NUL's,
  * we now use fwrite().
@@ -601,10 +530,9 @@ static int input (void );
  */
 #ifndef YY_INPUT
 #define YY_INPUT(buf,result,max_size) \
-       if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+       if ( yy_current_buffer->yy_is_interactive ) \
                { \
-               int c = '*'; \
-               size_t n; \
+               int c = '*', n; \
                for ( n = 0; n < max_size && \
                             (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
                        buf[n] = (char) c; \
@@ -614,22 +542,9 @@ static int input (void );
                        YY_FATAL_ERROR( "input in flex scanner failed" ); \
                result = n; \
                } \
-       else \
-               { \
-               errno=0; \
-               while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
-                       { \
-                       if( errno != EINTR) \
-                               { \
-                               YY_FATAL_ERROR( "input in flex scanner failed" ); \
-                               break; \
-                               } \
-                       errno=0; \
-                       clearerr(yyin); \
-                       } \
-               }\
-\
-
+       else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \
+                 && ferror( yyin ) ) \
+               YY_FATAL_ERROR( "input in flex scanner failed" );
 #endif
 
 /* No semi-colon after return; correct usage is to write "yyterminate();" -
@@ -650,18 +565,12 @@ static int input (void );
 #define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
 #endif
 
-/* end tables serialization structures and prototypes */
-
 /* Default declaration of generated scanner - a define so the user can
  * easily add parameters.
  */
 #ifndef YY_DECL
-#define YY_DECL_IS_OURS 1
-
-extern int yylex (void);
-
-#define YY_DECL int yylex (void)
-#endif /* !YY_DECL */
+#define YY_DECL int yylex YY_PROTO(( void ))
+#endif
 
 /* Code executed at the beginning of each rule, after yytext and yyleng
  * have been set up.
@@ -678,28 +587,26 @@ extern int yylex (void);
 #define YY_RULE_SETUP \
        YY_USER_ACTION
 
-/** The main scanner function which does all the work.
- */
 YY_DECL
-{
+       {
        register yy_state_type yy_current_state;
        register char *yy_cp, *yy_bp;
        register int yy_act;
-    
-#line 59 "lex.l"
 
-#line 691 "lex.yy.c"
+#line 59 "../../../lib/com_err/lex.l"
+
+#line 599 "lex.c"
 
-       if ( !(yy_init) )
+       if ( yy_init )
                {
-               (yy_init) = 1;
+               yy_init = 0;
 
 #ifdef YY_USER_INIT
                YY_USER_INIT;
 #endif
 
-               if ( ! (yy_start) )
-                       (yy_start) = 1; /* first start state */
+               if ( ! yy_start )
+                       yy_start = 1;   /* first start state */
 
                if ( ! yyin )
                        yyin = stdin;
@@ -707,36 +614,34 @@ YY_DECL
                if ( ! yyout )
                        yyout = stdout;
 
-               if ( ! YY_CURRENT_BUFFER ) {
-                       yyensure_buffer_stack ();
-                       YY_CURRENT_BUFFER_LVALUE =
-                               yy_create_buffer(yyin,YY_BUF_SIZE );
-               }
+               if ( ! yy_current_buffer )
+                       yy_current_buffer =
+                               yy_create_buffer( yyin, YY_BUF_SIZE );
 
-               yy_load_buffer_state( );
+               yy_load_buffer_state();
                }
 
        while ( 1 )             /* loops until end-of-file is reached */
                {
-               yy_cp = (yy_c_buf_p);
+               yy_cp = yy_c_buf_p;
 
                /* Support of yytext. */
-               *yy_cp = (yy_hold_char);
+               *yy_cp = yy_hold_char;
 
                /* yy_bp points to the position in yy_ch_buf of the start of
                 * the current run.
                 */
                yy_bp = yy_cp;
 
-               yy_current_state = (yy_start);
+               yy_current_state = yy_start;
 yy_match:
                do
                        {
                        register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
                        if ( yy_accept[yy_current_state] )
                                {
-                               (yy_last_accepting_state) = yy_current_state;
-                               (yy_last_accepting_cpos) = yy_cp;
+                               yy_last_accepting_state = yy_current_state;
+                               yy_last_accepting_cpos = yy_cp;
                                }
                        while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                                {
@@ -753,132 +658,133 @@ yy_find_action:
                yy_act = yy_accept[yy_current_state];
                if ( yy_act == 0 )
                        { /* have to back up */
-                       yy_cp = (yy_last_accepting_cpos);
-                       yy_current_state = (yy_last_accepting_state);
+                       yy_cp = yy_last_accepting_cpos;
+                       yy_current_state = yy_last_accepting_state;
                        yy_act = yy_accept[yy_current_state];
                        }
 
                YY_DO_BEFORE_ACTION;
 
+
 do_action:     /* This label is used only to access EOF actions. */
 
+
                switch ( yy_act )
        { /* beginning of action switch */
                        case 0: /* must back up */
                        /* undo the effects of YY_DO_BEFORE_ACTION */
-                       *yy_cp = (yy_hold_char);
-                       yy_cp = (yy_last_accepting_cpos);
-                       yy_current_state = (yy_last_accepting_state);
+                       *yy_cp = yy_hold_char;
+                       yy_cp = yy_last_accepting_cpos;
+                       yy_current_state = yy_last_accepting_state;
                        goto yy_find_action;
 
 case 1:
 YY_RULE_SETUP
-#line 60 "lex.l"
+#line 60 "../../../lib/com_err/lex.l"
 { return ET; }
        YY_BREAK
 case 2:
 YY_RULE_SETUP
-#line 61 "lex.l"
+#line 61 "../../../lib/com_err/lex.l"
 { return ET; }
        YY_BREAK
 case 3:
 YY_RULE_SETUP
-#line 62 "lex.l"
+#line 62 "../../../lib/com_err/lex.l"
 { return EC; }
        YY_BREAK
 case 4:
 YY_RULE_SETUP
-#line 63 "lex.l"
+#line 63 "../../../lib/com_err/lex.l"
 { return EC; }
        YY_BREAK
 case 5:
 YY_RULE_SETUP
-#line 64 "lex.l"
+#line 64 "../../../lib/com_err/lex.l"
 { return PREFIX; }
        YY_BREAK
 case 6:
 YY_RULE_SETUP
-#line 65 "lex.l"
+#line 65 "../../../lib/com_err/lex.l"
 { return INDEX; }
        YY_BREAK
 case 7:
 YY_RULE_SETUP
-#line 66 "lex.l"
+#line 66 "../../../lib/com_err/lex.l"
 { return ID; }
        YY_BREAK
 case 8:
 YY_RULE_SETUP
-#line 67 "lex.l"
+#line 67 "../../../lib/com_err/lex.l"
 { return END; }
        YY_BREAK
 case 9:
 YY_RULE_SETUP
-#line 68 "lex.l"
+#line 68 "../../../lib/com_err/lex.l"
 { yylval.number = atoi(yytext); return NUMBER; }
        YY_BREAK
 case 10:
 YY_RULE_SETUP
-#line 69 "lex.l"
+#line 69 "../../../lib/com_err/lex.l"
 ;
        YY_BREAK
 case 11:
 YY_RULE_SETUP
-#line 70 "lex.l"
+#line 70 "../../../lib/com_err/lex.l"
 ;
        YY_BREAK
 case 12:
-/* rule 12 can match eol */
 YY_RULE_SETUP
-#line 71 "lex.l"
+#line 71 "../../../lib/com_err/lex.l"
 { lineno++; }
        YY_BREAK
 case 13:
 YY_RULE_SETUP
-#line 72 "lex.l"
+#line 72 "../../../lib/com_err/lex.l"
 { return getstring(); }
        YY_BREAK
 case 14:
 YY_RULE_SETUP
-#line 73 "lex.l"
+#line 73 "../../../lib/com_err/lex.l"
 { yylval.string = strdup(yytext); return STRING; }
        YY_BREAK
 case 15:
 YY_RULE_SETUP
-#line 74 "lex.l"
+#line 74 "../../../lib/com_err/lex.l"
 { return *yytext; }
        YY_BREAK
 case 16:
 YY_RULE_SETUP
-#line 75 "lex.l"
+#line 75 "../../../lib/com_err/lex.l"
 ECHO;
        YY_BREAK
-#line 855 "lex.yy.c"
+#line 762 "lex.c"
 case YY_STATE_EOF(INITIAL):
        yyterminate();
 
        case YY_END_OF_BUFFER:
                {
                /* Amount of text matched not including the EOB char. */
-               int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
+               int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1;
 
                /* Undo the effects of YY_DO_BEFORE_ACTION. */
-               *yy_cp = (yy_hold_char);
+               *yy_cp = yy_hold_char;
                YY_RESTORE_YY_MORE_OFFSET
 
-               if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+               if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW )
                        {
                        /* We're scanning a new file or input source.  It's
                         * possible that this happened because the user
                         * just pointed yyin at a new source and called
                         * yylex().  If so, then we have to assure
-                        * consistency between YY_CURRENT_BUFFER and our
+                        * consistency between yy_current_buffer and our
                         * globals.  Here is the right place to do so, because
                         * this is the first action (other than possibly a
                         * back-up) that will match for the new input source.
                         */
-                       (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
-                       YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
-                       YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+                       yy_n_chars = yy_current_buffer->yy_n_chars;
+                       yy_current_buffer->yy_input_file = yyin;
+                       yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL;
                        }
 
                /* Note that here we test for yy_c_buf_p "<=" to the position
@@ -888,13 +794,13 @@ case YY_STATE_EOF(INITIAL):
                 * end-of-buffer state).  Contrast this with the test
                 * in input().
                 */
-               if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+               if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] )
                        { /* This was really a NUL. */
                        yy_state_type yy_next_state;
 
-                       (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
+                       yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text;
 
-                       yy_current_state = yy_get_previous_state(  );
+                       yy_current_state = yy_get_previous_state();
 
                        /* Okay, we're now positioned to make the NUL
                         * transition.  We couldn't have
@@ -907,30 +813,30 @@ case YY_STATE_EOF(INITIAL):
 
                        yy_next_state = yy_try_NUL_trans( yy_current_state );
 
-                       yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+                       yy_bp = yytext_ptr + YY_MORE_ADJ;
 
                        if ( yy_next_state )
                                {
                                /* Consume the NUL. */
-                               yy_cp = ++(yy_c_buf_p);
+                               yy_cp = ++yy_c_buf_p;
                                yy_current_state = yy_next_state;
                                goto yy_match;
                                }
 
                        else
                                {
-                               yy_cp = (yy_c_buf_p);
+                               yy_cp = yy_c_buf_p;
                                goto yy_find_action;
                                }
                        }
 
-               else switch ( yy_get_next_buffer(  ) )
+               else switch ( yy_get_next_buffer() )
                        {
                        case EOB_ACT_END_OF_FILE:
                                {
-                               (yy_did_buffer_switch_on_eof) = 0;
+                               yy_did_buffer_switch_on_eof = 0;
 
-                               if ( yywrap( ) )
+                               if ( yywrap() )
                                        {
                                        /* Note: because we've taken care in
                                         * yy_get_next_buffer() to have set up
@@ -941,7 +847,7 @@ case YY_STATE_EOF(INITIAL):
                                         * YY_NULL, it'll still work - another
                                         * YY_NULL will get returned.
                                         */
-                                       (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
+                                       yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;
 
                                        yy_act = YY_STATE_EOF(YY_START);
                                        goto do_action;
@@ -949,30 +855,30 @@ case YY_STATE_EOF(INITIAL):
 
                                else
                                        {
-                                       if ( ! (yy_did_buffer_switch_on_eof) )
+                                       if ( ! yy_did_buffer_switch_on_eof )
                                                YY_NEW_FILE;
                                        }
                                break;
                                }
 
                        case EOB_ACT_CONTINUE_SCAN:
-                               (yy_c_buf_p) =
-                                       (yytext_ptr) + yy_amount_of_matched_text;
+                               yy_c_buf_p =
+                                       yytext_ptr + yy_amount_of_matched_text;
 
-                               yy_current_state = yy_get_previous_state(  );
+                               yy_current_state = yy_get_previous_state();
 
-                               yy_cp = (yy_c_buf_p);
-                               yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+                               yy_cp = yy_c_buf_p;
+                               yy_bp = yytext_ptr + YY_MORE_ADJ;
                                goto yy_match;
 
                        case EOB_ACT_LAST_MATCH:
-                               (yy_c_buf_p) =
-                               &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
+                               yy_c_buf_p =
+                               &yy_current_buffer->yy_ch_buf[yy_n_chars];
 
-                               yy_current_state = yy_get_previous_state(  );
+                               yy_current_state = yy_get_previous_state();
 
-                               yy_cp = (yy_c_buf_p);
-                               yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+                               yy_cp = yy_c_buf_p;
+                               yy_bp = yytext_ptr + YY_MORE_ADJ;
                                goto yy_find_action;
                        }
                break;
@@ -983,7 +889,8 @@ case YY_STATE_EOF(INITIAL):
                        "fatal flex scanner internal error--no action found" );
        } /* end of action switch */
                } /* end of scanning one token */
-} /* end of yylex */
+       } /* end of yylex */
+
 
 /* yy_get_next_buffer - try to read in a new buffer
  *
@@ -992,20 +899,21 @@ case YY_STATE_EOF(INITIAL):
  *     EOB_ACT_CONTINUE_SCAN - continue scanning from current position
  *     EOB_ACT_END_OF_FILE - end of file
  */
-static int yy_get_next_buffer (void)
-{
-       register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
-       register char *source = (yytext_ptr);
+
+static int yy_get_next_buffer()
+       {
+       register char *dest = yy_current_buffer->yy_ch_buf;
+       register char *source = yytext_ptr;
        register int number_to_move, i;
        int ret_val;
 
-       if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
+       if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] )
                YY_FATAL_ERROR(
                "fatal flex scanner internal error--end of buffer missed" );
 
-       if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+       if ( yy_current_buffer->yy_fill_buffer == 0 )
                { /* Don't try to fill the buffer, so this is an EOF. */
-               if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
+               if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 )
                        {
                        /* We matched a single character, the EOB, so
                         * treat this as a final EOF.
@@ -1025,30 +933,34 @@ static int yy_get_next_buffer (void)
        /* Try to read more data. */
 
        /* First move last chars to start of buffer. */
-       number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
+       number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1;
 
        for ( i = 0; i < number_to_move; ++i )
                *(dest++) = *(source++);
 
-       if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+       if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING )
                /* don't do the read, it's not guaranteed to return an EOF,
                 * just force an EOF
                 */
-               YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
+               yy_current_buffer->yy_n_chars = yy_n_chars = 0;
 
        else
                {
-                       int num_to_read =
-                       YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+               int num_to_read =
+                       yy_current_buffer->yy_buf_size - number_to_move - 1;
 
                while ( num_to_read <= 0 )
                        { /* Not enough room in the buffer - grow it. */
+#ifdef YY_USES_REJECT
+                       YY_FATAL_ERROR(
+"input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
+#else
 
                        /* just a shorter name for the current buffer */
-                       YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
+                       YY_BUFFER_STATE b = yy_current_buffer;
 
                        int yy_c_buf_p_offset =
-                               (int) ((yy_c_buf_p) - b->yy_ch_buf);
+                               (int) (yy_c_buf_p - b->yy_ch_buf);
 
                        if ( b->yy_is_our_buffer )
                                {
@@ -1061,7 +973,8 @@ static int yy_get_next_buffer (void)
 
                                b->yy_ch_buf = (char *)
                                        /* Include room in for 2 EOB chars. */
-                                       yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2  );
+                                       yy_flex_realloc( (void *) b->yy_ch_buf,
+                                                        b->yy_buf_size + 2 );
                                }
                        else
                                /* Can't grow it, we don't own it. */
@@ -1071,35 +984,35 @@ static int yy_get_next_buffer (void)
                                YY_FATAL_ERROR(
                                "fatal error - scanner input buffer overflow" );
 
-                       (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
+                       yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
 
-                       num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+                       num_to_read = yy_current_buffer->yy_buf_size -
                                                number_to_move - 1;
-
+#endif
                        }
 
                if ( num_to_read > YY_READ_BUF_SIZE )
                        num_to_read = YY_READ_BUF_SIZE;
 
                /* Read in more data. */
-               YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
-                       (yy_n_chars), (size_t) num_to_read );
+               YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]),
+                       yy_n_chars, num_to_read );
 
-               YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+               yy_current_buffer->yy_n_chars = yy_n_chars;
                }
 
-       if ( (yy_n_chars) == 0 )
+       if ( yy_n_chars == 0 )
                {
                if ( number_to_move == YY_MORE_ADJ )
                        {
                        ret_val = EOB_ACT_END_OF_FILE;
-                       yyrestart(yyin  );
+                       yyrestart( yyin );
                        }
 
                else
                        {
                        ret_val = EOB_ACT_LAST_MATCH;
-                       YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+                       yy_current_buffer->yy_buffer_status =
                                YY_BUFFER_EOF_PENDING;
                        }
                }
@@ -1107,31 +1020,32 @@ static int yy_get_next_buffer (void)
        else
                ret_val = EOB_ACT_CONTINUE_SCAN;
 
-       (yy_n_chars) += number_to_move;
-       YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
-       YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
+       yy_n_chars += number_to_move;
+       yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+       yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
 
-       (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+       yytext_ptr = &yy_current_buffer->yy_ch_buf[0];
 
        return ret_val;
-}
+       }
+
 
 /* yy_get_previous_state - get the state just before the EOB char was reached */
 
-    static yy_state_type yy_get_previous_state (void)
-{
+static yy_state_type yy_get_previous_state()
+       {
        register yy_state_type yy_current_state;
        register char *yy_cp;
-    
-       yy_current_state = (yy_start);
 
-       for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
+       yy_current_state = yy_start;
+
+       for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp )
                {
                register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
                if ( yy_accept[yy_current_state] )
                        {
-                       (yy_last_accepting_state) = yy_current_state;
-                       (yy_last_accepting_cpos) = yy_cp;
+                       yy_last_accepting_state = yy_current_state;
+                       yy_last_accepting_cpos = yy_cp;
                        }
                while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                        {
@@ -1143,23 +1057,30 @@ static int yy_get_next_buffer (void)
                }
 
        return yy_current_state;
-}
+       }
+
 
 /* yy_try_NUL_trans - try to make a transition on the NUL character
  *
  * synopsis
  *     next_state = yy_try_NUL_trans( current_state );
  */
-    static yy_state_type yy_try_NUL_trans  (yy_state_type yy_current_state )
-{
+
+#ifdef YY_USE_PROTOS
+static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state )
+#else
+static yy_state_type yy_try_NUL_trans( yy_current_state )
+yy_state_type yy_current_state;
+#endif
+       {
        register int yy_is_jam;
-       register char *yy_cp = (yy_c_buf_p);
+       register char *yy_cp = yy_c_buf_p;
 
        register YY_CHAR yy_c = 1;
        if ( yy_accept[yy_current_state] )
                {
-               (yy_last_accepting_state) = yy_current_state;
-               (yy_last_accepting_cpos) = yy_cp;
+               yy_last_accepting_state = yy_current_state;
+               yy_last_accepting_cpos = yy_cp;
                }
        while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                {
@@ -1171,73 +1092,80 @@ static int yy_get_next_buffer (void)
        yy_is_jam = (yy_current_state == 45);
 
        return yy_is_jam ? 0 : yy_current_state;
-}
+       }
 
-    static void yyunput (int c, register char * yy_bp )
-{
-       register char *yy_cp;
-    
-    yy_cp = (yy_c_buf_p);
+
+#ifndef YY_NO_UNPUT
+#ifdef YY_USE_PROTOS
+static void yyunput( int c, register char *yy_bp )
+#else
+static void yyunput( c, yy_bp )
+int c;
+register char *yy_bp;
+#endif
+       {
+       register char *yy_cp = yy_c_buf_p;
 
        /* undo effects of setting up yytext */
-       *yy_cp = (yy_hold_char);
+       *yy_cp = yy_hold_char;
 
-       if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+       if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
                { /* need to shift things up to make room */
                /* +2 for EOB chars. */
-               register int number_to_move = (yy_n_chars) + 2;
-               register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
-                                       YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
+               register int number_to_move = yy_n_chars + 2;
+               register char *dest = &yy_current_buffer->yy_ch_buf[
+                                       yy_current_buffer->yy_buf_size + 2];
                register char *source =
-                               &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
+                               &yy_current_buffer->yy_ch_buf[number_to_move];
 
-               while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+               while ( source > yy_current_buffer->yy_ch_buf )
                        *--dest = *--source;
 
                yy_cp += (int) (dest - source);
                yy_bp += (int) (dest - source);
-               YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
-                       (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
+               yy_current_buffer->yy_n_chars =
+                       yy_n_chars = yy_current_buffer->yy_buf_size;
 
-               if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+               if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
                        YY_FATAL_ERROR( "flex scanner push-back overflow" );
                }
 
        *--yy_cp = (char) c;
 
-       (yytext_ptr) = yy_bp;
-       (yy_hold_char) = *yy_cp;
-       (yy_c_buf_p) = yy_cp;
-}
 
-#ifndef YY_NO_INPUT
+       yytext_ptr = yy_bp;
+       yy_hold_char = *yy_cp;
+       yy_c_buf_p = yy_cp;
+       }
+#endif /* ifndef YY_NO_UNPUT */
+
+
 #ifdef __cplusplus
-    static int yyinput (void)
+static int yyinput()
 #else
-    static int input  (void)
+static int input()
 #endif
-
-{
+       {
        int c;
-    
-       *(yy_c_buf_p) = (yy_hold_char);
 
-       if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
+       *yy_c_buf_p = yy_hold_char;
+
+       if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
                {
                /* yy_c_buf_p now points to the character we want to return.
                 * If this occurs *before* the EOB characters, then it's a
                 * valid NUL; if not, then we've hit the end of the buffer.
                 */
-               if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+               if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] )
                        /* This was really a NUL. */
-                       *(yy_c_buf_p) = '\0';
+                       *yy_c_buf_p = '\0';
 
                else
                        { /* need more input */
-                       int offset = (yy_c_buf_p) - (yytext_ptr);
-                       ++(yy_c_buf_p);
+                       int offset = yy_c_buf_p - yytext_ptr;
+                       ++yy_c_buf_p;
 
-                       switch ( yy_get_next_buffer(  ) )
+                       switch ( yy_get_next_buffer() )
                                {
                                case EOB_ACT_LAST_MATCH:
                                        /* This happens because yy_g_n_b()
@@ -1251,16 +1179,16 @@ static int yy_get_next_buffer (void)
                                         */
 
                                        /* Reset buffer status. */
-                                       yyrestart(yyin );
+                                       yyrestart( yyin );
 
-                                       /*FALLTHROUGH*/
+                                       /* fall through */
 
                                case EOB_ACT_END_OF_FILE:
                                        {
-                                       if ( yywrap( ) )
+                                       if ( yywrap() )
                                                return EOF;
 
-                                       if ( ! (yy_did_buffer_switch_on_eof) )
+                                       if ( ! yy_did_buffer_switch_on_eof )
                                                YY_NEW_FILE;
 #ifdef __cplusplus
                                        return yyinput();
@@ -1270,92 +1198,90 @@ static int yy_get_next_buffer (void)
                                        }
 
                                case EOB_ACT_CONTINUE_SCAN:
-                                       (yy_c_buf_p) = (yytext_ptr) + offset;
+                                       yy_c_buf_p = yytext_ptr + offset;
                                        break;
                                }
                        }
                }
 
-       c = *(unsigned char *) (yy_c_buf_p);    /* cast for 8-bit char's */
-       *(yy_c_buf_p) = '\0';   /* preserve yytext */
-       (yy_hold_char) = *++(yy_c_buf_p);
+       c = *(unsigned char *) yy_c_buf_p;      /* cast for 8-bit char's */
+       *yy_c_buf_p = '\0';     /* preserve yytext */
+       yy_hold_char = *++yy_c_buf_p;
+
 
        return c;
-}
-#endif /* ifndef YY_NO_INPUT */
+       }
 
-/** Immediately switch to a different input stream.
- * @param input_file A readable stream.
- * 
- * @note This function does not reset the start condition to @c INITIAL .
- */
-    void yyrestart  (FILE * input_file )
-{
-    
-       if ( ! YY_CURRENT_BUFFER ){
-        yyensure_buffer_stack ();
-               YY_CURRENT_BUFFER_LVALUE =
-            yy_create_buffer(yyin,YY_BUF_SIZE );
+
+#ifdef YY_USE_PROTOS
+void yyrestart( FILE *input_file )
+#else
+void yyrestart( input_file )
+FILE *input_file;
+#endif
+       {
+       if ( ! yy_current_buffer )
+               yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE );
+
+       yy_init_buffer( yy_current_buffer, input_file );
+       yy_load_buffer_state();
        }
 
-       yy_init_buffer(YY_CURRENT_BUFFER,input_file );
-       yy_load_buffer_state( );
-}
 
-/** Switch to a different input buffer.
- * @param new_buffer The new input buffer.
- * 
- */
-    void yy_switch_to_buffer  (YY_BUFFER_STATE  new_buffer )
-{
-    
-       /* TODO. We should be able to replace this entire function body
-        * with
-        *              yypop_buffer_state();
-        *              yypush_buffer_state(new_buffer);
-     */
-       yyensure_buffer_stack ();
-       if ( YY_CURRENT_BUFFER == new_buffer )
+#ifdef YY_USE_PROTOS
+void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
+#else
+void yy_switch_to_buffer( new_buffer )
+YY_BUFFER_STATE new_buffer;
+#endif
+       {
+       if ( yy_current_buffer == new_buffer )
                return;
 
-       if ( YY_CURRENT_BUFFER )
+       if ( yy_current_buffer )
                {
                /* Flush out information for old buffer. */
-               *(yy_c_buf_p) = (yy_hold_char);
-               YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
-               YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+               *yy_c_buf_p = yy_hold_char;
+               yy_current_buffer->yy_buf_pos = yy_c_buf_p;
+               yy_current_buffer->yy_n_chars = yy_n_chars;
                }
 
-       YY_CURRENT_BUFFER_LVALUE = new_buffer;
-       yy_load_buffer_state( );
+       yy_current_buffer = new_buffer;
+       yy_load_buffer_state();
 
        /* We don't actually know whether we did this switch during
         * EOF (yywrap()) processing, but the only time this flag
         * is looked at is after yywrap() is called, so it's safe
         * to go ahead and always set it.
         */
-       (yy_did_buffer_switch_on_eof) = 1;
-}
+       yy_did_buffer_switch_on_eof = 1;
+       }
 
-static void yy_load_buffer_state  (void)
-{
-       (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
-       (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
-       yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
-       (yy_hold_char) = *(yy_c_buf_p);
-}
 
-/** Allocate and initialize an input buffer state.
- * @param file A readable stream.
- * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
- * 
- * @return the allocated buffer state.
- */
-    YY_BUFFER_STATE yy_create_buffer  (FILE * file, int  size )
-{
+#ifdef YY_USE_PROTOS
+void yy_load_buffer_state( void )
+#else
+void yy_load_buffer_state()
+#endif
+       {
+       yy_n_chars = yy_current_buffer->yy_n_chars;
+       yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos;
+       yyin = yy_current_buffer->yy_input_file;
+       yy_hold_char = *yy_c_buf_p;
+       }
+
+
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_create_buffer( FILE *file, int size )
+#else
+YY_BUFFER_STATE yy_create_buffer( file, size )
+FILE *file;
+int size;
+#endif
+       {
        YY_BUFFER_STATE b;
-    
-       b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state )  );
+
+       b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
        if ( ! b )
                YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
 
@@ -1364,75 +1290,80 @@ static void yy_load_buffer_state  (void)
        /* yy_ch_buf has to be 2 characters longer than the size given because
         * we need to put in 2 end-of-buffer characters.
         */
-       b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2  );
+       b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 );
        if ( ! b->yy_ch_buf )
                YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
 
        b->yy_is_our_buffer = 1;
 
-       yy_init_buffer(b,file );
+       yy_init_buffer( b, file );
 
        return b;
-}
+       }
 
-/** Destroy the buffer.
- * @param b a buffer created with yy_create_buffer()
- * 
- */
-    void yy_delete_buffer (YY_BUFFER_STATE  b )
-{
-    
+
+#ifdef YY_USE_PROTOS
+void yy_delete_buffer( YY_BUFFER_STATE b )
+#else
+void yy_delete_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+       {
        if ( ! b )
                return;
 
-       if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
-               YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+       if ( b == yy_current_buffer )
+               yy_current_buffer = (YY_BUFFER_STATE) 0;
 
        if ( b->yy_is_our_buffer )
-               yyfree((void *) b->yy_ch_buf  );
+               yy_flex_free( (void *) b->yy_ch_buf );
 
-       yyfree((void *) b  );
-}
+       yy_flex_free( (void *) b );
+       }
 
-#ifndef __cplusplus
-extern int isatty (int );
-#endif /* __cplusplus */
-    
-/* Initializes or reinitializes a buffer.
- * This function is sometimes called more than once on the same buffer,
- * such as during a yyrestart() or at EOF.
- */
-    static void yy_init_buffer  (YY_BUFFER_STATE  b, FILE * file )
 
-{
-       int oerrno = errno;
-    
-       yy_flush_buffer(b );
+#ifndef YY_ALWAYS_INTERACTIVE
+#ifndef YY_NEVER_INTERACTIVE
+extern int isatty YY_PROTO(( int ));
+#endif
+#endif
+
+#ifdef YY_USE_PROTOS
+void yy_init_buffer( YY_BUFFER_STATE b, FILE *file )
+#else
+void yy_init_buffer( b, file )
+YY_BUFFER_STATE b;
+FILE *file;
+#endif
+
+
+       {
+       yy_flush_buffer( b );
 
        b->yy_input_file = file;
        b->yy_fill_buffer = 1;
 
-    /* If b is the current buffer, then yy_init_buffer was _probably_
-     * called from yyrestart() or through yy_get_next_buffer.
-     * In that case, we don't want to reset the lineno or column.
-     */
-    if (b != YY_CURRENT_BUFFER){
-        b->yy_bs_lineno = 1;
-        b->yy_bs_column = 0;
-    }
+#if YY_ALWAYS_INTERACTIVE
+       b->yy_is_interactive = 1;
+#else
+#if YY_NEVER_INTERACTIVE
+       b->yy_is_interactive = 0;
+#else
+       b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+#endif
+#endif
+       }
 
-        b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
-    
-       errno = oerrno;
-}
 
-/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
- * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
- * 
- */
-    void yy_flush_buffer (YY_BUFFER_STATE  b )
-{
-       if ( ! b )
+#ifdef YY_USE_PROTOS
+void yy_flush_buffer( YY_BUFFER_STATE b )
+#else
+void yy_flush_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+
+       {
+       if ( ! b )
                return;
 
        b->yy_n_chars = 0;
@@ -1449,121 +1380,29 @@ extern int isatty (int );
        b->yy_at_bol = 1;
        b->yy_buffer_status = YY_BUFFER_NEW;
 
-       if ( b == YY_CURRENT_BUFFER )
-               yy_load_buffer_state( );
-}
-
-/** Pushes the new state onto the stack. The new state becomes
- *  the current state. This function will allocate the stack
- *  if necessary.
- *  @param new_buffer The new state.
- *  
- */
-void yypush_buffer_state (YY_BUFFER_STATE new_buffer )
-{
-       if (new_buffer == NULL)
-               return;
-
-       yyensure_buffer_stack();
-
-       /* This block is copied from yy_switch_to_buffer. */
-       if ( YY_CURRENT_BUFFER )
-               {
-               /* Flush out information for old buffer. */
-               *(yy_c_buf_p) = (yy_hold_char);
-               YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
-               YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
-               }
-
-       /* Only push if top exists. Otherwise, replace top. */
-       if (YY_CURRENT_BUFFER)
-               (yy_buffer_stack_top)++;
-       YY_CURRENT_BUFFER_LVALUE = new_buffer;
-
-       /* copied from yy_switch_to_buffer. */
-       yy_load_buffer_state( );
-       (yy_did_buffer_switch_on_eof) = 1;
-}
-
-/** Removes and deletes the top of the stack, if present.
- *  The next element becomes the new top.
- *  
- */
-void yypop_buffer_state (void)
-{
-       if (!YY_CURRENT_BUFFER)
-               return;
-
-       yy_delete_buffer(YY_CURRENT_BUFFER );
-       YY_CURRENT_BUFFER_LVALUE = NULL;
-       if ((yy_buffer_stack_top) > 0)
-               --(yy_buffer_stack_top);
-
-       if (YY_CURRENT_BUFFER) {
-               yy_load_buffer_state( );
-               (yy_did_buffer_switch_on_eof) = 1;
-       }
-}
-
-/* Allocates the stack if it does not exist.
- *  Guarantees space for at least one push.
- */
-static void yyensure_buffer_stack (void)
-{
-       int num_to_alloc;
-    
-       if (!(yy_buffer_stack)) {
-
-               /* First allocation is just for 2 elements, since we don't know if this
-                * scanner will even need a stack. We use 2 instead of 1 to avoid an
-                * immediate realloc on the next call.
-         */
-               num_to_alloc = 1;
-               (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
-                                                               (num_to_alloc * sizeof(struct yy_buffer_state*)
-                                                               );
-               
-               memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
-                               
-               (yy_buffer_stack_max) = num_to_alloc;
-               (yy_buffer_stack_top) = 0;
-               return;
+       if ( b == yy_current_buffer )
+               yy_load_buffer_state();
        }
 
-       if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
 
-               /* Increase the buffer to prepare for a possible push. */
-               int grow_size = 8 /* arbitrary grow size */;
-
-               num_to_alloc = (yy_buffer_stack_max) + grow_size;
-               (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc
-                                                               ((yy_buffer_stack),
-                                                               num_to_alloc * sizeof(struct yy_buffer_state*)
-                                                               );
-
-               /* zero only the new slots.*/
-               memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
-               (yy_buffer_stack_max) = num_to_alloc;
-       }
-}
-
-/** Setup the input buffer state to scan directly from a user-specified character buffer.
- * @param base the character buffer
- * @param size the size in bytes of the character buffer
- * 
- * @return the newly allocated buffer state object. 
- */
-YY_BUFFER_STATE yy_scan_buffer  (char * base, yy_size_t  size )
-{
+#ifndef YY_NO_SCAN_BUFFER
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size )
+#else
+YY_BUFFER_STATE yy_scan_buffer( base, size )
+char *base;
+yy_size_t size;
+#endif
+       {
        YY_BUFFER_STATE b;
-    
+
        if ( size < 2 ||
             base[size-2] != YY_END_OF_BUFFER_CHAR ||
             base[size-1] != YY_END_OF_BUFFER_CHAR )
                /* They forgot to leave room for the EOB's. */
                return 0;
 
-       b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state )  );
+       b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
        if ( ! b )
                YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
 
@@ -1577,51 +1416,56 @@ YY_BUFFER_STATE yy_scan_buffer  (char * base, yy_size_t  size )
        b->yy_fill_buffer = 0;
        b->yy_buffer_status = YY_BUFFER_NEW;
 
-       yy_switch_to_buffer( );
+       yy_switch_to_buffer( b );
 
        return b;
-}
+       }
+#endif
 
-/** Setup the input buffer state to scan a string. The next call to yylex() will
- * scan from a @e copy of @a str.
- * @param yystr a NUL-terminated string to scan
- * 
- * @return the newly allocated buffer state object.
- * @note If you want to scan bytes that may contain NUL values, then use
- *       yy_scan_bytes() instead.
- */
-YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
-{
-    
-       return yy_scan_bytes(yystr,strlen(yystr) );
-}
 
-/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
- * scan from a @e copy of @a bytes.
- * @param bytes the byte buffer to scan
- * @param len the number of bytes in the buffer pointed to by @a bytes.
- * 
- * @return the newly allocated buffer state object.
- */
-YY_BUFFER_STATE yy_scan_bytes  (yyconst char * yybytes, int  _yybytes_len )
-{
+#ifndef YY_NO_SCAN_STRING
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str )
+#else
+YY_BUFFER_STATE yy_scan_string( yy_str )
+yyconst char *yy_str;
+#endif
+       {
+       int len;
+       for ( len = 0; yy_str[len]; ++len )
+               ;
+
+       return yy_scan_bytes( yy_str, len );
+       }
+#endif
+
+
+#ifndef YY_NO_SCAN_BYTES
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len )
+#else
+YY_BUFFER_STATE yy_scan_bytes( bytes, len )
+yyconst char *bytes;
+int len;
+#endif
+       {
        YY_BUFFER_STATE b;
        char *buf;
        yy_size_t n;
        int i;
-    
+
        /* Get memory for full buffer, including space for trailing EOB's. */
-       n = _yybytes_len + 2;
-       buf = (char *) yyalloc(n  );
+       n = len + 2;
+       buf = (char *) yy_flex_alloc( n );
        if ( ! buf )
                YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
 
-       for ( i = 0; i < _yybytes_len; ++i )
-               buf[i] = yybytes[i];
+       for ( i = 0; i < len; ++i )
+               buf[i] = bytes[i];
 
-       buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+       buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
 
-       b = yy_scan_buffer(buf,n );
+       b = yy_scan_buffer( buf, n );
        if ( ! b )
                YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
 
@@ -1631,196 +1475,148 @@ YY_BUFFER_STATE yy_scan_bytes  (yyconst char * yybytes, int  _yybytes_len )
        b->yy_is_our_buffer = 1;
 
        return b;
-}
-
-#ifndef YY_EXIT_FAILURE
-#define YY_EXIT_FAILURE 2
+       }
 #endif
 
-static void yy_fatal_error (yyconst char* msg )
-{
-       (void) fprintf( stderr, "%s\n", msg );
-       exit( YY_EXIT_FAILURE );
-}
-
-/* Redefine yyless() so it works in section 3 code. */
 
-#undef yyless
-#define yyless(n) \
-       do \
-               { \
-               /* Undo effects of setting up yytext. */ \
-        int yyless_macro_arg = (n); \
-        YY_LESS_LINENO(yyless_macro_arg);\
-               yytext[yyleng] = (yy_hold_char); \
-               (yy_c_buf_p) = yytext + yyless_macro_arg; \
-               (yy_hold_char) = *(yy_c_buf_p); \
-               *(yy_c_buf_p) = '\0'; \
-               yyleng = yyless_macro_arg; \
-               } \
-       while ( 0 )
+#ifndef YY_NO_PUSH_STATE
+#ifdef YY_USE_PROTOS
+static void yy_push_state( int new_state )
+#else
+static void yy_push_state( new_state )
+int new_state;
+#endif
+       {
+       if ( yy_start_stack_ptr >= yy_start_stack_depth )
+               {
+               yy_size_t new_size;
 
-/* Accessor  methods (get/set functions) to struct members. */
+               yy_start_stack_depth += YY_START_STACK_INCR;
+               new_size = yy_start_stack_depth * sizeof( int );
 
-/** Get the current line number.
- * 
- */
-int yyget_lineno  (void)
-{
-        
-    return yylineno;
-}
+               if ( ! yy_start_stack )
+                       yy_start_stack = (int *) yy_flex_alloc( new_size );
 
-/** Get the input stream.
- * 
- */
-FILE *yyget_in  (void)
-{
-        return yyin;
-}
+               else
+                       yy_start_stack = (int *) yy_flex_realloc(
+                                       (void *) yy_start_stack, new_size );
 
-/** Get the output stream.
- * 
- */
-FILE *yyget_out  (void)
-{
-        return yyout;
-}
+               if ( ! yy_start_stack )
+                       YY_FATAL_ERROR(
+                       "out of memory expanding start-condition stack" );
+               }
 
-/** Get the length of the current token.
- * 
- */
-int yyget_leng  (void)
-{
-        return yyleng;
-}
+       yy_start_stack[yy_start_stack_ptr++] = YY_START;
 
-/** Get the current token.
- * 
- */
+       BEGIN(new_state);
+       }
+#endif
 
-char *yyget_text  (void)
-{
-        return yytext;
-}
 
-/** Set the current line number.
- * @param line_number
- * 
- */
-void yyset_lineno (int  line_number )
-{
-    
-    yylineno = line_number;
-}
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state()
+       {
+       if ( --yy_start_stack_ptr < 0 )
+               YY_FATAL_ERROR( "start-condition stack underflow" );
 
-/** Set the input stream. This does not discard the current
- * input buffer.
- * @param in_str A readable stream.
- * 
- * @see yy_switch_to_buffer
- */
-void yyset_in (FILE *  in_str )
-{
-        yyin = in_str ;
-}
+       BEGIN(yy_start_stack[yy_start_stack_ptr]);
+       }
+#endif
 
-void yyset_out (FILE *  out_str )
-{
-        yyout = out_str ;
-}
 
-int yyget_debug  (void)
-{
-        return yy_flex_debug;
-}
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state()
+       {
+       return yy_start_stack[yy_start_stack_ptr - 1];
+       }
+#endif
 
-void yyset_debug (int  bdebug )
-{
-        yy_flex_debug = bdebug ;
-}
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
 
-static int yy_init_globals (void)
-{
-        /* Initialization is the same as for the non-reentrant scanner.
-     * This function is called from yylex_destroy(), so don't allocate here.
-     */
-
-    (yy_buffer_stack) = 0;
-    (yy_buffer_stack_top) = 0;
-    (yy_buffer_stack_max) = 0;
-    (yy_c_buf_p) = (char *) 0;
-    (yy_init) = 0;
-    (yy_start) = 0;
-
-/* Defined in main.c */
-#ifdef YY_STDINIT
-    yyin = stdin;
-    yyout = stdout;
+#ifdef YY_USE_PROTOS
+static void yy_fatal_error( yyconst char msg[] )
 #else
-    yyin = (FILE *) 0;
-    yyout = (FILE *) 0;
+static void yy_fatal_error( msg )
+char msg[];
 #endif
+       {
+       (void) fprintf( stderr, "%s\n", msg );
+       exit( YY_EXIT_FAILURE );
+       }
 
-    /* For future reference: Set errno on error, since we are called by
-     * yylex_init()
-     */
-    return 0;
-}
 
-/* yylex_destroy is for both reentrant and non-reentrant scanners. */
-int yylex_destroy  (void)
-{
-    
-    /* Pop the buffer stack, destroying each element. */
-       while(YY_CURRENT_BUFFER){
-               yy_delete_buffer(YY_CURRENT_BUFFER  );
-               YY_CURRENT_BUFFER_LVALUE = NULL;
-               yypop_buffer_state();
-       }
 
-       /* Destroy the stack itself. */
-       yyfree((yy_buffer_stack) );
-       (yy_buffer_stack) = NULL;
+/* Redefine yyless() so it works in section 3 code. */
 
-    /* Reset the globals. This is important in a non-reentrant scanner so the next time
-     * yylex() is called, initialization will occur. */
-    yy_init_globals( );
+#undef yyless
+#define yyless(n) \
+       do \
+               { \
+               /* Undo effects of setting up yytext. */ \
+               yytext[yyleng] = yy_hold_char; \
+               yy_c_buf_p = yytext + n; \
+               yy_hold_char = *yy_c_buf_p; \
+               *yy_c_buf_p = '\0'; \
+               yyleng = n; \
+               } \
+       while ( 0 )
 
-    return 0;
-}
 
-/*
- * Internal utility routines.
- */
+/* Internal utility routines. */
 
 #ifndef yytext_ptr
-static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
-{
+#ifdef YY_USE_PROTOS
+static void yy_flex_strncpy( char *s1, yyconst char *s2, int n )
+#else
+static void yy_flex_strncpy( s1, s2, n )
+char *s1;
+yyconst char *s2;
+int n;
+#endif
+       {
        register int i;
        for ( i = 0; i < n; ++i )
                s1[i] = s2[i];
-}
+       }
 #endif
 
 #ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * s )
-{
+#ifdef YY_USE_PROTOS
+static int yy_flex_strlen( yyconst char *s )
+#else
+static int yy_flex_strlen( s )
+yyconst char *s;
+#endif
+       {
        register int n;
        for ( n = 0; s[n]; ++n )
                ;
 
        return n;
-}
+       }
 #endif
 
-void *yyalloc (yy_size_t  size )
-{
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_alloc( yy_size_t size )
+#else
+static void *yy_flex_alloc( size )
+yy_size_t size;
+#endif
+       {
        return (void *) malloc( size );
-}
+       }
 
-void *yyrealloc  (void * ptr, yy_size_t  size )
-{
+#ifdef YY_USE_PROTOS
+static void *yy_flex_realloc( void *ptr, yy_size_t size )
+#else
+static void *yy_flex_realloc( ptr, size )
+void *ptr;
+yy_size_t size;
+#endif
+       {
        /* The cast to (char *) in the following accommodates both
         * implementations that use char* generic pointers, and those
         * that use void* generic pointers.  It works with the latter
@@ -1829,17 +1625,26 @@ void *yyrealloc  (void * ptr, yy_size_t  size )
         * as though doing an assignment.
         */
        return (void *) realloc( (char *) ptr, size );
-}
-
-void yyfree (void * ptr )
-{
-       free( (char *) ptr );   /* see yyrealloc() for (char *) cast */
-}
-
-#define YYTABLES_NAME "yytables"
+       }
 
-#line 75 "lex.l"
+#ifdef YY_USE_PROTOS
+static void yy_flex_free( void *ptr )
+#else
+static void yy_flex_free( ptr )
+void *ptr;
+#endif
+       {
+       free( ptr );
+       }
 
+#if YY_MAIN
+int main()
+       {
+       yylex();
+       return 0;
+       }
+#endif
+#line 75 "../../../lib/com_err/lex.l"
 
 
 #ifndef yywrap /* XXX */
@@ -1894,4 +1699,3 @@ error_message (const char *format, ...)
      va_end (args);
      numerror++;
 }
-
index e55dafa41efe0612084ebd54f9eb85cbc4302572..a7160a4d42fe5a4ec6c6504866c7e973fcf2aba4 100644 (file)
@@ -1,82 +1,19 @@
-/* A Bison parser, made by GNU Bison 2.0.  */
-
-/* Skeleton parser for Yacc-like parsing with Bison,
-   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2, or (at your option)
-   any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
-
-/* As a special exception, when this file is copied by Bison into a
-   Bison output file, you may use that output file without restriction.
-   This special exception was added by the Free Software Foundation
-   in version 1.24 of Bison.  */
-
-/* Written by Richard Stallman by simplifying the original so called
-   ``semantic'' parser.  */
-
-/* All symbols defined below should begin with yy or YY, to avoid
-   infringing on user name space.  This should be done even for local
-   variables, as they might otherwise be expanded by user macros.
-   There are some unavoidable exceptions within include files to
-   define necessary library symbols; they are noted "INFRINGES ON
-   USER NAME SPACE" below.  */
-
-/* Identify Bison output.  */
-#define YYBISON 1
-
-/* Skeleton name.  */
-#define YYSKELETON_NAME "yacc.c"
-
-/* Pure parsers.  */
-#define YYPURE 0
-
-/* Using locations.  */
-#define YYLSP_NEEDED 0
-
-
-
-/* Tokens.  */
-#ifndef YYTOKENTYPE
-# define YYTOKENTYPE
-   /* Put the tokens into the symbol table, so that GDB and other debuggers
-      know about them.  */
-   enum yytokentype {
-     ET = 258,
-     INDEX = 259,
-     PREFIX = 260,
-     EC = 261,
-     ID = 262,
-     END = 263,
-     STRING = 264,
-     NUMBER = 265
-   };
-#endif
-#define ET 258
-#define INDEX 259
-#define PREFIX 260
-#define EC 261
-#define ID 262
-#define END 263
-#define STRING 264
-#define NUMBER 265
 
+/*  A Bison parser, made from ../../../lib/com_err/parse.y
+    by GNU Bison version 1.28  */
 
+#define YYBISON 1  /* Identify Bison output.  */
 
+#define        ET      257
+#define        INDEX   258
+#define        PREFIX  259
+#define        EC      260
+#define        ID      261
+#define        END     262
+#define        STRING  263
+#define        NUMBER  264
 
-/* Copy the first part of user declarations.  */
-#line 1 "parse.y"
+#line 1 "../../../lib/com_err/parse.y"
 
 /*
  * Copyright (c) 1998 - 2000 Kungliga Tekniska Högskolan
@@ -128,748 +65,425 @@ extern char *yytext;
 #endif
 
 
-
-/* Enabling traces.  */
-#ifndef YYDEBUG
-# define YYDEBUG 0
-#endif
-
-/* Enabling verbose error messages.  */
-#ifdef YYERROR_VERBOSE
-# undef YYERROR_VERBOSE
-# define YYERROR_VERBOSE 1
-#else
-# define YYERROR_VERBOSE 0
-#endif
-
-#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
-#line 53 "parse.y"
-typedef union YYSTYPE {
+#line 53 "../../../lib/com_err/parse.y"
+typedef union {
   char *string;
   int number;
 } YYSTYPE;
-/* Line 190 of yacc.c.  */
-#line 153 "$base.c"
-# define yystype YYSTYPE /* obsolescent; will be withdrawn */
-# define YYSTYPE_IS_DECLARED 1
-# define YYSTYPE_IS_TRIVIAL 1
-#endif
-
-
-
-/* Copy the second part of user declarations.  */
-
+#include <stdio.h>
 
-/* Line 213 of yacc.c.  */
-#line 165 "$base.c"
+#ifndef __cplusplus
+#ifndef __STDC__
+#define const
+#endif
+#endif
 
-#if ! defined (yyoverflow) || YYERROR_VERBOSE
 
-# ifndef YYFREE
-#  define YYFREE free
-# endif
-# ifndef YYMALLOC
-#  define YYMALLOC malloc
-# endif
 
-/* The parser invokes alloca or malloc; define the necessary symbols.  */
+#define        YYFINAL         24
+#define        YYFLAG          -32768
+#define        YYNTBASE        12
+
+#define YYTRANSLATE(x) ((unsigned)(x) <= 264 ? yytranslate[x] : 18)
+
+static const char yytranslate[] = {     0,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,    11,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     1,     3,     4,     5,     6,
+     7,     8,     9,    10
+};
 
-# ifdef YYSTACK_USE_ALLOCA
-#  if YYSTACK_USE_ALLOCA
-#   ifdef __GNUC__
-#    define YYSTACK_ALLOC __builtin_alloca
-#   else
-#    define YYSTACK_ALLOC alloca
-#   endif
-#  endif
-# endif
+#if YYDEBUG != 0
+static const short yyprhs[] = {     0,
+     0,     1,     4,     7,     9,    12,    15,    19,    21,    24,
+    27,    30,    32,    37
+};
 
-# ifdef YYSTACK_ALLOC
-   /* Pacify GCC's `empty if-body' warning. */
-#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
-# else
-#  if defined (__STDC__) || defined (__cplusplus)
-#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-#   define YYSIZE_T size_t
-#  endif
-#  define YYSTACK_ALLOC YYMALLOC
-#  define YYSTACK_FREE YYFREE
-# endif
-#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
+static const short yyrhs[] = {    -1,
+    13,    16,     0,    14,    15,     0,    15,     0,     7,     9,
+     0,     3,     9,     0,     3,     9,     9,     0,    17,     0,
+    16,    17,     0,     4,    10,     0,     5,     9,     0,     5,
+     0,     6,     9,    11,     9,     0,     8,     0
+};
 
+#endif
 
-#if (! defined (yyoverflow) \
-     && (! defined (__cplusplus) \
-        || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL)))
+#if YYDEBUG != 0
+static const short yyrline[] = { 0,
+    64,    65,    68,    69,    72,    78,    84,    93,    94,    97,
+   101,   109,   116,   136
+};
+#endif
 
-/* A type that is properly aligned for any stack member.  */
-union yyalloc
-{
-  short int yyss;
-  YYSTYPE yyvs;
-  };
-
-/* The size of the maximum gap between one aligned stack and the next.  */
-# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
-
-/* The size of an array large to enough to hold all stacks, each with
-   N elements.  */
-# define YYSTACK_BYTES(N) \
-     ((N) * (sizeof (short int) + sizeof (YYSTYPE))                    \
-      + YYSTACK_GAP_MAXIMUM)
-
-/* Copy COUNT objects from FROM to TO.  The source and destination do
-   not overlap.  */
-# ifndef YYCOPY
-#  if defined (__GNUC__) && 1 < __GNUC__
-#   define YYCOPY(To, From, Count) \
-      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
-#  else
-#   define YYCOPY(To, From, Count)             \
-      do                                       \
-       {                                       \
-         register YYSIZE_T yyi;                \
-         for (yyi = 0; yyi < (Count); yyi++)   \
-           (To)[yyi] = (From)[yyi];            \
-       }                                       \
-      while (0)
-#  endif
-# endif
-
-/* Relocate STACK from its old location to the new one.  The
-   local variables YYSIZE and YYSTACKSIZE give the old and new number of
-   elements in the stack, and YYPTR gives the new location of the
-   stack.  Advance YYPTR to a properly aligned location for the next
-   stack.  */
-# define YYSTACK_RELOCATE(Stack)                                       \
-    do                                                                 \
-      {                                                                        \
-       YYSIZE_T yynewbytes;                                            \
-       YYCOPY (&yyptr->Stack, Stack, yysize);                          \
-       Stack = &yyptr->Stack;                                          \
-       yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
-       yyptr += yynewbytes / sizeof (*yyptr);                          \
-      }                                                                        \
-    while (0)
 
-#endif
+#if YYDEBUG != 0 || defined (YYERROR_VERBOSE)
 
-#if defined (__STDC__) || defined (__cplusplus)
-   typedef signed char yysigned_char;
-#else
-   typedef short int yysigned_char;
+static const char * const yytname[] = {   "$","error","$undefined.","ET","INDEX",
+"PREFIX","EC","ID","END","STRING","NUMBER","','","file","header","id","et","statements",
+"statement", NULL
+};
 #endif
 
-/* YYFINAL -- State number of the termination state. */
-#define YYFINAL  9
-/* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   23
-
-/* YYNTOKENS -- Number of terminals. */
-#define YYNTOKENS  12
-/* YYNNTS -- Number of nonterminals. */
-#define YYNNTS  7
-/* YYNRULES -- Number of rules. */
-#define YYNRULES  15
-/* YYNRULES -- Number of states. */
-#define YYNSTATES  24
-
-/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
-#define YYUNDEFTOK  2
-#define YYMAXUTOK   265
-
-#define YYTRANSLATE(YYX)                                               \
-  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
-
-/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
-static const unsigned char yytranslate[] =
-{
-       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,    11,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
-       5,     6,     7,     8,     9,    10
+static const short yyr1[] = {     0,
+    12,    12,    13,    13,    14,    15,    15,    16,    16,    17,
+    17,    17,    17,    17
 };
 
-#if YYDEBUG
-/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
-   YYRHS.  */
-static const unsigned char yyprhs[] =
-{
-       0,     0,     3,     4,     7,    10,    12,    15,    18,    22,
-      24,    27,    30,    33,    35,    40
+static const short yyr2[] = {     0,
+     0,     2,     2,     1,     2,     2,     3,     1,     2,     2,
+     2,     1,     4,     1
 };
 
-/* YYRHS -- A `-1'-separated list of the rules' RHS. */
-static const yysigned_char yyrhs[] =
-{
-      13,     0,    -1,    -1,    14,    17,    -1,    15,    16,    -1,
-      16,    -1,     7,     9,    -1,     3,     9,    -1,     3,     9,
-       9,    -1,    18,    -1,    17,    18,    -1,     4,    10,    -1,
-       5,     9,    -1,     5,    -1,     6,     9,    11,     9,    -1,
-       8,    -1
+static const short yydefact[] = {     1,
+     0,     0,     0,     0,     4,     6,     5,     0,    12,     0,
+    14,     2,     8,     3,     7,    10,    11,     0,     9,     0,
+    13,     0,     0,     0
 };
 
-/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
-static const unsigned char yyrline[] =
-{
-       0,    64,    64,    65,    68,    69,    72,    78,    84,    93,
-      94,    97,   101,   109,   116,   136
+static const short yydefgoto[] = {    22,
+     3,     4,     5,    12,    13
 };
-#endif
 
-#if YYDEBUG || YYERROR_VERBOSE
-/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
-   First, the terminals, then, starting at YYNTOKENS, nonterminals. */
-static const char *const yytname[] =
-{
-  "$end", "error", "$undefined", "ET", "INDEX", "PREFIX", "EC", "ID",
-  "END", "STRING", "NUMBER", "','", "$accept", "file", "header", "id",
-  "et", "statements", "statement", 0
+static const short yypact[] = {     0,
+    -3,    -1,    -4,     2,-32768,     1,-32768,     3,     5,     6,
+-32768,    -4,-32768,-32768,-32768,-32768,-32768,    -2,-32768,     7,
+-32768,    11,    12,-32768
 };
-#endif
 
-# ifdef YYPRINT
-/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
-   token YYLEX-NUM.  */
-static const unsigned short int yytoknum[] =
-{
-       0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
-     265,    44
+static const short yypgoto[] = {-32768,
+-32768,-32768,    13,-32768,     8
 };
-# endif
 
-/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
-static const unsigned char yyr1[] =
-{
-       0,    12,    13,    13,    14,    14,    15,    16,    16,    17,
-      17,    18,    18,    18,    18,    18
-};
 
-/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
-static const unsigned char yyr2[] =
-{
-       0,     2,     0,     2,     2,     1,     2,     2,     3,     1,
-       2,     2,     2,     1,     4,     1
-};
+#define        YYLAST          20
 
-/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
-   STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
-   means the default is an error.  */
-static const unsigned char yydefact[] =
-{
-       2,     0,     0,     0,     0,     0,     5,     7,     6,     1,
-       0,    13,     0,    15,     3,     9,     4,     8,    11,    12,
-       0,    10,     0,    14
-};
 
-/* YYDEFGOTO[NTERM-NUM]. */
-static const yysigned_char yydefgoto[] =
-{
-      -1,     3,     4,     5,     6,    14,    15
+static const short yytable[] = {     8,
+     9,    10,     1,    11,     1,     6,     2,     7,    20,    15,
+    23,    24,    16,    17,    18,    21,    14,     0,     0,    19
 };
 
-/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
-   STATE-NUM.  */
-#define YYPACT_NINF -5
-static const yysigned_char yypact[] =
-{
-       0,    -3,    -1,     5,    -4,     6,    -5,     1,    -5,    -5,
-       2,     4,     7,    -5,    -4,    -5,    -5,    -5,    -5,    -5,
-       3,    -5,     8,    -5
+static const short yycheck[] = {     4,
+     5,     6,     3,     8,     3,     9,     7,     9,    11,     9,
+     0,     0,    10,     9,     9,     9,     4,    -1,    -1,    12
 };
+/* -*-C-*-  Note some compilers choke on comments on `#line' lines.  */
+#line 3 "/usr/share/bison.simple"
+/* This file comes from bison-1.28.  */
 
-/* YYPGOTO[NTERM-NUM].  */
-static const yysigned_char yypgoto[] =
-{
-      -5,    -5,    -5,    -5,    10,    -5,     9
-};
+/* Skeleton output parser for bison,
+   Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
 
-/* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
-   positive, shift that token.  If negative, reduce the rule which
-   number is the opposite.  If zero, do what YYDEFACT says.
-   If YYTABLE_NINF, syntax error.  */
-#define YYTABLE_NINF -1
-static const unsigned char yytable[] =
-{
-      10,    11,    12,     1,    13,     9,     7,     2,     8,     1,
-      17,     0,    18,    19,    22,    16,    20,    23,     0,     0,
-       0,     0,     0,    21
-};
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
 
-static const yysigned_char yycheck[] =
-{
-       4,     5,     6,     3,     8,     0,     9,     7,     9,     3,
-       9,    -1,    10,     9,    11,     5,     9,     9,    -1,    -1,
-      -1,    -1,    -1,    14
-};
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
 
-/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
-   symbol of state STATE-NUM.  */
-static const unsigned char yystos[] =
-{
-       0,     3,     7,    13,    14,    15,    16,     9,     9,     0,
-       4,     5,     6,     8,    17,    18,    16,     9,    10,     9,
-       9,    18,    11,     9
-};
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
-#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
-# define YYSIZE_T __SIZE_TYPE__
-#endif
-#if ! defined (YYSIZE_T) && defined (size_t)
-# define YYSIZE_T size_t
+/* As a special exception, when this file is copied by Bison into a
+   Bison output file, you may use that output file without restriction.
+   This special exception was added by the Free Software Foundation
+   in version 1.24 of Bison.  */
+
+/* This is the parser code that is written into each bison parser
+  when the %semantic_parser declaration is not specified in the grammar.
+  It was written by Richard Stallman by simplifying the hairy parser
+  used when %semantic_parser is specified.  */
+
+#ifndef YYSTACK_USE_ALLOCA
+#ifdef alloca
+#define YYSTACK_USE_ALLOCA
+#else /* alloca not defined */
+#ifdef __GNUC__
+#define YYSTACK_USE_ALLOCA
+#define alloca __builtin_alloca
+#else /* not GNU C.  */
+#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) || (defined (__sun) && defined (__i386))
+#define YYSTACK_USE_ALLOCA
+#include <alloca.h>
+#else /* not sparc */
+/* We think this test detects Watcom and Microsoft C.  */
+/* This used to test MSDOS, but that is a bad idea
+   since that symbol is in the user namespace.  */
+#if (defined (_MSDOS) || defined (_MSDOS_)) && !defined (__TURBOC__)
+#if 0 /* No need for malloc.h, which pollutes the namespace;
+        instead, just don't use alloca.  */
+#include <malloc.h>
 #endif
-#if ! defined (YYSIZE_T)
-# if defined (__STDC__) || defined (__cplusplus)
-#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
-#  define YYSIZE_T size_t
-# endif
+#else /* not MSDOS, or __TURBOC__ */
+#if defined(_AIX)
+/* I don't know what this was needed for, but it pollutes the namespace.
+   So I turned it off.   rms, 2 May 1997.  */
+/* #include <malloc.h>  */
+ #pragma alloca
+#define YYSTACK_USE_ALLOCA
+#else /* not MSDOS, or __TURBOC__, or _AIX */
+#if 0
+#ifdef __hpux /* haible@ilog.fr says this works for HPUX 9.05 and up,
+                and on HPUX 10.  Eventually we can turn this on.  */
+#define YYSTACK_USE_ALLOCA
+#define alloca __builtin_alloca
+#endif /* __hpux */
 #endif
-#if ! defined (YYSIZE_T)
-# define YYSIZE_T unsigned int
+#endif /* not _AIX */
+#endif /* not MSDOS, or __TURBOC__ */
+#endif /* not sparc */
+#endif /* not GNU C */
+#endif /* alloca not defined */
+#endif /* YYSTACK_USE_ALLOCA not defined */
+
+#ifdef YYSTACK_USE_ALLOCA
+#define YYSTACK_ALLOC alloca
+#else
+#define YYSTACK_ALLOC malloc
 #endif
 
+/* Note: there must be only one dollar sign in this file.
+   It is replaced by the list of actions, each action
+   as one case of the switch.  */
+
 #define yyerrok                (yyerrstatus = 0)
 #define yyclearin      (yychar = YYEMPTY)
-#define YYEMPTY                (-2)
+#define YYEMPTY                -2
 #define YYEOF          0
-
 #define YYACCEPT       goto yyacceptlab
-#define YYABORT                goto yyabortlab
-#define YYERROR                goto yyerrorlab
-
-
-/* Like YYERROR except do call yyerror.  This remains here temporarily
-   to ease the transition to the new meaning of YYERROR, for GCC.
+#define YYABORT        goto yyabortlab
+#define YYERROR                goto yyerrlab1
+/* Like YYERROR except do call yyerror.
+   This remains here temporarily to ease the
+   transition to the new meaning of YYERROR, for GCC.
    Once GCC version 2 has supplanted version 1, this can go.  */
-
 #define YYFAIL         goto yyerrlab
-
 #define YYRECOVERING()  (!!yyerrstatus)
-
-#define YYBACKUP(Token, Value)                                 \
+#define YYBACKUP(token, value) \
 do                                                             \
   if (yychar == YYEMPTY && yylen == 1)                         \
-    {                                                          \
-      yychar = (Token);                                                \
-      yylval = (Value);                                                \
-      yytoken = YYTRANSLATE (yychar);                          \
+    { yychar = (token), yylval = (value);                      \
+      yychar1 = YYTRANSLATE (yychar);                          \
       YYPOPSTACK;                                              \
       goto yybackup;                                           \
     }                                                          \
   else                                                         \
-    {                                                          \
-      yyerror ("syntax error: cannot back up");\
-      YYERROR;                                                 \
-    }                                                          \
+    { yyerror ("syntax error: cannot back up"); YYERROR; }     \
 while (0)
 
-
 #define YYTERROR       1
 #define YYERRCODE      256
 
-
-/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
-   If N is 0, then set CURRENT to the empty location which ends
-   the previous symbol: RHS[0] (always defined).  */
-
-#define YYRHSLOC(Rhs, K) ((Rhs)[K])
-#ifndef YYLLOC_DEFAULT
-# define YYLLOC_DEFAULT(Current, Rhs, N)                               \
-    do                                                                 \
-      if (N)                                                           \
-       {                                                               \
-         (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;        \
-         (Current).first_column = YYRHSLOC (Rhs, 1).first_column;      \
-         (Current).last_line    = YYRHSLOC (Rhs, N).last_line;         \
-         (Current).last_column  = YYRHSLOC (Rhs, N).last_column;       \
-       }                                                               \
-      else                                                             \
-       {                                                               \
-         (Current).first_line   = (Current).last_line   =              \
-           YYRHSLOC (Rhs, 0).last_line;                                \
-         (Current).first_column = (Current).last_column =              \
-           YYRHSLOC (Rhs, 0).last_column;                              \
-       }                                                               \
-    while (0)
-#endif
-
-
-/* YY_LOCATION_PRINT -- Print the location on the stream.
-   This macro was not mandated originally: define only if we know
-   we won't break user code: when these are the locations we know.  */
-
-#ifndef YY_LOCATION_PRINT
-# if YYLTYPE_IS_TRIVIAL
-#  define YY_LOCATION_PRINT(File, Loc)                 \
-     fprintf (File, "%d.%d-%d.%d",                     \
-              (Loc).first_line, (Loc).first_column,    \
-              (Loc).last_line,  (Loc).last_column)
-# else
-#  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
-# endif
+#ifndef YYPURE
+#define YYLEX          yylex()
 #endif
 
-
-/* YYLEX -- calling `yylex' with the right arguments.  */
-
+#ifdef YYPURE
+#ifdef YYLSP_NEEDED
 #ifdef YYLEX_PARAM
-# define YYLEX yylex (YYLEX_PARAM)
+#define YYLEX          yylex(&yylval, &yylloc, YYLEX_PARAM)
 #else
-# define YYLEX yylex ()
+#define YYLEX          yylex(&yylval, &yylloc)
 #endif
-
-/* Enable debugging if requested.  */
-#if YYDEBUG
-
-# ifndef YYFPRINTF
-#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
-#  define YYFPRINTF fprintf
-# endif
-
-# define YYDPRINTF(Args)                       \
-do {                                           \
-  if (yydebug)                                 \
-    YYFPRINTF Args;                            \
-} while (0)
-
-# define YY_SYMBOL_PRINT(Title, Type, Value, Location)         \
-do {                                                           \
-  if (yydebug)                                                 \
-    {                                                          \
-      YYFPRINTF (stderr, "%s ", Title);                                \
-      yysymprint (stderr,                                      \
-                  Type, Value);        \
-      YYFPRINTF (stderr, "\n");                                        \
-    }                                                          \
-} while (0)
-
-/*------------------------------------------------------------------.
-| yy_stack_print -- Print the state stack from its BOTTOM up to its |
-| TOP (included).                                                   |
-`------------------------------------------------------------------*/
-
-#if defined (__STDC__) || defined (__cplusplus)
-static void
-yy_stack_print (short int *bottom, short int *top)
+#else /* not YYLSP_NEEDED */
+#ifdef YYLEX_PARAM
+#define YYLEX          yylex(&yylval, YYLEX_PARAM)
 #else
-static void
-yy_stack_print (bottom, top)
-    short int *bottom;
-    short int *top;
+#define YYLEX          yylex(&yylval)
+#endif
+#endif /* not YYLSP_NEEDED */
 #endif
-{
-  YYFPRINTF (stderr, "Stack now");
-  for (/* Nothing. */; bottom <= top; ++bottom)
-    YYFPRINTF (stderr, " %d", *bottom);
-  YYFPRINTF (stderr, "\n");
-}
 
-# define YY_STACK_PRINT(Bottom, Top)                           \
-do {                                                           \
-  if (yydebug)                                                 \
-    yy_stack_print ((Bottom), (Top));                          \
-} while (0)
+/* If nonreentrant, generate the variables here */
 
+#ifndef YYPURE
 
-/*------------------------------------------------.
-| Report that the YYRULE is going to be reduced.  |
-`------------------------------------------------*/
+int    yychar;                 /*  the lookahead symbol                */
+YYSTYPE        yylval;                 /*  the semantic value of the           */
+                               /*  lookahead symbol                    */
 
-#if defined (__STDC__) || defined (__cplusplus)
-static void
-yy_reduce_print (int yyrule)
-#else
-static void
-yy_reduce_print (yyrule)
-    int yyrule;
+#ifdef YYLSP_NEEDED
+YYLTYPE yylloc;                        /*  location data for the lookahead     */
+                               /*  symbol                              */
 #endif
-{
-  int yyi;
-  unsigned int yylno = yyrline[yyrule];
-  YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ",
-             yyrule - 1, yylno);
-  /* Print the symbols being reduced, and their result.  */
-  for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
-    YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]);
-  YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]);
-}
 
-# define YY_REDUCE_PRINT(Rule)         \
-do {                                   \
-  if (yydebug)                         \
-    yy_reduce_print (Rule);            \
-} while (0)
+int yynerrs;                   /*  number of parse errors so far       */
+#endif  /* not YYPURE */
 
-/* Nonzero means print parse trace.  It is left uninitialized so that
-   multiple parsers can coexist.  */
-int yydebug;
-#else /* !YYDEBUG */
-# define YYDPRINTF(Args)
-# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
-# define YY_STACK_PRINT(Bottom, Top)
-# define YY_REDUCE_PRINT(Rule)
-#endif /* !YYDEBUG */
+#if YYDEBUG != 0
+int yydebug;                   /*  nonzero means print parse trace     */
+/* Since this is uninitialized, it does not stop multiple parsers
+   from coexisting.  */
+#endif
 
+/*  YYINITDEPTH indicates the initial size of the parser's stacks      */
 
-/* YYINITDEPTH -- initial size of the parser's stacks.  */
 #ifndef        YYINITDEPTH
-# define YYINITDEPTH 200
+#define YYINITDEPTH 200
 #endif
 
-/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
-   if the built-in stack extension method is used).
+/*  YYMAXDEPTH is the maximum size the stacks can grow to
+    (effective only if the built-in stack extension method is used).  */
 
-   Do not make this value too large; the results are undefined if
-   SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
-   evaluated with infinite-precision integer arithmetic.  */
+#if YYMAXDEPTH == 0
+#undef YYMAXDEPTH
+#endif
 
 #ifndef YYMAXDEPTH
-# define YYMAXDEPTH 10000
+#define YYMAXDEPTH 10000
 #endif
-
 \f
-
-#if YYERROR_VERBOSE
-
-# ifndef yystrlen
-#  if defined (__GLIBC__) && defined (_STRING_H)
-#   define yystrlen strlen
-#  else
-/* Return the length of YYSTR.  */
-static YYSIZE_T
-#   if defined (__STDC__) || defined (__cplusplus)
-yystrlen (const char *yystr)
-#   else
-yystrlen (yystr)
-     const char *yystr;
-#   endif
-{
-  register const char *yys = yystr;
-
-  while (*yys++ != '\0')
-    continue;
-
-  return yys - yystr - 1;
-}
-#  endif
-# endif
-
-# ifndef yystpcpy
-#  if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
-#   define yystpcpy stpcpy
-#  else
-/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
-   YYDEST.  */
-static char *
-#   if defined (__STDC__) || defined (__cplusplus)
-yystpcpy (char *yydest, const char *yysrc)
-#   else
-yystpcpy (yydest, yysrc)
-     char *yydest;
-     const char *yysrc;
-#   endif
+/* Define __yy_memcpy.  Note that the size argument
+   should be passed with type unsigned int, because that is what the non-GCC
+   definitions require.  With GCC, __builtin_memcpy takes an arg
+   of type size_t, but it can handle unsigned int.  */
+
+#if __GNUC__ > 1               /* GNU C and GNU C++ define this.  */
+#define __yy_memcpy(TO,FROM,COUNT)     __builtin_memcpy(TO,FROM,COUNT)
+#else                          /* not GNU C or C++ */
+#ifndef __cplusplus
+
+/* This is the most reliable way to avoid incompatibilities
+   in available built-in functions on various systems.  */
+static void
+__yy_memcpy (to, from, count)
+     char *to;
+     char *from;
+     unsigned int count;
 {
-  register char *yyd = yydest;
-  register const char *yys = yysrc;
-
-  while ((*yyd++ = *yys++) != '\0')
-    continue;
+  register char *f = from;
+  register char *t = to;
+  register int i = count;
 
-  return yyd - 1;
+  while (i-- > 0)
+    *t++ = *f++;
 }
-#  endif
-# endif
-
-#endif /* !YYERROR_VERBOSE */
-
-\f
 
-#if YYDEBUG
-/*--------------------------------.
-| Print this symbol on YYOUTPUT.  |
-`--------------------------------*/
+#else /* __cplusplus */
 
-#if defined (__STDC__) || defined (__cplusplus)
-static void
-yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep)
-#else
+/* This is the most reliable way to avoid incompatibilities
+   in available built-in functions on various systems.  */
 static void
-yysymprint (yyoutput, yytype, yyvaluep)
-    FILE *yyoutput;
-    int yytype;
-    YYSTYPE *yyvaluep;
-#endif
+__yy_memcpy (char *to, char *from, unsigned int count)
 {
-  /* Pacify ``unused variable'' warnings.  */
-  (void) yyvaluep;
-
-  if (yytype < YYNTOKENS)
-    YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
-  else
-    YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
-
+  register char *t = to;
+  register char *f = from;
+  register int i = count;
 
-# ifdef YYPRINT
-  if (yytype < YYNTOKENS)
-    YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
-# endif
-  switch (yytype)
-    {
-      default:
-        break;
-    }
-  YYFPRINTF (yyoutput, ")");
+  while (i-- > 0)
+    *t++ = *f++;
 }
 
-#endif /* ! YYDEBUG */
-/*-----------------------------------------------.
-| Release the memory associated to this symbol.  |
-`-----------------------------------------------*/
-
-#if defined (__STDC__) || defined (__cplusplus)
-static void
-yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
-#else
-static void
-yydestruct (yymsg, yytype, yyvaluep)
-    const char *yymsg;
-    int yytype;
-    YYSTYPE *yyvaluep;
 #endif
-{
-  /* Pacify ``unused variable'' warnings.  */
-  (void) yyvaluep;
-
-  if (!yymsg)
-    yymsg = "Deleting";
-  YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
-
-  switch (yytype)
-    {
-
-      default:
-        break;
-    }
-}
+#endif
 \f
+#line 217 "/usr/share/bison.simple"
 
-/* Prevent warnings from -Wmissing-prototypes.  */
+/* The user can define YYPARSE_PARAM as the name of an argument to be passed
+   into yyparse.  The argument should have type void *.
+   It should actually point to an object.
+   Grammar actions can access the variable by casting it
+   to the proper pointer type.  */
 
 #ifdef YYPARSE_PARAM
-# if defined (__STDC__) || defined (__cplusplus)
-int yyparse (void *YYPARSE_PARAM);
-# else
-int yyparse ();
-# endif
-#else /* ! YYPARSE_PARAM */
-#if defined (__STDC__) || defined (__cplusplus)
-int yyparse (void);
-#else
-int yyparse ();
-#endif
-#endif /* ! YYPARSE_PARAM */
-
-
-
-/* The look-ahead symbol.  */
-int yychar;
-
-/* The semantic value of the look-ahead symbol.  */
-YYSTYPE yylval;
-
-/* Number of syntax errors so far.  */
-int yynerrs;
-
-
-
-/*----------.
-| yyparse.  |
-`----------*/
-
+#ifdef __cplusplus
+#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
+#define YYPARSE_PARAM_DECL
+#else /* not __cplusplus */
+#define YYPARSE_PARAM_ARG YYPARSE_PARAM
+#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
+#endif /* not __cplusplus */
+#else /* not YYPARSE_PARAM */
+#define YYPARSE_PARAM_ARG
+#define YYPARSE_PARAM_DECL
+#endif /* not YYPARSE_PARAM */
+
+/* Prevent warning if -Wstrict-prototypes.  */
+#ifdef __GNUC__
 #ifdef YYPARSE_PARAM
-# if defined (__STDC__) || defined (__cplusplus)
-int yyparse (void *YYPARSE_PARAM)
-# else
-int yyparse (YYPARSE_PARAM)
-  void *YYPARSE_PARAM;
-# endif
-#else /* ! YYPARSE_PARAM */
-#if defined (__STDC__) || defined (__cplusplus)
-int
-yyparse (void)
+int yyparse (void *);
 #else
-int
-yyparse ()
-
+int yyparse (void);
 #endif
 #endif
+
+int
+yyparse(YYPARSE_PARAM_ARG)
+     YYPARSE_PARAM_DECL
 {
-  
   register int yystate;
   register int yyn;
-  int yyresult;
-  /* Number of tokens to shift before error messages enabled.  */
-  int yyerrstatus;
-  /* Look-ahead token as an internal (translated) token number.  */
-  int yytoken = 0;
-
-  /* Three stacks and their tools:
-     `yyss': related to states,
-     `yyvs': related to semantic values,
-     `yyls': related to locations.
-
-     Refer to the stacks thru separate pointers, to allow yyoverflow
-     to reallocate them elsewhere.  */
-
-  /* The state stack.  */
-  short int yyssa[YYINITDEPTH];
-  short int *yyss = yyssa;
-  register short int *yyssp;
-
-  /* The semantic value stack.  */
-  YYSTYPE yyvsa[YYINITDEPTH];
-  YYSTYPE *yyvs = yyvsa;
+  register short *yyssp;
   register YYSTYPE *yyvsp;
+  int yyerrstatus;     /*  number of tokens to shift before error messages enabled */
+  int yychar1 = 0;             /*  lookahead token as an internal (translated) token number */
 
+  short        yyssa[YYINITDEPTH];     /*  the state stack                     */
+  YYSTYPE yyvsa[YYINITDEPTH];  /*  the semantic value stack            */
 
+  short *yyss = yyssa;         /*  refer to the stacks thru separate pointers */
+  YYSTYPE *yyvs = yyvsa;       /*  to allow yyoverflow to reallocate them elsewhere */
 
+#ifdef YYLSP_NEEDED
+  YYLTYPE yylsa[YYINITDEPTH];  /*  the location stack                  */
+  YYLTYPE *yyls = yylsa;
+  YYLTYPE *yylsp;
+
+#define YYPOPSTACK   (yyvsp--, yyssp--, yylsp--)
+#else
 #define YYPOPSTACK   (yyvsp--, yyssp--)
+#endif
 
-  YYSIZE_T yystacksize = YYINITDEPTH;
+  int yystacksize = YYINITDEPTH;
+  int yyfree_stacks = 0;
 
-  /* The variables used to return semantic value and location from the
-     action routines.  */
-  YYSTYPE yyval;
+#ifdef YYPURE
+  int yychar;
+  YYSTYPE yylval;
+  int yynerrs;
+#ifdef YYLSP_NEEDED
+  YYLTYPE yylloc;
+#endif
+#endif
 
+  YYSTYPE yyval;               /*  the variable used to return         */
+                               /*  semantic values from the action     */
+                               /*  routines                            */
 
-  /* When reducing, the number of symbols on the RHS of the reduced
-     rule.  */
   int yylen;
 
-  YYDPRINTF ((stderr, "Starting parse\n"));
+#if YYDEBUG != 0
+  if (yydebug)
+    fprintf(stderr, "Starting parse\n");
+#endif
 
   yystate = 0;
   yyerrstatus = 0;
@@ -881,254 +495,295 @@ yyparse ()
      so that they stay on the same level as the state stack.
      The wasted elements are never initialized.  */
 
-  yyssp = yyss;
+  yyssp = yyss - 1;
   yyvsp = yyvs;
+#ifdef YYLSP_NEEDED
+  yylsp = yyls;
+#endif
 
+/* Push a new state, which is found in  yystate  .  */
+/* In all cases, when you get here, the value and location stacks
+   have just been pushed. so pushing a state here evens the stacks.  */
+yynewstate:
 
-  yyvsp[0] = yylval;
-
-  goto yysetstate;
-
-/*------------------------------------------------------------.
-| yynewstate -- Push a new state, which is found in yystate.  |
-`------------------------------------------------------------*/
- yynewstate:
-  /* In all cases, when you get here, the value and location stacks
-     have just been pushed. so pushing a state here evens the stacks.
-     */
-  yyssp++;
-
- yysetstate:
-  *yyssp = yystate;
+  *++yyssp = yystate;
 
-  if (yyss + yystacksize - 1 <= yyssp)
+  if (yyssp >= yyss + yystacksize - 1)
     {
+      /* Give user a chance to reallocate the stack */
+      /* Use copies of these so that the &'s don't force the real ones into memory. */
+      YYSTYPE *yyvs1 = yyvs;
+      short *yyss1 = yyss;
+#ifdef YYLSP_NEEDED
+      YYLTYPE *yyls1 = yyls;
+#endif
+
       /* Get the current used size of the three stacks, in elements.  */
-      YYSIZE_T yysize = yyssp - yyss + 1;
+      int size = yyssp - yyss + 1;
 
 #ifdef yyoverflow
-      {
-       /* Give user a chance to reallocate the stack. Use copies of
-          these so that the &'s don't force the real ones into
-          memory.  */
-       YYSTYPE *yyvs1 = yyvs;
-       short int *yyss1 = yyss;
-
-
-       /* Each stack pointer address is followed by the size of the
-          data in use in that stack, in bytes.  This used to be a
-          conditional around just the two extra args, but that might
-          be undefined if yyoverflow is a macro.  */
-       yyoverflow ("parser stack overflow",
-                   &yyss1, yysize * sizeof (*yyssp),
-                   &yyvs1, yysize * sizeof (*yyvsp),
-
-                   &yystacksize);
-
-       yyss = yyss1;
-       yyvs = yyvs1;
-      }
+      /* Each stack pointer address is followed by the size of
+        the data in use in that stack, in bytes.  */
+#ifdef YYLSP_NEEDED
+      /* This used to be a conditional around just the two extra args,
+        but that might be undefined if yyoverflow is a macro.  */
+      yyoverflow("parser stack overflow",
+                &yyss1, size * sizeof (*yyssp),
+                &yyvs1, size * sizeof (*yyvsp),
+                &yyls1, size * sizeof (*yylsp),
+                &yystacksize);
+#else
+      yyoverflow("parser stack overflow",
+                &yyss1, size * sizeof (*yyssp),
+                &yyvs1, size * sizeof (*yyvsp),
+                &yystacksize);
+#endif
+
+      yyss = yyss1; yyvs = yyvs1;
+#ifdef YYLSP_NEEDED
+      yyls = yyls1;
+#endif
 #else /* no yyoverflow */
-# ifndef YYSTACK_RELOCATE
-      goto yyoverflowlab;
-# else
       /* Extend the stack our own way.  */
-      if (YYMAXDEPTH <= yystacksize)
-       goto yyoverflowlab;
+      if (yystacksize >= YYMAXDEPTH)
+       {
+         yyerror("parser stack overflow");
+         if (yyfree_stacks)
+           {
+             free (yyss);
+             free (yyvs);
+#ifdef YYLSP_NEEDED
+             free (yyls);
+#endif
+           }
+         return 2;
+       }
       yystacksize *= 2;
-      if (YYMAXDEPTH < yystacksize)
+      if (yystacksize > YYMAXDEPTH)
        yystacksize = YYMAXDEPTH;
-
-      {
-       short int *yyss1 = yyss;
-       union yyalloc *yyptr =
-         (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
-       if (! yyptr)
-         goto yyoverflowlab;
-       YYSTACK_RELOCATE (yyss);
-       YYSTACK_RELOCATE (yyvs);
-
-#  undef YYSTACK_RELOCATE
-       if (yyss1 != yyssa)
-         YYSTACK_FREE (yyss1);
-      }
-# endif
+#ifndef YYSTACK_USE_ALLOCA
+      yyfree_stacks = 1;
+#endif
+      yyss = (short *) YYSTACK_ALLOC (yystacksize * sizeof (*yyssp));
+      __yy_memcpy ((char *)yyss, (char *)yyss1,
+                  size * (unsigned int) sizeof (*yyssp));
+      yyvs = (YYSTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yyvsp));
+      __yy_memcpy ((char *)yyvs, (char *)yyvs1,
+                  size * (unsigned int) sizeof (*yyvsp));
+#ifdef YYLSP_NEEDED
+      yyls = (YYLTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yylsp));
+      __yy_memcpy ((char *)yyls, (char *)yyls1,
+                  size * (unsigned int) sizeof (*yylsp));
+#endif
 #endif /* no yyoverflow */
 
-      yyssp = yyss + yysize - 1;
-      yyvsp = yyvs + yysize - 1;
-
+      yyssp = yyss + size - 1;
+      yyvsp = yyvs + size - 1;
+#ifdef YYLSP_NEEDED
+      yylsp = yyls + size - 1;
+#endif
 
-      YYDPRINTF ((stderr, "Stack size increased to %lu\n",
-                 (unsigned long int) yystacksize));
+#if YYDEBUG != 0
+      if (yydebug)
+       fprintf(stderr, "Stack size increased to %d\n", yystacksize);
+#endif
 
-      if (yyss + yystacksize - 1 <= yyssp)
+      if (yyssp >= yyss + yystacksize - 1)
        YYABORT;
     }
 
-  YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+#if YYDEBUG != 0
+  if (yydebug)
+    fprintf(stderr, "Entering state %d\n", yystate);
+#endif
 
   goto yybackup;
-
-/*-----------.
-| yybackup.  |
-`-----------*/
-yybackup:
+ yybackup:
 
 /* Do appropriate processing given the current state.  */
-/* Read a look-ahead token if we need one and don't already have one.  */
+/* Read a lookahead token if we need one and don't already have one.  */
 /* yyresume: */
 
-  /* First try to decide what to do without reference to look-ahead token.  */
+  /* First try to decide what to do without reference to lookahead token.  */
 
   yyn = yypact[yystate];
-  if (yyn == YYPACT_NINF)
+  if (yyn == YYFLAG)
     goto yydefault;
 
-  /* Not known => get a look-ahead token if don't already have one.  */
+  /* Not known => get a lookahead token if don't already have one.  */
+
+  /* yychar is either YYEMPTY or YYEOF
+     or a valid token in external form.  */
 
-  /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol.  */
   if (yychar == YYEMPTY)
     {
-      YYDPRINTF ((stderr, "Reading a token: "));
+#if YYDEBUG != 0
+      if (yydebug)
+       fprintf(stderr, "Reading a token: ");
+#endif
       yychar = YYLEX;
     }
 
-  if (yychar <= YYEOF)
+  /* Convert token to internal form (in yychar1) for indexing tables with */
+
+  if (yychar <= 0)             /* This means end of input. */
     {
-      yychar = yytoken = YYEOF;
-      YYDPRINTF ((stderr, "Now at end of input.\n"));
+      yychar1 = 0;
+      yychar = YYEOF;          /* Don't call YYLEX any more */
+
+#if YYDEBUG != 0
+      if (yydebug)
+       fprintf(stderr, "Now at end of input.\n");
+#endif
     }
   else
     {
-      yytoken = YYTRANSLATE (yychar);
-      YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+      yychar1 = YYTRANSLATE(yychar);
+
+#if YYDEBUG != 0
+      if (yydebug)
+       {
+         fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]);
+         /* Give the individual parser a way to print the precise meaning
+            of a token, for further debugging info.  */
+#ifdef YYPRINT
+         YYPRINT (stderr, yychar, yylval);
+#endif
+         fprintf (stderr, ")\n");
+       }
+#endif
     }
 
-  /* If the proper action on seeing token YYTOKEN is to reduce or to
-     detect an error, take that action.  */
-  yyn += yytoken;
-  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+  yyn += yychar1;
+  if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
     goto yydefault;
+
   yyn = yytable[yyn];
-  if (yyn <= 0)
+
+  /* yyn is what to do for this token type in this state.
+     Negative => reduce, -yyn is rule number.
+     Positive => shift, yyn is new state.
+       New state is final state => don't bother to shift,
+       just return success.
+     0, or most negative number => error.  */
+
+  if (yyn < 0)
     {
-      if (yyn == 0 || yyn == YYTABLE_NINF)
+      if (yyn == YYFLAG)
        goto yyerrlab;
       yyn = -yyn;
       goto yyreduce;
     }
+  else if (yyn == 0)
+    goto yyerrlab;
 
   if (yyn == YYFINAL)
     YYACCEPT;
 
-  /* Shift the look-ahead token.  */
-  YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+  /* Shift the lookahead token.  */
+
+#if YYDEBUG != 0
+  if (yydebug)
+    fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
+#endif
 
   /* Discard the token being shifted unless it is eof.  */
   if (yychar != YYEOF)
     yychar = YYEMPTY;
 
   *++yyvsp = yylval;
+#ifdef YYLSP_NEEDED
+  *++yylsp = yylloc;
+#endif
 
-
-  /* Count tokens shifted since error; after three, turn off error
-     status.  */
-  if (yyerrstatus)
-    yyerrstatus--;
+  /* count tokens shifted since error; after three, turn off error status.  */
+  if (yyerrstatus) yyerrstatus--;
 
   yystate = yyn;
   goto yynewstate;
 
-
-/*-----------------------------------------------------------.
-| yydefault -- do the default action for the current state.  |
-`-----------------------------------------------------------*/
+/* Do the default action for the current state.  */
 yydefault:
+
   yyn = yydefact[yystate];
   if (yyn == 0)
     goto yyerrlab;
-  goto yyreduce;
-
 
-/*-----------------------------.
-| yyreduce -- Do a reduction.  |
-`-----------------------------*/
+/* Do a reduction.  yyn is the number of a rule to reduce with.  */
 yyreduce:
-  /* yyn is the number of a rule to reduce with.  */
   yylen = yyr2[yyn];
+  if (yylen > 0)
+    yyval = yyvsp[1-yylen]; /* implement default value of the action */
 
-  /* If YYLEN is nonzero, implement the default value of the action:
-     `$$ = $1'.
-
-     Otherwise, the following line sets YYVAL to garbage.
-     This behavior is undocumented and Bison
-     users should not rely upon it.  Assigning to YYVAL
-     unconditionally makes the parser a bit smaller, and it avoids a
-     GCC warning that YYVAL may be used uninitialized.  */
-  yyval = yyvsp[1-yylen];
-
-
-  YY_REDUCE_PRINT (yyn);
-  switch (yyn)
+#if YYDEBUG != 0
+  if (yydebug)
     {
-        case 6:
-#line 73 "parse.y"
-    {
-                   id_str = (yyvsp[0].string);
-               }
-    break;
+      int i;
 
-  case 7:
-#line 79 "parse.y"
-    {
-                   base_id = name2number((yyvsp[0].string));
-                   strlcpy(name, (yyvsp[0].string), sizeof(name));
-                   free((yyvsp[0].string));
-               }
-    break;
+      fprintf (stderr, "Reducing via rule %d (line %d), ",
+              yyn, yyrline[yyn]);
 
-  case 8:
-#line 85 "parse.y"
-    {
-                   base_id = name2number((yyvsp[-1].string));
-                   strlcpy(name, (yyvsp[0].string), sizeof(name));
-                   free((yyvsp[-1].string));
-                   free((yyvsp[0].string));
-               }
-    break;
+      /* Print the symbols being reduced, and their result.  */
+      for (i = yyprhs[yyn]; yyrhs[i] > 0; i++)
+       fprintf (stderr, "%s ", yytname[yyrhs[i]]);
+      fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]);
+    }
+#endif
 
-  case 11:
-#line 98 "parse.y"
-    {
-                       number = (yyvsp[0].number);
-               }
-    break;
 
-  case 12:
-#line 102 "parse.y"
-    {
+  switch (yyn) {
+
+case 5:
+#line 73 "../../../lib/com_err/parse.y"
+{
+                   id_str = yyvsp[0].string;
+               ;
+    break;}
+case 6:
+#line 79 "../../../lib/com_err/parse.y"
+{
+                   base_id = name2number(yyvsp[0].string);
+                   strlcpy(name, yyvsp[0].string, sizeof(name));
+                   free(yyvsp[0].string);
+               ;
+    break;}
+case 7:
+#line 85 "../../../lib/com_err/parse.y"
+{
+                   base_id = name2number(yyvsp[-1].string);
+                   strlcpy(name, yyvsp[0].string, sizeof(name));
+                   free(yyvsp[-1].string);
+                   free(yyvsp[0].string);
+               ;
+    break;}
+case 10:
+#line 98 "../../../lib/com_err/parse.y"
+{
+                       number = yyvsp[0].number;
+               ;
+    break;}
+case 11:
+#line 102 "../../../lib/com_err/parse.y"
+{
                    free(prefix);
-                   asprintf (&prefix, "%s_", (yyvsp[0].string));
+                   asprintf (&prefix, "%s_", yyvsp[0].string);
                    if (prefix == NULL)
                        errx(1, "malloc");
-                   free((yyvsp[0].string));
-               }
-    break;
-
-  case 13:
-#line 110 "parse.y"
-    {
+                   free(yyvsp[0].string);
+               ;
+    break;}
+case 12:
+#line 110 "../../../lib/com_err/parse.y"
+{
                    prefix = realloc(prefix, 1);
                    if (prefix == NULL)
                        errx(1, "malloc");
                    *prefix = '\0';
-               }
-    break;
-
-  case 14:
-#line 117 "parse.y"
-    {
+               ;
+    break;}
+case 13:
+#line 117 "../../../lib/com_err/parse.y"
+{
                    struct error_code *ec = malloc(sizeof(*ec));
                    
                    if (ec == NULL)
@@ -1137,258 +792,246 @@ yyreduce:
                    ec->next = NULL;
                    ec->number = number;
                    if(prefix && *prefix != '\0') {
-                       asprintf (&ec->name, "%s%s", prefix, (yyvsp[-2].string));
+                       asprintf (&ec->name, "%s%s", prefix, yyvsp[-2].string);
                        if (ec->name == NULL)
                            errx(1, "malloc");
-                       free((yyvsp[-2].string));
+                       free(yyvsp[-2].string);
                    } else
-                       ec->name = (yyvsp[-2].string);
-                   ec->string = (yyvsp[0].string);
+                       ec->name = yyvsp[-2].string;
+                   ec->string = yyvsp[0].string;
                    APPEND(codes, ec);
                    number++;
-               }
-    break;
-
-  case 15:
-#line 137 "parse.y"
-    {
+               ;
+    break;}
+case 14:
+#line 137 "../../../lib/com_err/parse.y"
+{
                        YYACCEPT;
-               }
-    break;
-
-
-    }
-
-/* Line 1037 of yacc.c.  */
-#line 1164 "$base.c"
+               ;
+    break;}
+}
+   /* the action file gets copied in in place of this dollarsign */
+#line 543 "/usr/share/bison.simple"
 \f
   yyvsp -= yylen;
   yyssp -= yylen;
+#ifdef YYLSP_NEEDED
+  yylsp -= yylen;
+#endif
 
-
-  YY_STACK_PRINT (yyss, yyssp);
+#if YYDEBUG != 0
+  if (yydebug)
+    {
+      short *ssp1 = yyss - 1;
+      fprintf (stderr, "state stack now");
+      while (ssp1 != yyssp)
+       fprintf (stderr, " %d", *++ssp1);
+      fprintf (stderr, "\n");
+    }
+#endif
 
   *++yyvsp = yyval;
 
+#ifdef YYLSP_NEEDED
+  yylsp++;
+  if (yylen == 0)
+    {
+      yylsp->first_line = yylloc.first_line;
+      yylsp->first_column = yylloc.first_column;
+      yylsp->last_line = (yylsp-1)->last_line;
+      yylsp->last_column = (yylsp-1)->last_column;
+      yylsp->text = 0;
+    }
+  else
+    {
+      yylsp->last_line = (yylsp+yylen-1)->last_line;
+      yylsp->last_column = (yylsp+yylen-1)->last_column;
+    }
+#endif
 
-  /* Now `shift' the result of the reduction.  Determine what state
-     that goes to, based on the state we popped back to and the rule
-     number reduced by.  */
+  /* Now "shift" the result of the reduction.
+     Determine what state that goes to,
+     based on the state we popped back to
+     and the rule number reduced by.  */
 
   yyn = yyr1[yyn];
 
-  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
-  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+  yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
+  if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
     yystate = yytable[yystate];
   else
-    yystate = yydefgoto[yyn - YYNTOKENS];
+    yystate = yydefgoto[yyn - YYNTBASE];
 
   goto yynewstate;
 
+yyerrlab:   /* here on detecting error */
 
-/*------------------------------------.
-| yyerrlab -- here on detecting error |
-`------------------------------------*/
-yyerrlab:
-  /* If not already recovering from an error, report this error.  */
-  if (!yyerrstatus)
+  if (! yyerrstatus)
+    /* If not already recovering from an error, report this error.  */
     {
       ++yynerrs;
-#if YYERROR_VERBOSE
+
+#ifdef YYERROR_VERBOSE
       yyn = yypact[yystate];
 
-      if (YYPACT_NINF < yyn && yyn < YYLAST)
+      if (yyn > YYFLAG && yyn < YYLAST)
        {
-         YYSIZE_T yysize = 0;
-         int yytype = YYTRANSLATE (yychar);
-         const char* yyprefix;
-         char *yymsg;
-         int yyx;
-
-         /* Start YYX at -YYN if negative to avoid negative indexes in
-            YYCHECK.  */
-         int yyxbegin = yyn < 0 ? -yyn : 0;
-
-         /* Stay within bounds of both yycheck and yytname.  */
-         int yychecklim = YYLAST - yyn;
-         int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
-         int yycount = 0;
-
-         yyprefix = ", expecting ";
-         for (yyx = yyxbegin; yyx < yyxend; ++yyx)
-           if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
-             {
-               yysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]);
-               yycount += 1;
-               if (yycount == 5)
-                 {
-                   yysize = 0;
-                   break;
-                 }
-             }
-         yysize += (sizeof ("syntax error, unexpected ")
-                    + yystrlen (yytname[yytype]));
-         yymsg = (char *) YYSTACK_ALLOC (yysize);
-         if (yymsg != 0)
+         int size = 0;
+         char *msg;
+         int x, count;
+
+         count = 0;
+         /* Start X at -yyn if nec to avoid negative indexes in yycheck.  */
+         for (x = (yyn < 0 ? -yyn : 0);
+              x < (sizeof(yytname) / sizeof(char *)); x++)
+           if (yycheck[x + yyn] == x)
+             size += strlen(yytname[x]) + 15, count++;
+         msg = (char *) malloc(size + 15);
+         if (msg != 0)
            {
-             char *yyp = yystpcpy (yymsg, "syntax error, unexpected ");
-             yyp = yystpcpy (yyp, yytname[yytype]);
+             strcpy(msg, "parse error");
 
-             if (yycount < 5)
+             if (count < 5)
                {
-                 yyprefix = ", expecting ";
-                 for (yyx = yyxbegin; yyx < yyxend; ++yyx)
-                   if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+                 count = 0;
+                 for (x = (yyn < 0 ? -yyn : 0);
+                      x < (sizeof(yytname) / sizeof(char *)); x++)
+                   if (yycheck[x + yyn] == x)
                      {
-                       yyp = yystpcpy (yyp, yyprefix);
-                       yyp = yystpcpy (yyp, yytname[yyx]);
-                       yyprefix = " or ";
+                       strcat(msg, count == 0 ? ", expecting `" : " or `");
+                       strcat(msg, yytname[x]);
+                       strcat(msg, "'");
+                       count++;
                      }
                }
-             yyerror (yymsg);
-             YYSTACK_FREE (yymsg);
+             yyerror(msg);
+             free(msg);
            }
          else
-           yyerror ("syntax error; also virtual memory exhausted");
+           yyerror ("parse error; also virtual memory exceeded");
        }
       else
 #endif /* YYERROR_VERBOSE */
-       yyerror ("syntax error");
+       yyerror("parse error");
     }
 
-
+  goto yyerrlab1;
+yyerrlab1:   /* here on error raised explicitly by an action */
 
   if (yyerrstatus == 3)
     {
-      /* If just tried and failed to reuse look-ahead token after an
-        error, discard it.  */
-
-      if (yychar <= YYEOF)
-        {
-          /* If at end of input, pop the error token,
-            then the rest of the stack, then return failure.  */
-         if (yychar == YYEOF)
-            for (;;)
-              {
-
-                YYPOPSTACK;
-                if (yyssp == yyss)
-                  YYABORT;
-                yydestruct ("Error: popping",
-                             yystos[*yyssp], yyvsp);
-              }
-        }
-      else
-       {
-         yydestruct ("Error: discarding", yytoken, &yylval);
-         yychar = YYEMPTY;
-       }
+      /* if just tried and failed to reuse lookahead token after an error, discard it.  */
+
+      /* return failure if at end of input */
+      if (yychar == YYEOF)
+       YYABORT;
+
+#if YYDEBUG != 0
+      if (yydebug)
+       fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
+#endif
+
+      yychar = YYEMPTY;
     }
 
-  /* Else will try to reuse look-ahead token after shifting the error
-     token.  */
-  goto yyerrlab1;
+  /* Else will try to reuse lookahead token
+     after shifting the error token.  */
 
+  yyerrstatus = 3;             /* Each real token shifted decrements this */
 
-/*---------------------------------------------------.
-| yyerrorlab -- error raised explicitly by YYERROR.  |
-`---------------------------------------------------*/
-yyerrorlab:
+  goto yyerrhandle;
 
-#ifdef __GNUC__
-  /* Pacify GCC when the user code never invokes YYERROR and the label
-     yyerrorlab therefore never appears in user code.  */
-  if (0)
-     goto yyerrorlab;
-#endif
+yyerrdefault:  /* current state does not do anything special for the error token. */
 
-yyvsp -= yylen;
-  yyssp -= yylen;
-  yystate = *yyssp;
-  goto yyerrlab1;
+#if 0
+  /* This is wrong; only states that explicitly want error tokens
+     should shift them.  */
+  yyn = yydefact[yystate];  /* If its default is to accept any token, ok.  Otherwise pop it.*/
+  if (yyn) goto yydefault;
+#endif
 
+yyerrpop:   /* pop the current state because it cannot handle the error token */
 
-/*-------------------------------------------------------------.
-| yyerrlab1 -- common code for both syntax error and YYERROR.  |
-`-------------------------------------------------------------*/
-yyerrlab1:
-  yyerrstatus = 3;     /* Each real token shifted decrements this.  */
+  if (yyssp == yyss) YYABORT;
+  yyvsp--;
+  yystate = *--yyssp;
+#ifdef YYLSP_NEEDED
+  yylsp--;
+#endif
 
-  for (;;)
+#if YYDEBUG != 0
+  if (yydebug)
     {
-      yyn = yypact[yystate];
-      if (yyn != YYPACT_NINF)
-       {
-         yyn += YYTERROR;
-         if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
-           {
-             yyn = yytable[yyn];
-             if (0 < yyn)
-               break;
-           }
-       }
+      short *ssp1 = yyss - 1;
+      fprintf (stderr, "Error: state stack now");
+      while (ssp1 != yyssp)
+       fprintf (stderr, " %d", *++ssp1);
+      fprintf (stderr, "\n");
+    }
+#endif
 
-      /* Pop the current state because it cannot handle the error token.  */
-      if (yyssp == yyss)
-       YYABORT;
+yyerrhandle:
+
+  yyn = yypact[yystate];
+  if (yyn == YYFLAG)
+    goto yyerrdefault;
 
+  yyn += YYTERROR;
+  if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
+    goto yyerrdefault;
 
-      yydestruct ("Error: popping", yystos[yystate], yyvsp);
-      YYPOPSTACK;
-      yystate = *yyssp;
-      YY_STACK_PRINT (yyss, yyssp);
+  yyn = yytable[yyn];
+  if (yyn < 0)
+    {
+      if (yyn == YYFLAG)
+       goto yyerrpop;
+      yyn = -yyn;
+      goto yyreduce;
     }
+  else if (yyn == 0)
+    goto yyerrpop;
 
   if (yyn == YYFINAL)
     YYACCEPT;
 
-  *++yyvsp = yylval;
-
+#if YYDEBUG != 0
+  if (yydebug)
+    fprintf(stderr, "Shifting error token, ");
+#endif
 
-  /* Shift the error token. */
-  YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+  *++yyvsp = yylval;
+#ifdef YYLSP_NEEDED
+  *++yylsp = yylloc;
+#endif
 
   yystate = yyn;
   goto yynewstate;
 
-
-/*-------------------------------------.
-| yyacceptlab -- YYACCEPT comes here.  |
-`-------------------------------------*/
-yyacceptlab:
-  yyresult = 0;
-  goto yyreturn;
-
-/*-----------------------------------.
-| yyabortlab -- YYABORT comes here.  |
-`-----------------------------------*/
-yyabortlab:
-  yydestruct ("Error: discarding lookahead",
-              yytoken, &yylval);
-  yychar = YYEMPTY;
-  yyresult = 1;
-  goto yyreturn;
-
-#ifndef yyoverflow
-/*----------------------------------------------.
-| yyoverflowlab -- parser overflow comes here.  |
-`----------------------------------------------*/
-yyoverflowlab:
-  yyerror ("parser stack overflow");
-  yyresult = 2;
-  /* Fall through.  */
+ yyacceptlab:
+  /* YYACCEPT comes here.  */
+  if (yyfree_stacks)
+    {
+      free (yyss);
+      free (yyvs);
+#ifdef YYLSP_NEEDED
+      free (yyls);
 #endif
+    }
+  return 0;
 
-yyreturn:
-#ifndef yyoverflow
-  if (yyss != yyssa)
-    YYSTACK_FREE (yyss);
+ yyabortlab:
+  /* YYABORT comes here.  */
+  if (yyfree_stacks)
+    {
+      free (yyss);
+      free (yyvs);
+#ifdef YYLSP_NEEDED
+      free (yyls);
 #endif
-  return yyresult;
+    }
+  return 1;
 }
-
-
-#line 142 "parse.y"
+#line 142 "../../../lib/com_err/parse.y"
 
 
 static long
@@ -1421,4 +1064,3 @@ yyerror (char *s)
 {
      error_message ("%s\n", s);
 }
-
index ef7b9ba91e2de083663557a7ef2e06174d2eec4e..07e33790d321b3d90151bce5b3a16292dd02863a 100644 (file)
@@ -1,70 +1,15 @@
-/* A Bison parser, made by GNU Bison 2.0.  */
-
-/* Skeleton parser for Yacc-like parsing with Bison,
-   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2, or (at your option)
-   any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
-
-/* As a special exception, when this file is copied by Bison into a
-   Bison output file, you may use that output file without restriction.
-   This special exception was added by the Free Software Foundation
-   in version 1.24 of Bison.  */
-
-/* Tokens.  */
-#ifndef YYTOKENTYPE
-# define YYTOKENTYPE
-   /* Put the tokens into the symbol table, so that GDB and other debuggers
-      know about them.  */
-   enum yytokentype {
-     ET = 258,
-     INDEX = 259,
-     PREFIX = 260,
-     EC = 261,
-     ID = 262,
-     END = 263,
-     STRING = 264,
-     NUMBER = 265
-   };
-#endif
-#define ET 258
-#define INDEX 259
-#define PREFIX 260
-#define EC 261
-#define ID 262
-#define END 263
-#define STRING 264
-#define NUMBER 265
-
-
-
-
-#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
-#line 53 "parse.y"
-typedef union YYSTYPE {
+typedef union {
   char *string;
   int number;
 } YYSTYPE;
-/* Line 1318 of yacc.c.  */
-#line 62 "parse.h"
-# define yystype YYSTYPE /* obsolescent; will be withdrawn */
-# define YYSTYPE_IS_DECLARED 1
-# define YYSTYPE_IS_TRIVIAL 1
-#endif
-
-extern YYSTYPE yylval;
-
+#define        ET      257
+#define        INDEX   258
+#define        PREFIX  259
+#define        EC      260
+#define        ID      261
+#define        END     262
+#define        STRING  263
+#define        NUMBER  264
 
 
+extern YYSTYPE yylval;
index fd6ac63ec2e4b5d5fe4e33c1be0588cc75bb5e4b..34480dbe7e855c1991dce370f7dc5c27d4935193 100644 (file)
 #include <md4.h>
 #include <md5.h>
 
+typedef int (*evp_md_init)(EVP_MD_CTX *);
+typedef int (*evp_md_update)(EVP_MD_CTX *,const void *, size_t);
+typedef int (*evp_md_final)(void *, EVP_MD_CTX *);
+typedef int (*evp_md_cleanup)(EVP_MD_CTX *);
+
 struct hc_evp_md {
     int hash_size;
     int block_size;
     int ctx_size;
-    int (*init)(EVP_MD_CTX *);
-    int (*update)(EVP_MD_CTX *,const void *, size_t );
-    int (*final)(void *, EVP_MD_CTX *);
-    int (*cleanup)(EVP_MD_CTX *);
+    evp_md_init init;
+    evp_md_update update;
+    evp_md_final final;
+    evp_md_cleanup cleanup;
 };
 
 /*
@@ -151,19 +156,18 @@ EVP_Digest(const void *data, size_t dsize, void *hash, unsigned int *hsize,
  *
  */
 
-static const struct hc_evp_md sha256 = {
-    32,
-    64,
-    sizeof(SHA256_CTX),
-    (void *)SHA256_Init,
-    (void *)SHA256_Update,
-    (void *)SHA256_Final,
-    NULL
-};
-
 const EVP_MD *
 EVP_sha256(void)
 {
+    static const struct hc_evp_md sha256 = {
+       32,
+       64,
+       sizeof(SHA256_CTX),
+       (evp_md_init)SHA256_Init,
+       (evp_md_update)SHA256_Update,
+       (evp_md_final)SHA256_Final,
+       NULL
+    };
     return &sha256;
 }
 
@@ -171,9 +175,9 @@ static const struct hc_evp_md sha1 = {
     20,
     64,
     sizeof(SHA_CTX),
-    (void *)SHA1_Init,
-    (void *)SHA1_Update,
-    (void *)SHA1_Final,
+    (evp_md_init)SHA1_Init,
+    (evp_md_update)SHA1_Update,
+    (evp_md_final)SHA1_Final,
     NULL
 };
 
@@ -196,9 +200,9 @@ EVP_md5(void)
        16,
        64,
        sizeof(MD5_CTX),
-       (void *)MD5_Init,
-       (void *)MD5_Update,
-       (void *)MD5_Final,
+       (evp_md_init)MD5_Init,
+       (evp_md_update)MD5_Update,
+       (evp_md_final)MD5_Final,
        NULL
     };
     return &md5;
@@ -211,9 +215,9 @@ EVP_md4(void)
        16,
        64,
        sizeof(MD4_CTX),
-       (void *)MD4_Init,
-       (void *)MD4_Update,
-       (void *)MD4_Final,
+       (evp_md_init)MD4_Init,
+       (evp_md_update)MD4_Update,
+       (evp_md_final)MD4_Final,
        NULL
     };
     return &md4;
@@ -226,9 +230,9 @@ EVP_md2(void)
        16,
        16,
        sizeof(MD2_CTX),
-       (void *)MD2_Init,
-       (void *)MD2_Update,
-       (void *)MD2_Final,
+       (evp_md_init)MD2_Init,
+       (evp_md_update)MD2_Update,
+       (evp_md_final)MD2_Final,
        NULL
     };
     return &md2;
@@ -258,9 +262,9 @@ EVP_md_null(void)
        0,
        0,
        0,
-       (void *)null_Init,
-       (void *)null_Update,
-       (void *)null_Final,
+       (evp_md_init)null_Init,
+       (evp_md_update)null_Update,
+       (evp_md_final)null_Final,
        NULL
     };
     return &null;
@@ -878,3 +882,24 @@ EVP_BytesToKey(const EVP_CIPHER *type,
     return EVP_CIPHER_key_length(type);
 }
 
+/*
+ *
+ */
+
+void
+OpenSSL_add_all_algorithms(void)
+{
+    return;
+}
+
+void
+OpenSSL_add_all_algorithms_conf(void)
+{
+    return;
+}
+
+void
+OpenSSL_add_all_algorithms_noconf(void)
+{
+    return;
+}
index 17d6d5fd4152768ede244943581c69cc7625603a..2fdf8d076543e0b1d06de9cb55c4d12b288b07e2 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
-/* $Id: evp.h,v 1.8 2006/04/21 15:00:54 lha Exp $ */
+/* $Id: evp.h,v 1.11 2006/10/07 17:21:24 lha Exp $ */
 
 #ifndef HEIM_EVP_H
 #define HEIM_EVP_H 1
@@ -89,6 +89,9 @@
 #define PKCS5_PBKDF2_HMAC_SHA1 hc_PKCS5_PBKDF2_HMAC_SHA1
 #define EVP_BytesToKey hc_EVP_BytesToKey
 #define EVP_get_cipherbyname hc_EVP_get_cipherbyname
+#define        OpenSSL_add_all_algorithms hc_OpenSSL_add_all_algorithms
+#define        OpenSSL_add_all_algorithms_conf hc_OpenSSL_add_all_algorithms_conf
+#define        OpenSSL_add_all_algorithms_noconf hc_OpenSSL_add_all_algorithms_noconf
 
 /*
  *
@@ -241,4 +244,12 @@ int        EVP_BytesToKey(const EVP_CIPHER *, const EVP_MD *,
                       unsigned int, void *, void *);
 
 
+/*
+ *
+ */
+
+void   OpenSSL_add_all_algorithms(void);
+void   OpenSSL_add_all_algorithms_conf(void);
+void   OpenSSL_add_all_algorithms_noconf(void);
+
 #endif /* HEIM_EVP_H */
index 4bcb0defa582dc7db97f5c7c637ba3aa3d0ca428..848b987a90c3295f75a041e6daf1f38c0fd54d8d 100644 (file)
@@ -29,8 +29,8 @@ HMAC_CTX_cleanup(HMAC_CTX *ctx)
        ctx->ipad = NULL;
     }
     if (ctx->ctx) {
-           EVP_MD_CTX_destroy(ctx->ctx);
-           ctx->ctx = NULL;
+       EVP_MD_CTX_destroy(ctx->ctx);
+       ctx->ctx = NULL;
     }
 }
 
diff --git a/source4/heimdal/lib/des/rand-unix.c b/source4/heimdal/lib/des/rand-unix.c
new file mode 100644 (file)
index 0000000..a51c6c0
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * 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. 
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+RCSID("$Id: rand-unix.c,v 1.2 2006/10/21 21:09:14 lha Exp $");
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <rand.h>
+
+#include <roken.h>
+
+/*
+ * Unix /dev/random
+ */
+
+static int
+get_device_fd(int flags)
+{
+    static const char *rnd_devices[] = {
+       "/dev/urandom",
+       "/dev/random",
+       "/dev/srandom",
+       "/dev/arandom",
+       NULL
+    };
+    const char **p;
+
+    for(p = rnd_devices; *p; p++) {
+       int fd = open(*p, flags | O_NDELAY);
+       if(fd >= 0)
+           return fd;
+    }
+    return -1;
+}
+
+static void
+unix_seed(const void *indata, int size)
+{
+    int fd;
+
+    if (size <= 0)
+       return;
+
+    fd = get_device_fd(O_WRONLY);
+    if (fd < 0)
+       return;
+
+    write(fd, indata, size);
+    close(fd);
+
+}
+
+static int 
+unix_bytes(unsigned char *outdata, int size)
+{
+    ssize_t count;
+    int fd;
+
+    if (size <= 0)
+       return 0;
+
+    fd = get_device_fd(O_RDONLY);
+    if (fd < 0)
+       return 0;
+
+    while (size > 0) {
+       count = read (fd, outdata, size);
+       if (count < 0 && errno == EINTR)
+           continue;
+       else if (count <= 0) {
+           close(fd);
+           return 0;
+       }
+       outdata += count;
+       size -= count;
+    }
+    close(fd);
+
+    return 1;
+}
+
+static void
+unix_cleanup(void)
+{
+}
+
+static void
+unix_add(const void *indata, int size, double entropi)
+{
+    unix_seed(indata, size);
+}
+
+static int
+unix_pseudorand(unsigned char *outdata, int size)
+{
+    return unix_bytes(outdata, size);
+}
+
+static int
+unix_status(void)
+{
+    int fd;
+
+    fd = get_device_fd(O_RDONLY);
+    if (fd < 0)
+       return 0;
+    close(fd);
+
+    return 1;
+}
+
+const RAND_METHOD hc_rand_unix_method = {
+    unix_seed,
+    unix_bytes,
+    unix_cleanup,
+    unix_add,
+    unix_pseudorand,
+    unix_status
+};
diff --git a/source4/heimdal/lib/des/rand.c b/source4/heimdal/lib/des/rand.c
new file mode 100644 (file)
index 0000000..6eb959b
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * 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. 
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+RCSID("$Id: rand.c,v 1.7 2006/10/16 10:23:01 lha Exp $");
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <rand.h>
+
+#include <roken.h>
+
+extern RAND_METHOD hc_rand_unix_method;
+static const RAND_METHOD *selected_meth = &hc_rand_unix_method;
+
+void
+RAND_seed(const void *indata, size_t size)
+{
+    (*selected_meth->seed)(indata, size);
+}
+
+int
+RAND_bytes(void *outdata, size_t size)
+{
+    return (*selected_meth->bytes)(outdata, size);
+}
+
+void
+RAND_cleanup(void)
+{
+    (*selected_meth->cleanup)();
+}
+
+void
+RAND_add(const void *indata, size_t size, double entropi)
+{
+    (*selected_meth->add)(indata, size, entropi);
+}
+
+int
+RAND_pseudo_bytes(void *outdata, size_t size)
+{
+    return (*selected_meth->pseudorand)(outdata, size);
+}
+
+int
+RAND_status(void)
+{
+    return (*selected_meth->status)();
+}
+
+int
+RAND_set_rand_method(const RAND_METHOD *meth)
+{
+    selected_meth = meth;
+    return 1;
+}
+
+const RAND_METHOD *
+RAND_get_rand_method(void)
+{
+    return selected_meth;
+}
+
+int
+RAND_set_rand_engine(ENGINE *engine)
+{
+    return 1;
+}
+
+int
+RAND_load_file(const char *filename, size_t size)
+{
+    return 1;
+}
+
+int
+RAND_write_file(const char *filename)
+{
+    return 1;
+}
+
+int
+RAND_egd(const char *filename)
+{
+    return 1;
+}
index 276367e18697f2d8dd9345e6b278688a00a90ad6..25b0ad293cc3a574bb1fea6d1f7dfed6de41bab4 100644 (file)
@@ -33,7 +33,7 @@
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
-RCSID("$Id: ui.c,v 1.5 2006/01/08 21:47:29 lha Exp $");
+RCSID("$Id: ui.c,v 1.6 2006/09/22 15:45:57 lha Exp $");
 #endif
 
 #include <stdio.h>
@@ -53,11 +53,16 @@ intr(int sig)
     intr_flag++;
 }
 
+#ifndef NSIG
+#define NSIG 47
+#endif
+
 static int
 read_string(const char *preprompt, const char *prompt, 
            char *buf, size_t len, int echo)
 {
-    struct sigaction sigs[47];
+    struct sigaction sigs[NSIG];
+    int oksigs[NSIG];
     struct sigaction sa;
     FILE *tty;
     int ret = 0;
@@ -68,12 +73,16 @@ read_string(const char *preprompt, const char *prompt,
 
     struct termios t_new, t_old;
 
+    memset(&oksigs, 0, sizeof(oksigs));
+
     memset(&sa, 0, sizeof(sa));
     sa.sa_handler = intr;
     sigemptyset(&sa.sa_mask);
     sa.sa_flags = 0;
-    for(i = 0; i < sizeof(sigs) / sizeof(sigs[0]); i++)
-       if (i != SIGALRM) sigaction(i, &sa, &sigs[i]);
+    for(i = 1; i < sizeof(sigs) / sizeof(sigs[0]); i++)
+       if (i != SIGALRM) 
+           if (sigaction(i, &sa, &sigs[i]) == 0)
+               oksigs[i] = 1;
 
     if((tty = fopen("/dev/tty", "r")) == NULL)
        tty = stdin;
@@ -114,8 +123,9 @@ read_string(const char *preprompt, const char *prompt,
     if(tty != stdin)
        fclose(tty);
 
-    for(i = 0; i < sizeof(sigs) / sizeof(sigs[0]); i++)
-       if (i != SIGALRM) sigaction(i, &sigs[i], NULL);
+    for(i = 1; i < sizeof(sigs) / sizeof(sigs[0]); i++)
+       if (oksigs[i])
+           sigaction(i, &sigs[i], NULL);
     
     if(ret)
        return -3;
diff --git a/source4/heimdal/lib/gssapi/accept_sec_context.c b/source4/heimdal/lib/gssapi/accept_sec_context.c
deleted file mode 100644 (file)
index 41a54bd..0000000
+++ /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;
-}
index eac2737f4306c730213e8f7000defd76f02ac970..340b35377d6c4de5ea694917fb0f0eac04bfabc3 100644 (file)
@@ -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. 
  *
  * 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 (file)
index 0000000..2389076
--- /dev/null
@@ -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 (file)
index 0000000..8c025c8
--- /dev/null
@@ -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 (file)
index 0000000..0a856e3
--- /dev/null
@@ -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 (file)
index 81169a8..0000000
+++ /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 (file)
index 0000000..a05919b
--- /dev/null
@@ -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 (file)
index 4f0d237..0000000
+++ /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 (file)
index 9ed1ff4..0000000
+++ /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;
-}
similarity index 88%
rename from source4/heimdal/lib/gssapi/8003.c
rename to source4/heimdal/lib/gssapi/krb5/8003.c
index 359bb6e7156baa798a58d568281ae6fa8321afa7..0123f67e0953b10873638230b1e2a9d5e93792fc 100644 (file)
  * 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 (file)
index 0000000..e42bb11
--- /dev/null
@@ -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;
+}
similarity index 63%
rename from source4/heimdal/lib/gssapi/acquire_cred.c
rename to source4/heimdal/lib/gssapi/krb5/acquire_cred.c
index fa5d709a30362756c5d00d6bac723efc41fd80af..df6e1374025b4a667076618e067dbc2121ed52d9 100644 (file)
@@ -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. 
  *
  * 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 (file)
index 0000000..4892e84
--- /dev/null
@@ -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;
+}
similarity index 90%
rename from source4/heimdal/lib/gssapi/add_oid_set_member.c
rename to source4/heimdal/lib/gssapi/krb5/add_oid_set_member.c
index ed654fc8c5b80505b2e59d1983e4deabaefc7003..b0ec2c60d8031a442300020a048461f84c145f32 100644 (file)
  * 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;
 
similarity index 88%
rename from source4/heimdal/lib/gssapi/address_to_krb5addr.c
rename to source4/heimdal/lib/gssapi/krb5/address_to_krb5addr.c
index 13a6825f5561b13e3e42c30cf82f57c9dc5b63b5..9aec53faaae69834c0b0600d18cfe32bbb18cdad 100644 (file)
  * 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;  
 }
similarity index 73%
rename from source4/heimdal/lib/gssapi/arcfour.c
rename to source4/heimdal/lib/gssapi/krb5/arcfour.c
index 936a20d403053ba265d03b1925906720e290d887..82851f5a789b225cca93ff868d30ccf5e2580340 100644 (file)
@@ -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);
@@ -325,40 +336,9 @@ _gssapi_verify_mic_arcfour(OM_uint32 * minor_status,
     return GSS_S_COMPLETE;
 }
 
-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 (file)
index 0000000..f69300b
--- /dev/null
@@ -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);
+}
similarity index 74%
rename from source4/heimdal/lib/gssapi/cfx.c
rename to source4/heimdal/lib/gssapi/krb5/cfx.c
index ef7907c0de1d4140b2fa02426b896556177ccd8a..cb3f9ee5d3178654817f9cd04ef612c60f0a7172 100755 (executable)
@@ -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;
     }
similarity index 64%
rename from source4/heimdal/lib/gssapi/cfx.h
rename to source4/heimdal/lib/gssapi/krb5/cfx.h
index d9bdd9da19e253bf2d912ce9056193a621b1cf77..1120544fbeb285876ae01e25478aa1a5c636f911 100755 (executable)
@@ -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 (file)
index 0000000..3e0f7ed
--- /dev/null
@@ -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;
+}
similarity index 63%
rename from source4/heimdal/lib/gssapi/compat.c
rename to source4/heimdal/lib/gssapi/krb5/compat.c
index 5605c48023fe50131b78bae82ab87e8d9e650e5e..0ea2fce0e8374bb1f011892f233c00f47338ae8a 100644 (file)
  * 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
similarity index 82%
rename from source4/heimdal/lib/gssapi/context_time.c
rename to source4/heimdal/lib/gssapi/krb5/context_time.c
index ee1dc6fe93af8de81232c943c4890b93a29c054a..4e9d9f5d1d7d4c7d5c6cfa0e57896e96a3c559cb 100644 (file)
  * 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;
 
similarity index 50%
rename from source4/heimdal/lib/gssapi/copy_ccache.c
rename to source4/heimdal/lib/gssapi/krb5/copy_ccache.c
index 782b701e4473b809e10a26b305d03e2ba534e9c8..99aa2ccb434cd470a6c422f6972cd8ad80c5b24a 100644 (file)
  * 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;
-}
similarity index 93%
rename from source4/heimdal/lib/gssapi/create_emtpy_oid_set.c
rename to source4/heimdal/lib/gssapi/krb5/create_emtpy_oid_set.c
index 1a25e0d7815e11d25e49cefeb7dd6db79aa7b573..550995125a8c088ec87bfde387bc9d6290dc03b6 100644 (file)
  * 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
            )
similarity index 91%
rename from source4/heimdal/lib/gssapi/decapsulate.c
rename to source4/heimdal/lib/gssapi/krb5/decapsulate.c
index 08df361776c3c0f34d2882fa7c9c2bff7998699d..eadec1ef03c03420e32b33fcb4498ca74b6c4334 100644 (file)
@@ -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);
similarity index 61%
rename from source4/heimdal/lib/gssapi/delete_sec_context.c
rename to source4/heimdal/lib/gssapi/krb5/delete_sec_context.c
index f1842def7c8c5d7f38e376a2726e31914ab09b3a..e890d7d2c2653bf282206f9ddffe65199bfb529f 100644 (file)
  * 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;
 }
similarity index 89%
rename from source4/heimdal/lib/gssapi/display_name.c
rename to source4/heimdal/lib/gssapi/krb5/display_name.c
index 27a232fd3cf6791bfec28f2f43193e50a5ebadd1..8fce7d8572446d11300073586e37e80c634e9c7c 100644 (file)
  * 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);
similarity index 88%
rename from source4/heimdal/lib/gssapi/display_status.c
rename to source4/heimdal/lib/gssapi/krb5/display_status.c
index 0aa88bb57c5faea6191f8f162060057053be7c82..11926ca5579f676d3e8525d8331b2157b0aa40aa 100644 (file)
@@ -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",
similarity index 85%
rename from source4/heimdal/lib/gssapi/duplicate_name.c
rename to source4/heimdal/lib/gssapi/krb5/duplicate_name.c
index 2b54e90ec89dfcdeb87a9c8356116eb731ef969a..475ae61efce0e79ec1d828a76266dc7e3a8e0852 100644 (file)
  * 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;
similarity index 87%
rename from source4/heimdal/lib/gssapi/encapsulate.c
rename to source4/heimdal/lib/gssapi/krb5/encapsulate.c
index 4d488a6c42240d8b52184978f16b16186c4ff49f..a015a95103d8e574e8d020b79968d9ab3a6ae250 100644 (file)
@@ -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 (file)
index 0000000..d00c458
--- /dev/null
@@ -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 (file)
index 0000000..aff03a0
--- /dev/null
@@ -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;
+}
similarity index 67%
rename from source4/heimdal/lib/gssapi/external.c
rename to source4/heimdal/lib/gssapi/krb5/external.c
index f8c1d23f981eae262e2fe84758aead6e6a18255d..7419bc2fe8edeef9b910910f92d4945d742a916e 100644 (file)
  * 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
@@ -225,18 +226,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
@@ -260,8 +249,160 @@ 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;
+}
similarity index 76%
rename from source4/heimdal/lib/gssapi/get_mic.c
rename to source4/heimdal/lib/gssapi/krb5/get_mic.c
index 76f69cf41c303660a4dab235d0f94f5f1e851629..5a078d634d0808e07079479fe1312415c3cb1784 100644 (file)
  * 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 (file)
index 0000000..426c0ab
--- /dev/null
@@ -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 (file)
index 0000000..4d81403
--- /dev/null
@@ -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
similarity index 84%
rename from source4/heimdal/lib/gssapi/import_name.c
rename to source4/heimdal/lib/gssapi/krb5/import_name.c
index d393aa1a51f318f8070fe98b0c824acd9c459db2..dc24ed5cf2088ecd9e9f1057a58c9ca16cc0d4ce 100644 (file)
  * 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 (file)
index 0000000..8131e26
--- /dev/null
@@ -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 (file)
index 0000000..3827533
--- /dev/null
@@ -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;
+}
similarity index 62%
rename from source4/heimdal/lib/gssapi/init.c
rename to source4/heimdal/lib/gssapi/krb5/init.c
index 11d7c9bb9ff950dd6a5045aeaac34e725e62063f..cbef8740b7af058a11bfadb78645e4f4acbdf8e7 100644 (file)
  * 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 (file)
index 0000000..00f2543
--- /dev/null
@@ -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 (file)
index 0000000..ef43e68
--- /dev/null
@@ -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 (file)
index 0000000..0593729
--- /dev/null
@@ -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;
+}
similarity index 51%
rename from source4/heimdal/lib/gssapi/arcfour.h
rename to source4/heimdal/lib/gssapi/krb5/inquire_cred_by_mech.c
index 0406b64b09923fae4b5122b71566005c011b20d7..954a5e3119c7b6a69009953fa90c3d0bf943588d 100644 (file)
  * 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 (file)
index 0000000..26927c7
--- /dev/null
@@ -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 (file)
index 0000000..5c1f082
--- /dev/null
@@ -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 (file)
index 0000000..5d8aefa
--- /dev/null
@@ -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 (file)
index 0000000..0b46cc5
--- /dev/null
@@ -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 (file)
index 0000000..99568c9
--- /dev/null
@@ -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;
+}
similarity index 93%
rename from source4/heimdal/lib/gssapi/release_buffer.c
rename to source4/heimdal/lib/gssapi/krb5/release_buffer.c
index 258b76f627687c493bb9a8d6609ecb2de5891690..b62ad0211783c42896510481e8ad7acd7c0bd528 100644 (file)
  * 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
            )
similarity index 66%
rename from source4/heimdal/lib/gssapi/release_cred.c
rename to source4/heimdal/lib/gssapi/krb5/release_cred.c
index fc9fc3fc01e81abe5e6a8627a77278c6d2732757..662461ccfd663df41023d4cb49899353ed4d55d0 100644 (file)
  * 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;
 }
 
similarity index 88%
rename from source4/heimdal/lib/gssapi/release_name.c
rename to source4/heimdal/lib/gssapi/krb5/release_name.c
index 6894ffae49c2a1122b90a20636e1535b54ac9f21..a92ad939a584cd6d96329d0ec0a0d299efb9236d 100644 (file)
  * 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;
 }
similarity index 93%
rename from source4/heimdal/lib/gssapi/release_oid_set.c
rename to source4/heimdal/lib/gssapi/krb5/release_oid_set.c
index 04eb01565f79237e801720633ff0d4edbffffe35..a9f79a30829ae7636f9cef46dfa5714910a710f7 100644 (file)
  * 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
            )
similarity index 97%
rename from source4/heimdal/lib/gssapi/sequence.c
rename to source4/heimdal/lib/gssapi/krb5/sequence.c
index 35a9b924afd32edbeb0fd08647bf47b77591e90a..3014edd04dee3b60be17656705c377619d25940f 100755 (executable)
@@ -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 (file)
index 0000000..5807ef0
--- /dev/null
@@ -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 (file)
index 0000000..67f5e8e
--- /dev/null
@@ -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;
+}
similarity index 82%
rename from source4/heimdal/lib/gssapi/test_oid_set_member.c
rename to source4/heimdal/lib/gssapi/krb5/test_oid_set_member.c
index e747c5acc1083871eeea969740828558c25060a0..5a0ac4418f71e5c5bd74b32095ac31d580291b61 100644 (file)
  * 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;
 }
similarity index 85%
rename from source4/heimdal/lib/gssapi/unwrap.c
rename to source4/heimdal/lib/gssapi/krb5/unwrap.c
index c358c1aa24d718c452538638f9a2ec16916db9dc..758390080cd3bcd882af9cb34c16140a85747c5c 100644 (file)
  * 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;
 }
similarity index 82%
rename from source4/heimdal/lib/gssapi/verify_mic.c
rename to source4/heimdal/lib/gssapi/krb5/verify_mic.c
index 7b7d437e9943285e5766768b6c5e4410acb6a23a..920937cafcdc81425a8b4557e1bb63fb39cee1c6 100644 (file)
  * 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;
 }
similarity index 57%
rename from source4/heimdal/lib/gssapi/wrap.c
rename to source4/heimdal/lib/gssapi/krb5/wrap.c
index 7072ca27546a7bd20982ab714584202071d6db3a..85141379992eccd08625ae2f7afc2a6e372355af 100644 (file)
@@ -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. 
  *
  * 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 (file)
index 0000000..7a215dd
--- /dev/null
@@ -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 (file)
index 0000000..df89e79
--- /dev/null
@@ -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 (file)
index 0000000..4d634bf
--- /dev/null
@@ -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 (file)
index 0000000..0b3554c
--- /dev/null
@@ -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 (file)
index 0000000..beffd54
--- /dev/null
@@ -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);
+}
+
old mode 100755 (executable)
new mode 100644 (file)
similarity index 66%
rename from source4/heimdal/lib/gssapi/ccache_name.c
rename to source4/heimdal/lib/gssapi/mech/gss_add_oid_set_member.c
index 3bebb83..5806cec
@@ -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. 
  *
  * 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 (file)
index 0000000..9e9bd5e
--- /dev/null
@@ -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 (file)
index 0000000..38a464b
--- /dev/null
@@ -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 (file)
index 0000000..1068bfa
--- /dev/null
@@ -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 (file)
index 0000000..4b17381
--- /dev/null
@@ -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 (file)
index 0000000..7298ec9
--- /dev/null
@@ -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 (file)
index 0000000..8ebb848
--- /dev/null
@@ -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 (file)
index 0000000..06ef8e6
--- /dev/null
@@ -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 (file)
index 0000000..79f62a7
--- /dev/null
@@ -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 (file)
index 0000000..7871f53
--- /dev/null
@@ -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 (file)
index 0000000..5ef828f
--- /dev/null
@@ -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 (file)
index 0000000..bfb0e75
--- /dev/null
@@ -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 (file)
index 0000000..d128581
--- /dev/null
@@ -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 (file)
index 0000000..bc1c39c
--- /dev/null
@@ -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 (file)
index 0000000..1acc72b
--- /dev/null
@@ -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 (file)
index 0000000..e9a8f29
--- /dev/null
@@ -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 (file)
index 0000000..9684301
--- /dev/null
@@ -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 (file)
index 0000000..5466f97
--- /dev/null
@@ -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 (file)
index 0000000..0da6c48
--- /dev/null
@@ -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 (file)
index 0000000..ccaf91b
--- /dev/null
@@ -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 (file)
index 0000000..88bbb39
--- /dev/null
@@ -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 (file)
index 0000000..2231402
--- /dev/null
@@ -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 (file)
index 0000000..771a695
--- /dev/null
@@ -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 (file)
index 0000000..3cfe89a
--- /dev/null
@@ -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 (file)
index 0000000..7052bf8
--- /dev/null
@@ -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 (file)
index 0000000..2293163
--- /dev/null
@@ -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 (file)
index 0000000..7f5632a
--- /dev/null
@@ -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 (file)
index 0000000..c6ea3ce
--- /dev/null
@@ -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 (file)
index 0000000..3d01ba6
--- /dev/null
@@ -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 (file)
index 0000000..833c582
--- /dev/null
@@ -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 (file)
index 0000000..1a8b811
--- /dev/null
@@ -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 (file)
index 0000000..1e6f399
--- /dev/null
@@ -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 (file)
index 0000000..66705bb
--- /dev/null
@@ -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 (file)
index 0000000..760621c
--- /dev/null
@@ -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 (file)
index 0000000..1286cd3
--- /dev/null
@@ -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 (file)
index 0000000..fc84fab
--- /dev/null
@@ -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 (file)
index 0000000..101657e
--- /dev/null
@@ -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 (file)
index 0000000..2f66f90
--- /dev/null
@@ -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 (file)
index 0000000..f8e013d
--- /dev/null
@@ -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 (file)
index 0000000..aa562a2
--- /dev/null
@@ -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 (file)
index 0000000..8c854e5
--- /dev/null
@@ -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 (file)
index 0000000..a71a8b7
--- /dev/null
@@ -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 (file)
index 0000000..128dc78
--- /dev/null
@@ -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 (file)
index 0000000..1c9484b
--- /dev/null
@@ -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 (file)
index 0000000..33ee033
--- /dev/null
@@ -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 (file)
index 0000000..a99d17e
--- /dev/null
@@ -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 (file)
index 0000000..b51ed7a
--- /dev/null
@@ -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 (file)
index 0000000..a97ec13
--- /dev/null
@@ -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 (file)
index 0000000..27493aa
--- /dev/null
@@ -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 (file)
index 0000000..544618b
--- /dev/null
@@ -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 (file)
index 0000000..f5db15c
--- /dev/null
@@ -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 (file)
index 0000000..0984d36
--- /dev/null
@@ -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 (file)
index 0000000..8434b76
--- /dev/null
@@ -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 (file)
index 0000000..3e7443b
--- /dev/null
@@ -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 (file)
index 0000000..75a5072
--- /dev/null
@@ -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 (executable)
index 5dc767c..0000000
+++ /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 (file)
index 0000000..8a885a3
--- /dev/null
@@ -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 (file)
index 0000000..aeae088
--- /dev/null
@@ -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 (file)
index 0000000..902ddbb
--- /dev/null
@@ -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 (file)
index 0000000..8f8edab
--- /dev/null
@@ -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 (file)
index 0000000..b7e02a5
--- /dev/null
@@ -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 (file)
index 0000000..5a652fd
--- /dev/null
@@ -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 (file)
index 0000000..df50f65
--- /dev/null
@@ -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 (file)
index 0000000..187ce0a
--- /dev/null
@@ -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 (file)
index 0000000..571bce5
--- /dev/null
@@ -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 */
index 4b4e6e673d90b298211b3c82c16e6886a9ff45d1..0bbf6f22107472bd80292fba2b5d346decbf283e 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "hdb_locl.h"
 
-RCSID("$Id: db.c,v 1.35 2005/12/13 11:52:55 lha Exp $");
+RCSID("$Id: db.c,v 1.36 2006/09/12 18:12:37 lha Exp $");
 
 #if HAVE_DB1
 
@@ -47,7 +47,7 @@ static krb5_error_code
 DB_close(krb5_context context, HDB *db)
 {
     DB *d = (DB*)db->hdb_db;
-    d->close(d);
+    (*d->close)(d);
     return 0;
 }
 
@@ -95,7 +95,7 @@ DB_seq(krb5_context context, HDB *db,
     code = db->hdb_lock(context, db, HDB_RLOCK);
     if(code == -1)
        return HDB_ERR_DB_INUSE;
-    code = d->seq(d, &key, &value, flag);
+    code = (*d->seq)(d, &key, &value, flag);
     db->hdb_unlock(context, db); /* XXX check value */
     if(code == -1)
        return errno;
@@ -172,7 +172,7 @@ DB__get(krb5_context context, HDB *db, krb5_data key, krb5_data *reply)
     code = db->hdb_lock(context, db, HDB_RLOCK);
     if(code)
        return code;
-    code = d->get(d, &k, &v, 0);
+    code = (*d->get)(d, &k, &v, 0);
     db->hdb_unlock(context, db);
     if(code < 0)
        return errno;
@@ -198,7 +198,7 @@ DB__put(krb5_context context, HDB *db, int replace,
     code = db->hdb_lock(context, db, HDB_WLOCK);
     if(code)
        return code;
-    code = d->put(d, &k, &v, replace ? 0 : R_NOOVERWRITE);
+    code = (*d->put)(d, &k, &v, replace ? 0 : R_NOOVERWRITE);
     db->hdb_unlock(context, db);
     if(code < 0)
        return errno;
@@ -218,7 +218,7 @@ DB__del(krb5_context context, HDB *db, krb5_data key)
     code = db->hdb_lock(context, db, HDB_WLOCK);
     if(code)
        return code;
-    code = d->del(d, &k, 0);
+    code = (*d->del)(d, &k, 0);
     db->hdb_unlock(context, db);
     if(code == 1)
        return HDB_ERR_NOENTRY;
index a8995e41388e5db949c36076b9dc9ca755a78c2b..141c63a8ac15003474d3111b90cf9375f621f48b 100644 (file)
@@ -34,7 +34,7 @@
 #include "hdb_locl.h"
 #include <der.h>
 
-RCSID("$Id: ext.c,v 1.2 2006/04/25 10:20:22 lha Exp $");
+RCSID("$Id: ext.c,v 1.6 2006/10/14 10:13:03 lha Exp $");
 
 krb5_error_code
 hdb_entry_check_mandatory(krb5_context context, const hdb_entry *ent)
@@ -219,6 +219,20 @@ hdb_entry_get_pkinit_acl(const hdb_entry *entry, const HDB_Ext_PKINIT_acl **a)
     return 0;
 }
 
+krb5_error_code
+hdb_entry_get_pkinit_hash(const hdb_entry *entry, const HDB_Ext_PKINIT_hash **a)
+{
+    const HDB_extension *ext;
+
+    ext = hdb_find_extension(entry, choice_HDB_extension_data_pkinit_cert_hash);
+    if (ext)
+       *a = &ext->data.u.pkinit_cert_hash;
+    else
+       *a = NULL;
+
+    return 0;
+}
+
 krb5_error_code
 hdb_entry_get_pw_change_time(const hdb_entry *entry, time_t *t)
 {
@@ -278,7 +292,7 @@ hdb_entry_get_password(krb5_context context, HDB *db,
                                    ext->data.u.password.password.length,
                                    &pw);
        } else {
-           ret = copy_octet_string(&ext->data.u.password.password, &pw);
+           ret = der_copy_octet_string(&ext->data.u.password.password, &pw);
        }
        if (ret) {
            krb5_clear_error_string(context);
@@ -293,7 +307,7 @@ hdb_entry_get_password(krb5_context context, HDB *db,
 
        *p = strdup(str);
 
-       free_octet_string(&pw);
+       der_free_octet_string(&pw);
        if (*p == NULL) {
            krb5_set_error_string(context, "malloc: out of memory");
            return ENOMEM;
@@ -364,3 +378,19 @@ hdb_entry_clear_password(krb5_context context, hdb_entry *entry)
     return hdb_clear_extension(context, entry, 
                               choice_HDB_extension_data_password);
 }
+
+krb5_error_code
+hdb_entry_get_ConstrainedDelegACL(const hdb_entry *entry, 
+                                 const HDB_Ext_Constrained_delegation_acl **a)
+{
+    const HDB_extension *ext;
+
+    ext = hdb_find_extension(entry, 
+                            choice_HDB_extension_data_allowed_to_delegate_to);
+    if (ext)
+       *a = &ext->data.u.allowed_to_delegate_to;
+    else
+       *a = NULL;
+
+    return 0;
+}
index 3cc7d2131a58476ce7bb8dcdeee19ceb12ec08d0..de0545a037f93e16617e8b714c96ae4f795057c7 100644 (file)
@@ -71,6 +71,11 @@ hdb_entry_clear_password (
        krb5_context /*context*/,
        hdb_entry */*entry*/);
 
+krb5_error_code
+hdb_entry_get_ConstrainedDelegACL (
+       const hdb_entry */*entry*/,
+       const HDB_Ext_Constrained_delegation_acl **/*a*/);
+
 int
 hdb_entry_get_password (
        krb5_context /*context*/,
@@ -83,6 +88,11 @@ hdb_entry_get_pkinit_acl (
        const hdb_entry */*entry*/,
        const HDB_Ext_PKINIT_acl **/*a*/);
 
+krb5_error_code
+hdb_entry_get_pkinit_hash (
+       const hdb_entry */*entry*/,
+       const HDB_Ext_PKINIT_hash **/*a*/);
+
 krb5_error_code
 hdb_entry_get_pw_change_time (
        const hdb_entry */*entry*/,
index c8a1a34b4f646d63d3e8e7910136e47e0ca5afd1..c8c276ff6e54aae9b5ca97f09ae1e9f038b3d57c 100644 (file)
@@ -1,4 +1,4 @@
--- $Id: hdb.asn1,v 1.13 2005/08/11 13:15:44 lha Exp $
+-- $Id: hdb.asn1,v 1.17 2006/08/24 10:45:19 lha Exp $
 HDB DEFINITIONS ::=
 BEGIN
 
@@ -41,7 +41,10 @@ HDBFlags ::= BIT STRING {
        require-hwauth(10),             -- must use hwauth
        ok-as-delegate(11),             -- as in TicketFlags
        user-to-user(12),               -- may use user-to-user auth
-       immutable(13)                   -- may not be deleted
+       immutable(13),                  -- may not be deleted
+       trusted-for-delegation(14),     -- Trusted to print forwardabled tickets
+       allow-kerberos4(15),            -- Allow Kerberos 4 requests
+       allow-digest(16)                -- Allow digest requests
 }
 
 GENERATION ::= SEQUENCE {
@@ -52,10 +55,14 @@ GENERATION ::= SEQUENCE {
 
 HDB-Ext-PKINIT-acl ::= SEQUENCE OF SEQUENCE {
        subject[0]      UTF8String,
-       issuer[1]       UTF8String
+       issuer[1]       UTF8String OPTIONAL,
+       anchor[2]       UTF8String OPTIONAL
 }
 
-HDB-Ext-PKINIT-certificate ::= SEQUENCE OF OCTET STRING
+HDB-Ext-PKINIT-hash ::= SEQUENCE OF SEQUENCE {
+       digest-type[0] OBJECT IDENTIFIER,
+       digest[1] OCTET STRING
+}
 
 HDB-Ext-Constrained-delegation-acl ::= SEQUENCE OF Principal
 
@@ -80,7 +87,7 @@ HDB-extension ::= SEQUENCE {
                                         --   be rejected
         data[1]          CHOICE {
                pkinit-acl[0]                   HDB-Ext-PKINIT-acl,
-               pkinit-cert[1]                  HDB-Ext-PKINIT-certificate,
+               pkinit-cert-hash[1]             HDB-Ext-PKINIT-hash,
                allowed-to-delegate-to[2]   HDB-Ext-Constrained-delegation-acl,
 --             referral-info[3]                HDB-Ext-Referrals,
                lm-owf[4]                       HDB-Ext-Lan-Manager-OWF,
index 555a0d53f64977b8f585a3ed03fed02505e6026a..d1fa4ffd6a6a0d54200c0c176ac70cf70a8f259b 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "hdb_locl.h"
 
-RCSID("$Id: hdb.c,v 1.61 2006/04/24 20:57:58 lha Exp $");
+RCSID("$Id: hdb.c,v 1.62 2006/10/06 16:47:22 lha Exp $");
 
 #ifdef HAVE_DLFCN_H
 #include <dlfcn.h>
@@ -57,6 +57,9 @@ static struct hdb_method methods[] = {
 #endif
 #ifdef _SAMBA_BUILD_
     {"ldb:",   hdb_ldb_create},
+#endif
+#ifdef HAVE_LDB /* Used for integrated samba build */
+    {"ldb:",   hdb_ldb_create},
 #endif
     {NULL,     NULL}
 };
@@ -262,7 +265,7 @@ find_dynamic_method (krb5_context context,
     if (prefix == NULL)
        krb5_errx(context, 1, "out of memory");
     
-    if (asprintf(&path, HDBDIR "/hdb_%s.so", prefix) == -1)
+    if (asprintf(&path, LIBDIR "/hdb_%s.so", prefix) == -1)
        krb5_errx(context, 1, "out of memory");
 
 #ifndef RTLD_NOW
@@ -398,6 +401,6 @@ hdb_create(krb5_context context, HDB **db, const char *filename)
        h = find_dynamic_method (context, filename, &residual);
 #endif
     if (h == NULL)
-       krb5_errx(context, 1, "No database support! (hdb_create(%s))", filename);
+       krb5_errx(context, 1, "No database support for %s", filename);
     return (*h->create)(context, db, residual);
 }
index d14eea7ddc4ec794c50cfa58d0b100c472dc9f37..69c91d12ad3c3b78b9e4afb2f8ab059d1b3c288c 100644 (file)
@@ -66,17 +66,17 @@ typedef struct hdb_entry_ex {
                                         struct hdb_entry_ex *, 
                                         METHOD_DATA* pa_data_seq,
                                         time_t authtime,
-                                        EncryptionKey *tgtkey,
-                                        EncryptionKey *sessionkey,
+                                        const EncryptionKey *tgtkey,
+                                        const EncryptionKey *sessionkey,
                                         AuthorizationData **out);
     krb5_error_code (*authz_data_tgs_req)(krb5_context, 
                                          struct hdb_entry_ex *, 
                                          krb5_principal client, 
                                          AuthorizationData *in, 
                                          time_t authtime,
-                                         EncryptionKey *tgtkey,
-                                         EncryptionKey *servicekey,
-                                         EncryptionKey *sessionkey,
+                                         const EncryptionKey *tgtkey,
+                                         const EncryptionKey *servicekey,
+                                         const EncryptionKey *sessionkey,
                                          AuthorizationData **out);
 } hdb_entry_ex;
 
index d7c2f2c89bdc6903815131b21c7e9674adff393d..8d4810f5c917c96ed93153d3ae5df1db7b32bbb0 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "hdb_locl.h"
 
-RCSID("$Id: keys.c,v 1.5 2006/04/25 08:09:38 lha Exp $");
+RCSID("$Id: keys.c,v 1.6 2006/10/22 09:40:12 lha Exp $");
 
 /*
  * free all the memory used by (len, keys)
@@ -334,6 +334,9 @@ hdb_generate_key_set(krb5_context context, krb5_principal principal,
     *ret_key_set = key_set;
 
  out:
+    if (ktypes != default_keytypes)
+       krb5_config_free_strings(ktypes);
+
     if (ret) {
        krb5_warn(context, ret, 
                  "failed to parse the [kadmin]default_keys values");
index c87b8eca2c7af0546c0bc4671a4534060d8fd28b..8f473a68a4161d7aa12b6b9487087ea390024db8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999 - 2002 Kungliga Tekniska Högskolan
+ * Copyright (c) 1999 - 2002 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
  * All rights reserved. 
  *
@@ -35,7 +35,7 @@
 
 /* keytab backend for HDB databases */
 
-RCSID("$Id: keytab.c,v 1.11 2006/04/27 11:01:30 lha Exp $");
+RCSID("$Id: keytab.c,v 1.16 2006/10/09 12:36:40 lha Exp $");
 
 struct hdb_data {
     char *dbname;
@@ -59,7 +59,7 @@ hdb_resolve(krb5_context context, const char *name, krb5_keytab id)
        return ENOMEM;
     }
     db = name;
-    mkey = strrchr(name, ':');
+    mkey = strchr(name, ':');
     if(mkey == NULL || mkey[1] == '\0') {
        if(*name == '\0')
            d->dbname = NULL;
@@ -201,6 +201,8 @@ hdb_get_entry(krb5_context context,
     const char *dbname = d->dbname;
     const char *mkey   = d->mkey;
 
+    memset(&ent, 0, sizeof(ent));
+
     if (dbname == NULL)
        find_db (context, &dbname, &mkey, principal);
 
@@ -218,26 +220,21 @@ hdb_get_entry(krb5_context context,
        (*db->hdb_destroy)(context, db);
        return ret;
     }
-    ret = (*db->hdb_fetch)(context, db, principal, HDB_F_DECRYPT|HDB_F_GET_CLIENT|HDB_F_GET_SERVER, &ent);
-
+    ret = (*db->hdb_fetch)(context, db, principal, 
+                          HDB_F_DECRYPT|
+                          HDB_F_GET_CLIENT|HDB_F_GET_SERVER|HDB_F_GET_KRBTGT,
+                          &ent);
 
-    /* Shutdown the hdb on error */
     if(ret == HDB_ERR_NOENTRY) {
-       (*db->hdb_close)(context, db);
-       (*db->hdb_destroy)(context, db);
-       return KRB5_KT_NOTFOUND;
-    } else if (ret) {
-       (*db->hdb_close)(context, db);
-       (*db->hdb_destroy)(context, db);
-       return ret;
-    }
+       ret = KRB5_KT_NOTFOUND;
+       goto out;
+    }else if(ret)
+       goto out;
+
     if(kvno && ent.entry.kvno != kvno) {
-       /* The order here matters, we must free these in this order
-        * due to hdb-ldb and Samba4's talloc */
        hdb_free_entry(context, &ent);
-       (*db->hdb_close)(context, db);
-       (*db->hdb_destroy)(context, db);
-       return KRB5_KT_NOTFOUND;
+       ret = KRB5_KT_NOTFOUND;
+       goto out;
     }
     if(enctype == 0)
        if(ent.entry.keys.len > 0)
@@ -254,9 +251,8 @@ hdb_get_entry(krb5_context context,
            break;
        }
     }
-    /* The order here matters, we must free these in this order
-     * due to hdb-ldb and Samba4's talloc */
     hdb_free_entry(context, &ent);
+out:
     (*db->hdb_close)(context, db);
     (*db->hdb_destroy)(context, db);
     return ret;
index b38104fc2d98a09f387d46e48a8e55a7e08d5cec..004926bc894ff88725c7b110cf8a39d11354722c 100644 (file)
@@ -37,7 +37,7 @@
 #include <dlfcn.h>
 #endif
 
-RCSID("$Id: acache.c,v 1.15 2006/03/27 04:22:23 lha Exp $");
+RCSID("$Id: acache.c,v 1.16 2006/10/19 11:41:38 lha Exp $");
 
 /* XXX should we fetch these for each open ? */
 static HEIMDAL_MUTEX acc_mutex = HEIMDAL_MUTEX_INITIALIZER;
@@ -113,7 +113,7 @@ init_ccapi(krb5_context context)
        return KRB5_CC_NOSUPP;
     }
 
-    init_func = dlsym(cc_handle, "cc_initialize");
+    init_func = (cc_initialize_func)dlsym(cc_handle, "cc_initialize");
     HEIMDAL_MUTEX_unlock(&acc_mutex);
     if (init_func == NULL) {
        krb5_set_error_string(context, "Failed to find cc_initialize"
index 895b01f9d85eea9c8c71b43746043c839dccb13d..f68be423b068c087e95ab035a5af07834b064f41 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: addr_families.c,v 1.52 2006/05/05 09:26:22 lha Exp $");
+RCSID("$Id: addr_families.c,v 1.53 2006/10/22 06:54:00 lha Exp $");
 
 struct addr_operations {
     int af;
@@ -551,6 +551,7 @@ arange_free (krb5_context context, krb5_address *addr)
     a = addr->address.data;
     krb5_free_address(context, &a->low);
     krb5_free_address(context, &a->high);
+    krb5_data_free(&addr->address);
     return 0;
 }
 
index 8f7b886e80e2a6b696fcff60a62f5a9aa0d44aee..b07e0585504f9c52f5f576dcfbd02db2db677914 100644 (file)
@@ -37,7 +37,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: asn1_glue.c,v 1.9 2004/12/29 18:54:15 lha Exp $");
+RCSID("$Id: asn1_glue.c,v 1.10 2006/10/06 17:02:48 lha Exp $");
 
 krb5_error_code KRB5_LIB_FUNCTION
 _krb5_principal2principalname (PrincipalName *p,
index b21d42d65317e4c60dcc2d72b9194b1b9bc8fdef..a96870a7de9201805eb5b8c03b480eafcd6add33 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: cache.c,v 1.79 2006/04/02 00:54:48 lha Exp $");
+RCSID("$Id: cache.c,v 1.82 2006/09/12 17:35:33 lha Exp $");
 
 /*
  * Add a new ccache type with operations `ops', overwriting any
@@ -188,7 +188,7 @@ krb5_cc_new_unique(krb5_context context, const char *type,
     const krb5_cc_ops *ops;
 
     if (type == NULL)
-       type = "FILE";
+       type = KRB5_DEFAULT_CCNAME;
 
     ops = krb5_cc_get_prefix_ops(context, type);
     if (ops == NULL) {
@@ -423,7 +423,7 @@ krb5_cc_initialize(krb5_context context,
                   krb5_ccache id,
                   krb5_principal primary_principal)
 {
-    return id->ops->init(context, id, primary_principal);
+    return (*id->ops->init)(context, id, primary_principal);
 }
 
 
@@ -438,7 +438,7 @@ krb5_cc_destroy(krb5_context context,
 {
     krb5_error_code ret;
 
-    ret = id->ops->destroy(context, id);
+    ret = (*id->ops->destroy)(context, id);
     krb5_cc_close (context, id);
     return ret;
 }
@@ -453,7 +453,7 @@ krb5_cc_close(krb5_context context,
              krb5_ccache id)
 {
     krb5_error_code ret;
-    ret = id->ops->close(context, id);
+    ret = (*id->ops->close)(context, id);
     free(id);
     return ret;
 }
@@ -468,7 +468,7 @@ krb5_cc_store_cred(krb5_context context,
                   krb5_ccache id,
                   krb5_creds *creds)
 {
-    return id->ops->store(context, id, creds);
+    return (*id->ops->store)(context, id, creds);
 }
 
 /*
@@ -488,8 +488,8 @@ krb5_cc_retrieve_cred(krb5_context context,
     krb5_cc_cursor cursor;
 
     if (id->ops->retrieve != NULL) {
-       return id->ops->retrieve(context, id, whichfields,
-                                mcreds, creds);
+       return (*id->ops->retrieve)(context, id, whichfields,
+                                   mcreds, creds);
     }
 
     krb5_cc_start_seq_get(context, id, &cursor);
@@ -514,7 +514,7 @@ krb5_cc_get_principal(krb5_context context,
                      krb5_ccache id,
                      krb5_principal *principal)
 {
-    return id->ops->get_princ(context, id, principal);
+    return (*id->ops->get_princ)(context, id, principal);
 }
 
 /*
@@ -528,7 +528,7 @@ krb5_cc_start_seq_get (krb5_context context,
                       const krb5_ccache id,
                       krb5_cc_cursor *cursor)
 {
-    return id->ops->get_first(context, id, cursor);
+    return (*id->ops->get_first)(context, id, cursor);
 }
 
 /*
@@ -543,7 +543,7 @@ krb5_cc_next_cred (krb5_context context,
                   krb5_cc_cursor *cursor,
                   krb5_creds *creds)
 {
-    return id->ops->get_next(context, id, cursor, creds);
+    return (*id->ops->get_next)(context, id, cursor, creds);
 }
 
 /* like krb5_cc_next_cred, but allow for selective retrieval */
@@ -576,7 +576,7 @@ krb5_cc_end_seq_get (krb5_context context,
                     const krb5_ccache id,
                     krb5_cc_cursor *cursor)
 {
-    return id->ops->end_get(context, id, cursor);
+    return (*id->ops->end_get)(context, id, cursor);
 }
 
 /*
@@ -607,7 +607,7 @@ krb5_cc_set_flags(krb5_context context,
                  krb5_ccache id,
                  krb5_flags flags)
 {
-    return id->ops->set_flags(context, id, flags);
+    return (*id->ops->set_flags)(context, id, flags);
 }
                    
 /*
@@ -672,7 +672,7 @@ krb5_cc_get_version(krb5_context context,
                    const krb5_ccache id)
 {
     if(id->ops->get_version)
-       return id->ops->get_version(context, id);
+       return (*id->ops->get_version)(context, id);
     else
        return 0;
 }
index 594665235b98268de8c717d2553cc63c4a12d49b..f7b3ffbf9e8c3fb262f0180f731495745ae24c7e 100644 (file)
@@ -34,7 +34,7 @@
 #include "krb5_locl.h"
 #include <com_err.h>
 
-RCSID("$Id: context.c,v 1.102 2005/05/18 04:20:50 lha Exp $");
+RCSID("$Id: context.c,v 1.108 2006/10/20 22:26:10 lha Exp $");
 
 #define INIT_FIELD(C, T, E, D, F)                                      \
     (C)->E = krb5_config_get_ ## T ## _default ((C), NULL, (D),        \
@@ -181,8 +181,8 @@ init_context_from_config_file(krb5_context context)
     INIT_FIELD(context, bool, srv_lookup, TRUE, "srv_lookup");
     INIT_FIELD(context, bool, srv_lookup, context->srv_lookup, "dns_lookup_kdc");
     INIT_FIELD(context, int, large_msg_size, 6000, "large_message_size");
+    INIT_FIELD(context, bool, dns_canonicalize_hostname, TRUE, "dns_canonize_hostname");
     context->default_cc_name = NULL;
-    INIT_FIELD(context, bool, fdns, TRUE, "fdns");
     return 0;
 }
 
@@ -263,7 +263,7 @@ krb5_free_context(krb5_context context)
        krb5_closelog(context, context->warn_dest);
     krb5_set_extra_addresses(context, NULL);
     krb5_set_ignore_addresses(context, NULL);
-    free(context->send_and_recv);
+    krb5_set_send_to_kdc_func(context, NULL, NULL);
     if (context->mutex != NULL) {
        HEIMDAL_MUTEX_destroy(context->mutex);
        free(context->mutex);
@@ -424,13 +424,17 @@ krb5_free_config_files(char **filenames)
 }
 
 /*
- * set `etype' to a malloced list of the default enctypes
+ * Returns the list of Kerberos encryption types sorted in order of
+ * most preferred to least preferred encryption type.  The array ends
+ * with ETYPE_NULL.  Note that some encryption types might be
+ * disabled, so you need to check with krb5_enctype_valid() before
+ * using the encryption type.
  */
 
-static krb5_error_code
-default_etypes(krb5_context context, krb5_enctype **etype)
+const krb5_enctype * KRB5_LIB_FUNCTION
+krb5_kerberos_enctypes(krb5_context context)
 {
-    krb5_enctype p[] = {
+    static const krb5_enctype p[] = {
        ETYPE_AES256_CTS_HMAC_SHA1_96,
        ETYPE_AES128_CTS_HMAC_SHA1_96,
        ETYPE_DES3_CBC_SHA1,
@@ -438,12 +442,26 @@ default_etypes(krb5_context context, krb5_enctype **etype)
        ETYPE_ARCFOUR_HMAC_MD5,
        ETYPE_DES_CBC_MD5,
        ETYPE_DES_CBC_MD4,
-       ETYPE_DES_CBC_CRC
+       ETYPE_DES_CBC_CRC,
+       ETYPE_NULL
     };
+    return p;
+}
+
+/*
+ * set `etype' to a malloced list of the default enctypes
+ */
+
+static krb5_error_code
+default_etypes(krb5_context context, krb5_enctype **etype)
+{
+    const krb5_enctype *p;
     krb5_enctype *e = NULL, *ep;
     int i, n = 0;
 
-    for (i = 0; i < sizeof(p)/sizeof(p[0]); i++) {
+    p = krb5_kerberos_enctypes(context);
+
+    for (i = 0; p[i] != ETYPE_NULL; i++) {
        if (krb5_enctype_valid(context, p[i]) != 0)
            continue;
        ep = realloc(e, (n + 2) * sizeof(*e));
@@ -537,6 +555,9 @@ krb5_init_ets(krb5_context context)
        krb5_add_et_list(context, initialize_asn1_error_table_r);
        krb5_add_et_list(context, initialize_heim_error_table_r);
        krb5_add_et_list(context, initialize_k524_error_table_r);
+#ifdef PKINIT
+       krb5_add_et_list(context, initialize_hx_error_table_r);
+#endif
     }
 }
 
@@ -662,3 +683,25 @@ krb5_is_thread_safe(void)
     return FALSE;
 #endif
 }
+
+void KRB5_LIB_FUNCTION
+krb5_set_dns_canonicalize_hostname (krb5_context context, krb5_boolean flag)
+{
+    context->dns_canonicalize_hostname = flag;
+}
+
+krb5_boolean KRB5_LIB_FUNCTION
+krb5_get_dns_canonize_hostname (krb5_context context)
+{
+    return context->dns_canonicalize_hostname;
+}
+
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_get_kdc_sec_offset (krb5_context context, int32_t *sec, int32_t *usec)
+{
+    if (sec)
+       *sec = context->kdc_sec_offset;
+    if (usec)
+       *usec = context->kdc_usec_offset;
+    return 0;
+}
index a3c58051f9ac79fb52051a1f6ddca48af3295640..9f6ef6b82b4e72643d6bd336dec3f795410f20c6 100644 (file)
@@ -32,7 +32,7 @@
  */
 
 #include "krb5_locl.h"
-RCSID("$Id: crypto.c,v 1.138 2006/05/08 13:47:24 lha Exp $");
+RCSID("$Id: crypto.c,v 1.145 2006/10/22 07:32:40 lha Exp $");
 
 #undef CRYPTO_DEBUG
 #ifdef CRYPTO_DEBUG
@@ -55,7 +55,6 @@ struct krb5_crypto_data {
     struct key_data key;
     int num_key_usage;
     struct key_usage *key_usage;
-    void *params;
 };
 
 #define kcrypto_oid_enc(n) { sizeof(n)/sizeof(n[0]), n }
@@ -89,13 +88,9 @@ struct key_type {
     krb5_enctype best_etype;
 #endif
     void (*random_key)(krb5_context, krb5_keyblock*);
-    void (*schedule)(krb5_context, struct key_data *, const void *);
+    void (*schedule)(krb5_context, struct key_data *);
     struct salt_type *string_to_key;
     void (*random_to_key)(krb5_context, krb5_keyblock*, const void*, size_t);
-    krb5_error_code (*get_params)(krb5_context, const krb5_data *,
-                                 void **, krb5_data *);
-    krb5_error_code (*set_params)(krb5_context, const void *,
-                                 const krb5_data *, krb5_data *);
 };
 
 struct checksum_type {
@@ -181,8 +176,7 @@ krb5_DES_random_key(krb5_context context,
 
 static void
 krb5_DES_schedule(krb5_context context,
-                 struct key_data *key,
-                 const void *params)
+                 struct key_data *key)
 {
     DES_set_key(key->key->keyvalue.data, key->schedule->data);
 }
@@ -392,8 +386,7 @@ DES3_random_key(krb5_context context,
 
 static void
 DES3_schedule(krb5_context context,
-             struct key_data *key,
-             const void *params)
+             struct key_data *key)
 {
     DES_cblock *k = key->key->keyvalue.data;
     DES_key_schedule *s = key->schedule->data;
@@ -546,8 +539,7 @@ DES3_random_to_key(krb5_context context,
 
 static void
 ARCFOUR_schedule(krb5_context context, 
-                struct key_data *kd,
-                const void *params)
+                struct key_data *kd)
 {
     RC4_set_key (kd->schedule->data,
                 kd->key->keyvalue.length, kd->key->keyvalue.data);
@@ -618,15 +610,16 @@ AES_string_to_key(krb5_context context,
     if (et == NULL)
        return KRB5_PROG_KEYTYPE_NOSUPP;
 
-    key->keytype = enctype;
-    ret = krb5_data_alloc(&key->keyvalue, et->keytype->size);
-    if (ret) {
-       krb5_set_error_string(context, "Failed to allocate pkcs5 key");
-       return ret;
+    kd.schedule = NULL;
+    ALLOC(kd.key, 1);
+    if(kd.key == NULL) {
+       krb5_set_error_string (context, "malloc: out of memory");
+       return ENOMEM;
     }
-    ret = krb5_copy_keyblock(context, key, &kd.key);
+    kd.key->keytype = enctype;
+    ret = krb5_data_alloc(&kd.key->keyvalue, et->keytype->size);
     if (ret) {
-       krb5_free_keyblock(context, key);
+       krb5_set_error_string(context, "Failed to allocate pkcs5 key");
        return ret;
     }
 
@@ -634,8 +627,8 @@ AES_string_to_key(krb5_context context,
                                 salt.saltvalue.data, salt.saltvalue.length,
                                 iter, 
                                 et->keytype->size, kd.key->keyvalue.data);
-    kd.schedule = NULL;
     if (ret != 1) {
+       free_key_data(context, &kd);
        krb5_set_error_string(context, "Error calculating s2k");
        return KRB5_PROG_KEYTYPE_NOSUPP;
     }
@@ -655,8 +648,7 @@ struct krb5_aes_schedule {
 
 static void
 AES_schedule(krb5_context context,
-            struct key_data *kd,
-            const void *params)
+            struct key_data *kd)
 {
     struct krb5_aes_schedule *key = kd->schedule->data;
     int bits = kd->key->keyvalue.length * 8;
@@ -666,115 +658,6 @@ AES_schedule(krb5_context context,
     AES_set_decrypt_key(kd->key->keyvalue.data, bits, &key->dkey);
 }
 
-/*
- * RC2
- */
-
-struct _RC2_params {
-    int maximum_effective_key;
-};
-
-static krb5_error_code
-rc2_get_params(krb5_context context,
-              const krb5_data *data,
-              void **params,
-              krb5_data *ivec)
-{
-    RC2CBCParameter rc2params;
-    struct _RC2_params *p;
-    krb5_error_code ret;
-    size_t size;
-
-    ret = decode_RC2CBCParameter(data->data, data->length, &rc2params, &size);
-    if (ret) {
-       krb5_set_error_string(context, "Can't decode RC2 parameters");
-       return ret;
-    }
-    p = malloc(sizeof(*p));
-    if (p == NULL) {
-       free_RC2CBCParameter(&rc2params);
-       krb5_set_error_string(context, "malloc - out of memory");
-       return ENOMEM;
-    }
-    /* XXX  */
-    switch(rc2params.rc2ParameterVersion) {
-    case 160:
-       p->maximum_effective_key = 40;
-       break;
-    case 120:
-       p->maximum_effective_key = 64;
-       break;
-    case 58:
-       p->maximum_effective_key = 128;
-       break;
-       
-    }
-    if (ivec)
-       ret = copy_octet_string(&rc2params.iv, ivec);
-    free_RC2CBCParameter(&rc2params);
-    *params = p;
-
-    return ret;
-}
-
-static krb5_error_code
-rc2_set_params(krb5_context context,
-              const void *params,
-              const krb5_data *ivec,
-              krb5_data *data)
-{
-    RC2CBCParameter rc2params;
-    const struct _RC2_params *p = params;
-    int maximum_effective_key = 128;
-    krb5_error_code ret;
-    size_t size;
-
-    memset(&rc2params, 0, sizeof(rc2params));
-
-    if (p)
-       maximum_effective_key = p->maximum_effective_key;
-
-    /* XXX */
-    switch(maximum_effective_key) {
-    case 40:
-       rc2params.rc2ParameterVersion = 160;
-       break;
-    case 64:
-       rc2params.rc2ParameterVersion = 120;
-       break;
-    case 128:
-       rc2params.rc2ParameterVersion = 58;
-       break;
-    }
-    ret = copy_octet_string(ivec, &rc2params.iv);
-    if (ret)
-       return ret;
-
-    ASN1_MALLOC_ENCODE(RC2CBCParameter, data->data, data->length,
-                      &rc2params, &size, ret);
-    if (ret == 0 && size != data->length)
-       krb5_abortx(context, "Internal asn1 encoder failure");
-    free_RC2CBCParameter(&rc2params);
-
-    return ret;
-}
-
-static void
-rc2_schedule(krb5_context context,
-            struct key_data *kd,
-            const void *params)
-{
-    const struct _RC2_params *p = params;
-    int maximum_effective_key = 128;
-    if (p)
-       maximum_effective_key = p->maximum_effective_key;
-    RC2_set_key (kd->schedule->data,
-                kd->key->keyvalue.length,
-                kd->key->keyvalue.data,
-                maximum_effective_key);
-}
-
-
 /*
  *
  */
@@ -898,18 +781,6 @@ static struct key_type keytype_aes128 = {
     AES_salt
 };
 
-static struct key_type keytype_aes192 = {
-    KEYTYPE_AES192,
-    "aes-192",
-    192,
-    24,
-    24,
-    sizeof(struct krb5_aes_schedule),
-    NULL,
-    AES_schedule,
-    AES_salt
-};
-
 static struct key_type keytype_aes256 = {
     KEYTYPE_AES256,
     "aes-256",
@@ -934,30 +805,13 @@ static struct key_type keytype_arcfour = {
     arcfour_salt
 };
 
-static struct key_type keytype_rc2 = {
-    KEYTYPE_RC2,
-    "rc2",
-    128,
-    16,
-    1,
-    sizeof(RC2_KEY),
-    NULL,
-    rc2_schedule,
-    NULL, /* XXX salt */
-    NULL,
-    rc2_get_params,
-    rc2_set_params
-};
-
 static struct key_type *keytypes[] = {
     &keytype_null,
     &keytype_des,
     &keytype_des3_derived,
     &keytype_des3,
     &keytype_aes128,
-    &keytype_aes192,
     &keytype_aes256,
-    &keytype_rc2,
     &keytype_arcfour
 };
 
@@ -1247,8 +1101,7 @@ krb5_generate_random_keyblock(krb5_context context,
 
 static krb5_error_code
 _key_schedule(krb5_context context,
-             struct key_data *key,
-             const void *params)
+             struct key_data *key)
 {
     krb5_error_code ret;
     struct encryption_type *et = _find_enctype(key->key->keytype);
@@ -1269,7 +1122,7 @@ _key_schedule(krb5_context context,
        key->schedule = NULL;
        return ret;
     }
-    (*kt->schedule)(context, key, params);
+    (*kt->schedule)(context, key);
     return 0;
 }
 
@@ -1933,7 +1786,7 @@ get_checksum_key(krb5_context context,
        *key = &crypto->key; 
     }
     if(ret == 0)
-       ret = _key_schedule(context, *key, crypto->params);
+       ret = _key_schedule(context, *key);
     return ret;
 }
 
@@ -2290,16 +2143,15 @@ DES_PCBC_encrypt_key_ivec(krb5_context context,
 
 void KRB5_LIB_FUNCTION
 _krb5_aes_cts_encrypt(const unsigned char *in, unsigned char *out,
-                     size_t len, const void *aes_key,
+                     size_t len, const AES_KEY *key,
                      unsigned char *ivec, const int encryptp)
 {
     unsigned char tmp[AES_BLOCK_SIZE];
-    const AES_KEY *key = aes_key; /* XXX remove this when we always have AES */
     int i;
 
     /*
      * In the framework of kerberos, the length can never be shorter
-     * than at least one blocksize.
+     * then at least one blocksize.
      */
 
     if (encryptp) {
@@ -2838,7 +2690,7 @@ krb5_string_to_enctype(krb5_context context,
 }
 
 krb5_error_code KRB5_LIB_FUNCTION
-krb5_enctype_to_oid(krb5_context context,
+_krb5_enctype_to_oid(krb5_context context,
                    krb5_enctype etype,
                    heim_oid *oid)
 {
@@ -2853,7 +2705,7 @@ krb5_enctype_to_oid(krb5_context context,
        return KRB5_PROG_ETYPE_NOSUPP;
     }
     krb5_clear_error_string(context);
-    return copy_oid(et->oid, oid);
+    return der_copy_oid(et->oid, oid);
 }
 
 krb5_error_code KRB5_LIB_FUNCTION
@@ -2863,7 +2715,7 @@ _krb5_oid_to_enctype(krb5_context context,
 {
     int i;
     for(i = 0; i < num_etypes; i++) {
-       if(etypes[i]->oid && heim_oid_cmp(etypes[i]->oid, oid) == 0) {
+       if(etypes[i]->oid && der_heim_oid_cmp(etypes[i]->oid, oid) == 0) {
            *etype = etypes[i]->type;
            return 0;
        }
@@ -3080,7 +2932,7 @@ encrypt_internal_derived(krb5_context context,
     ret = _get_derived_key(context, crypto, ENCRYPTION_USAGE(usage), &dkey);
     if(ret)
        goto fail;
-    ret = _key_schedule(context, dkey, crypto->params);
+    ret = _key_schedule(context, dkey);
     if(ret)
        goto fail;
 #ifdef CRYPTO_DEBUG
@@ -3146,7 +2998,7 @@ encrypt_internal(krb5_context context,
        goto fail;
     memcpy(p + et->confoundersize, cksum.checksum.data, cksum.checksum.length);
     free_Checksum(&cksum);
-    ret = _key_schedule(context, &crypto->key, crypto->params);
+    ret = _key_schedule(context, &crypto->key);
     if(ret)
        goto fail;
 #ifdef CRYPTO_DEBUG
@@ -3246,7 +3098,7 @@ decrypt_internal_derived(krb5_context context,
        free(p);
        return ret;
     }
-    ret = _key_schedule(context, dkey, crypto->params);
+    ret = _key_schedule(context, dkey);
     if(ret) {
        free(p);
        return ret;
@@ -3313,7 +3165,7 @@ decrypt_internal(krb5_context context,
     }
     memcpy(p, data, len);
     
-    ret = _key_schedule(context, &crypto->key, crypto->params);
+    ret = _key_schedule(context, &crypto->key);
     if(ret) {
        free(p);
        return ret;
@@ -3613,11 +3465,9 @@ derive_key(krb5_context context,
     unsigned char *k;
     unsigned int nblocks = 0, i;
     krb5_error_code ret = 0;
-    
     struct key_type *kt = et->keytype;
-    /* since RC2 is only the weird crypto alg with parameter and this
-     * function not defined with work with RC2, this is ok */
-    ret = _key_schedule(context, key, NULL);
+
+    ret = _key_schedule(context, key);
     if(ret)
        return ret;
     if(et->blocksize * 8 < kt->bits || 
@@ -3795,7 +3645,6 @@ krb5_crypto_init(krb5_context context,
     (*crypto)->key.schedule = NULL;
     (*crypto)->num_key_usage = 0;
     (*crypto)->key_usage = NULL;
-    (*crypto)->params = NULL;
     return 0;
 }
 
@@ -3825,79 +3674,10 @@ krb5_crypto_destroy(krb5_context context,
        free_key_usage(context, &crypto->key_usage[i]);
     free(crypto->key_usage);
     free_key_data(context, &crypto->key);
-    free(crypto->params);
     free (crypto);
     return 0;
 }
 
-krb5_error_code KRB5_LIB_FUNCTION
-krb5_crypto_get_params(krb5_context context,
-                      const krb5_crypto crypto,
-                      const krb5_data *params,
-                      krb5_data *ivec)
-{
-    krb5_error_code (*gp)(krb5_context, const krb5_data *,void **,krb5_data *);
-    krb5_error_code ret;
-
-    gp = crypto->et->keytype->get_params;
-    if (gp) {
-       if (crypto->params) {
-           krb5_set_error_string(context,
-                                 "krb5_crypto_get_params called "
-                                 "more than once");
-           return KRB5_PROG_ETYPE_NOSUPP;
-       }
-       ret = (*gp)(context, params, &crypto->params, ivec);
-    } else {
-       size_t size;
-       if (ivec == NULL)
-           return 0;
-       ret = decode_CBCParameter(params->data, params->length, ivec, &size);
-    }
-    if (ret)
-       return ret;
-    if (ivec->length < crypto->et->blocksize) {
-       krb5_data_free(ivec);
-       krb5_set_error_string(context, "%s IV of wrong size", 
-                             crypto->et->name);
-       return ASN1_PARSE_ERROR;
-    }
-    return 0;
-}
-
-krb5_error_code KRB5_LIB_FUNCTION
-krb5_crypto_set_params(krb5_context context,
-                      const krb5_crypto crypto,
-                      const krb5_data *ivec,
-                      krb5_data *params)
-{
-    krb5_error_code (*sp)(krb5_context, const void *,
-                         const krb5_data *, krb5_data *);
-    krb5_error_code ret;
-
-    sp = crypto->et->keytype->set_params;
-    if (sp == NULL) {
-       size_t size;
-       if (ivec == NULL)
-           return 0;
-       ASN1_MALLOC_ENCODE(CBCParameter, params->data, params->length,
-                          ivec, &size, ret);
-       if (ret)
-           return ret;
-       if (size != params->length)
-           krb5_abortx(context, "Internal asn1 encoder failure");
-       return 0;
-    }
-    if (crypto->params) {
-       krb5_set_error_string(context,
-                             "krb5_crypto_set_params called "
-                             "more than once");
-       return KRB5_PROG_ETYPE_NOSUPP;
-    }
-    return (*sp)(context, crypto->params, ivec, params);
-}
-
-
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_crypto_getblocksize(krb5_context context,
                         krb5_crypto crypto,
index 3192c4c64fde69120668b2297b9b4b0e6279293a..f0c6d00abe30c8a6c39592847c1438da88cbd88a 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: data.c,v 1.20 2006/04/02 01:06:07 lha Exp $");
+RCSID("$Id: data.c,v 1.21 2006/10/14 09:45:41 lha Exp $");
 
 void KRB5_LIB_FUNCTION
 krb5_data_zero(krb5_data *p)
@@ -110,7 +110,7 @@ krb5_copy_data(krb5_context context,
        krb5_set_error_string(context, "malloc: out of memory");
        return ENOMEM;
     }
-    ret = copy_octet_string(indata, *outdata);
+    ret = der_copy_octet_string(indata, *outdata);
     if(ret) {
        krb5_clear_error_string (context);
        free(*outdata);
index f03bf1580719097fd542f3d12bc800eb00f09db9..4d0692bcfa8cecb03fbdb2d42e8fee2e7dfa5118 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: expand_hostname.c,v 1.12 2004/05/25 21:24:14 lha Exp $");
+RCSID("$Id: expand_hostname.c,v 1.13 2006/10/17 09:16:32 lha Exp $");
 
 static krb5_error_code
 copy_hostname(krb5_context context,
@@ -62,13 +62,12 @@ krb5_expand_hostname (krb5_context context,
     struct addrinfo *ai, *a, hints;
     int error;
 
+    if (!context->dns_canonicalize_hostname)
+       return copy_hostname (context, orig_hostname, new_hostname);
+
     memset (&hints, 0, sizeof(hints));
     hints.ai_flags = AI_CANONNAME;
 
-    if (!context->fdns) {
-       return copy_hostname (context, orig_hostname, new_hostname);
-    }
-
     error = getaddrinfo (orig_hostname, NULL, &hints, &ai);
     if (error)
        return copy_hostname (context, orig_hostname, new_hostname);
@@ -128,10 +127,9 @@ krb5_expand_hostname_realms (krb5_context context,
     int error;
     krb5_error_code ret = 0;
 
-    if (!context->fdns) {
+    if (!context->dns_canonicalize_hostname)
        return vanilla_hostname (context, orig_hostname, new_hostname,
                                 realms);
-    }
 
     memset (&hints, 0, sizeof(hints));
     hints.ai_flags = AI_CANONNAME;
index 1fa3f9143e3b02c211d828d9bd108ff5b444cfc6..b404c30f6e9fa7e0663c953fdb5441d974daf6df 100644 (file)
@@ -33,7 +33,7 @@
 
 #include <krb5_locl.h>
 
-RCSID("$Id: get_cred.c,v 1.109 2006/02/03 11:41:02 lha Exp $");
+RCSID("$Id: get_cred.c,v 1.112 2006/06/06 21:22:54 lha Exp $");
 
 /*
  * Take the `body' and encode it into `padata' using the credentials
@@ -142,6 +142,7 @@ init_tgs_req (krb5_context context,
              krb5_creds *in_creds,
              krb5_creds *krbtgt,
              unsigned nonce,
+             const METHOD_DATA *padata,
              krb5_keyblock **subkey,
              TGS_REQ *t,
              krb5_key_usage usage)
@@ -220,12 +221,22 @@ init_tgs_req (krb5_context context,
        krb5_set_error_string(context, "malloc: out of memory");
        goto fail;
     }
-    ALLOC_SEQ(t->padata, 1);
+    ALLOC_SEQ(t->padata, 1 + padata->len);
     if (t->padata->val == NULL) {
        ret = ENOMEM;
        krb5_set_error_string(context, "malloc: out of memory");
        goto fail;
     }
+    {
+       int i;
+       for (i = 0; i < padata->len; i++) {
+           ret = copy_PA_DATA(&padata->val[i], &t->padata->val[i + 1]);
+           if (ret) {
+               krb5_set_error_string(context, "malloc: out of memory");
+               goto fail;
+           }
+       }
+    }
 
     {
        krb5_auth_context ac;
@@ -268,7 +279,7 @@ init_tgs_req (krb5_context context,
        ret = make_pa_tgs_req(context,
                              ac,
                              &t->req_body, 
-                             t->padata->val,
+                             &t->padata->val[0],
                              krbtgt,
                              usage);
        if(ret) {
@@ -383,8 +394,10 @@ get_cred_kdc_usage(krb5_context context,
                   krb5_ccache id, 
                   krb5_kdc_flags flags,
                   krb5_addresses *addresses, 
-                  krb5_creds *in_creds, 
+                  krb5_creds *in_creds,
                   krb5_creds *krbtgt,
+                  krb5_principal impersonate_principal,
+                  Ticket *second_ticket,
                   krb5_creds *out_creds,
                   krb5_key_usage usage)
 {
@@ -397,36 +410,91 @@ get_cred_kdc_usage(krb5_context context,
     unsigned nonce;
     krb5_keyblock *subkey = NULL;
     size_t len;
-    Ticket second_ticket;
+    Ticket second_ticket_data;
     int send_to_kdc_flags = 0;
+    METHOD_DATA padata;
     
     krb5_data_zero(&resp);
     krb5_data_zero(&enc);
+    padata.val = NULL;
+    padata.len = 0;
 
     krb5_generate_random_block(&nonce, sizeof(nonce));
     nonce &= 0xffffffff;
     
-    if(flags.b.enc_tkt_in_skey){
+    if(flags.b.enc_tkt_in_skey && second_ticket == NULL){
        ret = decode_Ticket(in_creds->second_ticket.data, 
                            in_creds->second_ticket.length, 
-                           &second_ticket, &len);
+                           &second_ticket_data, &len);
        if(ret)
            return ret;
+       second_ticket = &second_ticket_data;
+    }
+
+
+    if (impersonate_principal) {
+       krb5_crypto crypto;
+       PA_S4U2Self self;
+       krb5_data data;
+       void *buf;
+       size_t size;
+
+       self.name = impersonate_principal->name;
+       self.realm = impersonate_principal->realm;
+       self.auth = estrdup("Kerberos");
+       
+       ret = _krb5_s4u2self_to_checksumdata(context, &self, &data);
+       if (ret) {
+           free(self.auth);
+           goto out;
+       }
+
+       ret = krb5_crypto_init(context, &krbtgt->session, 0, &crypto);
+       if (ret) {
+           free(self.auth);
+           krb5_data_free(&data);
+           goto out;
+       }
+
+       ret = krb5_create_checksum(context,
+                                  crypto,
+                                  KRB5_KU_TGS_IMPERSONATE,
+                                  0,
+                                  data.data,
+                                  data.length, 
+                                  &self.cksum);
+       krb5_crypto_destroy(context, crypto);
+       krb5_data_free(&data);
+       if (ret) {
+           free(self.auth);
+           goto out;
+       }
+
+       ASN1_MALLOC_ENCODE(PA_S4U2Self, buf, len, &self, &size, ret);
+       free(self.auth);
+       free_Checksum(&self.cksum);
+       if (ret)
+           goto out;
+       if (len != size)
+           krb5_abortx(context, "internal asn1 error");
+       
+       ret = krb5_padata_add(context, &padata, KRB5_PADATA_S4U2SELF, buf, len);
+       if (ret)
+           goto out;
     }
 
     ret = init_tgs_req (context,
                        id,
                        addresses,
                        flags,
-                       flags.b.enc_tkt_in_skey ? &second_ticket : NULL,
+                       second_ticket,
                        in_creds,
                        krbtgt,
                        nonce,
+                       &padata,
                        &subkey, 
                        &req,
                        usage);
-    if(flags.b.enc_tkt_in_skey)
-       free_Ticket(&second_ticket);
     if (ret)
        goto out;
 
@@ -475,7 +543,7 @@ again:
                                   &krbtgt->addresses,
                                   nonce,
                                   TRUE,
-                                  flags.b.request_anonymous,
+                                  TRUE /* flags.b.request_anonymous */,
                                   decrypt_tkt_with_subkey,
                                   subkey);
        krb5_free_kdc_rep(context, &rep);
@@ -497,6 +565,9 @@ again:
     }
 
 out:
+    if (second_ticket == &second_ticket_data)
+       free_Ticket(&second_ticket_data);
+    free_METHOD_DATA(&padata);
     krb5_data_free(&resp);
     krb5_data_free(&enc);
     if(subkey){
@@ -514,16 +585,20 @@ get_cred_kdc(krb5_context context,
             krb5_addresses *addresses, 
             krb5_creds *in_creds, 
             krb5_creds *krbtgt,
+            krb5_principal impersonate_principal,
+            Ticket *second_ticket,
             krb5_creds *out_creds)
 {
     krb5_error_code ret;
 
     ret = get_cred_kdc_usage(context, id, flags, addresses, in_creds,
-                            krbtgt, out_creds, KRB5_KU_TGS_REQ_AUTH);
+                            krbtgt, impersonate_principal, second_ticket,
+                            out_creds, KRB5_KU_TGS_REQ_AUTH);
     if (ret == KRB5KRB_AP_ERR_BAD_INTEGRITY) {
        krb5_clear_error_string (context);
        ret = get_cred_kdc_usage(context, id, flags, addresses, in_creds,
-                                krbtgt, out_creds, KRB5_KU_AP_REQ_AUTH);
+                                krbtgt, impersonate_principal, second_ticket,
+                                out_creds, KRB5_KU_AP_REQ_AUTH);
     }
     return ret;
 }
@@ -533,6 +608,7 @@ get_cred_kdc(krb5_context context,
 static krb5_error_code
 get_cred_kdc_la(krb5_context context, krb5_ccache id, krb5_kdc_flags flags, 
                krb5_creds *in_creds, krb5_creds *krbtgt, 
+               krb5_principal impersonate_principal, Ticket *second_ticket,
                krb5_creds *out_creds)
 {
     krb5_error_code ret;
@@ -543,7 +619,8 @@ get_cred_kdc_la(krb5_context context, krb5_ccache id, krb5_kdc_flags flags,
     if(addresses.len == 0)
        addrs = NULL;
     ret = get_cred_kdc(context, id, flags, addrs, 
-                      in_creds, krbtgt, out_creds);
+                      in_creds, krbtgt, impersonate_principal, second_ticket,
+                      out_creds);
     krb5_free_addresses(context, &addresses);
     return ret;
 }
@@ -575,7 +652,7 @@ krb5_get_kdc_cred(krb5_context context,
        return ret;
     }
     ret = get_cred_kdc(context, id, flags, addresses, 
-                      in_creds, krbtgt, *out_creds);
+                      in_creds, krbtgt, NULL, NULL, *out_creds);
     krb5_free_creds (context, krbtgt);
     if(ret)
        free(*out_creds);
@@ -607,7 +684,17 @@ find_cred(krb5_context context,
        }
        tgts++;
     }
-    krb5_clear_error_string(context);
+    {
+       char *str;
+       ret = krb5_unparse_name(context, server, &str);
+       if(ret == 0) {
+           krb5_set_error_string(context, "Matching credential "
+                                 "(%s) not found", str);
+           free(str);
+       } else {
+           krb5_clear_error_string(context);
+       }
+    }
     return KRB5_CC_NOTFOUND;
 }
 
@@ -650,6 +737,8 @@ get_cred_from_kdc_flags(krb5_context context,
                        krb5_kdc_flags flags,
                        krb5_ccache ccache,
                        krb5_creds *in_creds,
+                       krb5_principal impersonate_principal,
+                       Ticket *second_ticket,                  
                        krb5_creds **out_creds,
                        krb5_creds ***ret_tgts)
 {
@@ -707,10 +796,16 @@ get_cred_from_kdc_flags(krb5_context context,
 
                if (noaddr)
                    ret = get_cred_kdc(context, ccache, flags, NULL,
-                                      in_creds, &tgts, *out_creds);
+                                      in_creds, &tgts,
+                                      impersonate_principal, 
+                                      second_ticket,
+                                      *out_creds);
                else
                    ret = get_cred_kdc_la(context, ccache, flags, 
-                                         in_creds, &tgts, *out_creds);
+                                         in_creds, &tgts, 
+                                         impersonate_principal, 
+                                         second_ticket,
+                                         *out_creds);
                if (ret) {
                    free (*out_creds);
                    *out_creds = NULL;
@@ -731,7 +826,7 @@ get_cred_from_kdc_flags(krb5_context context,
        heim_general_string tgt_inst;
 
        ret = get_cred_from_kdc_flags(context, flags, ccache, &tmp_creds, 
-                                     &tgt, ret_tgts);
+                                     NULL, NULL, &tgt, ret_tgts);
        if(ret) {
            krb5_free_principal(context, tmp_creds.server);
            krb5_free_principal(context, tmp_creds.client);
@@ -776,10 +871,12 @@ get_cred_from_kdc_flags(krb5_context context,
                                &noaddr);
        if (noaddr)
            ret = get_cred_kdc (context, ccache, flags, NULL,
-                               in_creds, tgt, *out_creds);
+                               in_creds, tgt, NULL, NULL,
+                               *out_creds);
        else
            ret = get_cred_kdc_la(context, ccache, flags, 
-                                 in_creds, tgt, *out_creds);
+                                 in_creds, tgt, NULL, NULL,
+                                 *out_creds);
        if (ret) {
            free (*out_creds);
            *out_creds = NULL;
@@ -800,7 +897,8 @@ krb5_get_cred_from_kdc_opt(krb5_context context,
     krb5_kdc_flags f;
     f.i = flags;
     return get_cred_from_kdc_flags(context, f, ccache, 
-                                  in_creds, out_creds, ret_tgts);
+                                  in_creds, NULL, NULL,
+                                  out_creds, ret_tgts);
 }
 
 krb5_error_code KRB5_LIB_FUNCTION
@@ -879,15 +977,18 @@ krb5_get_credentials_with_flags(krb5_context context,
     }
     if(options & KRB5_GC_USER_USER)
        flags.b.enc_tkt_in_skey = 1;
+    if (flags.b.enc_tkt_in_skey)
+       options |= KRB5_GC_NO_STORE;
+
     tgts = NULL;
     ret = get_cred_from_kdc_flags(context, flags, ccache, 
-                                 in_creds, out_creds, &tgts);
+                                 in_creds, NULL, NULL, out_creds, &tgts);
     for(i = 0; tgts && tgts[i]; i++) {
        krb5_cc_store_cred(context, ccache, tgts[i]);
        krb5_free_creds(context, tgts[i]);
     }
     free(tgts);
-    if(ret == 0 && flags.b.enc_tkt_in_skey == 0)
+    if(ret == 0 && (options & KRB5_GC_NO_STORE) == 0)
        krb5_cc_store_cred(context, ccache, *out_creds);
     return ret;
 }
@@ -904,3 +1005,200 @@ krb5_get_credentials(krb5_context context,
     return krb5_get_credentials_with_flags(context, options, flags,
                                           ccache, in_creds, out_creds);
 }
+
+struct krb5_get_creds_opt_data {
+    krb5_principal self;
+    krb5_flags options;
+    krb5_enctype enctype;
+    Ticket *ticket;
+};
+
+
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_get_creds_opt_alloc(krb5_context context, krb5_get_creds_opt *opt)
+{
+    *opt = calloc(1, sizeof(**opt));
+    if (*opt == NULL) {
+       krb5_set_error_string(context, "malloc: out of memory");
+       return ENOMEM;
+    }
+    return 0;
+}
+
+void KRB5_LIB_FUNCTION
+krb5_get_creds_opt_free(krb5_context context, krb5_get_creds_opt opt)
+{
+    if (opt->self)
+       krb5_free_principal(context, opt->self);
+    memset(opt, 0, sizeof(*opt));
+    free(opt);
+}
+
+void KRB5_LIB_FUNCTION
+krb5_get_creds_opt_set_options(krb5_context context,
+                              krb5_get_creds_opt opt,
+                              krb5_flags options)
+{
+    opt->options = options;
+}
+
+void KRB5_LIB_FUNCTION
+krb5_get_creds_opt_add_options(krb5_context context,
+                              krb5_get_creds_opt opt,
+                              krb5_flags options)
+{
+    opt->options |= options;
+}
+
+void KRB5_LIB_FUNCTION
+krb5_get_creds_opt_set_enctype(krb5_context context,
+                              krb5_get_creds_opt opt,
+                              krb5_enctype enctype)
+{
+    opt->enctype = enctype;
+}
+
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_get_creds_opt_set_impersonate(krb5_context context,
+                                  krb5_get_creds_opt opt,
+                                  krb5_const_principal self)
+{
+    if (opt->self)
+       krb5_free_principal(context, opt->self);
+    return krb5_copy_principal(context, self, &opt->self);
+}
+
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_get_creds_opt_set_ticket(krb5_context context,
+                             krb5_get_creds_opt opt,
+                             const Ticket *ticket)
+{
+    if (opt->ticket) {
+       free_Ticket(opt->ticket);
+       free(opt->ticket);
+       opt->ticket = NULL;
+    }
+    if (ticket) {
+       krb5_error_code ret;
+
+       opt->ticket = malloc(sizeof(*ticket));
+       if (opt->ticket == NULL) {
+           krb5_set_error_string(context, "malloc: out of memory");
+           return ENOMEM;
+       }
+       ret = copy_Ticket(ticket, opt->ticket);
+       if (ret) {
+           free(opt->ticket);
+           opt->ticket = NULL;
+           krb5_set_error_string(context, "malloc: out of memory");
+           return ret;
+       }
+    }
+    return 0;
+}
+
+
+
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_get_creds(krb5_context context,
+              krb5_get_creds_opt opt,
+              krb5_ccache ccache,
+              krb5_const_principal inprinc,
+              krb5_creds **out_creds)
+{
+    krb5_kdc_flags flags;
+    krb5_flags options;
+    krb5_creds in_creds;
+    krb5_error_code ret;
+    krb5_creds **tgts;
+    krb5_creds *res_creds;
+    int i;
+    
+    memset(&in_creds, 0, sizeof(in_creds));
+    in_creds.server = rk_UNCONST(inprinc);
+
+    ret = krb5_cc_get_principal(context, ccache, &in_creds.client);
+    if (ret)
+       return ret;
+
+    options = opt->options;
+    flags.i = 0;
+
+    *out_creds = NULL;
+    res_creds = calloc(1, sizeof(*res_creds));
+    if (res_creds == NULL) {
+       krb5_free_principal(context, in_creds.client);
+       krb5_set_error_string(context, "malloc: out of memory");
+       return ENOMEM;
+    }
+
+    if (opt->enctype) {
+       in_creds.session.keytype = opt->enctype;
+       options |= KRB5_TC_MATCH_KEYTYPE;
+    }
+
+    /* 
+     * If we got a credential, check if credential is expired before
+     * returning it.
+     */
+    ret = krb5_cc_retrieve_cred(context,
+                                ccache,
+                               opt->enctype ? KRB5_TC_MATCH_KEYTYPE : 0,
+                                &in_creds, res_creds);
+    /* 
+     * If we got a credential, check if credential is expired before
+     * returning it, but only if KRB5_GC_EXPIRED_OK is not set.
+     */
+    if (ret == 0) {
+       krb5_timestamp timeret;
+
+       /* If expired ok, don't bother checking */
+        if(options & KRB5_GC_EXPIRED_OK) {
+            *out_creds = res_creds;
+           krb5_free_principal(context, in_creds.client);
+            return 0;
+        }
+           
+       krb5_timeofday(context, &timeret);
+       if(res_creds->times.endtime > timeret) {
+           *out_creds = res_creds;
+           krb5_free_principal(context, in_creds.client);
+           return 0;
+       }
+       if(options & KRB5_GC_CACHED)
+           krb5_cc_remove_cred(context, ccache, 0, res_creds);
+
+    } else if(ret != KRB5_CC_END) {
+        free(res_creds);
+       krb5_free_principal(context, in_creds.client);
+        return ret;
+    }
+    free(res_creds);
+    if(options & KRB5_GC_CACHED) {
+        krb5_clear_error_string (context);        
+       krb5_free_principal(context, in_creds.client);
+        return KRB5_CC_NOTFOUND;
+    }
+    if(options & KRB5_GC_USER_USER) {
+       flags.b.enc_tkt_in_skey = 1;
+       options |= KRB5_GC_NO_STORE;
+    }
+    if (options & KRB5_GC_FORWARDABLE)
+       flags.b.forwardable = 1;
+    if (options & KRB5_GC_NO_TRANSIT_CHECK)
+       flags.b.disable_transited_check = 1;
+
+    tgts = NULL;
+    ret = get_cred_from_kdc_flags(context, flags, ccache, 
+                                 &in_creds, opt->self, opt->ticket,
+                                 out_creds, &tgts);
+    krb5_free_principal(context, in_creds.client);
+    for(i = 0; tgts && tgts[i]; i++) {
+       krb5_cc_store_cred(context, ccache, tgts[i]);
+       krb5_free_creds(context, tgts[i]);
+    }
+    free(tgts);
+    if(ret == 0 && (options & KRB5_GC_NO_STORE) == 0)
+       krb5_cc_store_cred(context, ccache, *out_creds);
+    return ret;
+}
index f042cdb5735316291aaaf485254d02d379a6575e..661d05663b7cb1db3316b85b20395ce14e221c3f 100644 (file)
@@ -376,7 +376,7 @@ krb5_get_forwarded_creds (krb5_context          context,
        cred.enc_part.cipher.length = buf_size;
     } else {
        /* 
-        * Here older versions than 0.7.2 of Heimdal used the local or
+        * Here older versions then 0.7.2 of Heimdal used the local or
         * remote subkey. That is wrong, the session key should be
         * used. Heimdal 0.7.2 and newer have code to try both in the
         * receiving end.
index 33a3438b12f24c93ca2feb5c9f05d9c963853726..ffc646d98bbadadcd9a67b25439037990851e50a 100644 (file)
@@ -34,7 +34,7 @@
 #include "krb5_locl.h"
 #include <resolve.h>
 
-RCSID("$Id: get_host_realm.c,v 1.35 2005/08/23 08:14:02 lha Exp $");
+RCSID("$Id: get_host_realm.c,v 1.37 2006/10/17 19:28:36 lha Exp $");
 
 /* To automagically find the correct realm of a host (without
  * [domain_realm] in krb5.conf) add a text record for your domain with
@@ -187,65 +187,71 @@ _krb5_get_host_realm_int (krb5_context context,
                return 0;
        }
     }
-
-    *realms = malloc(2 * sizeof(krb5_realm));
-    if (*realms == NULL) {
-           krb5_set_error_string(context, "malloc: out of memory");
-           return ENOMEM;
-    }
-    
-    (*realms)[1] = NULL;
-
     p = strchr(host, '.');
     if(p != NULL) {
        p++;
-       (*realms)[0] = strdup(p);
-       if((*realms)[0] == NULL) {
-           free(*realms);
+       *realms = malloc(2 * sizeof(krb5_realm));
+       if (*realms == NULL) {
            krb5_set_error_string(context, "malloc: out of memory");
            return ENOMEM;
        }
-       strupr((*realms)[0]);
-    } else {
-       krb5_error_code ret;
-       ret = krb5_get_default_realm(context, &(*realms)[0]);
-       if(ret) {
+
+       (*realms)[0] = strdup(p);
+       if((*realms)[0] == NULL) {
            free(*realms);
            krb5_set_error_string(context, "malloc: out of memory");
            return ENOMEM;
        }
-       if((*realms)[0] == NULL) {
-           free(*realms);
-           krb5_set_error_string(context, "unable to find realm of host %s", host);
-           return KRB5_ERR_HOST_REALM_UNKNOWN;
-       }
+       strupr((*realms)[0]);
+       (*realms)[1] = NULL;
+       return 0;
     }
-    return 0;
+    krb5_set_error_string(context, "unable to find realm of host %s", host);
+    return KRB5_ERR_HOST_REALM_UNKNOWN;
 }
 
 /*
- * Return the realm(s) of `host' as a NULL-terminated list in `realms'.
+ * Return the realm(s) of `host' as a NULL-terminated list in
+ * `realms'. Free `realms' with krb5_free_host_realm().
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_get_host_realm(krb5_context context,
-                   const char *host,
+                   const char *targethost,
                    krb5_realm **realms)
 {
+    const char *host = targethost;
     char hostname[MAXHOSTNAMELEN];
-    krb5_boolean use_dns;
+    krb5_error_code ret;
+    int use_dns;
 
     if (host == NULL) {
-       if (gethostname (hostname, sizeof(hostname)))
+       if (gethostname (hostname, sizeof(hostname))) {
+           *realms = NULL;
            return errno;
+       }
        host = hostname;
     }
 
-    if (strchr(host, '.') == NULL) {
-           use_dns = FALSE;
-    } else {
-           use_dns = TRUE;
-    }
+    /* 
+     * If our local hostname is without components, don't even try to dns.
+     */
+
+    use_dns = (strchr(host, '.') != NULL);
 
-    return _krb5_get_host_realm_int (context, host, use_dns, realms);
+    ret = _krb5_get_host_realm_int (context, host, use_dns, realms);
+    if (ret && targethost != NULL) {
+       /*
+        * If there was no realm mapping for the host (and we wasn't
+        * looking for ourself), guess at the local realm, maybe our
+        * KDC knows better then we do and we get a referral back.
+        */
+       ret = krb5_get_default_realms(context, realms);
+       if (ret) {
+           krb5_set_error_string(context, "Unable to find realm of host %s",
+                                 host);
+           return KRB5_ERR_HOST_REALM_UNKNOWN;
+       }
+    }
+    return ret;
 }
index 5c488d1ddc766d9b3749cc2d6d30f620738a4a71..ebc96f227993850ec5b3ee6d8920040ab6b557aa 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: get_in_tkt.c,v 1.116 2005/06/15 02:53:20 lha Exp $");
+RCSID("$Id: get_in_tkt.c,v 1.119 2006/10/06 17:05:08 lha Exp $");
 
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_init_etype (krb5_context context,
@@ -137,7 +137,7 @@ _krb5_extract_ticket(krb5_context context,
     time_t tmp_time;
     krb5_timestamp sec_now;
 
-    ret = _krb5_principalname2krb5_principal (context, 
+    ret = _krb5_principalname2krb5_principal (context,
                                              &tmp_principal,
                                              rep->kdc_rep.cname,
                                              rep->kdc_rep.crealm);
@@ -171,7 +171,7 @@ _krb5_extract_ticket(krb5_context context,
 
     /* compare server */
 
-    ret = _krb5_principalname2krb5_principal (context, 
+    ret = _krb5_principalname2krb5_principal (context,
                                              &tmp_principal,
                                              rep->kdc_rep.ticket.sname,
                                              rep->kdc_rep.ticket.realm);
@@ -411,7 +411,7 @@ add_padata(krb5_context context,
 
 static krb5_error_code
 init_as_req (krb5_context context,
-            krb5_kdc_flags opts,
+            KDCOptions opts,
             krb5_creds *creds,
             const krb5_addresses *addrs,
             const krb5_enctype *etypes,
@@ -429,7 +429,7 @@ init_as_req (krb5_context context,
 
     a->pvno = 5;
     a->msg_type = krb_as_req;
-    a->req_body.kdc_options = opts.b;
+    a->req_body.kdc_options = opts;
     a->req_body.cname = malloc(sizeof(*a->req_body.cname));
     if (a->req_body.cname == NULL) {
        ret = ENOMEM;
@@ -649,14 +649,14 @@ krb5_get_in_cred(krb5_context context,
     krb5_salt salt;
     krb5_keyblock *key;
     size_t size;
-    krb5_kdc_flags opts;
+    KDCOptions opts;
     PA_DATA *pa;
     krb5_enctype etype;
     krb5_preauthdata *my_preauth = NULL;
     unsigned nonce;
     int done;
 
-    opts.i = options;
+    opts = int2KDCOptions(options);
 
     krb5_generate_random_block (&nonce, sizeof(nonce));
     nonce &= 0xffffffff;
@@ -771,7 +771,7 @@ krb5_get_in_cred(krb5_context context,
                               NULL, 
                               nonce, 
                               FALSE, 
-                              opts.b.request_anonymous,
+                              opts.request_anonymous,
                               decrypt_proc, 
                               decryptarg);
     memset (key->keyvalue.data, 0, key->keyvalue.length);
@@ -801,12 +801,9 @@ krb5_get_in_tkt(krb5_context context,
                krb5_kdc_rep *ret_as_reply)
 {
     krb5_error_code ret;
-    krb5_kdc_flags opts;
-    opts.i = 0;
-    opts.b = int2KDCOptions(options);
     
     ret = krb5_get_in_cred (context,
-                           opts.i,
+                           options,
                            addrs,
                            etypes,
                            ptypes,
diff --git a/source4/heimdal/lib/krb5/heim_err.c b/source4/heimdal/lib/krb5/heim_err.c
new file mode 100644 (file)
index 0000000..f72a265
--- /dev/null
@@ -0,0 +1,162 @@
+/* Generated from heim_err.et */
+/* $Id: heim_err.et,v 1.13 2004/02/13 16:23:40 lha Exp $ */
+
+#include <stddef.h>
+#include <com_err.h>
+#include "heim_err.h"
+
+static const char *heim_error_strings[] = {
+       /* 000 */ "Error parsing log destination",
+       /* 001 */ "Failed to convert v4 principal",
+       /* 002 */ "Salt type is not supported by enctype",
+       /* 003 */ "Host not found",
+       /* 004 */ "Operation not supported",
+       /* 005 */ "End of file",
+       /* 006 */ "Failed to get the master key",
+       /* 007 */ "Unacceptable service used",
+       /* 008 */ "Reserved heim error (8)",
+       /* 009 */ "Reserved heim error (9)",
+       /* 010 */ "Reserved heim error (10)",
+       /* 011 */ "Reserved heim error (11)",
+       /* 012 */ "Reserved heim error (12)",
+       /* 013 */ "Reserved heim error (13)",
+       /* 014 */ "Reserved heim error (14)",
+       /* 015 */ "Reserved heim error (15)",
+       /* 016 */ "Reserved heim error (16)",
+       /* 017 */ "Reserved heim error (17)",
+       /* 018 */ "Reserved heim error (18)",
+       /* 019 */ "Reserved heim error (19)",
+       /* 020 */ "Reserved heim error (20)",
+       /* 021 */ "Reserved heim error (21)",
+       /* 022 */ "Reserved heim error (22)",
+       /* 023 */ "Reserved heim error (23)",
+       /* 024 */ "Reserved heim error (24)",
+       /* 025 */ "Reserved heim error (25)",
+       /* 026 */ "Reserved heim error (26)",
+       /* 027 */ "Reserved heim error (27)",
+       /* 028 */ "Reserved heim error (28)",
+       /* 029 */ "Reserved heim error (29)",
+       /* 030 */ "Reserved heim error (30)",
+       /* 031 */ "Reserved heim error (31)",
+       /* 032 */ "Reserved heim error (32)",
+       /* 033 */ "Reserved heim error (33)",
+       /* 034 */ "Reserved heim error (34)",
+       /* 035 */ "Reserved heim error (35)",
+       /* 036 */ "Reserved heim error (36)",
+       /* 037 */ "Reserved heim error (37)",
+       /* 038 */ "Reserved heim error (38)",
+       /* 039 */ "Reserved heim error (39)",
+       /* 040 */ "Reserved heim error (40)",
+       /* 041 */ "Reserved heim error (41)",
+       /* 042 */ "Reserved heim error (42)",
+       /* 043 */ "Reserved heim error (43)",
+       /* 044 */ "Reserved heim error (44)",
+       /* 045 */ "Reserved heim error (45)",
+       /* 046 */ "Reserved heim error (46)",
+       /* 047 */ "Reserved heim error (47)",
+       /* 048 */ "Reserved heim error (48)",
+       /* 049 */ "Reserved heim error (49)",
+       /* 050 */ "Reserved heim error (50)",
+       /* 051 */ "Reserved heim error (51)",
+       /* 052 */ "Reserved heim error (52)",
+       /* 053 */ "Reserved heim error (53)",
+       /* 054 */ "Reserved heim error (54)",
+       /* 055 */ "Reserved heim error (55)",
+       /* 056 */ "Reserved heim error (56)",
+       /* 057 */ "Reserved heim error (57)",
+       /* 058 */ "Reserved heim error (58)",
+       /* 059 */ "Reserved heim error (59)",
+       /* 060 */ "Reserved heim error (60)",
+       /* 061 */ "Reserved heim error (61)",
+       /* 062 */ "Reserved heim error (62)",
+       /* 063 */ "Reserved heim error (63)",
+       /* 064 */ "Certificate missing",
+       /* 065 */ "Private key missing",
+       /* 066 */ "No valid certificate authority",
+       /* 067 */ "Certificate invalid",
+       /* 068 */ "Private key invalid",
+       /* 069 */ "Reserved heim error (69)",
+       /* 070 */ "Reserved heim error (70)",
+       /* 071 */ "Reserved heim error (71)",
+       /* 072 */ "Reserved heim error (72)",
+       /* 073 */ "Reserved heim error (73)",
+       /* 074 */ "Reserved heim error (74)",
+       /* 075 */ "Reserved heim error (75)",
+       /* 076 */ "Reserved heim error (76)",
+       /* 077 */ "Reserved heim error (77)",
+       /* 078 */ "Reserved heim error (78)",
+       /* 079 */ "Reserved heim error (79)",
+       /* 080 */ "Reserved heim error (80)",
+       /* 081 */ "Reserved heim error (81)",
+       /* 082 */ "Reserved heim error (82)",
+       /* 083 */ "Reserved heim error (83)",
+       /* 084 */ "Reserved heim error (84)",
+       /* 085 */ "Reserved heim error (85)",
+       /* 086 */ "Reserved heim error (86)",
+       /* 087 */ "Reserved heim error (87)",
+       /* 088 */ "Reserved heim error (88)",
+       /* 089 */ "Reserved heim error (89)",
+       /* 090 */ "Reserved heim error (90)",
+       /* 091 */ "Reserved heim error (91)",
+       /* 092 */ "Reserved heim error (92)",
+       /* 093 */ "Reserved heim error (93)",
+       /* 094 */ "Reserved heim error (94)",
+       /* 095 */ "Reserved heim error (95)",
+       /* 096 */ "Reserved heim error (96)",
+       /* 097 */ "Reserved heim error (97)",
+       /* 098 */ "Reserved heim error (98)",
+       /* 099 */ "Reserved heim error (99)",
+       /* 100 */ "Reserved heim error (100)",
+       /* 101 */ "Reserved heim error (101)",
+       /* 102 */ "Reserved heim error (102)",
+       /* 103 */ "Reserved heim error (103)",
+       /* 104 */ "Reserved heim error (104)",
+       /* 105 */ "Reserved heim error (105)",
+       /* 106 */ "Reserved heim error (106)",
+       /* 107 */ "Reserved heim error (107)",
+       /* 108 */ "Reserved heim error (108)",
+       /* 109 */ "Reserved heim error (109)",
+       /* 110 */ "Reserved heim error (110)",
+       /* 111 */ "Reserved heim error (111)",
+       /* 112 */ "Reserved heim error (112)",
+       /* 113 */ "Reserved heim error (113)",
+       /* 114 */ "Reserved heim error (114)",
+       /* 115 */ "Reserved heim error (115)",
+       /* 116 */ "Reserved heim error (116)",
+       /* 117 */ "Reserved heim error (117)",
+       /* 118 */ "Reserved heim error (118)",
+       /* 119 */ "Reserved heim error (119)",
+       /* 120 */ "Reserved heim error (120)",
+       /* 121 */ "Reserved heim error (121)",
+       /* 122 */ "Reserved heim error (122)",
+       /* 123 */ "Reserved heim error (123)",
+       /* 124 */ "Reserved heim error (124)",
+       /* 125 */ "Reserved heim error (125)",
+       /* 126 */ "Reserved heim error (126)",
+       /* 127 */ "Reserved heim error (127)",
+       /* 128 */ "unknown error from getaddrinfo",
+       /* 129 */ "address family for nodename not supported",
+       /* 130 */ "temporary failure in name resolution",
+       /* 131 */ "invalid value for ai_flags",
+       /* 132 */ "non-recoverable failure in name resolution",
+       /* 133 */ "ai_family not supported",
+       /* 134 */ "memory allocation failure",
+       /* 135 */ "no address associated with nodename",
+       /* 136 */ "nodename nor servname provided, or not known",
+       /* 137 */ "servname not supported for ai_socktype",
+       /* 138 */ "ai_socktype not supported",
+       /* 139 */ "system error returned in errno",
+       NULL
+};
+
+#define num_errors 140
+
+void initialize_heim_error_table_r(struct et_list **list)
+{
+    initialize_error_table_r(list, heim_error_strings, num_errors, ERROR_TABLE_BASE_heim);
+}
+
+void initialize_heim_error_table(void)
+{
+    init_error_table(heim_error_strings, ERROR_TABLE_BASE_heim, num_errors);
+}
index 41f0f83306ba629010bcf42b8de33e28fea5b453..3ebe66beee16b2abf1442bca3c2f6097aaec1b55 100755 (executable)
@@ -53,7 +53,7 @@
 /* 
  * NetBSD have a thread lib that we can use that part of libc that
  * works regardless if application are linked to pthreads or not.
- * NetBSD newer than 2.99.11 just use pthread.h, and the same thing
+ * NetBSD newer then 2.99.11 just use pthread.h, and the same thing
  * will happen.
  */
 #include <threadlib.h>
index 88de280a00003fda4268b2d18b93dde6de516298..6dacb316d8c7b1ddd507c44491a47dee1ad9eff0 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: init_creds.c,v 1.23 2006/04/02 01:08:30 lha Exp $");
+RCSID("$Id: init_creds.c,v 1.28 2006/09/04 14:28:54 lha Exp $");
 
 void KRB5_LIB_FUNCTION
 krb5_get_init_creds_opt_init(krb5_get_init_creds_opt *opt)
@@ -96,6 +96,39 @@ _krb5_get_init_creds_opt_copy(krb5_context context,
     return 0;
 }
 
+void KRB5_LIB_FUNCTION
+_krb5_get_init_creds_opt_free_krb5_error(krb5_get_init_creds_opt *opt)
+{
+    if (opt->opt_private == NULL || opt->opt_private->error == NULL)
+       return;
+    free_KRB_ERROR(opt->opt_private->error);
+    free(opt->opt_private->error);
+    opt->opt_private->error = NULL;
+}
+
+void KRB5_LIB_FUNCTION
+_krb5_get_init_creds_opt_set_krb5_error(krb5_context context,
+                                       krb5_get_init_creds_opt *opt, 
+                                       const KRB_ERROR *error)
+{
+    krb5_error_code ret;
+
+    if (opt->opt_private == NULL)
+       return;
+
+    _krb5_get_init_creds_opt_free_krb5_error(opt);
+
+    opt->opt_private->error = malloc(sizeof(*opt->opt_private->error));
+    if (opt->opt_private->error == NULL)
+       return;
+    ret = copy_KRB_ERROR(error, opt->opt_private->error);
+    if (ret) {
+       free(opt->opt_private->error);
+       opt->opt_private->error = NULL;
+    }  
+}
+
+
 void KRB5_LIB_FUNCTION
 krb5_get_init_creds_opt_free(krb5_get_init_creds_opt *opt)
 {
@@ -104,6 +137,7 @@ krb5_get_init_creds_opt_free(krb5_get_init_creds_opt *opt)
     if (opt->opt_private->refcount < 1) /* abort ? */
        return;
     if (--opt->opt_private->refcount == 0) {
+       _krb5_get_init_creds_opt_free_krb5_error(opt);
        _krb5_get_init_creds_opt_free_pkinit(opt);
        free(opt->opt_private);
     }
@@ -160,8 +194,6 @@ get_config_bool (krb5_context context,
  * [realms] or [libdefaults] for some of the values.
  */
 
-static krb5_addresses no_addrs = {0, NULL};
-
 void KRB5_LIB_FUNCTION
 krb5_get_init_creds_opt_set_default_flags(krb5_context context,
                                          const char *appname,
@@ -192,9 +224,9 @@ krb5_get_init_creds_opt_set_default_flags(krb5_context context,
        krb5_get_init_creds_opt_set_renew_life(opt, t);
 
     krb5_appdefault_boolean(context, appname, realm, "no-addresses", 
-                           KRB5_ADDRESSLESS_DEFAULT, &b);
+                           FALSE, &b);
     if (b)
-       krb5_get_init_creds_opt_set_address_list (opt, &no_addrs);
+       krb5_get_init_creds_opt_set_addressless (context, opt, TRUE);
 
 #if 0
     krb5_appdefault_boolean(context, appname, realm, "anonymous", FALSE, &b);
@@ -326,7 +358,52 @@ krb5_get_init_creds_opt_set_pac_request(krb5_context context,
     if (ret)
        return ret;
     opt->opt_private->req_pac = req_pac ?
-       KRB5_PA_PAC_REQ_TRUE :
-       KRB5_PA_PAC_REQ_FALSE;
+       KRB5_INIT_CREDS_TRISTATE_TRUE :
+       KRB5_INIT_CREDS_TRISTATE_FALSE;
+    return 0;
+}
+
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_get_init_creds_opt_get_error(krb5_context context,
+                                 krb5_get_init_creds_opt *opt,
+                                 KRB_ERROR **error)
+{
+    krb5_error_code ret;
+
+    *error = NULL;
+
+    ret = require_ext_opt(context, opt, "init_creds_opt_get_error");
+    if (ret)
+       return ret;
+
+    if (opt->opt_private->error == NULL)
+       return 0;
+
+    *error = malloc(sizeof(**error));
+    if (*error == NULL) {
+       krb5_set_error_string(context, "malloc - out memory");
+       return ENOMEM;
+    }
+
+    ret = copy_KRB_ERROR(*error, opt->opt_private->error);
+    if (ret)
+       krb5_clear_error_string(context);
+
+    return 0;
+}
+
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_get_init_creds_opt_set_addressless(krb5_context context,
+                                       krb5_get_init_creds_opt *opt,
+                                       krb5_boolean addressless)
+{
+    krb5_error_code ret;
+    ret = require_ext_opt(context, opt, "init_creds_opt_set_pac_req");
+    if (ret)
+       return ret;
+    if (addressless)
+       opt->opt_private->addressless = KRB5_INIT_CREDS_TRISTATE_TRUE;
+    else
+       opt->opt_private->addressless = KRB5_INIT_CREDS_TRISTATE_FALSE;
     return 0;
 }
index c05386ec238cdf39868fb31151b765bdcc81b9ba..d43ae0ae6ff54c0e151b56f9d5926578f1192e66 100644 (file)
 
 #include "krb5_locl.h"
 
-RCSID("$Id: init_creds_pw.c,v 1.94 2006/04/24 08:49:08 lha Exp $");
+RCSID("$Id: init_creds_pw.c,v 1.101 2006/10/02 12:00:59 lha Exp $");
 
 typedef struct krb5_get_init_creds_ctx {
-    krb5_kdc_flags flags;
+    KDCOptions flags;
     krb5_creds cred;
     krb5_addresses *addrs;
     krb5_enctype *etypes;
@@ -52,7 +52,7 @@ typedef struct krb5_get_init_creds_ctx {
     const char *password;
     krb5_s2k_proc key_proc;
 
-    krb5_get_init_creds_req_pac req_pac;
+    krb5_get_init_creds_tristate req_pac;
 
     krb5_pk_init_ctx pk_init_ctx;
 } krb5_get_init_creds_ctx;
@@ -256,9 +256,10 @@ print_expire (krb5_context context,
     }
 }
 
+static krb5_addresses no_addrs = { 0, NULL };
+
 static krb5_error_code
 get_init_creds_common(krb5_context context,
-                     krb5_creds *creds,
                      krb5_principal client,
                      krb5_deltat start_time,
                      const char *in_tkt_service,
@@ -275,6 +276,8 @@ get_init_creds_common(krb5_context context,
     if (options == NULL) {
        krb5_get_init_creds_opt_init (&default_opt);
        options = &default_opt;
+    } else {
+       _krb5_get_init_creds_opt_free_krb5_error(options);
     }
 
     if (options->opt_private) {
@@ -283,13 +286,12 @@ get_init_creds_common(krb5_context context,
        ctx->req_pac = options->opt_private->req_pac;
        ctx->pk_init_ctx = options->opt_private->pk_init_ctx;
     } else
-       ctx->req_pac = KRB5_PA_PAC_DONT_CARE;
+       ctx->req_pac = KRB5_INIT_CREDS_TRISTATE_UNSET;
 
     if (ctx->key_proc == NULL)
        ctx->key_proc = default_s2k_func;
 
     ctx->pre_auth_types = NULL;
-    ctx->flags.i = 0;
     ctx->addrs = NULL;
     ctx->etypes = NULL;
     ctx->pre_auth_types = NULL;
@@ -300,20 +302,35 @@ get_init_creds_common(krb5_context context,
     if (ret)
        return ret;
 
-    ctx->flags.i = 0;
-
     if (options->flags & KRB5_GET_INIT_CREDS_OPT_FORWARDABLE)
-       ctx->flags.b.forwardable = options->forwardable;
+       ctx->flags.forwardable = options->forwardable;
 
     if (options->flags & KRB5_GET_INIT_CREDS_OPT_PROXIABLE)
-       ctx->flags.b.proxiable = options->proxiable;
+       ctx->flags.proxiable = options->proxiable;
 
     if (start_time)
-       ctx->flags.b.postdated = 1;
+       ctx->flags.postdated = 1;
     if (ctx->cred.times.renew_till)
-       ctx->flags.b.renewable = 1;
-    if (options->flags & KRB5_GET_INIT_CREDS_OPT_ADDRESS_LIST)
+       ctx->flags.renewable = 1;
+    if (options->flags & KRB5_GET_INIT_CREDS_OPT_ADDRESS_LIST) {
        ctx->addrs = options->address_list;
+    } else if (options->opt_private) {
+       switch (options->opt_private->addressless) {
+       case KRB5_INIT_CREDS_TRISTATE_UNSET:
+#if KRB5_ADDRESSLESS_DEFAULT == TRUE
+           ctx->addrs = &no_addrs;
+#else
+           ctx->addrs = NULL;
+#endif
+           break;
+       case KRB5_INIT_CREDS_TRISTATE_FALSE:
+           ctx->addrs = NULL;
+           break;
+       case KRB5_INIT_CREDS_TRISTATE_TRUE:
+           ctx->addrs = &no_addrs;
+           break;
+       }
+    }
     if (options->flags & KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST) {
        etypes = malloc((options->etype_list_length + 1)
                        * sizeof(krb5_enctype));
@@ -341,7 +358,7 @@ get_init_creds_common(krb5_context context,
     if (options->flags & KRB5_GET_INIT_CREDS_OPT_SALT)
        ;                       /* XXX */
     if (options->flags & KRB5_GET_INIT_CREDS_OPT_ANONYMOUS)
-       ctx->flags.b.request_anonymous = options->anonymous;
+       ctx->flags.request_anonymous = options->anonymous;
     return 0;
 }
 
@@ -478,7 +495,7 @@ krb5_get_init_creds_keytab(krb5_context context,
     krb5_error_code ret;
     krb5_keytab_key_proc_args *a;
     
-    ret = get_init_creds_common(context, creds, client, start_time,
+    ret = get_init_creds_common(context, client, start_time,
                                in_tkt_service, options, &ctx);
     if (ret)
        goto out;
@@ -493,7 +510,7 @@ krb5_get_init_creds_keytab(krb5_context context,
     a->keytab    = keytab;
 
     ret = krb5_get_in_cred (context,
-                           ctx.flags.i,
+                           KDCOptions2int(ctx.flags),
                            ctx.addrs,
                            ctx.etypes,
                            ctx.pre_auth_types,
@@ -522,7 +539,7 @@ krb5_get_init_creds_keytab(krb5_context context,
 
 static krb5_error_code
 init_creds_init_as_req (krb5_context context,
-                       krb5_kdc_flags opts,
+                       KDCOptions opts,
                        const krb5_creds *creds,
                        const krb5_addresses *addrs,
                        const krb5_enctype *etypes,
@@ -534,7 +551,7 @@ init_creds_init_as_req (krb5_context context,
 
     a->pvno = 5;
     a->msg_type = krb_as_req;
-    a->req_body.kdc_options = opts.b;
+    a->req_body.kdc_options = opts;
     a->req_body.cname = malloc(sizeof(*a->req_body.cname));
     if (a->req_body.cname == NULL) {
        ret = ENOMEM;
@@ -1028,12 +1045,12 @@ pa_data_add_pac_request(krb5_context context,
     void *buf;
     
     switch (ctx->req_pac) {
-    case KRB5_PA_PAC_DONT_CARE:
+    case KRB5_INIT_CREDS_TRISTATE_UNSET:
        return 0; /* don't bother */
-    case KRB5_PA_PAC_REQ_TRUE:
+    case KRB5_INIT_CREDS_TRISTATE_TRUE:
        req.include_pac = 1;
        break;
-    case KRB5_PA_PAC_REQ_FALSE:
+    case KRB5_INIT_CREDS_TRISTATE_FALSE:
        req.include_pac = 0;
     }  
 
@@ -1176,7 +1193,7 @@ process_pa_data_to_key(krb5_context context,
 
 static krb5_error_code
 init_cred_loop(krb5_context context,
-              const krb5_get_init_creds_opt *init_cred_opts,
+              krb5_get_init_creds_opt *init_cred_opts,
               const krb5_prompter_fct prompter,
               void *prompter_data,
               krb5_get_init_creds_ctx *ctx,
@@ -1196,6 +1213,8 @@ init_cred_loop(krb5_context context,
     memset(&md, 0, sizeof(md));
     memset(&rep, 0, sizeof(rep));
 
+    _krb5_get_init_creds_opt_free_krb5_error(init_cred_opts);
+
     if (ret_as_reply)
        memset(ret_as_reply, 0, sizeof(*ret_as_reply));
 
@@ -1211,7 +1230,7 @@ init_cred_loop(krb5_context context,
     ctx->pk_nonce = ctx->nonce;
 
     /*
-     * Increase counter when we want other pre-auth types than
+     * Increase counter when we want other pre-auth types then
      * KRB5_PA_ENC_TIMESTAMP.
      */
 #define MAX_PA_COUNTER 3 
@@ -1306,6 +1325,9 @@ init_cred_loop(krb5_context context,
                krb5_free_error_contents(context, &error);
                send_to_kdc_flags |= KRB5_KRBHST_FLAGS_LARGE_MSG;
            } else {
+               _krb5_get_init_creds_opt_set_krb5_error(context,
+                                                       init_cred_opts,
+                                                       &error);
                if (ret_as_reply)
                    rep.error = error;
                else
@@ -1332,7 +1354,7 @@ init_cred_loop(krb5_context context,
                                   NULL,
                                   ctx->nonce,
                                   FALSE,
-                                  ctx->flags.b.request_anonymous,
+                                  ctx->flags.request_anonymous,
                                   NULL,
                                   NULL);
        krb5_free_keyblock(context, key);
@@ -1344,7 +1366,7 @@ out:
 
     if (ret == 0 && ret_as_reply)
        *ret_as_reply = rep;
-    else
+    else 
        krb5_free_kdc_rep (context, &rep);
     return ret;
 }
@@ -1367,7 +1389,7 @@ krb5_get_init_creds(krb5_context context,
 
     memset(&kdc_reply, 0, sizeof(kdc_reply));
 
-    ret = get_init_creds_common(context, creds, client, start_time,
+    ret = get_init_creds_common(context, client, start_time,
                                in_tkt_service, options, &ctx);
     if (ret)
        goto out;
@@ -1391,7 +1413,7 @@ krb5_get_init_creds(krb5_context context,
        case KRB5KDC_ERR_KEY_EXPIRED :
            /* try to avoid recursion */
 
-           /* don't try to change password where there where none */
+           /* don't try to change password where then where none */
            if (prompter == NULL || ctx.password == NULL)
                goto out;
 
@@ -1528,13 +1550,13 @@ krb5_get_init_creds_keyblock(krb5_context context,
     struct krb5_get_init_creds_ctx ctx;
     krb5_error_code ret;
     
-    ret = get_init_creds_common(context, creds, client, start_time,
+    ret = get_init_creds_common(context, client, start_time,
                                in_tkt_service, options, &ctx);
     if (ret)
        goto out;
 
     ret = krb5_get_in_cred (context,
-                           ctx.flags.i,
+                           KDCOptions2int(ctx.flags),
                            ctx.addrs,
                            ctx.etypes,
                            ctx.pre_auth_types,
diff --git a/source4/heimdal/lib/krb5/k524_err.c b/source4/heimdal/lib/krb5/k524_err.c
new file mode 100644 (file)
index 0000000..266d3ee
--- /dev/null
@@ -0,0 +1,30 @@
+/* Generated from k524_err.et */
+/* $Id: k524_err.et,v 1.1 2001/06/20 02:44:11 joda Exp $ */
+
+#include <stddef.h>
+#include <com_err.h>
+#include "k524_err.h"
+
+static const char *k524_error_strings[] = {
+       /* 000 */ "wrong keytype in ticket",
+       /* 001 */ "incorrect network address",
+       /* 002 */ "cannot convert V5 principal",
+       /* 003 */ "V5 realm name longer than V4 maximum",
+       /* 004 */ "kerberos V4 error server",
+       /* 005 */ "encoding too large at server",
+       /* 006 */ "decoding out of data",
+       /* 007 */ "service not responding",
+       NULL
+};
+
+#define num_errors 8
+
+void initialize_k524_error_table_r(struct et_list **list)
+{
+    initialize_error_table_r(list, k524_error_strings, num_errors, ERROR_TABLE_BASE_k524);
+}
+
+void initialize_k524_error_table(void)
+{
+    init_error_table(k524_error_strings, ERROR_TABLE_BASE_k524, num_errors);
+}
index 9ba288e22b32c500f219f85cf1036f42b2d1c0e1..968b6079b7f0b9252286a968a0c06370fcbb4736 100644 (file)
@@ -17,7 +17,7 @@ _krb5_aes_cts_encrypt (
        const unsigned char */*in*/,
        unsigned char */*out*/,
        size_t /*len*/,
-       const void */*aes_key*/,
+       const AES_KEY */*key*/,
        unsigned char */*ivec*/,
        const int /*encryptp*/);
 
@@ -46,6 +46,12 @@ _krb5_dh_group_ok (
        struct krb5_dh_moduli **/*moduli*/,
        char **/*name*/);
 
+krb5_error_code KRB5_LIB_FUNCTION
+_krb5_enctype_to_oid (
+       krb5_context /*context*/,
+       krb5_enctype /*etype*/,
+       heim_oid */*oid*/);
+
 krb5_error_code
 _krb5_expand_default_cc_name (
        krb5_context /*context*/,
@@ -100,9 +106,18 @@ _krb5_get_init_creds_opt_copy (
        const krb5_get_init_creds_opt */*in*/,
        krb5_get_init_creds_opt **/*out*/);
 
+void KRB5_LIB_FUNCTION
+_krb5_get_init_creds_opt_free_krb5_error (krb5_get_init_creds_opt */*opt*/);
+
 void KRB5_LIB_FUNCTION
 _krb5_get_init_creds_opt_free_pkinit (krb5_get_init_creds_opt */*opt*/);
 
+void KRB5_LIB_FUNCTION
+_krb5_get_init_creds_opt_set_krb5_error (
+       krb5_context /*context*/,
+       krb5_get_init_creds_opt */*opt*/,
+       const KRB_ERROR */*error*/);
+
 krb5_ssize_t KRB5_LIB_FUNCTION
 _krb5_get_int (
        void */*buffer*/,
@@ -312,8 +327,8 @@ _krb5_pk_load_id (
        struct krb5_pk_identity **/*ret_id*/,
        const char */*user_id*/,
        const char */*anchor_id*/,
-       char * const */*chain*/,
-       char * const */*revoke*/,
+       char * const */*chain_list*/,
+       char * const */*revoke_list*/,
        krb5_prompter_fct /*prompter*/,
        void */*prompter_data*/,
        char */*password*/);
@@ -372,7 +387,7 @@ _krb5_principal2principalname (
 
 krb5_error_code KRB5_LIB_FUNCTION
 _krb5_principalname2krb5_principal (
-       krb5_context /* context */,
+       krb5_context /*context*/,
        krb5_principal */*principal*/,
        const PrincipalName /*from*/,
        const Realm /*realm*/);
@@ -383,6 +398,12 @@ _krb5_put_int (
        unsigned long /*value*/,
        size_t /*size*/);
 
+krb5_error_code KRB5_LIB_FUNCTION
+_krb5_s4u2self_to_checksumdata (
+       krb5_context /*context*/,
+       const PA_S4U2Self */*self*/,
+       krb5_data */*data*/);
+
 int
 _krb5_send_and_recv_tcp (
        int /*fd*/,
index 37293ff9824ca11ac50485905b21255bfb8bc1d1..2010e25f5aecf84cf54a595e51d37e554103c03c 100644 (file)
@@ -1065,13 +1065,6 @@ krb5_crypto_get_checksum_type (
        krb5_crypto /*crypto*/,
        krb5_cksumtype */*type*/);
 
-krb5_error_code KRB5_LIB_FUNCTION
-krb5_crypto_get_params (
-       krb5_context /*context*/,
-       const krb5_crypto /*crypto*/,
-       const krb5_data */*params*/,
-       krb5_data */*ivec*/);
-
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_crypto_getblocksize (
        krb5_context /*context*/,
@@ -1103,13 +1096,6 @@ krb5_crypto_init (
        krb5_enctype /*etype*/,
        krb5_crypto */*crypto*/);
 
-krb5_error_code KRB5_LIB_FUNCTION
-krb5_crypto_set_params (
-       krb5_context /*context*/,
-       const krb5_crypto /*crypto*/,
-       const krb5_data */*ivec*/,
-       krb5_data */*params*/);
-
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_data_alloc (
        krb5_data */*p*/,
@@ -1246,6 +1232,169 @@ krb5_derive_key (
        size_t /*constant_len*/,
        krb5_keyblock **/*derived_key*/);
 
+krb5_error_code
+krb5_digest_alloc (
+       krb5_context /*context*/,
+       krb5_digest */*digest*/);
+
+void
+krb5_digest_free (krb5_digest /*digest*/);
+
+krb5_error_code
+krb5_digest_get_a1_hash (
+       krb5_context /*context*/,
+       krb5_digest /*digest*/,
+       krb5_data */*data*/);
+
+krb5_error_code
+krb5_digest_get_client_binding (
+       krb5_context /*context*/,
+       krb5_digest /*digest*/,
+       char **/*type*/,
+       char **/*binding*/);
+
+const char *
+krb5_digest_get_identifier (
+       krb5_context /*context*/,
+       krb5_digest /*digest*/);
+
+const char *
+krb5_digest_get_opaque (
+       krb5_context /*context*/,
+       krb5_digest /*digest*/);
+
+const char *
+krb5_digest_get_responseData (
+       krb5_context /*context*/,
+       krb5_digest /*digest*/);
+
+const char *
+krb5_digest_get_rsp (
+       krb5_context /*context*/,
+       krb5_digest /*digest*/);
+
+const char *
+krb5_digest_get_server_nonce (
+       krb5_context /*context*/,
+       krb5_digest /*digest*/);
+
+krb5_error_code
+krb5_digest_get_tickets (
+       krb5_context /*context*/,
+       krb5_digest /*digest*/,
+       Ticket **/*tickets*/);
+
+krb5_error_code
+krb5_digest_init_request (
+       krb5_context /*context*/,
+       krb5_digest /*digest*/,
+       krb5_realm /*realm*/,
+       krb5_ccache /*ccache*/);
+
+krb5_error_code
+krb5_digest_request (
+       krb5_context /*context*/,
+       krb5_digest /*digest*/,
+       krb5_realm /*realm*/,
+       krb5_ccache /*ccache*/);
+
+krb5_error_code
+krb5_digest_set_authentication_user (
+       krb5_context /*context*/,
+       krb5_digest /*digest*/,
+       krb5_principal /*authentication_user*/);
+
+krb5_error_code
+krb5_digest_set_authid (
+       krb5_context /*context*/,
+       krb5_digest /*digest*/,
+       const char */*authid*/);
+
+krb5_error_code
+krb5_digest_set_client_nonce (
+       krb5_context /*context*/,
+       krb5_digest /*digest*/,
+       const char */*nonce*/);
+
+krb5_error_code
+krb5_digest_set_digest (
+       krb5_context /*context*/,
+       krb5_digest /*digest*/,
+       const char */*dgst*/);
+
+krb5_error_code
+krb5_digest_set_hostname (
+       krb5_context /*context*/,
+       krb5_digest /*digest*/,
+       const char */*hostname*/);
+
+krb5_error_code
+krb5_digest_set_identifier (
+       krb5_context /*context*/,
+       krb5_digest /*digest*/,
+       const char */*id*/);
+
+krb5_error_code
+krb5_digest_set_method (
+       krb5_context /*context*/,
+       krb5_digest /*digest*/,
+       const char */*method*/);
+
+krb5_error_code
+krb5_digest_set_nonceCount (
+       krb5_context /*context*/,
+       krb5_digest /*digest*/,
+       const char */*nonce_count*/);
+
+krb5_error_code
+krb5_digest_set_opaque (
+       krb5_context /*context*/,
+       krb5_digest /*digest*/,
+       const char */*opaque*/);
+
+krb5_error_code
+krb5_digest_set_qop (
+       krb5_context /*context*/,
+       krb5_digest /*digest*/,
+       const char */*qop*/);
+
+krb5_error_code
+krb5_digest_set_realm (
+       krb5_context /*context*/,
+       krb5_digest /*digest*/,
+       const char */*realm*/);
+
+krb5_error_code
+krb5_digest_set_server_cb (
+       krb5_context /*context*/,
+       krb5_digest /*digest*/,
+       const char */*type*/,
+       const char */*binding*/);
+
+krb5_error_code
+krb5_digest_set_server_nonce (
+       krb5_context /*context*/,
+       krb5_digest /*digest*/,
+       const char */*nonce*/);
+
+krb5_error_code
+krb5_digest_set_type (
+       krb5_context /*context*/,
+       krb5_digest /*digest*/,
+       const char */*type*/);
+
+krb5_error_code
+krb5_digest_set_uri (
+       krb5_context /*context*/,
+       krb5_digest /*digest*/,
+       const char */*uri*/);
+
+krb5_error_code
+krb5_digest_set_username (
+       krb5_context /*context*/,
+       krb5_digest /*digest*/,
+       const char */*username*/);
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_domain_x500_decode (
        krb5_context /*context*/,
@@ -1376,12 +1525,6 @@ krb5_enctype_to_keytype (
        krb5_enctype /*etype*/,
        krb5_keytype */*keytype*/);
 
-krb5_error_code KRB5_LIB_FUNCTION
-krb5_enctype_to_oid (
-       krb5_context /*context*/,
-       krb5_enctype /*etype*/,
-       heim_oid */*oid*/);
-
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_enctype_to_string (
        krb5_context /*context*/,
@@ -1651,6 +1794,54 @@ krb5_get_credentials_with_flags (
        krb5_creds */*in_creds*/,
        krb5_creds **/*out_creds*/);
 
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_get_creds (
+       krb5_context /*context*/,
+       krb5_get_creds_opt /*opt*/,
+       krb5_ccache /*ccache*/,
+       krb5_const_principal /*inprinc*/,
+       krb5_creds **/*out_creds*/);
+
+void KRB5_LIB_FUNCTION
+krb5_get_creds_opt_add_options (
+       krb5_context /*context*/,
+       krb5_get_creds_opt /*opt*/,
+       krb5_flags /*options*/);
+
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_get_creds_opt_alloc (
+       krb5_context /*context*/,
+       krb5_get_creds_opt */*opt*/);
+
+void KRB5_LIB_FUNCTION
+krb5_get_creds_opt_free (
+       krb5_context /*context*/,
+       krb5_get_creds_opt /*opt*/);
+
+void KRB5_LIB_FUNCTION
+krb5_get_creds_opt_set_enctype (
+       krb5_context /*context*/,
+       krb5_get_creds_opt /*opt*/,
+       krb5_enctype /*enctype*/);
+
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_get_creds_opt_set_impersonate (
+       krb5_context /*context*/,
+       krb5_get_creds_opt /*opt*/,
+       krb5_const_principal /*self*/);
+
+void KRB5_LIB_FUNCTION
+krb5_get_creds_opt_set_options (
+       krb5_context /*context*/,
+       krb5_get_creds_opt /*opt*/,
+       krb5_flags /*options*/);
+
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_get_creds_opt_set_ticket (
+       krb5_context /*context*/,
+       krb5_get_creds_opt /*opt*/,
+       const Ticket */*ticket*/);
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_get_default_config_files (char ***/*pfilenames*/);
 
@@ -1674,6 +1865,9 @@ krb5_get_default_realms (
        krb5_context /*context*/,
        krb5_realm **/*realms*/);
 
+krb5_boolean KRB5_LIB_FUNCTION
+krb5_get_dns_canonize_hostname (krb5_context /*context*/);
+
 const char* KRB5_LIB_FUNCTION
 krb5_get_err_text (
        krb5_context /*context*/,
@@ -1710,7 +1904,7 @@ krb5_get_forwarded_creds (
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_get_host_realm (
        krb5_context /*context*/,
-       const char */*host*/,
+       const char */*targethost*/,
        krb5_realm **/*realms*/);
 
 krb5_error_code KRB5_LIB_FUNCTION
@@ -1823,6 +2017,12 @@ krb5_get_init_creds_opt_alloc (
 void KRB5_LIB_FUNCTION
 krb5_get_init_creds_opt_free (krb5_get_init_creds_opt */*opt*/);
 
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_get_init_creds_opt_get_error (
+       krb5_context /*context*/,
+       krb5_get_init_creds_opt */*opt*/,
+       KRB_ERROR **/*error*/);
+
 void KRB5_LIB_FUNCTION
 krb5_get_init_creds_opt_init (krb5_get_init_creds_opt */*opt*/);
 
@@ -1831,6 +2031,12 @@ krb5_get_init_creds_opt_set_address_list (
        krb5_get_init_creds_opt */*opt*/,
        krb5_addresses */*addresses*/);
 
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_get_init_creds_opt_set_addressless (
+       krb5_context /*context*/,
+       krb5_get_init_creds_opt */*opt*/,
+       krb5_boolean /*addressless*/);
+
 void KRB5_LIB_FUNCTION
 krb5_get_init_creds_opt_set_anonymous (
        krb5_get_init_creds_opt */*opt*/,
@@ -1874,8 +2080,8 @@ krb5_get_init_creds_opt_set_pkinit (
        krb5_principal /*principal*/,
        const char */*user_id*/,
        const char */*x509_anchors*/,
-       char * const * /*chain*/,
-       char * const * /*revoke*/,
+       char * const * /*pool*/,
+       char * const * /*pki_revoke*/,
        int /*flags*/,
        krb5_prompter_fct /*prompter*/,
        void */*prompter_data*/,
@@ -1929,6 +2135,12 @@ krb5_get_kdc_cred (
        krb5_creds */*in_creds*/,
        krb5_creds **out_creds );
 
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_get_kdc_sec_offset (
+       krb5_context /*context*/,
+       int32_t */*sec*/,
+       int32_t */*usec*/);
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_get_krb524hst (
        krb5_context /*context*/,
@@ -2035,6 +2247,9 @@ krb5_initlog (
 krb5_boolean KRB5_LIB_FUNCTION
 krb5_is_thread_safe (void);
 
+const krb5_enctype * KRB5_LIB_FUNCTION
+krb5_kerberos_enctypes (krb5_context /*context*/);
+
 krb5_enctype
 krb5_keyblock_get_enctype (const krb5_keyblock */*block*/);
 
@@ -2412,15 +2627,10 @@ krb5_parse_name (
        krb5_principal */*principal*/);
 
 krb5_error_code KRB5_LIB_FUNCTION
-krb5_parse_name_mustrealm (
-       krb5_context /*context*/,
-       const char */*name*/,
-       krb5_principal */*principal*/);
-
-krb5_error_code KRB5_LIB_FUNCTION
-krb5_parse_name_norealm (
+krb5_parse_name_flags (
        krb5_context /*context*/,
        const char */*name*/,
+       int /*flags*/,
        krb5_principal */*principal*/);
 
 const char* KRB5_LIB_FUNCTION
@@ -2447,7 +2657,7 @@ krb5_prepend_config_files_default (
        const char */*filelist*/,
        char ***/*pfilenames*/);
 
-krb5_realm* KRB5_LIB_FUNCTION
+krb5_realm * KRB5_LIB_FUNCTION
 krb5_princ_realm (
        krb5_context /*context*/,
        krb5_principal /*principal*/);
@@ -2792,6 +3002,11 @@ krb5_ret_string (
        krb5_storage */*sp*/,
        char **/*string*/);
 
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_ret_stringnl (
+       krb5_storage */*sp*/,
+       char **/*string*/);
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_ret_stringz (
        krb5_storage */*sp*/,
@@ -2877,6 +3092,11 @@ krb5_set_default_realm (
        krb5_context /*context*/,
        const char */*realm*/);
 
+void KRB5_LIB_FUNCTION
+krb5_set_dns_canonicalize_hostname (
+       krb5_context /*context*/,
+       krb5_boolean /*flag*/);
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_set_error_string (
        krb5_context /*context*/,
@@ -2926,10 +3146,9 @@ krb5_set_real_time (
        int32_t /*usec*/);
 
 krb5_error_code KRB5_LIB_FUNCTION
-krb5_set_send_recv_func (
+krb5_set_send_to_kdc_func (
        krb5_context /*context*/,
-       krb5_send_and_recv_func_t /*func*/,
-       krb5_send_and_recv_close_func_t /*close_fn*/,
+       krb5_send_to_kdc_func /*func*/,
        void */*data*/);
 
 void KRB5_LIB_FUNCTION
@@ -3109,6 +3328,11 @@ krb5_store_string (
        krb5_storage */*sp*/,
        const char */*s*/);
 
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_store_stringnl (
+       krb5_storage */*sp*/,
+       const char */*s*/);
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_store_stringz (
        krb5_storage */*sp*/,
@@ -3254,24 +3478,26 @@ krb5_unparse_name_fixed (
        size_t /*len*/);
 
 krb5_error_code KRB5_LIB_FUNCTION
-krb5_unparse_name_fixed_short (
+krb5_unparse_name_fixed_flags (
        krb5_context /*context*/,
        krb5_const_principal /*principal*/,
+       int /*flags*/,
        char */*name*/,
        size_t /*len*/);
 
 krb5_error_code KRB5_LIB_FUNCTION
-krb5_unparse_name_norealm (
+krb5_unparse_name_fixed_short (
        krb5_context /*context*/,
        krb5_const_principal /*principal*/,
-       char **/*name*/);
+       char */*name*/,
+       size_t /*len*/);
 
 krb5_error_code KRB5_LIB_FUNCTION
-krb5_unparse_name_norealm_fixed (
+krb5_unparse_name_flags (
        krb5_context /*context*/,
        krb5_const_principal /*principal*/,
-       char */*name*/,
-       size_t /*len*/);
+       int /*flags*/,
+       char **/*name*/);
 
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_unparse_name_short (
index 32fdd6d38313dbbad8d1a73a52a1d676039f2664..4b5058094b0815f49e236ae41524738d30c1467f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997 - 2004 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2006 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
  * All rights reserved. 
  *
@@ -31,7 +31,7 @@
  * SUCH DAMAGE. 
  */
 
-/* $Id: krb5.h,v 1.241 2006/05/05 09:29:36 lha Exp $ */
+/* $Id: krb5.h,v 1.253 2006/10/20 18:12:06 lha Exp $ */
 
 #ifndef __KRB5_H__
 #define __KRB5_H__
@@ -72,6 +72,12 @@ typedef const void *krb5_const_pointer;
 struct krb5_crypto_data;
 typedef struct krb5_crypto_data *krb5_crypto;
 
+struct krb5_get_creds_opt_data;
+typedef struct krb5_get_creds_opt_data *krb5_get_creds_opt;
+
+struct krb5_digest;
+typedef struct krb5_digest *krb5_digest;
+
 typedef CKSUMTYPE krb5_cksumtype;
 
 typedef Checksum krb5_checksum;
@@ -203,8 +209,16 @@ typedef enum krb5_key_usage {
     /* Encryption of the SAM-TRACK-ID field */
     KRB5_KU_PA_SERVER_REFERRAL = 26,
     /* Keyusage for the server referral in a TGS req */
-    KRB5_KU_SAM_ENC_NONCE_SAD = 27
+    KRB5_KU_SAM_ENC_NONCE_SAD = 27,
     /* Encryption of the SAM-NONCE-OR-SAD field */
+    KRB5_KU_TGS_IMPERSONATE = -17,
+    /* Checksum type used in the impersonate field */
+    KRB5_KU_DIGEST_ENCRYPT = -18,
+    /* Encryption key usage used in the digest encryption field */
+    KRB5_KU_DIGEST_OPAQUE = -19,
+    /* Checksum key usage used in the digest opaque field */
+    KRB5_KU_KRB5SIGNEDPATH = -21
+    /* Checksum key usage on KRB5SignedPath */
 } krb5_key_usage;
 
 typedef krb5_key_usage krb5_keyusage;
@@ -256,9 +270,7 @@ typedef enum krb5_keytype {
     KEYTYPE_AES128     = 17,
     KEYTYPE_AES256     = 18,
     KEYTYPE_ARCFOUR    = 23,
-    KEYTYPE_ARCFOUR_56 = 24,
-    KEYTYPE_RC2                = -0x1005,
-    KEYTYPE_AES192     = -0x1006
+    KEYTYPE_ARCFOUR_56 = 24
 } krb5_keytype;
 
 typedef EncryptionKey krb5_keyblock;
@@ -339,6 +351,9 @@ typedef union {
 #define KRB5_GC_CACHED                 (1U << 0)
 #define KRB5_GC_USER_USER              (1U << 1)
 #define KRB5_GC_EXPIRED_OK             (1U << 2)
+#define KRB5_GC_NO_STORE               (1U << 3)
+#define KRB5_GC_FORWARDABLE            (1U << 4)
+#define KRB5_GC_NO_TRANSIT_CHECK       (1U << 5)
 
 /* constants for compare_creds (and cc_retrieve_cred) */
 #define KRB5_TC_DONT_MATCH_REALM       (1U << 31)
@@ -413,49 +428,6 @@ typedef struct krb5_config_binding krb5_config_binding;
 
 typedef krb5_config_binding krb5_config_section;
 
-typedef struct krb5_context_data {
-    krb5_enctype *etypes;
-    krb5_enctype *etypes_des;
-    char **default_realms;
-    time_t max_skew;
-    time_t kdc_timeout;
-    unsigned max_retries;
-    int32_t kdc_sec_offset;
-    int32_t kdc_usec_offset;
-    krb5_config_section *cf;
-    struct et_list *et_list;
-    struct krb5_log_facility *warn_dest;
-    krb5_cc_ops *cc_ops;
-    int num_cc_ops;
-    const char *http_proxy;
-    const char *time_fmt;
-    krb5_boolean log_utc;
-    const char *default_keytab;
-    const char *default_keytab_modify;
-    krb5_boolean use_admin_kdc;
-    krb5_addresses *extra_addresses;
-    krb5_boolean scan_interfaces;      /* `ifconfig -a' */
-    krb5_boolean srv_lookup;           /* do SRV lookups */
-    krb5_boolean srv_try_txt;          /* try TXT records also */
-    int32_t fcache_vno;                        /* create cache files w/ this
-                                           version */
-    int num_kt_types;                  /* # of registered keytab types */
-    struct krb5_keytab_data *kt_types;  /* registered keytab types */
-    const char *date_fmt;
-    char *error_string;
-    char error_buf[256];
-    krb5_addresses *ignore_addresses;
-    char *default_cc_name;
-    int pkinit_flags;
-    void *mutex;                       /* protects error_string/error_buf */
-    int large_msg_size;
-    krb5_boolean fdns;                  /* Lookup hostnames to find full name, or send as-is */
-    struct send_and_recv *send_and_recv; /* Alternate functions for KDC communication */
-    void *mem_ctx;                      /* Some parts of Samba4 need a valid 
-                                           memory context (under the event 
-                                          context) to use */
-} krb5_context_data;
-
 enum {
     KRB5_PKINIT_WIN2K          = 1,    /* wire compatible with Windows 2k */
     KRB5_PKINIT_PACKET_CABLE   = 2     /* use packet cable standard */
@@ -578,8 +550,8 @@ typedef struct krb5_auth_context_data {
   
     krb5_rcache rcache;
 
-    krb5_keytype keytype;      /* Ã‚¿requested key type ? */
-    krb5_cksumtype cksumtype;  /* Ã‚¡requested checksum type! */
+    krb5_keytype keytype;      /* Â¿requested key type ? */
+    krb5_cksumtype cksumtype;  /* Â¡requested checksum type! */
   
 }krb5_auth_context_data, *krb5_auth_context;
 
@@ -609,6 +581,8 @@ typedef EncAPRepPart krb5_ap_rep_enc_part;
 #define KRB5_TGS_NAME_SIZE (6)
 #define KRB5_TGS_NAME ("krbtgt")
 
+#define KRB5_DIGEST_NAME ("digest")
+
 /* variables */
 
 extern const char *krb5_config_file;
@@ -618,7 +592,8 @@ typedef enum {
     KRB5_PROMPT_TYPE_PASSWORD          = 0x1,
     KRB5_PROMPT_TYPE_NEW_PASSWORD      = 0x2,
     KRB5_PROMPT_TYPE_NEW_PASSWORD_AGAIN = 0x3,
-    KRB5_PROMPT_TYPE_PREAUTH           = 0x4
+    KRB5_PROMPT_TYPE_PREAUTH           = 0x4,
+    KRB5_PROMPT_TYPE_INFO              = 0x5
 } krb5_prompt_type;
 
 typedef struct _krb5_prompt {
@@ -754,12 +729,23 @@ enum {
     KRB5_KRBHST_FLAGS_LARGE_MSG          = 2
 };
 
-typedef int (*krb5_send_and_recv_func_t)(krb5_context,
-                                        void *,
-                                        krb5_krbhst_info *,
-                                        const krb5_data *,
-                                        krb5_data *);
-typedef void (*krb5_send_and_recv_close_func_t)(krb5_context, void*);
+typedef krb5_error_code (*krb5_send_to_kdc_func)(krb5_context, 
+                                                void *, 
+                                                krb5_krbhst_info *,
+                                                const krb5_data *,
+                                                krb5_data *);
+
+/* flags for krb5_parse_name_flags */
+enum {
+    KRB5_PRINCIPAL_PARSE_NO_REALM = 1,
+    KRB5_PRINCIPAL_PARSE_MUST_REALM = 2
+};
+
+/* flags for krb5_unparse_name_flags */
+enum {
+    KRB5_PRINCIPAL_UNPARSE_SHORT = 1,
+    KRB5_PRINCIPAL_UNPARSE_NO_REALM = 2
+};
 
 struct credentials; /* this is to keep the compiler happy */
 struct getargs;
diff --git a/source4/heimdal/lib/krb5/krb5_err.c b/source4/heimdal/lib/krb5/krb5_err.c
new file mode 100644 (file)
index 0000000..9185f72
--- /dev/null
@@ -0,0 +1,271 @@
+/* Generated from krb5_err.et */
+/* $Id: krb5_err.et,v 1.14 2006/02/13 11:28:22 lha Exp $ */
+
+#include <stddef.h>
+#include <com_err.h>
+#include "krb5_err.h"
+
+static const char *krb5_error_strings[] = {
+       /* 000 */ "No error",
+       /* 001 */ "Client's entry in database has expired",
+       /* 002 */ "Server's entry in database has expired",
+       /* 003 */ "Requested protocol version not supported",
+       /* 004 */ "Client's key is encrypted in an old master key",
+       /* 005 */ "Server's key is encrypted in an old master key",
+       /* 006 */ "Client not found in Kerberos database",
+       /* 007 */ "Server not found in Kerberos database",
+       /* 008 */ "Principal has multiple entries in Kerberos database",
+       /* 009 */ "Client or server has a null key",
+       /* 010 */ "Ticket is ineligible for postdating",
+       /* 011 */ "Requested effective lifetime is negative or too short",
+       /* 012 */ "KDC policy rejects request",
+       /* 013 */ "KDC can't fulfill requested option",
+       /* 014 */ "KDC has no support for encryption type",
+       /* 015 */ "KDC has no support for checksum type",
+       /* 016 */ "KDC has no support for padata type",
+       /* 017 */ "KDC has no support for transited type",
+       /* 018 */ "Clients credentials have been revoked",
+       /* 019 */ "Credentials for server have been revoked",
+       /* 020 */ "TGT has been revoked",
+       /* 021 */ "Client not yet valid - try again later",
+       /* 022 */ "Server not yet valid - try again later",
+       /* 023 */ "Password has expired",
+       /* 024 */ "Preauthentication failed",
+       /* 025 */ "Additional pre-authentication required",
+       /* 026 */ "Requested server and ticket don't match",
+       /* 027 */ "Reserved krb5 error (27)",
+       /* 028 */ "Reserved krb5 error (28)",
+       /* 029 */ "Reserved krb5 error (29)",
+       /* 030 */ "Reserved krb5 error (30)",
+       /* 031 */ "Decrypt integrity check failed",
+       /* 032 */ "Ticket expired",
+       /* 033 */ "Ticket not yet valid",
+       /* 034 */ "Request is a replay",
+       /* 035 */ "The ticket isn't for us",
+       /* 036 */ "Ticket/authenticator don't match",
+       /* 037 */ "Clock skew too great",
+       /* 038 */ "Incorrect net address",
+       /* 039 */ "Protocol version mismatch",
+       /* 040 */ "Invalid message type",
+       /* 041 */ "Message stream modified",
+       /* 042 */ "Message out of order",
+       /* 043 */ "Invalid cross-realm ticket",
+       /* 044 */ "Key version is not available",
+       /* 045 */ "Service key not available",
+       /* 046 */ "Mutual authentication failed",
+       /* 047 */ "Incorrect message direction",
+       /* 048 */ "Alternative authentication method required",
+       /* 049 */ "Incorrect sequence number in message",
+       /* 050 */ "Inappropriate type of checksum in message",
+       /* 051 */ "Policy rejects transited path",
+       /* 052 */ "Response too big for UDP, retry with TCP",
+       /* 053 */ "Reserved krb5 error (53)",
+       /* 054 */ "Reserved krb5 error (54)",
+       /* 055 */ "Reserved krb5 error (55)",
+       /* 056 */ "Reserved krb5 error (56)",
+       /* 057 */ "Reserved krb5 error (57)",
+       /* 058 */ "Reserved krb5 error (58)",
+       /* 059 */ "Reserved krb5 error (59)",
+       /* 060 */ "Generic error (see e-text)",
+       /* 061 */ "Field is too long for this implementation",
+       /* 062 */ "Client not trusted",
+       /* 063 */ "KDC not trusted",
+       /* 064 */ "Invalid signature",
+       /* 065 */ "DH parameters not accepted",
+       /* 066 */ "Reserved krb5 error (66)",
+       /* 067 */ "Reserved krb5 error (67)",
+       /* 068 */ "Reserved krb5 error (68)",
+       /* 069 */ "User to user required",
+       /* 070 */ "Cannot verify certificate",
+       /* 071 */ "Certificate invalid",
+       /* 072 */ "Certificate revoked",
+       /* 073 */ "Revocation status unknown",
+       /* 074 */ "Revocation status unknown",
+       /* 075 */ "Inconsistent key purpose",
+       /* 076 */ "Digest in certificate not accepted",
+       /* 077 */ "paChecksum must be included",
+       /* 078 */ "Digest in signedData not accepted",
+       /* 079 */ "Public key encryption not supported",
+       /* 080 */ "Reserved krb5 error (80)",
+       /* 081 */ "Reserved krb5 error (81)",
+       /* 082 */ "Reserved krb5 error (82)",
+       /* 083 */ "Reserved krb5 error (83)",
+       /* 084 */ "Reserved krb5 error (84)",
+       /* 085 */ "Reserved krb5 error (85)",
+       /* 086 */ "Reserved krb5 error (86)",
+       /* 087 */ "Reserved krb5 error (87)",
+       /* 088 */ "Reserved krb5 error (88)",
+       /* 089 */ "Reserved krb5 error (89)",
+       /* 090 */ "Reserved krb5 error (90)",
+       /* 091 */ "Reserved krb5 error (91)",
+       /* 092 */ "Reserved krb5 error (92)",
+       /* 093 */ "Reserved krb5 error (93)",
+       /* 094 */ "Reserved krb5 error (94)",
+       /* 095 */ "Reserved krb5 error (95)",
+       /* 096 */ "Reserved krb5 error (96)",
+       /* 097 */ "Reserved krb5 error (97)",
+       /* 098 */ "Reserved krb5 error (98)",
+       /* 099 */ "Reserved krb5 error (99)",
+       /* 100 */ "Reserved krb5 error (100)",
+       /* 101 */ "Reserved krb5 error (101)",
+       /* 102 */ "Reserved krb5 error (102)",
+       /* 103 */ "Reserved krb5 error (103)",
+       /* 104 */ "Reserved krb5 error (104)",
+       /* 105 */ "Reserved krb5 error (105)",
+       /* 106 */ "Reserved krb5 error (106)",
+       /* 107 */ "Reserved krb5 error (107)",
+       /* 108 */ "Reserved krb5 error (108)",
+       /* 109 */ "Reserved krb5 error (109)",
+       /* 110 */ "Reserved krb5 error (110)",
+       /* 111 */ "Reserved krb5 error (111)",
+       /* 112 */ "Reserved krb5 error (112)",
+       /* 113 */ "Reserved krb5 error (113)",
+       /* 114 */ "Reserved krb5 error (114)",
+       /* 115 */ "Reserved krb5 error (115)",
+       /* 116 */ "Reserved krb5 error (116)",
+       /* 117 */ "Reserved krb5 error (117)",
+       /* 118 */ "Reserved krb5 error (118)",
+       /* 119 */ "Reserved krb5 error (119)",
+       /* 120 */ "Reserved krb5 error (120)",
+       /* 121 */ "Reserved krb5 error (121)",
+       /* 122 */ "Reserved krb5 error (122)",
+       /* 123 */ "Reserved krb5 error (123)",
+       /* 124 */ "Reserved krb5 error (124)",
+       /* 125 */ "Reserved krb5 error (125)",
+       /* 126 */ "Reserved krb5 error (126)",
+       /* 127 */ "Reserved krb5 error (127)",
+       /* 128 */ "$Id: krb5_err.et,v 1.14 2006/02/13 11:28:22 lha Exp $",
+       /* 129 */ "Invalid flag for file lock mode",
+       /* 130 */ "Cannot read password",
+       /* 131 */ "Password mismatch",
+       /* 132 */ "Password read interrupted",
+       /* 133 */ "Invalid character in component name",
+       /* 134 */ "Malformed representation of principal",
+       /* 135 */ "Can't open/find configuration file",
+       /* 136 */ "Improper format of configuration file",
+       /* 137 */ "Insufficient space to return complete information",
+       /* 138 */ "Invalid message type specified for encoding",
+       /* 139 */ "Credential cache name malformed",
+       /* 140 */ "Unknown credential cache type",
+       /* 141 */ "Matching credential not found",
+       /* 142 */ "End of credential cache reached",
+       /* 143 */ "Request did not supply a ticket",
+       /* 144 */ "Wrong principal in request",
+       /* 145 */ "Ticket has invalid flag set",
+       /* 146 */ "Requested principal and ticket don't match",
+       /* 147 */ "KDC reply did not match expectations",
+       /* 148 */ "Clock skew too great in KDC reply",
+       /* 149 */ "Client/server realm mismatch in initial ticket request",
+       /* 150 */ "Program lacks support for encryption type",
+       /* 151 */ "Program lacks support for key type",
+       /* 152 */ "Requested encryption type not used in message",
+       /* 153 */ "Program lacks support for checksum type",
+       /* 154 */ "Cannot find KDC for requested realm",
+       /* 155 */ "Kerberos service unknown",
+       /* 156 */ "Cannot contact any KDC for requested realm",
+       /* 157 */ "No local name found for principal name",
+       /* 158 */ "Mutual authentication failed",
+       /* 159 */ "Replay cache type is already registered",
+       /* 160 */ "No more memory to allocate (in replay cache code)",
+       /* 161 */ "Replay cache type is unknown",
+       /* 162 */ "Generic unknown RC error",
+       /* 163 */ "Message is a replay",
+       /* 164 */ "Replay I/O operation failed XXX",
+       /* 165 */ "Replay cache type does not support non-volatile storage",
+       /* 166 */ "Replay cache name parse/format error",
+       /* 167 */ "End-of-file on replay cache I/O",
+       /* 168 */ "No more memory to allocate (in replay cache I/O code)",
+       /* 169 */ "Permission denied in replay cache code",
+       /* 170 */ "I/O error in replay cache i/o code",
+       /* 171 */ "Generic unknown RC/IO error",
+       /* 172 */ "Insufficient system space to store replay information",
+       /* 173 */ "Can't open/find realm translation file",
+       /* 174 */ "Improper format of realm translation file",
+       /* 175 */ "Can't open/find lname translation database",
+       /* 176 */ "No translation available for requested principal",
+       /* 177 */ "Improper format of translation database entry",
+       /* 178 */ "Cryptosystem internal error",
+       /* 179 */ "Key table name malformed",
+       /* 180 */ "Unknown Key table type",
+       /* 181 */ "Key table entry not found",
+       /* 182 */ "End of key table reached",
+       /* 183 */ "Cannot write to specified key table",
+       /* 184 */ "Error writing to key table",
+       /* 185 */ "Cannot find ticket for requested realm",
+       /* 186 */ "DES key has bad parity",
+       /* 187 */ "DES key is a weak key",
+       /* 188 */ "Bad encryption type",
+       /* 189 */ "Key size is incompatible with encryption type",
+       /* 190 */ "Message size is incompatible with encryption type",
+       /* 191 */ "Credentials cache type is already registered.",
+       /* 192 */ "Key table type is already registered.",
+       /* 193 */ "Credentials cache I/O operation failed XXX",
+       /* 194 */ "Credentials cache file permissions incorrect",
+       /* 195 */ "No credentials cache file found",
+       /* 196 */ "Internal file credentials cache error",
+       /* 197 */ "Error writing to credentials cache file",
+       /* 198 */ "No more memory to allocate (in credentials cache code)",
+       /* 199 */ "Bad format in credentials cache",
+       /* 200 */ "No credentials found with supported encryption types",
+       /* 201 */ "Invalid KDC option combination (library internal error)",
+       /* 202 */ "Request missing second ticket",
+       /* 203 */ "No credentials supplied to library routine",
+       /* 204 */ "Bad sendauth version was sent",
+       /* 205 */ "Bad application version was sent (via sendauth)",
+       /* 206 */ "Bad response (during sendauth exchange)",
+       /* 207 */ "Server rejected authentication (during sendauth exchange)",
+       /* 208 */ "Unsupported preauthentication type",
+       /* 209 */ "Required preauthentication key not supplied",
+       /* 210 */ "Generic preauthentication failure",
+       /* 211 */ "Unsupported replay cache format version number",
+       /* 212 */ "Unsupported credentials cache format version number",
+       /* 213 */ "Unsupported key table format version number",
+       /* 214 */ "Program lacks support for address type",
+       /* 215 */ "Message replay detection requires rcache parameter",
+       /* 216 */ "Hostname cannot be canonicalized",
+       /* 217 */ "Cannot determine realm for host",
+       /* 218 */ "Conversion to service principal undefined for name type",
+       /* 219 */ "Initial Ticket response appears to be Version 4",
+       /* 220 */ "Cannot resolve KDC for requested realm",
+       /* 221 */ "Requesting ticket can't get forwardable tickets",
+       /* 222 */ "Bad principal name while trying to forward credentials",
+       /* 223 */ "Looping detected inside krb5_get_in_tkt",
+       /* 224 */ "Configuration file does not specify default realm",
+       /* 225 */ "Bad SAM flags in obtain_sam_padata",
+       /* 226 */ "Invalid encryption type in SAM challenge",
+       /* 227 */ "Missing checksum in SAM challenge",
+       /* 228 */ "Bad checksum in SAM challenge",
+       /* 229 */ "Reserved krb5 error (229)",
+       /* 230 */ "Reserved krb5 error (230)",
+       /* 231 */ "Reserved krb5 error (231)",
+       /* 232 */ "Reserved krb5 error (232)",
+       /* 233 */ "Reserved krb5 error (233)",
+       /* 234 */ "Reserved krb5 error (234)",
+       /* 235 */ "Reserved krb5 error (235)",
+       /* 236 */ "Reserved krb5 error (236)",
+       /* 237 */ "Reserved krb5 error (237)",
+       /* 238 */ "Program called an obsolete, deleted function",
+       /* 239 */ "Reserved krb5 error (239)",
+       /* 240 */ "Reserved krb5 error (240)",
+       /* 241 */ "Reserved krb5 error (241)",
+       /* 242 */ "Reserved krb5 error (242)",
+       /* 243 */ "Reserved krb5 error (243)",
+       /* 244 */ "Reserved krb5 error (244)",
+       /* 245 */ "Invalid key generation parameters from KDC",
+       /* 246 */ "Service not available",
+       /* 247 */ "Credential cache function not supported",
+       /* 248 */ "Invalid format of Kerberos lifetime or clock skew string",
+       NULL
+};
+
+#define num_errors 249
+
+void initialize_krb5_error_table_r(struct et_list **list)
+{
+    initialize_error_table_r(list, krb5_error_strings, num_errors, ERROR_TABLE_BASE_krb5);
+}
+
+void initialize_krb5_error_table(void)
+{
+    init_error_table(krb5_error_strings, ERROR_TABLE_BASE_krb5, num_errors);
+}
index 4dcac40c7af3ad3e08ac7558054c13ef6bb02f00..89b3c6ad402350fb6b6b14f8ab871167eec29da3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997-2002 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997-2002 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
  * All rights reserved. 
  *
@@ -31,7 +31,7 @@
  * SUCH DAMAGE. 
  */
 
-/* $Id: krb5_locl.h,v 1.87 2006/02/09 11:36:27 lha Exp $ */
+/* $Id: krb5_locl.h,v 1.93 2006/10/20 18:13:31 lha Exp $ */
 
 #ifndef __KRB5_LOCL_H__
 #define __KRB5_LOCL_H__
@@ -136,6 +136,8 @@ struct sockaddr_dl;
 
 #include <krb5_asn1.h>
 
+struct send_to_kdc;
+
 /* XXX glue for pkinit */
 struct krb5_pk_identity;
 struct krb5_pk_cert;
@@ -151,6 +153,9 @@ struct _krb5_krb_auth_data;
 #include <krb5.h>
 #include <krb5_err.h>
 #include <asn1_err.h>
+#ifdef PKINIT
+#include <hx509_err.h>
+#endif
 #include <krb5-private.h>
 
 #include "heim_threads.h"
@@ -171,10 +176,10 @@ struct _krb5_krb_auth_data;
 #define KRB5_BUFSIZ 1024
 
 typedef enum {
-    KRB5_PA_PAC_DONT_CARE = 0, 
-    KRB5_PA_PAC_REQ_TRUE,
-    KRB5_PA_PAC_REQ_FALSE
-} krb5_get_init_creds_req_pac;
+    KRB5_INIT_CREDS_TRISTATE_UNSET = 0,
+    KRB5_INIT_CREDS_TRISTATE_TRUE,
+    KRB5_INIT_CREDS_TRISTATE_FALSE
+} krb5_get_init_creds_tristate;
 
 struct _krb5_get_init_creds_opt_private {
     int refcount;
@@ -182,12 +187,57 @@ struct _krb5_get_init_creds_opt_private {
     const char *password;
     krb5_s2k_proc key_proc;
     /* PA_PAC_REQUEST */
-    krb5_get_init_creds_req_pac req_pac;
+    krb5_get_init_creds_tristate req_pac;
     /* PKINIT */
     krb5_pk_init_ctx pk_init_ctx;
     int canonicalize;
+    KRB_ERROR *error;
+    krb5_get_init_creds_tristate addressless;
 };
 
+typedef struct krb5_context_data {
+    krb5_enctype *etypes;
+    krb5_enctype *etypes_des;
+    char **default_realms;
+    time_t max_skew;
+    time_t kdc_timeout;
+    unsigned max_retries;
+    int32_t kdc_sec_offset;
+    int32_t kdc_usec_offset;
+    krb5_config_section *cf;
+    struct et_list *et_list;
+    struct krb5_log_facility *warn_dest;
+    krb5_cc_ops *cc_ops;
+    int num_cc_ops;
+    const char *http_proxy;
+    const char *time_fmt;
+    krb5_boolean log_utc;
+    const char *default_keytab;
+    const char *default_keytab_modify;
+    krb5_boolean use_admin_kdc;
+    krb5_addresses *extra_addresses;
+    krb5_boolean scan_interfaces;      /* `ifconfig -a' */
+    krb5_boolean srv_lookup;           /* do SRV lookups */
+    krb5_boolean srv_try_txt;          /* try TXT records also */
+    int32_t fcache_vno;                        /* create cache files w/ this
+                                           version */
+    int num_kt_types;                  /* # of registered keytab types */
+    struct krb5_keytab_data *kt_types;  /* registered keytab types */
+    const char *date_fmt;
+    char *error_string;
+    char error_buf[256];
+    krb5_addresses *ignore_addresses;
+    char *default_cc_name;
+    int pkinit_flags;
+    void *mutex;                       /* protects error_string/error_buf */
+    int large_msg_size;
+    int dns_canonicalize_hostname;
+    struct send_to_kdc *send_to_kdc;
+    void *mem_ctx;                      /* Some parts of Samba4 need a valid 
+                                           memory context (under the event 
+                                          context) to use */
+} krb5_context_data;
+
 /*
  * Configurable options
  */
@@ -201,7 +251,7 @@ struct _krb5_get_init_creds_opt_private {
 #endif
 
 #ifndef KRB5_ADDRESSLESS_DEFAULT
-#define KRB5_ADDRESSLESS_DEFAULT FALSE
+#define KRB5_ADDRESSLESS_DEFAULT TRUE
 #endif
 
 #endif /* __KRB5_LOCL_H__ */
index 221bd706f448f27de7d2f8a5d8376794c8696de9..e7b2579229a63ba7d59ae53a1c5a83ff7edc2f37 100644 (file)
@@ -34,7 +34,7 @@
 #include "krb5_locl.h"
 #include <resolve.h>
 
-RCSID("$Id: krbhst.c,v 1.55 2006/04/02 10:32:20 lha Exp $");
+RCSID("$Id: krbhst.c,v 1.57 2006/10/06 17:11:02 lha Exp $");
 
 static int
 string_to_proto(const char *string)
@@ -422,6 +422,15 @@ fallback_get_hosts(krb5_context context, struct krb5_krbhst_data *kd,
     struct addrinfo hints;
     char portstr[NI_MAXSERV];
 
+    /* 
+     * Don't try forever in case the DNS server keep returning us
+     * entries (like wildcard entries or the .nu TLD)
+     */
+    if(kd->fallback_count >= 5) {
+       kd->flags |= KD_FALLBACK;
+       return 0;
+    }
+
     if(kd->fallback_count == 0)
        asprintf(&host, "%s.%s.", serv_string, kd->realm);
     else
@@ -659,9 +668,8 @@ common_init(krb5_context context,
     }
 
     /* For 'realms' without a . do not even think of going to DNS */
-    if (!strchr(realm, '.')) {
+    if (!strchr(realm, '.'))
        kd->flags |= KD_CONFIG_EXISTS;
-    }
 
     if (flags & KRB5_KRBHST_FLAGS_LARGE_MSG)
        kd->flags |= KD_LARGE_MSG;
index baf63f6d525d7b157829822afcd579412230475a..f04f8d99967c6e33f29ffbc0ef52cedb29b2e92d 100644 (file)
 
 #include "krb5_locl.h"
 
-RCSID("$Id: misc.c,v 1.5 1999/12/02 17:05:11 joda Exp $");
+RCSID("$Id: misc.c,v 1.6 2006/06/06 14:57:47 lha Exp $");
+
+krb5_error_code KRB5_LIB_FUNCTION
+_krb5_s4u2self_to_checksumdata(krb5_context context, 
+                              const PA_S4U2Self *self, 
+                              krb5_data *data)
+{
+    krb5_error_code ret;
+    krb5_ssize_t ssize;
+    krb5_storage *sp;
+    size_t size;
+    int i;
+
+    sp = krb5_storage_emem();
+    if (sp == NULL) {
+       krb5_clear_error_string(context);
+       return ENOMEM;
+    }
+    ret = krb5_store_int32(sp, self->name.name_type);
+    if (ret)
+       goto out;
+    for (i = 0; i < self->name.name_string.len; i++) {
+       size = strlen(self->name.name_string.val[i]);
+       ssize = krb5_storage_write(sp, self->name.name_string.val[i], size);
+       if (ssize != size) {
+           ret = ENOMEM;
+           goto out;
+       }
+    }
+    size = strlen(self->realm);
+    ssize = krb5_storage_write(sp, self->realm, size);
+    if (ssize != size) {
+       ret = ENOMEM;
+       goto out;
+    }
+    size = strlen(self->auth);
+    ssize = krb5_storage_write(sp, self->auth, size);
+    if (ssize != size) {
+       ret = ENOMEM;
+       goto out;
+    }
+
+    ret = krb5_storage_to_data(sp, data);
+    krb5_storage_free(sp);
+    return ret;
+
+out:
+    krb5_clear_error_string(context);
+    return ret;
+}
index b7f06c1582ae24fceae9c9a7e5a70d78da94a376..b9075b3079ab559be096d323bcca397a15e97464 100755 (executable)
@@ -32,7 +32,7 @@
  */
 
 #include "krb5_locl.h"
-RCSID("$Id: mit_glue.c,v 1.7 2005/05/18 04:21:44 lha Exp $");
+RCSID("$Id: mit_glue.c,v 1.8 2006/10/14 09:51:02 lha Exp $");
 
 /*
  * Glue for MIT API
@@ -98,7 +98,7 @@ krb5_c_get_checksum(krb5_context context, const krb5_checksum *cksum,
        if (*data == NULL)
            return ENOMEM;
 
-       ret = copy_octet_string(&cksum->checksum, *data);
+       ret = der_copy_octet_string(&cksum->checksum, *data);
        if (ret) {
            free(*data);
            *data = NULL;
@@ -113,7 +113,7 @@ krb5_c_set_checksum(krb5_context context, krb5_checksum *cksum,
                    krb5_cksumtype type, const krb5_data *data)
 {
     cksum->cksumtype = type;
-    return copy_octet_string(data, &cksum->checksum);
+    return der_copy_octet_string(data, &cksum->checksum);
 }
 
 void KRB5_LIB_FUNCTION 
index 00f7b4ebd9b91bcb1733dde33488f4b36b089167..f519b5ad08608d3d92d98a50587365ddd93ade19 100755 (executable)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: pkinit.c,v 1.99 2006/05/07 12:32:38 lha Exp $");
+RCSID("$Id: pkinit.c,v 1.110 2006/10/14 09:52:50 lha Exp $");
 
 struct krb5_dh_moduli {
     char *name;
@@ -69,7 +69,7 @@ struct krb5_pk_identity {
     hx509_certs certs;
     hx509_certs anchors;
     hx509_certs certpool;
-    hx509_revoke_ctx revoke;
+    hx509_revoke_ctx revokectx;
 };
 
 struct krb5_pk_cert {
@@ -344,8 +344,8 @@ build_auth_pack(krb5_context context,
        ALLOC(a->clientPublicValue, 1);
        if (a->clientPublicValue == NULL)
            return ENOMEM;
-       ret = copy_oid(oid_id_dhpublicnumber(),
-                      &a->clientPublicValue->algorithm.algorithm);
+       ret = der_copy_oid(oid_id_dhpublicnumber(),
+                          &a->clientPublicValue->algorithm.algorithm);
        if (ret)
            return ret;
        
@@ -392,7 +392,7 @@ build_auth_pack(krb5_context context,
 
        ASN1_MALLOC_ENCODE(DHPublicKey, dhbuf.data, dhbuf.length,
                           &dh_pub_key, &size, ret);
-       free_heim_integer(&dh_pub_key);
+       der_free_heim_integer(&dh_pub_key);
        if (ret)
            return ret;
        if (size != dhbuf.length)
@@ -413,7 +413,7 @@ _krb5_pk_mk_ContentInfo(krb5_context context,
 {
     krb5_error_code ret;
 
-    ret = copy_oid(oid, &content_info->contentType);
+    ret = der_copy_oid(oid, &content_info->contentType);
     if (ret)
        return ret;
     ALLOC(content_info->content, 1);
@@ -672,8 +672,16 @@ _krb5_pk_verify_sign(krb5_context context,
                                  contentType,
                                  content,
                                  &signer_certs);
-    if (ret)
+    if (ret) {
+       char *s = hx509_get_error_string(id->hx509ctx, ret);
+       if (s) {
+           krb5_set_error_string(context,
+                                 "CMS verify signed failed with %s", s);
+           free(s);
+       } else
+           krb5_clear_error_string(context);
        return ret;
+    }
 
     *signer = calloc(1, sizeof(**signer));
     if (*signer == NULL) {
@@ -833,7 +841,9 @@ pk_verify_host(krb5_context context,
                                                       oid_id_pkinit_san(),
                                                       &list);
        if (ret) {
-           krb5_clear_error_string(context);
+           krb5_set_error_string(context, "Failed to find the PK-INIT "
+                                 "subjectAltName in the KDC certificate");
+
            return ret;
        }
 
@@ -845,7 +855,9 @@ pk_verify_host(krb5_context context,
                                           &r,
                                           NULL);
            if (ret) {
-               krb5_clear_error_string(context);
+               krb5_set_error_string(context, "Failed to decode the PK-INIT "
+                                     "subjectAltName in the KDC certificate");
+
                break;
            }
 
@@ -856,7 +868,7 @@ pk_verify_host(krb5_context context,
            {
                krb5_set_error_string(context, "KDC have wrong realm name in "
                                      "the certificate");
-               ret = EINVAL;
+               ret = KRB5_KDC_ERR_INVALID_CERTIFICATE;
            }
 
            free_KRB5PrincipalName(&r);
@@ -875,7 +887,8 @@ pk_verify_host(krb5_context context,
                                    hi->ai->ai_addr, hi->ai->ai_addrlen);
 
        if (ret)
-           krb5_set_error_string(context, "Address mismatch in the KDC certificate");
+           krb5_set_error_string(context, "Address mismatch in "
+                                 "the KDC certificate");
     }
     return ret;
 }
@@ -901,7 +914,7 @@ pk_rd_pa_reply_enckey(krb5_context context,
     krb5_data content;
     heim_oid contentType = { 0, NULL };
 
-    if (heim_oid_cmp(oid_id_pkcs7_envelopedData(), &rep->contentType)) {
+    if (der_heim_oid_cmp(oid_id_pkcs7_envelopedData(), &rep->contentType)) {
        krb5_set_error_string(context, "PKINIT: Invalid content type");
        return EINVAL;
     }
@@ -913,8 +926,10 @@ pk_rd_pa_reply_enckey(krb5_context context,
 
     ret = hx509_cms_unenvelope(ctx->id->hx509ctx,
                               ctx->id->certs,
+                              HX509_CMS_UE_DONT_REQUIRE_KU_ENCIPHERMENT,
                               rep->content->data,
                               rep->content->length,
+                              NULL,
                               &contentType,
                               &content);
     if (ret)
@@ -935,7 +950,7 @@ pk_rd_pa_reply_enckey(krb5_context context,
            goto out;
        }
 
-       if (heim_oid_cmp(&ci.contentType, oid_id_pkcs7_signedData())) {
+       if (der_heim_oid_cmp(&ci.contentType, oid_id_pkcs7_signedData())) {
            ret = EINVAL; /* XXX */
            krb5_set_error_string(context, "PKINIT: Invalid content type");
            goto out;
@@ -964,19 +979,18 @@ pk_rd_pa_reply_enckey(krb5_context context,
     /* make sure that it is the kdc's certificate */
     ret = pk_verify_host(context, realm, hi, ctx, host);
     if (ret) {
-       krb5_set_error_string(context, "PKINIT: failed verify host: %d", ret);
        goto out;
     }
 
 #if 0
     if (type == COMPAT_WIN2K) {
-       if (heim_oid_cmp(&contentType, oid_id_pkcs7_data()) != 0) {
+       if (der_heim_oid_cmp(&contentType, oid_id_pkcs7_data()) != 0) {
            krb5_set_error_string(context, "PKINIT: reply key, wrong oid");
            ret = KRB5KRB_AP_ERR_MSG_TYPE;
            goto out;
        }
     } else {
-       if (heim_oid_cmp(&contentType, oid_id_pkrkeydata()) != 0) {
+       if (der_heim_oid_cmp(&contentType, oid_id_pkrkeydata()) != 0) {
            krb5_set_error_string(context, "PKINIT: reply key, wrong oid");
            ret = KRB5KRB_AP_ERR_MSG_TYPE;
            goto out;
@@ -1002,7 +1016,7 @@ pk_rd_pa_reply_enckey(krb5_context context,
  out:
     if (host)
        _krb5_pk_cert_free(host);
-    free_oid(&contentType);
+    der_free_oid(&contentType);
     krb5_data_free(&content);
 
     return ret;
@@ -1034,7 +1048,7 @@ pk_rd_pa_reply_dh(krb5_context context,
     krb5_data_zero(&content);
     memset(&kdc_dh_info, 0, sizeof(kdc_dh_info));
 
-    if (heim_oid_cmp(oid_id_pkcs7_signedData(), &rep->contentType)) {
+    if (der_heim_oid_cmp(oid_id_pkcs7_signedData(), &rep->contentType)) {
        krb5_set_error_string(context, "PKINIT: Invalid content type");
        return EINVAL;
     }
@@ -1059,7 +1073,7 @@ pk_rd_pa_reply_dh(krb5_context context,
     if (ret)
        goto out;
 
-    if (heim_oid_cmp(&contentType, oid_id_pkdhkeydata())) {
+    if (der_heim_oid_cmp(&contentType, oid_id_pkdhkeydata())) {
        krb5_set_error_string(context, "pkinit - dh reply contains wrong oid");
        ret = KRB5KRB_AP_ERR_MSG_TYPE;
        goto out;
@@ -1324,20 +1338,28 @@ hx_pass_prompter(void *data, const hx509_prompt *prompter)
    
     password_data.data   = prompter->reply.data;
     password_data.length = prompter->reply.length;
-    prompt.prompt = "Enter your private key passphrase: ";
-    prompt.hidden = 1;
+
+    prompt.prompt = prompter->prompt;
+    prompt.hidden = hx509_prompt_hidden(prompter->type);
     prompt.reply  = &password_data;
-    if (prompter->hidden)
+
+    switch (prompter->type) {
+    case HX509_PROMPT_TYPE_INFO:
+       prompt.type   = KRB5_PROMPT_TYPE_INFO;
+       break;
+    case HX509_PROMPT_TYPE_PASSWORD:
+    case HX509_PROMPT_TYPE_QUESTION:
+    default:
        prompt.type   = KRB5_PROMPT_TYPE_PASSWORD;
-    else
-       prompt.type   = KRB5_PROMPT_TYPE_PREAUTH; /* XXX */
+       break;
+    }  
    
     ret = (*p->prompter)(p->context, p->prompter_data, NULL, NULL, 1, &prompt);
     if (ret) {
        memset (prompter->reply.data, 0, prompter->reply.length);
-       return 0;
+       return 1;
     }
-    return strlen(prompter->reply.data);
+    return 0;
 }
 
 
@@ -1354,8 +1376,8 @@ _krb5_pk_load_id(krb5_context context,
                 struct krb5_pk_identity **ret_id,
                 const char *user_id,
                 const char *anchor_id,
-                char * const *chain,
-                char * const *revoke,
+                char * const *chain_list,
+                char * const *revoke_list,
                 krb5_prompter_fct prompter,
                 void *prompter_data,
                 char *password)
@@ -1392,7 +1414,7 @@ _krb5_pk_load_id(krb5_context context,
        goto out;
 
     ret = hx509_lock_init(id->hx509ctx, &lock);
-    if (password)
+    if (password && password[0])
        hx509_lock_add_password(lock, password);
 
     if (prompter) {
@@ -1405,7 +1427,7 @@ _krb5_pk_load_id(krb5_context context,
            goto out;
     }
 
-    ret = hx509_certs_init(id->hx509ctx, user_id, 0, NULL, &id->certs);
+    ret = hx509_certs_init(id->hx509ctx, user_id, 0, lock, &id->certs);
     if (ret)
        goto out;
 
@@ -1418,33 +1440,36 @@ _krb5_pk_load_id(krb5_context context,
     if (ret)
        goto out;
 
-    while (chain && *chain) {
-       ret = hx509_certs_append(id->hx509ctx, id->certpool, NULL, *chain);
+    while (chain_list && *chain_list) {
+       ret = hx509_certs_append(id->hx509ctx, id->certpool,
+                                NULL, *chain_list);
        if (ret) {
            krb5_set_error_string(context,
                                  "pkinit failed to load chain %s",
-                                 *chain);
+                                 *chain_list);
            goto out;
        }
-       chain++;
+       chain_list++;
     }
 
-    if (revoke) {
-       ret = hx509_revoke_init(id->hx509ctx, &id->revoke);
+    if (revoke_list) {
+       ret = hx509_revoke_init(id->hx509ctx, &id->revokectx);
        if (ret) {
            krb5_set_error_string(context, "revoke failed to init");
            goto out;
        }
 
-       while (*revoke) {
-           ret = hx509_revoke_add_crl(id->hx509ctx, id->revoke, *revoke);
+       while (*revoke_list) {
+           ret = hx509_revoke_add_crl(id->hx509ctx, 
+                                      id->revokectx,
+                                      *revoke_list);
            if (ret) {
                krb5_set_error_string(context,
                                      "pkinit failed to load revoke %s",
-                                     *revoke);
+                                     *revoke_list);
                goto out;
            }
-           revoke++;
+           revoke_list++;
        }
     } else
        hx509_context_set_missing_revoke(id->hx509ctx, 1);
@@ -1454,7 +1479,7 @@ _krb5_pk_load_id(krb5_context context,
        goto out;
 
     hx509_verify_attach_anchors(id->verify_ctx, id->anchors);
-    hx509_verify_attach_revoke(id->verify_ctx, id->revoke);
+    hx509_verify_attach_revoke(id->verify_ctx, id->revokectx);
 
 out:
     if (ret) {
@@ -1462,7 +1487,7 @@ out:
        hx509_certs_free(&id->certs);
        hx509_certs_free(&id->anchors);
        hx509_certs_free(&id->certpool);
-       hx509_revoke_free(&id->revoke);
+       hx509_revoke_free(&id->revokectx);
        hx509_context_free(&id->hx509ctx);
        free(id);
     } else
@@ -1588,9 +1613,9 @@ _krb5_parse_moduli_line(krb5_context context,
     return 0;
 out:
     free(m1->name);
-    free_heim_integer(&m1->p);
-    free_heim_integer(&m1->g);
-    free_heim_integer(&m1->q);
+    der_free_heim_integer(&m1->p);
+    der_free_heim_integer(&m1->g);
+    der_free_heim_integer(&m1->q);
     free(m1);
     return ret;
 }
@@ -1601,9 +1626,9 @@ _krb5_free_moduli(struct krb5_dh_moduli **moduli)
     int i;
     for (i = 0; moduli[i] != NULL; i++) {
        free(moduli[i]->name);
-       free_heim_integer(&moduli[i]->p);
-       free_heim_integer(&moduli[i]->g);
-       free_heim_integer(&moduli[i]->q);
+       der_free_heim_integer(&moduli[i]->p);
+       der_free_heim_integer(&moduli[i]->g);
+       der_free_heim_integer(&moduli[i]->q);
        free(moduli[i]);
     }
     free(moduli);
@@ -1712,9 +1737,9 @@ _krb5_dh_group_ok(krb5_context context, unsigned long bits,
        *name = NULL;
 
     for (i = 0; moduli[i] != NULL; i++) {
-       if (heim_integer_cmp(&moduli[i]->g, g) == 0 &&
-           heim_integer_cmp(&moduli[i]->p, p) == 0 &&
-           (q == NULL || heim_integer_cmp(&moduli[i]->q, q) == 0))
+       if (der_heim_integer_cmp(&moduli[i]->g, g) == 0 &&
+           der_heim_integer_cmp(&moduli[i]->p, p) == 0 &&
+           (q == NULL || der_heim_integer_cmp(&moduli[i]->q, q) == 0))
        {
            if (bits && bits > moduli[i]->bits) {
                krb5_set_error_string(context, "PKINIT: DH group parameter %s "
@@ -1769,8 +1794,8 @@ krb5_get_init_creds_opt_set_pkinit(krb5_context context,
                                   krb5_principal principal,
                                   const char *user_id,
                                   const char *x509_anchors,
-                                  char * const * chain,
-                                  char * const * revoke,
+                                  char * const * pool,
+                                  char * const * pki_revoke,
                                   int flags,
                                   krb5_prompter_fct prompter,
                                   void *prompter_data,
@@ -1778,6 +1803,7 @@ krb5_get_init_creds_opt_set_pkinit(krb5_context context,
 {
 #ifdef PKINIT
     krb5_error_code ret;
+    char *anchors = NULL;
 
     if (opt->opt_private == NULL) {
        krb5_set_error_string(context, "PKINIT: on non extendable opt");
@@ -1797,12 +1823,33 @@ krb5_get_init_creds_opt_set_pkinit(krb5_context context,
     opt->opt_private->pk_init_ctx->require_eku = 1;
     opt->opt_private->pk_init_ctx->require_krbtgt_otherName = 1;
 
+
+    /* XXX implement krb5_appdefault_strings  */
+    if (pool == NULL)
+       pool = krb5_config_get_strings(context, NULL,
+                                      "appdefaults", 
+                                      "pkinit-pool", 
+                                      NULL);
+
+    if (pki_revoke == NULL)
+       pki_revoke = krb5_config_get_strings(context, NULL,
+                                            "appdefaults", 
+                                            "pkinit-revoke", 
+                                            NULL);
+
+    if (x509_anchors == NULL) {
+       krb5_appdefault_string(context, "kinit",
+                              krb5_principal_get_realm(context, principal), 
+                              "pkinit-anchors", NULL, &anchors);
+       x509_anchors = anchors;
+    }
+
     ret = _krb5_pk_load_id(context,
                           &opt->opt_private->pk_init_ctx->id,
                           user_id,
                           x509_anchors,
-                          chain,
-                          revoke,
+                          pool,
+                          pki_revoke,
                           prompter,
                           prompter_data,
                           password);
index f6e3847cceafa94b4be4d34326ffb71ffd866232..4d13e7db11ff526b2158d0dbb1d27474c06ea3b5 100644 (file)
@@ -41,7 +41,7 @@
 #include <fnmatch.h>
 #include "resolve.h"
 
-RCSID("$Id: principal.c,v 1.95 2006/04/24 15:16:14 lha Exp $");
+RCSID("$Id: principal.c,v 1.99 2006/10/18 06:53:22 lha Exp $");
 
 #define princ_num_comp(P) ((P)->name.name_string.len)
 #define princ_type(P) ((P)->name.name_type)
@@ -91,17 +91,11 @@ krb5_principal_get_comp_string(krb5_context context,
     return princ_ncomp(principal, component);
 }
 
-enum realm_presence {
-       MAY,
-       MUSTNOT,
-       MUST
-};
-
-static krb5_error_code 
-parse_name(krb5_context context,
-          const char *name,
-          enum realm_presence realm_presence,
-          krb5_principal *principal)
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_parse_name_flags(krb5_context context,
+                     const char *name,
+                     int flags,
+                     krb5_principal *principal)
 {
     krb5_error_code ret;
     heim_general_string *comp;
@@ -117,6 +111,17 @@ parse_name(krb5_context context,
     char c;
     int got_realm = 0;
   
+    *principal = NULL;
+
+#define RFLAGS (KRB5_PRINCIPAL_PARSE_NO_REALM|KRB5_PRINCIPAL_PARSE_MUST_REALM)
+
+    if ((flags & RFLAGS) == RFLAGS) {
+       krb5_set_error_string(context, "Can't require both realm and "
+                             "no realm at the same time");
+       return KRB5_ERR_NO_SERVICE;
+    }
+#undef RFLAGS
+
     /* count number of component */
     ncomp = 1;
     for(p = name; *p; p++){
@@ -191,32 +196,33 @@ parse_name(krb5_context context,
        }
        *q++ = c;
     }
-    if (got_realm) {
-       if (realm_presence == MUSTNOT) {
-           krb5_set_error_string (context, "realm found in 'short' principal expected to be without one!");
+    if(got_realm){
+       if (flags & KRB5_PRINCIPAL_PARSE_NO_REALM) {
+           krb5_set_error_string (context, "realm found in 'short' principal "
+                                  "expected to be without one");
            ret = KRB5_PARSE_MALFORMED;
            goto exit;
-       } else {
-           realm = malloc(q - start + 1);
-           if (realm == NULL) {
-               krb5_set_error_string (context, "malloc: out of memory");
-               ret = ENOMEM;
-               goto exit;
-           }
-           memcpy(realm, start, q - start);
-           realm[q - start] = 0;
        }
+       realm = malloc(q - start + 1);
+       if (realm == NULL) {
+           krb5_set_error_string (context, "malloc: out of memory");
+           ret = ENOMEM;
+           goto exit;
+       }
+       memcpy(realm, start, q - start);
+       realm[q - start] = 0;
     }else{
-       if (realm_presence == MAY) {
-           ret = krb5_get_default_realm (context, &realm);
-           if (ret)
-               goto exit;
-       } else if (realm_presence == MUSTNOT) {
-           realm = NULL;
-       } else if (realm_presence == MUST) {
-           krb5_set_error_string (context, "realm NOT found in principal expected to be with one!");
+       if (flags & KRB5_PRINCIPAL_PARSE_MUST_REALM) {
+           krb5_set_error_string (context, "realm NOT found in principal "
+                                  "expected to be with one");
            ret = KRB5_PARSE_MALFORMED;
            goto exit;
+       } else if (flags & KRB5_PRINCIPAL_PARSE_NO_REALM) {
+           realm = NULL;
+       } else {
+           ret = krb5_get_default_realm (context, &realm);
+           if (ret)
+               goto exit;
        }
 
        comp[n] = malloc(q - start + 1);
@@ -256,24 +262,9 @@ krb5_parse_name(krb5_context context,
                const char *name,
                krb5_principal *principal)
 {
-    return parse_name(context, name, MAY, principal);
+    return krb5_parse_name_flags(context, name, 0, principal);
 }
 
-krb5_error_code KRB5_LIB_FUNCTION
-krb5_parse_name_norealm(krb5_context context,
-                       const char *name,
-                       krb5_principal *principal)
-{
-    return parse_name(context, name, MUSTNOT, principal);
-}
-
-krb5_error_code KRB5_LIB_FUNCTION
-krb5_parse_name_mustrealm(krb5_context context,
-                         const char *name,
-                         krb5_principal *principal)
-{
-    return parse_name(context, name, MUST, principal);
-}
 static const char quotable_chars[] = " \n\t\b\\/@";
 static const char replace_chars[] = " ntb\\/@";
 
@@ -301,23 +292,47 @@ unparse_name_fixed(krb5_context context,
                   krb5_const_principal principal,
                   char *name,
                   size_t len,
-                  krb5_boolean short_form)
+                  int flags)
 {
     size_t idx = 0;
     int i;
+    int short_form = (flags & KRB5_PRINCIPAL_UNPARSE_SHORT) != 0;
+    int no_realm = (flags & KRB5_PRINCIPAL_UNPARSE_NO_REALM) != 0;
+
+    if (!no_realm && princ_realm(principal) == NULL) {
+       krb5_set_error_string(context, "Realm missing from principal, "
+                             "can't unparse");
+       return ERANGE;
+    }
+
     for(i = 0; i < princ_num_comp(principal); i++){
        if(i)
            add_char(name, idx, len, '/');
        idx = quote_string(princ_ncomp(principal, i), name, idx, len);
-       if(idx == len)
+       if(idx == len) {
+           krb5_set_error_string(context, "Out of space printing principal");
            return ERANGE;
+       }
     } 
     /* add realm if different from default realm */
-    if(!short_form) {
+    if(short_form && !no_realm) {
+       krb5_realm r;
+       krb5_error_code ret;
+       ret = krb5_get_default_realm(context, &r);
+       if(ret)
+           return ret;
+       if(strcmp(princ_realm(principal), r) != 0)
+           short_form = 0;
+       free(r);
+    }
+    if(!short_form && !no_realm) {
        add_char(name, idx, len, '@');
        idx = quote_string(princ_realm(principal), name, idx, len);
-       if(idx == len)
+       if(idx == len) {
+           krb5_set_error_string(context, 
+                                 "Out of space printing realm of principal");
            return ERANGE;
+       }
     }
     return 0;
 }
@@ -328,57 +343,48 @@ krb5_unparse_name_fixed(krb5_context context,
                        char *name,
                        size_t len)
 {
-    return unparse_name_fixed(context, principal, name, len, FALSE);
+    return unparse_name_fixed(context, principal, name, len, 0);
 }
 
 krb5_error_code KRB5_LIB_FUNCTION
-krb5_unparse_name_norealm_fixed(krb5_context context,
-                               krb5_const_principal principal,
-                               char *name,
-                               size_t len)
+krb5_unparse_name_fixed_short(krb5_context context,
+                             krb5_const_principal principal,
+                             char *name,
+                             size_t len)
 {
-    return unparse_name_fixed(context, principal, name, len, TRUE);
+    return unparse_name_fixed(context, principal, name, len, 
+                             KRB5_PRINCIPAL_UNPARSE_SHORT);
 }
 
 krb5_error_code KRB5_LIB_FUNCTION
-krb5_unparse_name_fixed_short(krb5_context context,
+krb5_unparse_name_fixed_flags(krb5_context context,
                              krb5_const_principal principal,
+                             int flags,
                              char *name,
                              size_t len)
 {
-    krb5_realm r;
-    krb5_error_code ret;
-    krb5_boolean short_form = TRUE;
-    ret = krb5_get_default_realm(context, &r);
-    if(ret)
-       return ret;
-    if(strcmp(princ_realm(principal), r) != 0)
-       short_form = 0;
-    free(r);
-    return unparse_name_fixed(context, principal, name, len, short_form);
+    return unparse_name_fixed(context, principal, name, len, flags);
 }
 
 static krb5_error_code
 unparse_name(krb5_context context,
             krb5_const_principal principal,
             char **name,
-            krb5_boolean short_flag)
+            int flags)
 {
     size_t len = 0, plen;
     int i;
     krb5_error_code ret;
     /* count length */
-    if (!short_flag) {
+    if (princ_realm(principal)) {
        plen = strlen(princ_realm(principal));
+
        if(strcspn(princ_realm(principal), quotable_chars) == plen)
            len += plen;
        else
            len += 2*plen;
-       len++;
-    } else {
-       len = 0;
+       len++; /* '@' */
     }
-
     for(i = 0; i < princ_num_comp(principal); i++){
        plen = strlen(princ_ncomp(principal, i));
        if(strcspn(princ_ncomp(principal, i), quotable_chars) == plen)
@@ -387,13 +393,13 @@ unparse_name(krb5_context context,
            len += 2*plen;
        len++;
     }
-    len++;
+    len++; /* '\0' */
     *name = malloc(len);
     if(*name == NULL) {
        krb5_set_error_string (context, "malloc: out of memory");
        return ENOMEM;
     }
-    ret = unparse_name_fixed(context, principal, *name, len, short_flag);
+    ret = unparse_name_fixed(context, principal, *name, len, flags);
     if(ret) {
        free(*name);
        *name = NULL;
@@ -406,32 +412,24 @@ krb5_unparse_name(krb5_context context,
                  krb5_const_principal principal,
                  char **name)
 {
-    return unparse_name(context, principal, name, FALSE);
+    return unparse_name(context, principal, name, 0);
 }
 
 krb5_error_code KRB5_LIB_FUNCTION
-krb5_unparse_name_short(krb5_context context,
+krb5_unparse_name_flags(krb5_context context,
                        krb5_const_principal principal,
+                       int flags,
                        char **name)
 {
-    krb5_realm r;
-    krb5_error_code ret;
-    krb5_boolean short_form = TRUE;
-    ret = krb5_get_default_realm(context, &r);
-    if(ret)
-       return ret;
-    if(strcmp(princ_realm(principal), r) != 0)
-       short_form = 0;
-    free(r);
-    return unparse_name(context, principal, name, short_form);
+    return unparse_name(context, principal, name, flags);
 }
 
 krb5_error_code KRB5_LIB_FUNCTION
-krb5_unparse_name_norealm(krb5_context context,
-                              krb5_const_principal principal,
-                              char **name)
+krb5_unparse_name_short(krb5_context context,
+                       krb5_const_principal principal,
+                       char **name)
 {
-    return unparse_name(context, principal, name, TRUE);
+    return unparse_name(context, principal, name, KRB5_PRINCIPAL_UNPARSE_SHORT);
 }
 
 #if 0 /* not implemented */
@@ -447,7 +445,7 @@ krb5_unparse_name_ext(krb5_context context,
 
 #endif
 
-krb5_realm* KRB5_LIB_FUNCTION
+krb5_realm * KRB5_LIB_FUNCTION
 krb5_princ_realm(krb5_context context,
                 krb5_principal principal)
 {
@@ -455,7 +453,6 @@ krb5_princ_realm(krb5_context context,
 }
 
 
-
 void KRB5_LIB_FUNCTION
 krb5_princ_set_realm(krb5_context context,
                     krb5_principal principal,
index 01b5188bae4d543ac804c9876b5d168b3d5dfd14..46a36c9aac7d189534746b936c7d8a25c2ff6289 100644 (file)
@@ -33,7 +33,7 @@
 
 #include <krb5_locl.h>
 
-RCSID("$Id: rd_cred.c,v 1.28 2006/04/02 02:27:33 lha Exp $");
+RCSID("$Id: rd_cred.c,v 1.29 2006/10/06 17:04:47 lha Exp $");
 
 static krb5_error_code
 compare_addrs(krb5_context context,
@@ -265,7 +265,8 @@ krb5_rd_cred(krb5_context context,
            krb5_abortx(context, "internal error in ASN.1 encoder");
        copy_EncryptionKey (&kci->key, &creds->session);
        if (kci->prealm && kci->pname)
-           _krb5_principalname2krb5_principal (context, &creds->client,
+           _krb5_principalname2krb5_principal (context,
+                                               &creds->client,
                                                *kci->pname,
                                                *kci->prealm);
        if (kci->flags)
index 53138d9f458a7bd61be8bd5ae047632be2bc5b97..6b7f27c3cffa2c8e81335fa4e3138b1423e13be4 100644 (file)
@@ -33,7 +33,7 @@
 
 #include <krb5_locl.h>
 
-RCSID("$Id: rd_rep.c,v 1.25 2005/06/17 07:49:33 lha Exp $");
+RCSID("$Id: rd_rep.c,v 1.26 2006/08/21 09:19:22 lha Exp $");
 
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_rd_rep(krb5_context context,
@@ -92,7 +92,10 @@ krb5_rd_rep(krb5_context context,
   
     if (auth_context->flags & KRB5_AUTH_CONTEXT_DO_TIME) { 
        if ((*repl)->ctime != auth_context->authenticator->ctime ||
-           (*repl)->cusec != auth_context->authenticator->cusec) {
+           (*repl)->cusec != auth_context->authenticator->cusec) 
+       {
+           krb5_free_ap_rep_enc_part(context, *repl);
+           *repl = NULL;
            ret = KRB5KRB_AP_ERR_MUT_FAIL;
            krb5_clear_error_string (context);
            goto out;
@@ -114,6 +117,8 @@ void KRB5_LIB_FUNCTION
 krb5_free_ap_rep_enc_part (krb5_context context,
                           krb5_ap_rep_enc_part *val)
 {
-    free_EncAPRepPart (val);
-    free (val);
+    if (val) {
+       free_EncAPRepPart (val);
+       free (val);
+    }
 }
index c0bb710a59bfca4e865cb199539f889e22b5807d..c424a73a34d621dbc2c36a028e343751de582304 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997 - 2001, 2003 - 2005 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2001, 2003 - 2005 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
  * All rights reserved. 
  *
@@ -33,7 +33,7 @@
 
 #include <krb5_locl.h>
 
-RCSID("$Id: rd_req.c,v 1.63 2006/04/10 10:14:44 lha Exp $");
+RCSID("$Id: rd_req.c,v 1.66 2006/10/06 17:04:29 lha Exp $");
 
 static krb5_error_code
 decrypt_tkt_enc_part (krb5_context context,
@@ -376,12 +376,14 @@ krb5_verify_ap_req2(krb5_context context,
     if(ret)
        goto out;
 
-    ret = _krb5_principalname2krb5_principal(context, 
-                                            &t->server, ap_req->ticket.sname, 
+    ret = _krb5_principalname2krb5_principal(context,
+                                            &t->server,
+                                            ap_req->ticket.sname, 
                                             ap_req->ticket.realm);
     if (ret) goto out;
-    ret = _krb5_principalname2krb5_principal(context, 
-                                            &t->client, t->ticket.cname, 
+    ret = _krb5_principalname2krb5_principal(context,
+                                            &t->client,
+                                            t->ticket.cname, 
                                             t->ticket.crealm);
     if (ret) goto out;
 
@@ -402,10 +404,12 @@ krb5_verify_ap_req2(krb5_context context,
        krb5_principal p1, p2;
        krb5_boolean res;
        
-       _krb5_principalname2krb5_principal(context, &p1,
+       _krb5_principalname2krb5_principal(context,
+                                          &p1,
                                           ac->authenticator->cname,
                                           ac->authenticator->crealm);
-       _krb5_principalname2krb5_principal(context, &p2, 
+       _krb5_principalname2krb5_principal(context,
+                                          &p2, 
                                           t->ticket.cname,
                                           t->ticket.crealm);
        res = krb5_principal_compare (context, p1, p2);
@@ -607,7 +611,8 @@ krb5_rd_req_return_keyblock(krb5_context context,
        return ret;
 
     if(server == NULL){
-       _krb5_principalname2krb5_principal(context, &service,
+       _krb5_principalname2krb5_principal(context,
+                                          &service,
                                           ap_req.ticket.sname,
                                           ap_req.ticket.realm);
        server = service;
index 0bcafa70a114e33ff94dd12a62f978418e6c3c43..11c07c9e8f0ab4c84d60bfa31b4f6deef220c893 100644 (file)
 
 #include "krb5_locl.h"
 
-RCSID("$Id: send_to_kdc.c,v 1.58 2006/04/02 02:32:03 lha Exp $");
+RCSID("$Id: send_to_kdc.c,v 1.60 2006/10/20 18:42:01 lha Exp $");
 
-struct send_and_recv {
-       krb5_send_and_recv_func_t func;
-       krb5_send_and_recv_close_func_t close;
-       void *data;
+struct send_to_kdc {
+    krb5_send_to_kdc_func func;
+    void *data;
 };
 
-krb5_error_code KRB5_LIB_FUNCTION
-krb5_set_send_recv_func(krb5_context context,
-                       krb5_send_and_recv_func_t func,
-                       krb5_send_and_recv_close_func_t close_fn,
-                       void *data)
-{
-       free(context->send_and_recv);
-       context->send_and_recv = malloc(sizeof(*context->send_and_recv));
-       if (!context->send_and_recv) {
-               return ENOMEM;
-       }
-       context->send_and_recv->func = func;
-       context->send_and_recv->close = close_fn;
-       context->send_and_recv->data = data;
-       return 0;
-}
-
-
 /*
  * send the data in `req' on the socket `fd' (which is datagram iff udp)
  * waiting `tmout' for a reply and returning the reply in `rep'.
@@ -346,7 +327,7 @@ krb5_sendto (krb5_context context,
             krb5_krbhst_handle handle,      
             krb5_data *receive)
 {
-     krb5_error_code ret = 0;
+     krb5_error_code ret;
      int fd;
      int i;
 
@@ -356,27 +337,22 @@ krb5_sendto (krb5_context context,
         while (krb5_krbhst_next(context, handle, &hi) == 0) {
             struct addrinfo *ai, *a;
 
-            if (context->send_and_recv) {
-                ret = context->send_and_recv->func(context, 
-                                                   context->send_and_recv->data, 
-                                                   hi, send_data, receive);
-                if (ret) {
-                    continue;
-                } else if (receive->length != 0) {
-                    return 0;
-                } else {
-                    continue;
-                }
+            if (context->send_to_kdc) {
+                struct send_to_kdc *s = context->send_to_kdc;
+
+                ret = (*s->func)(context, s->data, 
+                                 hi, send_data, receive);
+                if (ret == 0 && receive->length != 0)
+                    goto out;
+                continue;
             }
 
             if(hi->proto == KRB5_KRBHST_HTTP && context->http_proxy) {
-                if (send_via_proxy (context, hi, send_data, receive)) {
-                    /* Try again, with next host */
-                    continue;
-                } else {
-                    /* Success */
-                    return 0;
+                if (send_via_proxy (context, hi, send_data, receive) == 0) {
+                    ret = 0;
+                    goto out;
                 }
+                continue;
             }
 
             ret = krb5_krbhst_get_addrinfo(context, hi, &ai);
@@ -406,15 +382,16 @@ krb5_sendto (krb5_context context,
                     break;
                 }
                 close (fd);
-                if(ret == 0 && receive->length != 0) {
-                    return 0;
-                }
+                if(ret == 0 && receive->length != 0)
+                    goto out;
             }
         }
         krb5_krbhst_reset(context, handle);
      }
      krb5_clear_error_string (context);
-     return KRB5_KDC_UNREACH;
+     ret = KRB5_KDC_UNREACH;
+out:
+     return ret;
 }
 
 krb5_error_code KRB5_LIB_FUNCTION
@@ -456,3 +433,27 @@ krb5_sendto_kdc_flags(krb5_context context,
                              "unable to reach any KDC in realm %s", *realm);
     return ret;
 }
+
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_set_send_to_kdc_func(krb5_context context, 
+                         krb5_send_to_kdc_func func,
+                         void *data)
+{
+    free(context->send_to_kdc);
+    if (func == NULL) {
+       context->send_to_kdc = NULL;
+       return 0;
+    }
+
+    context->send_to_kdc = malloc(sizeof(*context->send_to_kdc));
+    if (context->send_to_kdc == NULL) {
+       krb5_set_error_string(context, "Out of memory");
+       return ENOMEM;
+    }
+
+    context->send_to_kdc->func = func;
+    context->send_to_kdc->data = data;
+    return 0;
+}
+
+
index fd57b6fe679c3434a7258d833ba4c8f6e0f3d863..965883309c023df36a2152296e55efd944290db1 100644 (file)
@@ -77,19 +77,8 @@ krb5_set_default_realm(krb5_context context,
                                          "libdefaults",
                                          "default_realm",
                                          NULL);
-       if (realms == NULL) {
-           char hostname[MAXHOSTNAMELEN];
-           if (gethostname (hostname, sizeof(hostname))) {
-               return errno;
-           }
-
-           if (strchr(hostname, '.') == NULL) {
-               /* There is no way we can get this mapping, as we can't do DNS */
-               return KRB5_CONFIG_NODEFREALM;
-           }
-           ret = krb5_get_host_realm(context, hostname,
-                                     &realms);
-       }
+       if (realms == NULL)
+           ret = krb5_get_host_realm(context, NULL, &realms);
     } else {
        ret = string_to_list (context, realm, &realms);
     }
index a6f4a011a1bbdf398fbe45ae7be7a5a1cb6e5660..e75f28ca5fafb5f4e186ac06ec40e9e211b1c19f 100644 (file)
@@ -34,7 +34,7 @@
 #include "krb5_locl.h"
 #include "store-int.h"
 
-RCSID("$Id: store.c,v 1.58 2006/05/05 07:15:18 lha Exp $");
+RCSID("$Id: store.c,v 1.59 2006/08/18 08:39:13 lha Exp $");
 
 #define BYTEORDER_IS(SP, V) (((SP)->flags & KRB5_STORAGE_BYTEORDER_MASK) == (V))
 #define BYTEORDER_IS_LE(SP) BYTEORDER_IS((SP), KRB5_STORAGE_BYTEORDER_LE)
@@ -440,6 +440,76 @@ krb5_ret_stringz(krb5_storage *sp,
     return 0;
 }
 
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_store_stringnl(krb5_storage *sp, const char *s)
+{
+    size_t len = strlen(s);
+    ssize_t ret;
+
+    ret = sp->store(sp, s, len);
+    if(ret != len) {
+       if(ret < 0)
+           return ret;
+       else
+           return sp->eof_code;
+    }
+    ret = sp->store(sp, "\n", 1);
+    if(ret != 1) {
+       if(ret < 0)
+           return ret;
+       else
+           return sp->eof_code;
+    }
+
+    return 0;
+
+}
+
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_ret_stringnl(krb5_storage *sp,
+                 char **string)
+{
+    int expect_nl = 0;
+    char c;
+    char *s = NULL;
+    size_t len = 0;
+    ssize_t ret;
+
+    while((ret = sp->fetch(sp, &c, 1)) == 1){
+       char *tmp;
+
+       if (c == '\r') {
+           expect_nl = 1;
+           continue;
+       }
+       if (expect_nl && c != '\n') {
+           free(s);
+           return KRB5_BADMSGTYPE;
+       }
+
+       len++;
+       tmp = realloc (s, len);
+       if (tmp == NULL) {
+           free (s);
+           return ENOMEM;
+       }
+       s = tmp;
+       if(c == '\n') {
+           s[len - 1] = '\0';
+           break;
+       }
+       s[len - 1] = c;
+    }
+    if(ret != 1){
+       free(s);
+       if(ret == 0)
+           return sp->eof_code;
+       return ret;
+    }
+    *string = s;
+    return 0;
+}
+
 
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_store_principal(krb5_storage *sp,
index 46043a6761a9898855c533b16f05a30597e0dbc5..835d3478e22289ab756a859750bdcc74f379139c 100644 (file)
@@ -34,7 +34,7 @@
 #include "krb5_locl.h"
 #include "store-int.h"
 
-RCSID("$Id: store_fd.c,v 1.12 2004/05/25 21:43:57 lha Exp $");
+RCSID("$Id: store_fd.c,v 1.13 2006/06/30 21:23:19 lha Exp $");
 
 typedef struct fd_storage {
     int fd;
@@ -74,13 +74,16 @@ krb5_storage_from_fd(int fd)
     fd = dup(fd);
     if (fd < 0)
        return NULL;
-    sp = malloc(sizeof(krb5_storage));
 
-    if (sp == NULL)
+    sp = malloc(sizeof(krb5_storage));
+    if (sp == NULL) {
+       close(fd);
        return NULL;
+    }
 
     sp->data = malloc(sizeof(fd_storage));
     if (sp->data == NULL) {
+       close(fd);
        free(sp);
        return NULL;
     }
index 99cb778722a9a0d8957b38eca58dd1b6dfe53599..fdc2a1b3a5d8a8e8a71871c25aeb4d81a2804041 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: ticket.c,v 1.14 2005/10/27 13:21:42 lha Exp $");
+RCSID("$Id: ticket.c,v 1.15 2006/10/14 09:53:19 lha Exp $");
 
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_free_ticket(krb5_context context,
@@ -107,12 +107,16 @@ find_type_in_ad(krb5_context context,
                const AuthorizationData *ad,
                int level)
 {
-    krb5_error_code ret = ENOENT;
+    /* It is not an error if nothing in here, that is reported by *found */
+    /* Setting a default error causes found to be set to FALSE, on
+     * recursion to an second embedded authz data even if the first
+     * element contains the required type */
+    krb5_error_code ret = 0;
     int i;
 
     if (level > 9) {
        krb5_set_error_string(context, "Authorization data nested deeper "
-                             "than %d levels, stop searching", level);
+                             "then %d levels, stop searching", level);
        ret = ENOENT; /* XXX */
        goto out;
     }
@@ -124,7 +128,7 @@ find_type_in_ad(krb5_context context,
      */
     for (i = 0; i < ad->len; i++) {
        if (!*found && ad->val[i].ad_type == type) {
-           ret = copy_octet_string(&ad->val[i].ad_data, data);
+           ret = der_copy_octet_string(&ad->val[i].ad_data, data);
            if (ret) {
                krb5_set_error_string(context, "malloc - out of memory");
                goto out;
index dd7ea832af6b72885397c188b573da09ea952209..48b587d2db9149f5de0354266a2d72ae11104183 100644 (file)
@@ -34,7 +34,7 @@
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
-#include <roken.h>
+#include "roken.h"
 
 RCSID("$Id: bswap.c,v 1.4 2005/04/12 11:28:35 lha Exp $");
 
index 7d458dc1b98a794f257b10ef593b8f2d912839b2..d11fa16303738f19ddce323009015aaeda47f0ce 100644 (file)
@@ -36,7 +36,7 @@
 RCSID("$Id: copyhostent.c,v 1.3 2005/04/12 11:28:36 lha Exp $");
 #endif
 
-#include <roken.h>
+#include "roken.h"
 
 /*
  * return a malloced copy of `h'
index cd2898036bf094be7e15874afcc79be85d116a8c..6311aa29d8b917215dbb16a397655f0c30a2cfdf 100644 (file)
@@ -36,7 +36,7 @@
 RCSID("$Id: freeaddrinfo.c,v 1.5 2005/04/12 11:28:41 lha Exp $");
 #endif
 
-#include <roken.h>
+#include "roken.h"
 
 /*
  * free the list of `struct addrinfo' starting at `ai'
index 1ebb01361c0bf5d886196a8b8b8d634b14f1e9f5..d837ba250362490682a4edc216730267528afd74 100644 (file)
@@ -36,7 +36,7 @@
 RCSID("$Id: freehostent.c,v 1.3 2005/04/12 11:28:41 lha Exp $");
 #endif
 
-#include <roken.h>
+#include "roken.h"
 
 /*
  * free a malloced hostent
index 102aa75ea138832d07dc0858960391c112e8917c..52db0f88420c6aaf70ce07fc6bddf14f71f4363e 100644 (file)
@@ -36,7 +36,7 @@
 RCSID("$Id: gai_strerror.c,v 1.7 2005/08/05 09:31:35 lha Exp $");
 #endif
 
-#include <roken.h>
+#include "roken.h"
 
 static struct gai_error {
     int code;
index 86af8b72cc845ea7bcff499cd490e6b4f09c1808..b39131de74cd91023aaccaf8327c234eeec23ea7 100644 (file)
@@ -36,7 +36,7 @@
 RCSID("$Id: getaddrinfo.c,v 1.14 2005/06/16 17:49:29 lha Exp $");
 #endif
 
-#include <roken.h>
+#include "roken.h"
 
 /*
  * uses hints->ai_socktype and hints->ai_protocol
index 3f447d6d0643caf6bc553202c723f0c334b86587..841fc46a80f1444cfab46323deee3205400f178f 100644 (file)
@@ -36,7 +36,7 @@
 RCSID("$Id: getipnodebyaddr.c,v 1.3 2005/04/12 11:28:47 lha Exp $");
 #endif
 
-#include <roken.h>
+#include "roken.h"
 
 /*
  * lookup `src, len' (address family `af') in DNS and return a pointer
index b928efcc539f4b8f76339b006149512ae110d610..0707e4c16c68ab5c72f56a53d3451fd2b796ea49 100644 (file)
@@ -36,7 +36,7 @@
 RCSID("$Id: getipnodebyname.c,v 1.4 2005/04/12 11:28:47 lha Exp $");
 #endif
 
-#include <roken.h>
+#include "roken.h"
 
 #ifndef HAVE_H_ERRNO
 static int h_errno = NO_RECOVERY;
index 7eabe40093b44cf20363b7eb4debdc0f795fe793..f8f1e9d4a22c790b9dad74efc039760c59aa04bb 100644 (file)
@@ -36,7 +36,7 @@
 RCSID("$Id: getprogname.c,v 1.3 2005/04/12 11:28:48 lha Exp $");
 #endif
 
-#include <roken.h>
+#include "roken.h"
 
 #ifndef HAVE___PROGNAME
 const char *__progname;
index e41b508fcb3f7d561bd94ba74b8ce898f1271b0e..ba0f4a4fdac9a18d17b0cfce6a317ded5d93e2d1 100644 (file)
@@ -35,7 +35,7 @@
 #include <config.h>
 RCSID("$Id: hex.c,v 1.8 2006/01/09 17:09:29 lha Exp $");
 #endif
-#include <roken.h>
+#include "roken.h"
 #include <ctype.h>
 #include "hex.h"
 
index 1762b112262b78264744f040044e3af5e2e5738a..24f3b843d8950f1e66031b1bbcd3923328d21053 100644 (file)
@@ -36,7 +36,7 @@
 RCSID("$Id: hostent_find_fqdn.c,v 1.3 2005/04/12 11:28:51 lha Exp $");
 #endif
 
-#include <roken.h>
+#include "roken.h"
 
 /*
  * Try to find a fqdn (with `.') in he if possible, else return h_name
index 0483a05256b563be98f79a9c262a53aa79147870..b26dcb87ff8e8d52dcccc31b8a8c975352a9d6b6 100644 (file)
@@ -36,7 +36,7 @@
 RCSID("$Id: inet_aton.c,v 1.14 2005/04/12 11:28:52 lha Exp $");
 #endif
 
-#include <roken.h>
+#include "roken.h"
 
 /* Minimal implementation of inet_aton.
  * Cannot distinguish between failure and a local broadcast address. */
index e6b524816488459cbcf89ce51cc0b831a29cd58f..7ccf615451c29c2c01a4fd064aab28548cbccde5 100644 (file)
@@ -36,7 +36,7 @@
 RCSID("$Id: issuid.c,v 1.6 2005/05/13 07:42:03 lha Exp $");
 #endif
 
-#include <roken.h>
+#include "roken.h"
 
 int ROKEN_LIB_FUNCTION
 issuid(void)
index a72fb24eab5692f070b249ef19d48f61efb50116..6a14547c62dade38929e4f65f41607ba5e5f147f 100644 (file)
@@ -34,7 +34,7 @@
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
-#include <roken.h>
+#include "roken.h"
 #ifdef HAVE_ARPA_NAMESER_H
 #include <arpa/nameser.h>
 #endif
index 853de9b11280f5341bb38a7c10720f5e2b552d21..9d1ead97e29d7f0ed4dcde118ae1f0938bb40b1b 100644 (file)
@@ -1,6 +1,12 @@
+/* This is an OS dependent, generated file */
+
+
+#ifndef __ROKEN_H__
+#define __ROKEN_H__
+
 /* -*- C -*- */
 /*
- * Copyright (c) 1995-2005 Kungliga Tekniska Högskolan
+ * Copyright (c) 1995-2005 Kungliga Tekniska H
  * (Royal Institute of Technology, Stockholm, Sweden).
  * All rights reserved.
  * 
  * SUCH DAMAGE.
  */
 
-/* $Id: roken.h.in,v 1.178 2005/09/28 03:04:54 lha Exp $ */
+/* $Id: roken.h.in,v 1.182 2006/10/19 16:35:16 lha Exp $ */
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdarg.h>
-#ifdef HAVE_STDINT_H
 #include <stdint.h>
-#endif
 #include <string.h>
 #include <signal.h>
 
-#ifdef _AIX
-struct ether_addr;
-struct sockaddr_dl;
-#endif
-#ifdef HAVE_SYS_PARAM_H
 #include <sys/param.h>
-#endif
-#ifdef HAVE_INTTYPES_H
 #include <inttypes.h>
-#endif
-#ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_BITYPES_H
 #include <sys/bitypes.h>
-#endif
-#ifdef HAVE_BIND_BITYPES_H
-#include <bind/bitypes.h>
-#endif
-#ifdef HAVE_NETINET_IN6_MACHTYPES_H
-#include <netinet/in6_machtypes.h>
-#endif
-#ifdef HAVE_UNISTD_H
 #include <unistd.h>
-#endif
-#ifdef HAVE_SYS_SOCKET_H
 #include <sys/socket.h>
-#endif
-#ifdef HAVE_SYS_UIO_H
 #include <sys/uio.h>
-#endif
-#ifdef HAVE_GRP_H
 #include <grp.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
 #include <sys/stat.h>
-#endif
-#ifdef HAVE_NETINET_IN_H
 #include <netinet/in.h>
-#endif
-#ifdef HAVE_NETINET_IN6_H
-#include <netinet/in6.h>
-#endif
-#ifdef HAVE_NETINET6_IN6_H
-#include <netinet6/in6.h>
-#endif
-#ifdef HAVE_ARPA_INET_H
 #include <arpa/inet.h>
-#endif
-#ifdef HAVE_NETDB_H
 #include <netdb.h>
-#endif
-#ifdef HAVE_ARPA_NAMESER_H
 #include <arpa/nameser.h>
-#endif
-#ifdef HAVE_RESOLV_H
 #include <resolv.h>
-#endif
-#ifdef HAVE_SYSLOG_H
 #include <syslog.h>
-#endif
-#ifdef HAVE_FCNTL_H
 #include <fcntl.h>
-#endif
-#ifdef HAVE_ERRNO_H
 #include <errno.h>
-#endif
 #include <err.h>
-#ifdef HAVE_TERMIOS_H
 #include <termios.h>
-#endif
-#if defined(HAVE_SYS_IOCTL_H) && SunOS != 40
 #include <sys/ioctl.h>
-#endif
-#ifdef TIME_WITH_SYS_TIME
 #include <sys/time.h>
 #include <time.h>
-#elif defined(HAVE_SYS_TIME_H)
-#include <sys/time.h>
-#else
-#include <time.h>
-#endif
-#ifdef HAVE_STRINGS_H
 #include <strings.h>
-#endif
 
-#ifdef HAVE_PATHS_H
 #include <paths.h>
-#endif
 
-#ifndef HAVE_SSIZE_T
-typedef int ssize_t;
-#endif
 
 #include <roken-common.h>
 
 ROKEN_CPP_START
 
-#ifdef HAVE_UINTPTR_T
 #define rk_UNCONST(x) ((void *)(uintptr_t)(const void *)(x))
-#else
-#define rk_UNCONST(x) ((void *)(unsigned long)(const void *)(x))
-#endif
 
-#if !defined(HAVE_SETSID) && defined(HAVE__SETSID)
-#define setsid _setsid
-#endif
 
-#ifndef HAVE_PUTENV
-int ROKEN_LIB_FUNCTION putenv(const char *);
-#endif
 
-#if !defined(HAVE_SETENV) || defined(NEED_SETENV_PROTO)
-int ROKEN_LIB_FUNCTION setenv(const char *, const char *, int);
-#endif
 
-#if !defined(HAVE_UNSETENV) || defined(NEED_UNSETENV_PROTO)
-void ROKEN_LIB_FUNCTION unsetenv(const char *);
-#endif
 
-#if !defined(HAVE_GETUSERSHELL) || defined(NEED_GETUSERSHELL_PROTO)
-char * ROKEN_LIB_FUNCTION getusershell(void);
-void ROKEN_LIB_FUNCTION endusershell(void);
-#endif
 
-#if !defined(HAVE_SNPRINTF) || defined(NEED_SNPRINTF_PROTO)
-int ROKEN_LIB_FUNCTION snprintf (char *, size_t, const char *, ...)
-     __attribute__ ((format (printf, 3, 4)));
-#endif
 
-#if !defined(HAVE_VSNPRINTF) || defined(NEED_VSNPRINTF_PROTO)
-int ROKEN_LIB_FUNCTION 
-     vsnprintf (char *, size_t, const char *, va_list)
-     __attribute__((format (printf, 3, 0)));
-#endif
 
-#if !defined(HAVE_ASPRINTF) || defined(NEED_ASPRINTF_PROTO)
-int ROKEN_LIB_FUNCTION
-     asprintf (char **, const char *, ...)
-     __attribute__ ((format (printf, 2, 3)));
-#endif
 
-#if !defined(HAVE_VASPRINTF) || defined(NEED_VASPRINTF_PROTO)
-int ROKEN_LIB_FUNCTION
-    vasprintf (char **, const char *, va_list)
-     __attribute__((format (printf, 2, 0)));
-#endif
 
-#if !defined(HAVE_ASNPRINTF) || defined(NEED_ASNPRINTF_PROTO)
 int ROKEN_LIB_FUNCTION
     asnprintf (char **, size_t, const char *, ...)
      __attribute__ ((format (printf, 3, 4)));
-#endif
 
-#if !defined(HAVE_VASNPRINTF) || defined(NEED_VASNPRINTF_PROTO)
 int ROKEN_LIB_FUNCTION
     vasnprintf (char **, size_t, const char *, va_list)
      __attribute__((format (printf, 3, 0)));
-#endif
 
-#ifndef HAVE_STRDUP
-char * ROKEN_LIB_FUNCTION strdup(const char *);
-#endif
 
-#if !defined(HAVE_STRNDUP) || defined(NEED_STRNDUP_PROTO)
-char * ROKEN_LIB_FUNCTION strndup(const char *, size_t);
-#endif
 
-#ifndef HAVE_STRLWR
 char * ROKEN_LIB_FUNCTION strlwr(char *);
-#endif
 
-#ifndef HAVE_STRNLEN
-size_t ROKEN_LIB_FUNCTION strnlen(const char*, size_t);
-#endif
 
-#if !defined(HAVE_STRSEP) || defined(NEED_STRSEP_PROTO)
-char * ROKEN_LIB_FUNCTION strsep(char**, const char*);
-#endif
 
-#if !defined(HAVE_STRSEP_COPY) || defined(NEED_STRSEP_COPY_PROTO)
 ssize_t ROKEN_LIB_FUNCTION strsep_copy(const char**, const char*, char*, size_t);
-#endif
 
-#ifndef HAVE_STRCASECMP
-int ROKEN_LIB_FUNCTION strcasecmp(const char *, const char *);
-#endif
 
-#ifdef NEED_FCLOSE_PROTO
-int ROKEN_LIB_FUNCTION fclose(FILE *);
-#endif
 
-#ifdef NEED_STRTOK_R_PROTO
-char * ROKEN_LIB_FUNCTION strtok_r(char *, const char *, char **);
-#endif
 
-#ifndef HAVE_STRUPR
 char * ROKEN_LIB_FUNCTION strupr(char *);
-#endif
 
-#ifndef HAVE_STRLCPY
 size_t ROKEN_LIB_FUNCTION strlcpy (char *, const char *, size_t);
-#endif
 
-#ifndef HAVE_STRLCAT
 size_t ROKEN_LIB_FUNCTION strlcat (char *, const char *, size_t);
-#endif
 
-#ifndef HAVE_GETDTABLESIZE
-int ROKEN_LIB_FUNCTION getdtablesize(void);
-#endif
 
-#if !defined(HAVE_STRERROR) && !defined(strerror)
-char * ROKEN_LIB_FUNCTION strerror(int);
-#endif
 
-#if !defined(HAVE_HSTRERROR) || defined(NEED_HSTRERROR_PROTO)
-/* This causes a fatal error under Psoriasis */
-#if !(defined(SunOS) && (SunOS >= 50))
-const char * ROKEN_LIB_FUNCTION hstrerror(int);
-#endif
-#endif
 
-#if !HAVE_DECL_H_ERRNO
-extern int h_errno;
-#endif
 
-#if !defined(HAVE_INET_ATON) || defined(NEED_INET_ATON_PROTO)
-int ROKEN_LIB_FUNCTION inet_aton(const char *, struct in_addr *);
-#endif
 
-#ifndef HAVE_INET_NTOP
-const char * ROKEN_LIB_FUNCTION
-inet_ntop(int af, const void *src, char *dst, size_t size);
-#endif
 
-#ifndef HAVE_INET_PTON
-int ROKEN_LIB_FUNCTION
-inet_pton(int, const char *, void *);
-#endif
 
-#if !defined(HAVE_GETCWD)
-char* ROKEN_LIB_FUNCTION getcwd(char *, size_t);
-#endif
 
-#ifdef HAVE_PWD_H
 #include <pwd.h>
 struct passwd * ROKEN_LIB_FUNCTION k_getpwnam (const char *);
 struct passwd * ROKEN_LIB_FUNCTION k_getpwuid (uid_t);
-#endif
 
 const char * ROKEN_LIB_FUNCTION get_default_username (void);
 
-#ifndef HAVE_SETEUID
-int ROKEN_LIB_FUNCTION seteuid(uid_t);
-#endif
 
-#ifndef HAVE_SETEGID
-int ROKEN_LIB_FUNCTION setegid(gid_t);
-#endif
 
-#ifndef HAVE_LSTAT
-int ROKEN_LIB_FUNCTION lstat(const char *, struct stat *);
-#endif
 
-#if !defined(HAVE_MKSTEMP) || defined(NEED_MKSTEMP_PROTO)
 int ROKEN_LIB_FUNCTION mkstemp(char *);
-#endif
 
-#ifndef HAVE_CGETENT
 int ROKEN_LIB_FUNCTION cgetent(char **, char **, const char *);
 int ROKEN_LIB_FUNCTION cgetstr(char *, const char *, char **);
-#endif
 
-#ifndef HAVE_INITGROUPS
-int ROKEN_LIB_FUNCTION initgroups(const char *, gid_t);
-#endif
 
-#ifndef HAVE_FCHOWN
-int ROKEN_LIB_FUNCTION fchown(int, uid_t, gid_t);
-#endif
 
-#if !defined(HAVE_DAEMON) || defined(NEED_DAEMON_PROTO)
-int ROKEN_LIB_FUNCTION daemon(int, int);
-#endif
 
-#ifndef HAVE_INNETGR
-int ROKEN_LIB_FUNCTION innetgr(const char *, const char *, 
-           const char *, const char *);
-#endif
 
-#ifndef HAVE_CHOWN
-int ROKEN_LIB_FUNCTION chown(const char *, uid_t, gid_t);
-#endif
 
-#ifndef HAVE_RCMD
-int ROKEN_LIB_FUNCTION
-    rcmd(char **, unsigned short, const char *,
-        const char *, const char *, int *);
-#endif
-
-#if !defined(HAVE_INNETGR) || defined(NEED_INNETGR_PROTO)
-int ROKEN_LIB_FUNCTION innetgr(const char*, const char*,
-    const char*, const char*);
-#endif
-
-#ifndef HAVE_IRUSEROK
-int ROKEN_LIB_FUNCTION iruserok(unsigned, int, 
-    const char *, const char *);
-#endif
-
-#if !defined(HAVE_GETHOSTNAME) || defined(NEED_GETHOSTNAME_PROTO)
-int ROKEN_LIB_FUNCTION gethostname(char *, int);
-#endif
-
-#ifndef HAVE_WRITEV
-ssize_t ROKEN_LIB_FUNCTION
-writev(int, const struct iovec *, int);
-#endif
-
-#ifndef HAVE_READV
-ssize_t ROKEN_LIB_FUNCTION
-readv(int, const struct iovec *, int);
-#endif
-
-#ifndef HAVE_MKSTEMP
-int ROKEN_LIB_FUNCTION
-mkstemp(char *);
-#endif
 
-#ifndef HAVE_PIDFILE
+
+
+
+
+
+
 void ROKEN_LIB_FUNCTION pidfile (const char*);
-#endif
 
-#ifndef HAVE_BSWAP32
 unsigned int ROKEN_LIB_FUNCTION bswap32(unsigned int);
-#endif
 
-#ifndef HAVE_BSWAP16
 unsigned short ROKEN_LIB_FUNCTION bswap16(unsigned short);
-#endif
-
-#ifndef HAVE_FLOCK
-#ifndef LOCK_SH
-#define LOCK_SH   1            /* Shared lock */
-#endif
-#ifndef        LOCK_EX
-#define LOCK_EX   2            /* Exclusive lock */
-#endif
-#ifndef LOCK_NB
-#define LOCK_NB   4            /* Don't block when locking */
-#endif
-#ifndef LOCK_UN
-#define LOCK_UN   8            /* Unlock */
-#endif
-
-int flock(int fd, int operation);
-#endif /* HAVE_FLOCK */
+
 
 time_t ROKEN_LIB_FUNCTION tm2time (struct tm, int);
 
@@ -421,140 +174,30 @@ ssize_t ROKEN_LIB_FUNCTION net_read (int, void *, size_t);
 
 int ROKEN_LIB_FUNCTION issuid(void);
 
-#ifndef HAVE_STRUCT_WINSIZE
-struct winsize {
-       unsigned short ws_row, ws_col;
-       unsigned short ws_xpixel, ws_ypixel;
-};
-#endif
 
 int ROKEN_LIB_FUNCTION get_window_size(int fd, struct winsize *);
 
-#ifndef HAVE_VSYSLOG
-void ROKEN_LIB_FUNCTION vsyslog(int, const char *, va_list);
-#endif
-
-#if !HAVE_DECL_OPTARG
-extern char *optarg;
-#endif
-#if !HAVE_DECL_OPTIND
-extern int optind;
-#endif
-#if !HAVE_DECL_OPTERR
-extern int opterr;
-#endif
-
-#if !HAVE_DECL_ENVIRON
-extern char **environ;
-#endif
-
-#ifndef HAVE_GETIPNODEBYNAME
+
+
+
 struct hostent * ROKEN_LIB_FUNCTION
 getipnodebyname (const char *, int, int, int *);
-#endif
 
-#ifndef HAVE_GETIPNODEBYADDR
 struct hostent * ROKEN_LIB_FUNCTION
 getipnodebyaddr (const void *, size_t, int, int *);
-#endif
 
-#ifndef HAVE_FREEHOSTENT
 void ROKEN_LIB_FUNCTION
 freehostent (struct hostent *);
-#endif
 
-#ifndef HAVE_COPYHOSTENT
 struct hostent * ROKEN_LIB_FUNCTION
 copyhostent (const struct hostent *);
-#endif
 
-#ifndef HAVE_SOCKLEN_T
-typedef int socklen_t;
-#endif
 
-#ifndef HAVE_STRUCT_SOCKADDR_STORAGE
 
-#ifndef HAVE_SA_FAMILY_T
-typedef unsigned short sa_family_t;
-#endif
 
-#ifdef HAVE_IPV6
-#define _SS_MAXSIZE sizeof(struct sockaddr_in6)
-#else
-#define _SS_MAXSIZE sizeof(struct sockaddr_in)
-#endif
 
-#define _SS_ALIGNSIZE  sizeof(unsigned long)
 
-#if HAVE_STRUCT_SOCKADDR_SA_LEN
 
-typedef unsigned char roken_sa_family_t;
-
-#define _SS_PAD1SIZE   ((2 * _SS_ALIGNSIZE - sizeof (roken_sa_family_t) - sizeof(unsigned char)) % _SS_ALIGNSIZE)
-#define _SS_PAD2SIZE   (_SS_MAXSIZE - (sizeof (roken_sa_family_t) + sizeof(unsigned char) + _SS_PAD1SIZE + _SS_ALIGNSIZE))
-
-struct sockaddr_storage {
-    unsigned char      ss_len;
-    roken_sa_family_t  ss_family;
-    char               __ss_pad1[_SS_PAD1SIZE];
-    unsigned long      __ss_align[_SS_PAD2SIZE / sizeof(unsigned long) + 1];
-};
-
-#else /* !HAVE_STRUCT_SOCKADDR_SA_LEN */
-
-typedef unsigned short roken_sa_family_t;
-
-#define _SS_PAD1SIZE   ((2 * _SS_ALIGNSIZE - sizeof (roken_sa_family_t)) % _SS_ALIGNSIZE)
-#define _SS_PAD2SIZE   (_SS_MAXSIZE - (sizeof (roken_sa_family_t) + _SS_PAD1SIZE + _SS_ALIGNSIZE))
-
-struct sockaddr_storage {
-    roken_sa_family_t  ss_family;
-    char               __ss_pad1[_SS_PAD1SIZE];
-    unsigned long      __ss_align[_SS_PAD2SIZE / sizeof(unsigned long) + 1];
-};
-
-#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
-
-#endif /* HAVE_STRUCT_SOCKADDR_STORAGE */
-
-#ifndef HAVE_STRUCT_ADDRINFO
-struct addrinfo {
-    int    ai_flags;
-    int    ai_family;
-    int    ai_socktype;
-    int    ai_protocol;
-    size_t ai_addrlen;
-    char  *ai_canonname;
-    struct sockaddr *ai_addr;
-    struct addrinfo *ai_next;
-};
-#endif
-
-#ifndef HAVE_GETADDRINFO
-int ROKEN_LIB_FUNCTION
-getaddrinfo(const char *,
-           const char *,
-           const struct addrinfo *,
-           struct addrinfo **);
-#endif
-
-#ifndef HAVE_GETNAMEINFO
-int ROKEN_LIB_FUNCTION
-getnameinfo(const struct sockaddr *, socklen_t,
-               char *, size_t,
-               char *, size_t,
-               int);
-#endif
-
-#ifndef HAVE_FREEADDRINFO
-void ROKEN_LIB_FUNCTION
-freeaddrinfo(struct addrinfo *);
-#endif
-
-#ifndef HAVE_GAI_STRERROR
-const char * ROKEN_LIB_FUNCTION
-gai_strerror(int);
-#endif
 
 int ROKEN_LIB_FUNCTION
 getnameinfo_verified(const struct sockaddr *, socklen_t,
@@ -567,130 +210,68 @@ roken_getaddrinfo_hostspec(const char *, int, struct addrinfo **);
 int ROKEN_LIB_FUNCTION
 roken_getaddrinfo_hostspec2(const char *, int, int, struct addrinfo **);
 
-#ifndef HAVE_STRFTIME
-size_t ROKEN_LIB_FUNCTION
-strftime (char *, size_t, const char *, const struct tm *);
-#endif
 
-#ifndef HAVE_STRPTIME
-char * ROKEN_LIB_FUNCTION
-strptime (const char *, const char *, struct tm *);
-#endif
 
-#ifndef HAVE_EMALLOC
 void * ROKEN_LIB_FUNCTION emalloc (size_t);
-#endif
-#ifndef HAVE_ECALLOC
 void * ROKEN_LIB_FUNCTION ecalloc(size_t, size_t);
-#endif
-#ifndef HAVE_EREALLOC
 void * ROKEN_LIB_FUNCTION erealloc (void *, size_t);
-#endif
-#ifndef HAVE_ESTRDUP
 char * ROKEN_LIB_FUNCTION estrdup (const char *);
-#endif
 
 /*
  * kludges and such
  */
 
-#if 1
 int ROKEN_LIB_FUNCTION
 roken_gethostby_setup(const char*, const char*);
 struct hostent* ROKEN_LIB_FUNCTION
 roken_gethostbyname(const char*);
 struct hostent* ROKEN_LIB_FUNCTION 
 roken_gethostbyaddr(const void*, size_t, int);
-#else
-#ifdef GETHOSTBYNAME_PROTO_COMPATIBLE
-#define roken_gethostbyname(x) gethostbyname(x)
-#else
-#define roken_gethostbyname(x) gethostbyname((char *)x)
-#endif
-
-#ifdef GETHOSTBYADDR_PROTO_COMPATIBLE
-#define roken_gethostbyaddr(a, l, t) gethostbyaddr(a, l, t)
-#else
-#define roken_gethostbyaddr(a, l, t) gethostbyaddr((char *)a, l, t)
-#endif
-#endif
-
-#ifdef GETSERVBYNAME_PROTO_COMPATIBLE
+
 #define roken_getservbyname(x,y) getservbyname(x,y)
-#else
-#define roken_getservbyname(x,y) getservbyname((char *)x, (char *)y)
-#endif
 
-#ifdef OPENLOG_PROTO_COMPATIBLE
 #define roken_openlog(a,b,c) openlog(a,b,c)
-#else
-#define roken_openlog(a,b,c) openlog((char *)a,b,c)
-#endif
 
-#ifdef GETSOCKNAME_PROTO_COMPATIBLE
 #define roken_getsockname(a,b,c) getsockname(a,b,c)
-#else
-#define roken_getsockname(a,b,c) getsockname(a, b, (void*)c)
-#endif
 
-#ifndef HAVE_SETPROGNAME
 void ROKEN_LIB_FUNCTION setprogname(const char *);
-#endif
 
-#ifndef HAVE_GETPROGNAME
 const char * ROKEN_LIB_FUNCTION getprogname(void);
-#endif
 
-#if !defined(HAVE_SETPROGNAME) && !defined(HAVE_GETPROGNAME) && !HAVE_DECL___PROGNAME
 extern const char *__progname;
-#endif
 
 void ROKEN_LIB_FUNCTION mini_inetd_addrinfo (struct addrinfo*);
 void ROKEN_LIB_FUNCTION mini_inetd (int);
 
-#ifndef HAVE_LOCALTIME_R
-struct tm * ROKEN_LIB_FUNCTION
-localtime_r(const time_t *, struct tm *);
-#endif
 
-#if !defined(HAVE_STRSVIS) || defined(NEED_STRSVIS_PROTO)
 int ROKEN_LIB_FUNCTION
 strsvis(char *, const char *, int, const char *);
-#endif
 
-#if !defined(HAVE_STRUNVIS) || defined(NEED_STRUNVIS_PROTO)
 int ROKEN_LIB_FUNCTION
 strunvis(char *, const char *);
-#endif
 
-#if !defined(HAVE_STRVIS) || defined(NEED_STRVIS_PROTO)
 int ROKEN_LIB_FUNCTION
 strvis(char *, const char *, int);
-#endif
 
-#if !defined(HAVE_STRVISX) || defined(NEED_STRVISX_PROTO)
 int ROKEN_LIB_FUNCTION
 strvisx(char *, const char *, size_t, int);
-#endif
 
-#if !defined(HAVE_SVIS) || defined(NEED_SVIS_PROTO)
 char * ROKEN_LIB_FUNCTION
 svis(char *, int, int, int, const char *);
-#endif
 
-#if !defined(HAVE_UNVIS) || defined(NEED_UNVIS_PROTO)
 int ROKEN_LIB_FUNCTION
 unvis(char *, int, int *, int);
-#endif
 
-#if !defined(HAVE_VIS) || defined(NEED_VIS_PROTO)
 char * ROKEN_LIB_FUNCTION
 vis(char *, int, int, int);
-#endif
 
-#if !defined(HAVE_CLOSEFROM)
 int ROKEN_LIB_FUNCTION
 closefrom(int);
-#endif
+
+
+#include <socket_wrapper.h>
 
 ROKEN_CPP_END
+#define ROKEN_VERSION 0.8pre-samba
+
+#endif /* __ROKEN_H__ */
index c13e8d4ee1ba4ad2c2018379e168c2c9838351bc..315fa52e503807e249ba345e5953256ece2e00ae 100644 (file)
@@ -36,7 +36,7 @@
 RCSID("$Id: setprogname.c,v 1.4 2005/08/23 10:19:20 lha Exp $");
 #endif
 
-#include <roken.h>
+#include "roken.h"
 
 #ifndef HAVE___PROGNAME
 extern const char *__progname;
index 7076847fb3577fc8e7d3488a0cfcd2927cbcae3d..d92742d9fbbc042c36e33dbcfeb4f80e8235c3f4 100644 (file)
@@ -37,7 +37,7 @@ RCSID("$Id: signal.c,v 1.13 2005/04/12 11:29:05 lha Exp $");
 #endif
 
 #include <signal.h>
-#include <roken.h>
+#include "roken.h"
 
 /*
  * We would like to always use this signal but there is a link error
index f08c33b7a5e0577f54fe7cc2f29d5e6911141a4f..e34c10fe266287ed24075b595b8fe77f4a7ab29b 100644 (file)
@@ -38,7 +38,7 @@ RCSID("$Id: strsep.c,v 1.4 2005/04/12 11:29:10 lha Exp $");
 
 #include <string.h>
 
-#include <roken.h>
+#include "roken.h"
 
 #ifndef HAVE_STRSEP
 
index 34759fe15c98c1d6fe2c4d5aa5db509543fa46fb..5149838547625884e3a833c665c0a379a64a4b72 100644 (file)
@@ -38,7 +38,7 @@ RCSID("$Id: strsep_copy.c,v 1.5 2005/04/12 11:29:11 lha Exp $");
 
 #include <string.h>
 
-#include <roken.h>
+#include "roken.h"
 
 #ifndef HAVE_STRSEP_COPY
 
index 9c4a65976b25494813e9422aad1eb818d0664d04..74a77d041bcc8cf93fbcd8a47fb7412f3a8930b8 100755 (executable)
@@ -7,7 +7,7 @@ use File::Basename;
 
 my $file = shift;
 my $prefix = shift;
-my $options = shift;
+my $options = join(' ', @ARGV);
 my $x_file;
 my @x_files = ();
 my $c_file;
@@ -24,7 +24,7 @@ my $header = "$dirname/$prefix.h";
 
 print "$header: $file bin/asn1_compile\n";
 print "\t\@echo \"Compiling ASN1 file $file\"\n";
-print "\t\@cd $dirname && ../../../bin/asn1_compile $options $basename $prefix\n\n";
+print "\t\@startdir=`pwd` && cd $dirname && " . ' $$startdir/bin/asn1_compile ' . "$options $basename $prefix\n\n";
 
 open(IN,$file) or die("Can't open $file: $!");
 foreach(<IN>) {
index e955c28fa689714aa0a432a02cf566b9cac5ce06..cd476765b3b53ec61cc019f9765e0fe88333d0e6 100644 (file)
@@ -5,14 +5,26 @@ CFLAGS = -Iheimdal_build -Iheimdal/kdc
 OBJ_FILES = \
        ../heimdal/kdc/default_config.o \
        ../heimdal/kdc/kerberos5.o \
+       ../heimdal/kdc/krb5tgs.o \
        ../heimdal/kdc/pkinit.o \
        ../heimdal/kdc/log.o \
        ../heimdal/kdc/misc.o \
        ../heimdal/kdc/524.o \
        ../heimdal/kdc/kerberos4.o \
        ../heimdal/kdc/kaserver.o \
-       ../heimdal/kdc/process.o
-PRIVATE_DEPENDENCIES = HEIMDAL_ROKEN HEIMDAL_KRB5 HEIMDAL_HDB
+       ../heimdal/kdc/digest.o \
+       ../heimdal/kdc/process.o \
+       ../heimdal/lib/asn1/asn1_DigestREQ.o \
+       ../heimdal/lib/asn1/asn1_DigestRequest.o \
+       ../heimdal/lib/asn1/asn1_DigestInit.o \
+       ../heimdal/lib/asn1/asn1_DigestReqInner.o \
+       ../heimdal/lib/asn1/asn1_DigestREP.o \
+       ../heimdal/lib/asn1/asn1_DigestRepInner.o \
+       ../heimdal/lib/asn1/asn1_DigestResponse.o \
+       ../heimdal/lib/asn1/asn1_DigestInitReply.o \
+       ../heimdal/lib/asn1/asn1_DigestError.o \
+       ../heimdal/lib/asn1/asn1_KRB5SignedPath.o
+PRIVATE_DEPENDENCIES = HEIMDAL_ROKEN HEIMDAL_KRB5 HEIMDAL_HDB HEIMDAL_ASN1 HEIMDAL_DES
 # End SUBSYSTEM HEIMDAL_KDC
 #######################
 
@@ -42,61 +54,136 @@ OBJ_FILES = \
        ../heimdal/lib/hdb/asn1_HDB_Ext_Constrained_delegation_acl.o \
        ../heimdal/lib/hdb/asn1_HDB_Ext_Lan_Manager_OWF.o \
        ../heimdal/lib/hdb/asn1_HDB_Ext_PKINIT_acl.o \
-       ../heimdal/lib/hdb/asn1_HDB_Ext_PKINIT_certificate.o \
+       ../heimdal/lib/hdb/asn1_HDB_Ext_PKINIT_hash.o \
        ../heimdal/lib/hdb/asn1_HDB_Ext_Password.o \
        ../heimdal/lib/hdb/asn1_HDB_extension.o \
        ../heimdal/lib/hdb/asn1_HDB_extensions.o \
        ../heimdal/lib/hdb/asn1_hdb_entry.o \
        ../heimdal/lib/hdb/hdb_err.o
-PUBLIC_DEPENDENCIES = HDB_LDB HEIMDAL_HDB_KEYS HEIMDAL_ROKEN
+PRIVATE_DEPENDENCIES = HDB_LDB HEIMDAL_HDB_KEYS HEIMDAL_ROKEN
 # End SUBSYSTEM HEIMDAL_HDB
 #######################
 
 #######################
 # Start SUBSYSTEM HEIMDAL_GSSAPI
 [SUBSYSTEM::HEIMDAL_GSSAPI]
-CFLAGS = -Iheimdal_build -Iheimdal/lib/gssapi
+CFLAGS = -Iheimdal_build -Iheimdal/lib/gssapi/spnego -Iheimdal/lib/gssapi -Iheimdal/lib/gssapi/krb5 -I heimdal/lib/gssapi/mech
 OBJ_FILES = \
-       ../heimdal/lib/gssapi/init_sec_context.o \
-       ../heimdal/lib/gssapi/inquire_cred.o \
-       ../heimdal/lib/gssapi/release_buffer.o \
-       ../heimdal/lib/gssapi/release_cred.o \
-       ../heimdal/lib/gssapi/release_name.o \
-       ../heimdal/lib/gssapi/release_oid_set.o \
-       ../heimdal/lib/gssapi/sequence.o \
-       ../heimdal/lib/gssapi/test_oid_set_member.o \
-       ../heimdal/lib/gssapi/unwrap.o \
-       ../heimdal/lib/gssapi/verify_mic.o \
-       ../heimdal/lib/gssapi/wrap.o \
-       ../heimdal/lib/gssapi/address_to_krb5addr.o \
-       ../heimdal/lib/gssapi/asn1_ContextFlags.o \
-       ../heimdal/lib/gssapi/asn1_MechType.o \
-       ../heimdal/lib/gssapi/asn1_MechTypeList.o \
-       ../heimdal/lib/gssapi/asn1_NegotiationToken.o \
-       ../heimdal/lib/gssapi/asn1_NegTokenInit.o \
-       ../heimdal/lib/gssapi/asn1_NegTokenTarg.o \
-       ../heimdal/lib/gssapi/8003.o \
-       ../heimdal/lib/gssapi/accept_sec_context.o \
-       ../heimdal/lib/gssapi/acquire_cred.o \
-       ../heimdal/lib/gssapi/add_oid_set_member.o \
-       ../heimdal/lib/gssapi/arcfour.o \
-       ../heimdal/lib/gssapi/ccache_name.o \
-       ../heimdal/lib/gssapi/copy_ccache.o \
-       ../heimdal/lib/gssapi/cfx.o \
-       ../heimdal/lib/gssapi/compat.o \
-       ../heimdal/lib/gssapi/context_time.o \
-       ../heimdal/lib/gssapi/create_emtpy_oid_set.o \
-       ../heimdal/lib/gssapi/decapsulate.o \
-       ../heimdal/lib/gssapi/delete_sec_context.o \
-       ../heimdal/lib/gssapi/display_name.o \
-       ../heimdal/lib/gssapi/display_status.o \
-       ../heimdal/lib/gssapi/duplicate_name.o \
-       ../heimdal/lib/gssapi/encapsulate.o \
-       ../heimdal/lib/gssapi/external.o \
-       ../heimdal/lib/gssapi/get_mic.o \
-       ../heimdal/lib/gssapi/import_name.o \
-       ../heimdal/lib/gssapi/init.o
-PUBLIC_DEPENDENCIES = HEIMDAL_KRB5 
+       ../heimdal/lib/gssapi/mech/gss_krb5.o \
+       ../heimdal/lib/gssapi/mech/gss_mech_switch.o \
+       ../heimdal/lib/gssapi/mech/gss_process_context_token.o \
+       ../heimdal/lib/gssapi/mech/gss_buffer_set.o \
+       ../heimdal/lib/gssapi/mech/gss_add_cred.o \
+       ../heimdal/lib/gssapi/mech/gss_add_oid_set_member.o \
+       ../heimdal/lib/gssapi/mech/gss_compare_name.o \
+       ../heimdal/lib/gssapi/mech/gss_release_oid_set.o \
+       ../heimdal/lib/gssapi/mech/gss_create_empty_oid_set.o \
+       ../heimdal/lib/gssapi/mech/gss_decapsulate_token.o \
+       ../heimdal/lib/gssapi/mech/gss_inquire_cred_by_oid.o \
+       ../heimdal/lib/gssapi/mech/gss_canonicalize_name.o \
+       ../heimdal/lib/gssapi/mech/gss_inquire_sec_context_by_oid.o \
+       ../heimdal/lib/gssapi/mech/gss_inquire_names_for_mech.o \
+../heimdal/lib/gssapi/mech/gss_inquire_mechs_for_name.o \
+../heimdal/lib/gssapi/mech/gss_wrap_size_limit.o \
+../heimdal/lib/gssapi/mech/gss_names.o \
+../heimdal/lib/gssapi/mech/gss_verify.o \
+../heimdal/lib/gssapi/mech/gss_display_name.o \
+../heimdal/lib/gssapi/mech/gss_duplicate_oid.o \
+../heimdal/lib/gssapi/mech/gss_display_status.o \
+../heimdal/lib/gssapi/mech/gss_release_buffer.o \
+../heimdal/lib/gssapi/mech/gss_release_oid.o \
+../heimdal/lib/gssapi/mech/gss_test_oid_set_member.o \
+../heimdal/lib/gssapi/mech/gss_release_cred.o \
+../heimdal/lib/gssapi/mech/gss_set_sec_context_option.o \
+../heimdal/lib/gssapi/mech/gss_export_name.o \
+../heimdal/lib/gssapi/mech/gss_seal.o \
+../heimdal/lib/gssapi/mech/mech_switch.h \
+../heimdal/lib/gssapi/mech/gss_acquire_cred.o \
+../heimdal/lib/gssapi/mech/gss_unseal.o \
+../heimdal/lib/gssapi/mech/gss_verify_mic.o \
+../heimdal/lib/gssapi/mech/gss_accept_sec_context.o \
+../heimdal/lib/gssapi/mech/gss_inquire_cred_by_mech.o \
+../heimdal/lib/gssapi/mech/gss_indicate_mechs.o \
+../heimdal/lib/gssapi/mech/gss_delete_sec_context.o \
+../heimdal/lib/gssapi/mech/gss_sign.o \
+../heimdal/lib/gssapi/mech/gss_utils.o \
+../heimdal/lib/gssapi/mech/gss_init_sec_context.o \
+../heimdal/lib/gssapi/mech/gss_oid_equal.o \
+../heimdal/lib/gssapi/mech/gss_context_time.o \
+../heimdal/lib/gssapi/mech/gss_encapsulate_token.o \
+../heimdal/lib/gssapi/mech/gss_get_mic.o \
+../heimdal/lib/gssapi/mech/gss_import_sec_context.o \
+../heimdal/lib/gssapi/mech/gss_inquire_cred.o \
+../heimdal/lib/gssapi/mech/gss_wrap.o \
+../heimdal/lib/gssapi/mech/gss_import_name.o \
+../heimdal/lib/gssapi/mech/gss_duplicate_name.o \
+../heimdal/lib/gssapi/mech/gss_unwrap.o \
+../heimdal/lib/gssapi/mech/gss_export_sec_context.o \
+../heimdal/lib/gssapi/mech/gss_inquire_context.o \
+../heimdal/lib/gssapi/mech/gss_release_name.o \
+../heimdal/lib/gssapi/mech/gss_set_cred_option.o \
+../heimdal/lib/gssapi/mech/asn1_GSSAPIContextToken.o \
+       ../heimdal/lib/gssapi/spnego/init_sec_context.o \
+       ../heimdal/lib/gssapi/spnego/external.o \
+       ../heimdal/lib/gssapi/spnego/compat.o \
+       ../heimdal/lib/gssapi/spnego/context_stubs.o \
+       ../heimdal/lib/gssapi/spnego/cred_stubs.o \
+       ../heimdal/lib/gssapi/spnego/accept_sec_context.o \
+       ../heimdal/lib/gssapi/spnego/asn1_ContextFlags.o \
+       ../heimdal/lib/gssapi/spnego/asn1_MechType.o \
+       ../heimdal/lib/gssapi/spnego/asn1_MechTypeList.o \
+       ../heimdal/lib/gssapi/spnego/asn1_NegHints.o \
+       ../heimdal/lib/gssapi/spnego/asn1_NegTokenInit.o \
+       ../heimdal/lib/gssapi/spnego/asn1_NegTokenResp.o \
+       ../heimdal/lib/gssapi/krb5/copy_ccache.o \
+       ../heimdal/lib/gssapi/krb5/delete_sec_context.o \
+       ../heimdal/lib/gssapi/krb5/init_sec_context.o \
+       ../heimdal/lib/gssapi/krb5/context_time.o \
+       ../heimdal/lib/gssapi/krb5/init.o \
+       ../heimdal/lib/gssapi/krb5/address_to_krb5addr.o \
+       ../heimdal/lib/gssapi/krb5/get_mic.o \
+       ../heimdal/lib/gssapi/krb5/inquire_context.o \
+       ../heimdal/lib/gssapi/krb5/add_cred.o \
+       ../heimdal/lib/gssapi/krb5/inquire_cred.o \
+       ../heimdal/lib/gssapi/krb5/inquire_cred_by_oid.o \
+       ../heimdal/lib/gssapi/krb5/inquire_cred_by_mech.o \
+       ../heimdal/lib/gssapi/krb5/inquire_mechs_for_name.o \
+       ../heimdal/lib/gssapi/krb5/inquire_names_for_mech.o \
+       ../heimdal/lib/gssapi/krb5/indicate_mechs.o \
+       ../heimdal/lib/gssapi/krb5/inquire_sec_context_by_oid.o \
+       ../heimdal/lib/gssapi/krb5/export_sec_context.o \
+       ../heimdal/lib/gssapi/krb5/import_sec_context.o \
+       ../heimdal/lib/gssapi/krb5/duplicate_name.o \
+       ../heimdal/lib/gssapi/krb5/import_name.o \
+       ../heimdal/lib/gssapi/krb5/compare_name.o \
+       ../heimdal/lib/gssapi/krb5/export_name.o \
+       ../heimdal/lib/gssapi/krb5/canonicalize_name.o \
+       ../heimdal/lib/gssapi/krb5/unwrap.o \
+       ../heimdal/lib/gssapi/krb5/wrap.o \
+       ../heimdal/lib/gssapi/krb5/release_name.o \
+       ../heimdal/lib/gssapi/krb5/cfx.o \
+       ../heimdal/lib/gssapi/krb5/add_oid_set_member.o \
+       ../heimdal/lib/gssapi/krb5/release_oid_set.o \
+       ../heimdal/lib/gssapi/krb5/create_emtpy_oid_set.o \
+       ../heimdal/lib/gssapi/krb5/8003.o \
+       ../heimdal/lib/gssapi/krb5/arcfour.o \
+       ../heimdal/lib/gssapi/krb5/encapsulate.o \
+       ../heimdal/lib/gssapi/krb5/display_name.o \
+       ../heimdal/lib/gssapi/krb5/sequence.o \
+       ../heimdal/lib/gssapi/krb5/display_status.o \
+       ../heimdal/lib/gssapi/krb5/release_buffer.o \
+       ../heimdal/lib/gssapi/krb5/test_oid_set_member.o \
+       ../heimdal/lib/gssapi/krb5/external.o \
+       ../heimdal/lib/gssapi/krb5/compat.o \
+       ../heimdal/lib/gssapi/krb5/acquire_cred.o \
+       ../heimdal/lib/gssapi/krb5/release_cred.o \
+       ../heimdal/lib/gssapi/krb5/set_cred_option.o \
+       ../heimdal/lib/gssapi/krb5/decapsulate.o \
+       ../heimdal/lib/gssapi/krb5/verify_mic.o \
+       ../heimdal/lib/gssapi/krb5/accept_sec_context.o \
+       ../heimdal/lib/gssapi/krb5/set_sec_context_option.o \
+       ../heimdal/lib/gssapi/krb5/process_context_token.o
+PRIVATE_DEPENDENCIES = HEIMDAL_KRB5 HEIMDAL_ROKEN HEIMDAL_DES HEIMDAL_ASN1 HEIMDAL_GLUE 
 # End SUBSYSTEM HEIMDAL_GSSAPI
 #######################
 
@@ -202,8 +289,9 @@ OBJ_FILES = \
        ../heimdal/lib/asn1/der_length.o \
        ../heimdal/lib/asn1/der_copy.o \
        ../heimdal/lib/asn1/der_cmp.o \
+       ../heimdal/lib/asn1/extra.o \
+       ../heimdal/lib/asn1/timegm.o \
        ../heimdal/lib/asn1/asn1_AD_IF_RELEVANT.o \
-       ../heimdal/lib/asn1/asn1_AD_KDCIssued.o \
        ../heimdal/lib/asn1/asn1_APOptions.o \
        ../heimdal/lib/asn1/asn1_AP_REP.o \
        ../heimdal/lib/asn1/asn1_AP_REQ.o \
@@ -211,7 +299,7 @@ OBJ_FILES = \
        ../heimdal/lib/asn1/asn1_AS_REQ.o \
        ../heimdal/lib/asn1/asn1_Authenticator.o \
        ../heimdal/lib/asn1/asn1_AuthorizationData.o \
-       ../heimdal/lib/asn1/asn1_CBCParameter.o \
+       ../heimdal/lib/asn1/asn1_AuthorizationDataElement.o \
        ../heimdal/lib/asn1/asn1_CKSUMTYPE.o \
        ../heimdal/lib/asn1/asn1_ChangePasswdDataMS.o \
        ../heimdal/lib/asn1/asn1_Checksum.o \
@@ -251,15 +339,17 @@ OBJ_FILES = \
        ../heimdal/lib/asn1/asn1_PA_DATA.o \
        ../heimdal/lib/asn1/asn1_PA_ENC_TS_ENC.o \
        ../heimdal/lib/asn1/asn1_PA_PAC_REQUEST.o \
+       ../heimdal/lib/asn1/asn1_PA_S4U2Self.o \
        ../heimdal/lib/asn1/asn1_Principal.o \
        ../heimdal/lib/asn1/asn1_PrincipalName.o \
-       ../heimdal/lib/asn1/asn1_RC2CBCParameter.o \
        ../heimdal/lib/asn1/asn1_Realm.o \
        ../heimdal/lib/asn1/asn1_TGS_REP.o \
        ../heimdal/lib/asn1/asn1_TGS_REQ.o \
        ../heimdal/lib/asn1/asn1_Ticket.o \
        ../heimdal/lib/asn1/asn1_TicketFlags.o \
        ../heimdal/lib/asn1/asn1_TransitedEncoding.o \
+       ../heimdal/lib/asn1/asn1_KRB5SignedPathData.o \
+       ../heimdal/lib/asn1/asn1_KRB5SignedPathPrincipals.o \
        ../heimdal/lib/asn1/asn1_err.o \
        ../heimdal/lib/asn1/asn1_krb5int32.o \
        ../heimdal/lib/asn1/asn1_krb5uint32.o
@@ -287,6 +377,8 @@ OBJ_FILES = \
        ../heimdal/lib/des/ui.o \
        ../heimdal/lib/des/evp.o \
        ../heimdal/lib/des/pkcs5.o \
+       ../heimdal/lib/des/rand.o \
+       ../heimdal/lib/des/rand-unix.o \
        ../heimdal/lib/des/hmac.o
 # End SUBSYSTEM HEIMDAL_DES
 #######################
@@ -294,19 +386,19 @@ OBJ_FILES = \
 #######################
 # Start SUBSYSTEM HEIMDAL_ROKEN_GAI_STRERROR
 [SUBSYSTEM::HEIMDAL_ROKEN_GAI_STRERROR]
-CFLAGS = -Iheimdal_build -Iheimdal/lib/roken
+CFLAGS = -Iheimdal_build -Iheimdal/lib/roken  -Ilib/socket_wrapper
 OBJ_FILES = ../heimdal/lib/roken/gai_strerror.o
 
 [SUBSYSTEM::HEIMDAL_ROKEN_INET_ATON]
-CFLAGS = -Iheimdal_build -Iheimdal/lib/roken
+CFLAGS = -Iheimdal_build -Iheimdal/lib/roken  -Ilib/socket_wrapper
 OBJ_FILES = ../heimdal/lib/roken/inet_aton.o
 
 [SUBSYSTEM::HEIMDAL_ROKEN_GETPROGNAME]
-CFLAGS = -Iheimdal_build -Iheimdal/lib/roken
+CFLAGS = -Iheimdal_build -Iheimdal/lib/roken  -Ilib/socket_wrapper
 OBJ_FILES = ../heimdal/lib/roken/getprogname.o
 
-[SUBSYSTEM::HEIMDAL_ROKEN_GETPROGNAME_H]
-CFLAGS = -Iheimdal_build -Iheimdal/lib/roken
+[SUBSYSTEM::HEIMDAL_ROKEN_GETPROGNAME_H] 
+CFLAGS = -Iheimdal_build -Iheimdal/lib/roken  -Ilib/socket_wrapper
 OBJ_FILES = ../heimdal/lib/roken/getprogname.ho
 
 #######################
@@ -326,7 +418,7 @@ PRIVATE_DEPENDENCIES = EXT_SOCKET
 #######################
 # Start SUBSYSTEM HEIMDAL_ROKEN
 [SUBSYSTEM::HEIMDAL_ROKEN]
-CFLAGS =  -Iheimdal_build -Iheimdal/lib/roken
+CFLAGS =  -Iheimdal_build -Iheimdal/lib/roken -Ilib/socket_wrapper
 OBJ_FILES = \
        ../heimdal/lib/roken/base64.o \
        ../heimdal/lib/roken/hex.o \
@@ -347,6 +439,7 @@ OBJ_FILES = \
        ../heimdal/lib/roken/strsep.o \
        ../heimdal/lib/roken/strupr.o \
        ../heimdal/lib/roken/strpool.o \
+       ../heimdal/lib/roken/estrdup.o \
        replace.o
 PUBLIC_DEPENDENCIES = \
                        HEIMDAL_ROKEN_ADDRINFO \
@@ -363,7 +456,7 @@ PUBLIC_DEPENDENCIES = \
 #######################
 # Start SUBSYSTEM HEIMDAL_GLUE
 [SUBSYSTEM::HEIMDAL_GLUE]
-CFLAGS = -Iheimdal_build -Iheimdal/lib/krb5 -Iheimdal/lib/asn1 -Iheimdal/lib/com_err
+CFLAGS = -Iheimdal_build -Iheimdal/lib/krb5 -Iheimdal/lib/asn1 -Iheimdal/lib/com_err 
 OBJ_FILES = glue.o
 PUBLIC_DEPENDENCIES = LIBNETIF
 # End SUBSYSTEM HEIMDAL_GLUE
@@ -383,7 +476,7 @@ PRIVATE_DEPENDENCIES = HEIMDAL_ROKEN
 #######################
 # Start SUBSYSTEM HEIMDAL_ASN1_COMPILE_LEX
 [SUBSYSTEM::HEIMDAL_ASN1_COMPILE_LEX]
-CFLAGS = -Iheimdal_build -Iheimdal/lib/asn1 -Iheimdal/lib/roken
+CFLAGS = -Iheimdal_build -Iheimdal/lib/asn1 -Iheimdal/lib/roken  -Ilib/socket_wrapper
 OBJ_FILES = ../heimdal/lib/asn1/lex.ho 
 # End SUBSYSTEM HEIMDAL_ASN1_COMPILE_LEX
 #######################
@@ -402,6 +495,7 @@ OBJ_FILES = \
        ../heimdal/lib/asn1/gen_free.ho \
        ../heimdal/lib/asn1/gen_glue.ho \
        ../heimdal/lib/asn1/gen_length.ho \
+       ../heimdal/lib/asn1/gen_seq.ho \
        ../heimdal/lib/asn1/hash.ho \
        ../heimdal/lib/asn1/parse.ho \
        ../heimdal/lib/roken/emalloc.ho \
@@ -421,7 +515,7 @@ PRIVATE_DEPENDENCIES = HEIMDAL_ASN1_COMPILE_LEX HEIMDAL_ROKEN_GETPROGNAME_H
 #######################
 # Start SUBSYSTEM HEIMDAL_COM_ERR_COMPILE_LEX
 [SUBSYSTEM::HEIMDAL_COM_ERR_COMPILE_LEX]
-CFLAGS = -Iheimdal_build -Iheimdal/lib/com_err -Iheimdal/lib/roken
+CFLAGS = -Iheimdal_build -Iheimdal/lib/com_err -Iheimdal/lib/roken  -Ilib/socket_wrapper
 OBJ_FILES = ../heimdal/lib/com_err/lex.ho 
 # End SUBSYSTEM HEIMDAL_COM_ERR_COMPILE_LEX
 #######################
@@ -444,8 +538,10 @@ PRIVATE_DEPENDENCIES = HEIMDAL_COM_ERR_COMPILE_LEX HEIMDAL_ROKEN_GETPROGNAME_H
 #######################
 
 include perl_path_wrapper.sh asn1_deps.pl heimdal/lib/hdb/hdb.asn1 hdb_asn1|
-include perl_path_wrapper.sh asn1_deps.pl heimdal/lib/gssapi/spnego.asn1 spnego_asn1|
-include perl_path_wrapper.sh asn1_deps.pl heimdal/lib/asn1/k5.asn1 krb5_asn1 --encode-rfc1510-bit-string|
+include perl_path_wrapper.sh asn1_deps.pl heimdal/lib/gssapi/spnego/spnego.asn1 spnego_asn1|
+include perl_path_wrapper.sh asn1_deps.pl heimdal/lib/gssapi/mech/gssapi.asn1 gssapi_asn1|
+include perl_path_wrapper.sh asn1_deps.pl heimdal/lib/asn1/k5.asn1 krb5_asn1 --encode-rfc1510-bit-string --sequence=KRB5SignedPathPrincipals --sequence=AuthorizationData|
+include perl_path_wrapper.sh asn1_deps.pl heimdal/lib/asn1/digest.asn1 digest_asn1|
 
 include perl_path_wrapper.sh et_deps.pl heimdal/lib/asn1/asn1_err.et|
 include perl_path_wrapper.sh et_deps.pl heimdal/lib/hdb/hdb_err.et|
index 7359fe63c3734d3603b8533c62be7045d5345192..8fd69aecb1b7f0992ed70ca26f988e9c4f7680c4 100644 (file)
@@ -462,7 +462,7 @@ static krb5_error_code LDB_lookup_principal(krb5_context context, struct ldb_con
 
        struct ldb_result *res = NULL;
 
-       ret = krb5_unparse_name_norealm(context, principal, &short_princ);
+       ret = krb5_unparse_name_flags(context, principal,  KRB5_PRINCIPAL_UNPARSE_NO_REALM, &short_princ);
 
        if (ret != 0) {
                krb5_set_error_string(context, "LDB_lookup_principal: could not parse principal");
@@ -713,7 +713,9 @@ static krb5_error_code LDB_fetch_server(krb5_context context, HDB *db,
                struct ldb_dn *user_dn, *domain_dn;
                char *principal_string;
                
-               ret = krb5_unparse_name_norealm(context, principal, &principal_string);
+               ret = krb5_unparse_name_flags(context, principal, 
+                                             KRB5_PRINCIPAL_UNPARSE_NO_REALM, 
+                                             &principal_string);
                if (ret != 0) {
                        return ret;
                }
index 5da6be6eca8cc6515fbbee8f478e5161716e624d..7d6155e1c0593d1654bc5c8e1fdc17a2bb6dc3fb 100644 (file)
@@ -49,7 +49,8 @@ typedef BOOL (*kdc_process_fn_t)(struct kdc_server *kdc,
                                 DATA_BLOB *input, 
                                 DATA_BLOB *reply,
                                 struct socket_address *peer_addr, 
-                                struct socket_address *my_addr);
+                                struct socket_address *my_addr, 
+                                int datagram);
 
 /* hold information about one kdc socket */
 struct kdc_socket {
@@ -157,7 +158,8 @@ static void kdc_recv_handler(struct kdc_socket *kdc_socket)
                                  tmp_ctx, 
                                  &blob,  
                                  &reply,
-                                 src, my_addr);
+                                 src, my_addr,
+                                 1 /* Datagram */);
        if (!ret) {
                talloc_free(tmp_ctx);
                return;
@@ -240,7 +242,8 @@ static NTSTATUS kdc_tcp_recv(void *private, DATA_BLOB blob)
                               &input,
                               &reply,
                               src_addr,
-                              my_addr);
+                              my_addr,
+                              0 /* Not datagram */);
        if (!ret) {
                talloc_free(tmp_ctx);
                return NT_STATUS_INTERNAL_ERROR;
@@ -306,10 +309,12 @@ static BOOL kdc_process(struct kdc_server *kdc,
                        DATA_BLOB *input, 
                        DATA_BLOB *reply,
                        struct socket_address *peer_addr, 
-                       struct socket_address *my_addr)
+                       struct socket_address *my_addr,
+                       int datagram_reply)
 {
        int ret;        
        krb5_data k5_reply;
+       krb5_data_zero(&k5_reply);
 
        DEBUG(10,("Received KDC packet of length %lu from %s:%d\n", 
                  (long)input->length - 4, peer_addr->addr, peer_addr->port));
@@ -319,13 +324,18 @@ static BOOL kdc_process(struct kdc_server *kdc,
                                            input->data, input->length,
                                            &k5_reply,
                                            peer_addr->addr,
-                                           peer_addr->sockaddr);
+                                           peer_addr->sockaddr,
+                                           datagram_reply);
        if (ret == -1) {
                *reply = data_blob(NULL, 0);
                return False;
        }
-       *reply = data_blob_talloc(mem_ctx, k5_reply.data, k5_reply.length);
-       krb5_data_free(&k5_reply);
+       if (k5_reply.length) {
+               *reply = data_blob_talloc(mem_ctx, k5_reply.data, k5_reply.length);
+               krb5_free_data_contents(kdc->smb_krb5_context->krb5_context, &k5_reply);
+       } else {
+               *reply = data_blob(NULL, 0);    
+       }
        return True;
 }
 
index f0d2479a251ebbfa28c9a08e03d058d462593b06..9cd51f1d973ab97c1e262746d69dc4860c288683 100644 (file)
@@ -37,7 +37,8 @@ BOOL kpasswdd_process(struct kdc_server *kdc,
                      DATA_BLOB *input, 
                      DATA_BLOB *reply,
                      struct socket_address *peer_addr, 
-                     struct socket_address *my_addr);
+                     struct socket_address *my_addr,
+                     int datagram_reply);
 
 /*
   top level context structure for the kdc server
index 0dcbf9833d391c552dc02993e3da029cf833416a..6bc10cdced0cce1e0dca65ed4fb9d6dd6270db6c 100644 (file)
@@ -410,7 +410,8 @@ BOOL kpasswdd_process(struct kdc_server *kdc,
                      DATA_BLOB *input, 
                      DATA_BLOB *reply,
                      struct socket_address *peer_addr,
-                     struct socket_address *my_addr)
+                     struct socket_address *my_addr,
+                     int datagram_reply)
 {
        BOOL ret;
        const uint16_t header_len = 6;
index e80ad060edaff9cdb94fceb321fb1e4e42b5d662..143690ff0d479bcf8b315194700473a1071fd885 100644 (file)
@@ -32,7 +32,7 @@
 struct krb5_dh_moduli;
 struct _krb5_krb_auth_data;
 
-#include "heimdal/lib/krb5/krb5-private.h"
+#include "heimdal/lib/krb5/krb5_locl.h"
 
 /* Given the right private pointer from hdb_ldb, get a PAC from the attached ldb messages */
 static krb5_error_code samba_get_pac(krb5_context context, 
index b8708f9ebee2c03c19eb2c0ee49c66e5b0056292..60e5b1f5841e00e202629070bd82471fff526bca 100644 (file)
 #include "includes.h"
 #include "smbd/process_model.h"
 
-/* For sepecifiying event context to GSSAPI below */
-#include "system/kerberos.h"
-#include "heimdal/lib/gssapi/gssapi_locl.h"
-
-
 /*
   called when the process model is selected
 */
 static void single_model_init(struct event_context *ev)
 {
-       /* Hack to ensure that GSSAPI uses the right event context */
-       gssapi_krb5_init_ev(ev);
 }
 
 /*
index 1efdd3d0c4c22ce15914c7c25765a75e6b308932..ec774b92dfbf34ac84a388ce0bb8f3e0d535cd17 100644 (file)
 #include "lib/socket/socket.h"
 #include "smbd/process_model.h"
 
-/* For specifiying event context to GSSAPI below */
-#include "system/kerberos.h"
-#include "heimdal/lib/gssapi/gssapi_locl.h"
-
 #include "param/secrets.h"
 
 #ifdef HAVE_SETPROCTITLE
@@ -115,9 +111,6 @@ static void standard_accept_connection(struct event_context *ev,
                DEBUG(0,("standard_accept_connection: tdb_reopen_all failed.\n"));
        }
 
-       /* Hack to ensure that GSSAPI uses the right event context */
-       gssapi_krb5_init_ev(ev2);
-
        /* Ensure that the forked children do not expose identical random streams */
        set_need_random_reseed();
 
index 3ee1c5310026404f286398e7f15cd4018ec10dee..96edd97e43f12efc0c2c937bb9ff7a17bd7b9463 100644 (file)
@@ -20,9 +20,11 @@ heimdal_basics: \
        heimdal/lib/roken/vis.h \
        heimdal/lib/roken/err.h \
        heimdal/lib/hdb/hdb_asn1.h \
-       heimdal/lib/gssapi/spnego_asn1.h \
+       heimdal/lib/gssapi/spnego/spnego_asn1.h \
+       heimdal/lib/gssapi/mech/gssapi_asn1.h \
        heimdal/lib/asn1/krb5_asn1.h \
        heimdal/lib/asn1/asn1_err.h \
+       heimdal/lib/asn1/digest_asn1.h \
        heimdal/lib/hdb/hdb_err.h \
        heimdal/lib/krb5/heim_err.h \
        heimdal/lib/krb5/k524_err.h \
index 629b573ec3a8d6067564ecfb3c275c40b7dc9434..3c122c930bd591a83f282e1f2db2ec2b5c7d77c4 100644 (file)
@@ -97,14 +97,16 @@ static bool torture_pac_self_check(struct torture_context *tctx)
                torture_fail(tctx, "auth_anonymous_server_info");
        }
 
-       ret = krb5_parse_name_norealm(smb_krb5_context->krb5_context, 
-                                     server_info->account_name, &client_principal);
+       ret = krb5_parse_name_flags(smb_krb5_context->krb5_context, 
+                                   server_info->account_name, 
+                                   KRB5_PRINCIPAL_PARSE_NO_REALM, 
+                                   &client_principal);
        if (ret) {
                krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
                                            &server_keyblock);
                krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
                                            &krbtgt_keyblock);
-               torture_fail(tctx, "krb5_parse_name_norealm");
+               torture_fail(tctx, "krb5_parse_name_flags(norealm)");
        }
 
        /* OK, go ahead and make a PAC */