s4:heimdal: import lorikeet-heimdal-200906080040 (commit 904d0124b46eed7a8ad6e5b73e89...
authorAndrew Bartlett <abartlet@samba.org>
Mon, 8 Jun 2009 09:06:16 +0000 (19:06 +1000)
committerAndrew Bartlett <abartlet@samba.org>
Thu, 11 Jun 2009 21:45:48 +0000 (07:45 +1000)
Also including the supporting changes required to pass make test

A number of heimdal functions and constants have changed since we last
imported a tree (for the better, but inconvenient for us).

Andrew Bartlett

328 files changed:
lib/replace/system/kerberos.h
source4/auth/credentials/credentials_krb5.c
source4/auth/gensec/gensec_gssapi.c
source4/auth/kerberos/clikrb5.c
source4/auth/kerberos/config.m4
source4/auth/kerberos/kerberos.c
source4/auth/kerberos/kerberos_pac.c
source4/dsdb/samdb/cracknames.c
source4/heimdal/README
source4/heimdal/cf/make-proto.pl
source4/heimdal/cf/resolv.m4
source4/heimdal/include/heim_threads.h [moved from source4/heimdal/lib/krb5/heim_threads.h with 100% similarity]
source4/heimdal/kdc/524.c [deleted file]
source4/heimdal/kdc/default_config.c
source4/heimdal/kdc/digest.c
source4/heimdal/kdc/headers.h
source4/heimdal/kdc/kaserver.c
source4/heimdal/kdc/kdc.h
source4/heimdal/kdc/kdc_locl.h
source4/heimdal/kdc/kerberos4.c [deleted file]
source4/heimdal/kdc/kerberos5.c
source4/heimdal/kdc/krb5tgs.c
source4/heimdal/kdc/kx509.c
source4/heimdal/kdc/pkinit.c
source4/heimdal/kdc/process.c
source4/heimdal/kpasswd/kpasswd.c
source4/heimdal/kuser/kinit.c
source4/heimdal/kuser/kuser_locl.h
source4/heimdal/lib/asn1/asn1_err.et
source4/heimdal/lib/asn1/asn1_gen.c
source4/heimdal/lib/asn1/canthandle.asn1
source4/heimdal/lib/asn1/cms.asn1 [moved from source4/heimdal/lib/asn1/CMS.asn1 with 95% similarity]
source4/heimdal/lib/asn1/cms.opt [new file with mode: 0644]
source4/heimdal/lib/asn1/der.h
source4/heimdal/lib/asn1/der_get.c
source4/heimdal/lib/asn1/der_locl.h
source4/heimdal/lib/asn1/der_put.c
source4/heimdal/lib/asn1/digest.asn1
source4/heimdal/lib/asn1/extra.c
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_encode.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/krb5.asn1 [moved from source4/heimdal/lib/asn1/k5.asn1 with 86% similarity]
source4/heimdal/lib/asn1/krb5.opt [new file with mode: 0644]
source4/heimdal/lib/asn1/kx509.asn1
source4/heimdal/lib/asn1/lex.l
source4/heimdal/lib/asn1/main.c
source4/heimdal/lib/asn1/parse.y [deleted file]
source4/heimdal/lib/asn1/pkcs12.asn1
source4/heimdal/lib/asn1/pkcs8.asn1
source4/heimdal/lib/asn1/pkinit.asn1
source4/heimdal/lib/asn1/rfc2459.asn1
source4/heimdal/lib/asn1/test.asn1
source4/heimdal/lib/com_err/com_err.c
source4/heimdal/lib/com_err/compile_et.c
source4/heimdal/lib/com_err/compile_et.h
source4/heimdal/lib/com_err/error.c
source4/heimdal/lib/com_err/lex.l
source4/heimdal/lib/com_err/parse.y
source4/heimdal/lib/gssapi/gssapi/gssapi.h
source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h
source4/heimdal/lib/gssapi/gssapi_mech.h
source4/heimdal/lib/gssapi/krb5/8003.c
source4/heimdal/lib/gssapi/krb5/accept_sec_context.c
source4/heimdal/lib/gssapi/krb5/acquire_cred.c
source4/heimdal/lib/gssapi/krb5/add_cred.c
source4/heimdal/lib/gssapi/krb5/address_to_krb5addr.c
source4/heimdal/lib/gssapi/krb5/aeap.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/krb5/arcfour.c
source4/heimdal/lib/gssapi/krb5/canonicalize_name.c
source4/heimdal/lib/gssapi/krb5/cfx.c
source4/heimdal/lib/gssapi/krb5/compare_name.c
source4/heimdal/lib/gssapi/krb5/compat.c
source4/heimdal/lib/gssapi/krb5/context_time.c
source4/heimdal/lib/gssapi/krb5/copy_ccache.c
source4/heimdal/lib/gssapi/krb5/decapsulate.c
source4/heimdal/lib/gssapi/krb5/delete_sec_context.c
source4/heimdal/lib/gssapi/krb5/display_name.c
source4/heimdal/lib/gssapi/krb5/display_status.c
source4/heimdal/lib/gssapi/krb5/duplicate_name.c
source4/heimdal/lib/gssapi/krb5/encapsulate.c
source4/heimdal/lib/gssapi/krb5/export_name.c
source4/heimdal/lib/gssapi/krb5/export_sec_context.c
source4/heimdal/lib/gssapi/krb5/external.c
source4/heimdal/lib/gssapi/krb5/get_mic.c
source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h
source4/heimdal/lib/gssapi/krb5/import_name.c
source4/heimdal/lib/gssapi/krb5/import_sec_context.c
source4/heimdal/lib/gssapi/krb5/indicate_mechs.c
source4/heimdal/lib/gssapi/krb5/init.c
source4/heimdal/lib/gssapi/krb5/init_sec_context.c
source4/heimdal/lib/gssapi/krb5/inquire_context.c
source4/heimdal/lib/gssapi/krb5/inquire_cred.c
source4/heimdal/lib/gssapi/krb5/inquire_cred_by_mech.c
source4/heimdal/lib/gssapi/krb5/inquire_cred_by_oid.c
source4/heimdal/lib/gssapi/krb5/inquire_mechs_for_name.c
source4/heimdal/lib/gssapi/krb5/inquire_names_for_mech.c
source4/heimdal/lib/gssapi/krb5/inquire_sec_context_by_oid.c
source4/heimdal/lib/gssapi/krb5/prf.c
source4/heimdal/lib/gssapi/krb5/process_context_token.c
source4/heimdal/lib/gssapi/krb5/release_buffer.c
source4/heimdal/lib/gssapi/krb5/release_cred.c
source4/heimdal/lib/gssapi/krb5/release_name.c
source4/heimdal/lib/gssapi/krb5/sequence.c
source4/heimdal/lib/gssapi/krb5/set_cred_option.c
source4/heimdal/lib/gssapi/krb5/set_sec_context_option.c
source4/heimdal/lib/gssapi/krb5/unwrap.c
source4/heimdal/lib/gssapi/krb5/verify_mic.c
source4/heimdal/lib/gssapi/krb5/wrap.c
source4/heimdal/lib/gssapi/mech/context.c
source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c
source4/heimdal/lib/gssapi/mech/gss_acquire_cred.c
source4/heimdal/lib/gssapi/mech/gss_aeap.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_canonicalize_name.c
source4/heimdal/lib/gssapi/mech/gss_get_mic.c
source4/heimdal/lib/gssapi/mech/gss_import_name.c
source4/heimdal/lib/gssapi/mech/gss_krb5.c
source4/heimdal/lib/gssapi/mech/gss_mech_switch.c
source4/heimdal/lib/gssapi/mech/gss_pseudo_random.c
source4/heimdal/lib/gssapi/mech/gss_verify_mic.c
source4/heimdal/lib/gssapi/mech/gss_wrap.c
source4/heimdal/lib/gssapi/mech/gss_wrap_size_limit.c
source4/heimdal/lib/gssapi/mech/mech_locl.h
source4/heimdal/lib/gssapi/mech/mech_switch.h
source4/heimdal/lib/gssapi/spnego/accept_sec_context.c
source4/heimdal/lib/gssapi/spnego/compat.c
source4/heimdal/lib/gssapi/spnego/context_stubs.c
source4/heimdal/lib/gssapi/spnego/cred_stubs.c
source4/heimdal/lib/gssapi/spnego/external.c
source4/heimdal/lib/gssapi/spnego/init_sec_context.c
source4/heimdal/lib/gssapi/spnego/spnego_locl.h
source4/heimdal/lib/hcrypto/bn.c
source4/heimdal/lib/hcrypto/bn.h
source4/heimdal/lib/hcrypto/evp-aes-cts.c
source4/heimdal/lib/hcrypto/evp.c
source4/heimdal/lib/hcrypto/rand-unix.c
source4/heimdal/lib/hcrypto/rand.c
source4/heimdal/lib/hdb/dbinfo.c
source4/heimdal/lib/hdb/ext.c
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/hdb/mkey.c
source4/heimdal/lib/hdb/ndbm.c
source4/heimdal/lib/hx509/ca.c
source4/heimdal/lib/hx509/cert.c
source4/heimdal/lib/hx509/cms.c
source4/heimdal/lib/hx509/collector.c
source4/heimdal/lib/hx509/crypto.c
source4/heimdal/lib/hx509/env.c
source4/heimdal/lib/hx509/error.c
source4/heimdal/lib/hx509/file.c
source4/heimdal/lib/hx509/hx509.h
source4/heimdal/lib/hx509/hx509_err.et
source4/heimdal/lib/hx509/hx_locl.h
source4/heimdal/lib/hx509/keyset.c
source4/heimdal/lib/hx509/ks_dir.c
source4/heimdal/lib/hx509/ks_file.c
source4/heimdal/lib/hx509/ks_keychain.c
source4/heimdal/lib/hx509/ks_mem.c
source4/heimdal/lib/hx509/ks_null.c
source4/heimdal/lib/hx509/ks_p11.c
source4/heimdal/lib/hx509/ks_p12.c
source4/heimdal/lib/hx509/lock.c
source4/heimdal/lib/hx509/name.c
source4/heimdal/lib/hx509/peer.c
source4/heimdal/lib/hx509/print.c
source4/heimdal/lib/hx509/req.c
source4/heimdal/lib/hx509/revoke.c
source4/heimdal/lib/hx509/sel-gram.y
source4/heimdal/lib/hx509/test_name.c
source4/heimdal/lib/krb5/acache.c
source4/heimdal/lib/krb5/add_et_list.c
source4/heimdal/lib/krb5/addr_families.c
source4/heimdal/lib/krb5/appdefault.c
source4/heimdal/lib/krb5/asn1_glue.c
source4/heimdal/lib/krb5/auth_context.c
source4/heimdal/lib/krb5/build_ap_req.c
source4/heimdal/lib/krb5/build_auth.c
source4/heimdal/lib/krb5/cache.c
source4/heimdal/lib/krb5/changepw.c
source4/heimdal/lib/krb5/codec.c
source4/heimdal/lib/krb5/config_file.c
source4/heimdal/lib/krb5/config_file_netinfo.c [deleted file]
source4/heimdal/lib/krb5/constants.c
source4/heimdal/lib/krb5/context.c
source4/heimdal/lib/krb5/convert_creds.c
source4/heimdal/lib/krb5/copy_host_realm.c
source4/heimdal/lib/krb5/crc.c
source4/heimdal/lib/krb5/creds.c
source4/heimdal/lib/krb5/crypto.c
source4/heimdal/lib/krb5/data.c
source4/heimdal/lib/krb5/eai_to_heim_errno.c
source4/heimdal/lib/krb5/error_string.c
source4/heimdal/lib/krb5/expand_hostname.c
source4/heimdal/lib/krb5/fcache.c
source4/heimdal/lib/krb5/free.c
source4/heimdal/lib/krb5/free_host_realm.c
source4/heimdal/lib/krb5/generate_seq_number.c
source4/heimdal/lib/krb5/generate_subkey.c
source4/heimdal/lib/krb5/get_addrs.c
source4/heimdal/lib/krb5/get_cred.c
source4/heimdal/lib/krb5/get_default_principal.c
source4/heimdal/lib/krb5/get_default_realm.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/get_port.c
source4/heimdal/lib/krb5/heim_err.et
source4/heimdal/lib/krb5/init_creds.c
source4/heimdal/lib/krb5/init_creds_pw.c
source4/heimdal/lib/krb5/kcm.c
source4/heimdal/lib/krb5/keyblock.c
source4/heimdal/lib/krb5/keytab.c
source4/heimdal/lib/krb5/keytab_any.c
source4/heimdal/lib/krb5/keytab_file.c
source4/heimdal/lib/krb5/keytab_keyfile.c
source4/heimdal/lib/krb5/keytab_memory.c
source4/heimdal/lib/krb5/krb5.h
source4/heimdal/lib/krb5/krb5_ccapi.h
source4/heimdal/lib/krb5/krb5_err.et
source4/heimdal/lib/krb5/krb5_locl.h
source4/heimdal/lib/krb5/krbhst.c
source4/heimdal/lib/krb5/locate_plugin.h
source4/heimdal/lib/krb5/log.c
source4/heimdal/lib/krb5/mcache.c
source4/heimdal/lib/krb5/misc.c
source4/heimdal/lib/krb5/mit_glue.c
source4/heimdal/lib/krb5/mk_error.c
source4/heimdal/lib/krb5/mk_priv.c
source4/heimdal/lib/krb5/mk_rep.c
source4/heimdal/lib/krb5/mk_req.c
source4/heimdal/lib/krb5/mk_req_ext.c
source4/heimdal/lib/krb5/n-fold.c
source4/heimdal/lib/krb5/pac.c
source4/heimdal/lib/krb5/padata.c
source4/heimdal/lib/krb5/pkinit.c
source4/heimdal/lib/krb5/plugin.c
source4/heimdal/lib/krb5/principal.c
source4/heimdal/lib/krb5/prog_setup.c
source4/heimdal/lib/krb5/prompter_posix.c
source4/heimdal/lib/krb5/rd_cred.c
source4/heimdal/lib/krb5/rd_error.c
source4/heimdal/lib/krb5/rd_priv.c
source4/heimdal/lib/krb5/rd_rep.c
source4/heimdal/lib/krb5/rd_req.c
source4/heimdal/lib/krb5/replay.c
source4/heimdal/lib/krb5/send_to_kdc.c
source4/heimdal/lib/krb5/set_default_realm.c
source4/heimdal/lib/krb5/store-int.h
source4/heimdal/lib/krb5/store.c
source4/heimdal/lib/krb5/store_emem.c
source4/heimdal/lib/krb5/store_fd.c
source4/heimdal/lib/krb5/store_mem.c
source4/heimdal/lib/krb5/ticket.c
source4/heimdal/lib/krb5/time.c
source4/heimdal/lib/krb5/transited.c
source4/heimdal/lib/krb5/v4_glue.c
source4/heimdal/lib/krb5/version.c
source4/heimdal/lib/krb5/warn.c
source4/heimdal/lib/ntlm/ntlm.c
source4/heimdal/lib/roken/base64.c
source4/heimdal/lib/roken/bswap.c
source4/heimdal/lib/roken/cloexec.c
source4/heimdal/lib/roken/closefrom.c
source4/heimdal/lib/roken/copyhostent.c
source4/heimdal/lib/roken/dumpdata.c
source4/heimdal/lib/roken/ecalloc.c
source4/heimdal/lib/roken/emalloc.c
source4/heimdal/lib/roken/erealloc.c
source4/heimdal/lib/roken/estrdup.c
source4/heimdal/lib/roken/freeaddrinfo.c
source4/heimdal/lib/roken/freehostent.c
source4/heimdal/lib/roken/gai_strerror.c
source4/heimdal/lib/roken/get_window_size.c
source4/heimdal/lib/roken/getaddrinfo.c
source4/heimdal/lib/roken/getarg.c
source4/heimdal/lib/roken/getdtablesize.c [moved from source4/heimdal/lib/krb5/get_in_tkt_with_keytab.c with 50% similarity]
source4/heimdal/lib/roken/getipnodebyaddr.c
source4/heimdal/lib/roken/getipnodebyname.c
source4/heimdal/lib/roken/getnameinfo.c
source4/heimdal/lib/roken/getprogname.c
source4/heimdal/lib/roken/h_errno.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/inet_ntop.c
source4/heimdal/lib/roken/inet_pton.c
source4/heimdal/lib/roken/issuid.c
source4/heimdal/lib/roken/net_read.c
source4/heimdal/lib/roken/net_write.c
source4/heimdal/lib/roken/parse_time.c
source4/heimdal/lib/roken/parse_units.c
source4/heimdal/lib/roken/resolve.c
source4/heimdal/lib/roken/resolve.h
source4/heimdal/lib/roken/rkpty.c
source4/heimdal/lib/roken/roken-common.h
source4/heimdal/lib/roken/roken.h.in
source4/heimdal/lib/roken/roken_gethostby.c
source4/heimdal/lib/roken/rtbl.c
source4/heimdal/lib/roken/setprogname.c
source4/heimdal/lib/roken/signal.c
source4/heimdal/lib/roken/simple_exec.c
source4/heimdal/lib/roken/socket.c
source4/heimdal/lib/roken/strcollect.c
source4/heimdal/lib/roken/strlwr.c
source4/heimdal/lib/roken/strpool.c
source4/heimdal/lib/roken/strsep.c
source4/heimdal/lib/roken/strsep_copy.c
source4/heimdal/lib/roken/strupr.c
source4/heimdal/lib/roken/vis.c
source4/heimdal/lib/roken/xfree.c
source4/heimdal/lib/vers/print_version.c
source4/heimdal/lib/wind/normalize.c
source4/heimdal/lib/wind/stringprep.c
source4/heimdal/lib/wind/utf8.c
source4/heimdal/lib/wind/wind_err.et
source4/heimdal_build/asn1_deps.pl
source4/heimdal_build/internal.mk
source4/kdc/hdb-samba4.c
source4/kdc/kdc.c
source4/libcli/resolve/dns_ex.c

index 2981024bee5ee9e7b29cd20c7ee7eab875b67ba9..a1685ad33301f5ef18e1b31659c09ff3915c4da3 100644 (file)
@@ -59,7 +59,9 @@
 /* Define to 1 if you have the `krb5_free_data_contents' function. */
 #define HAVE_KRB5_FREE_DATA_CONTENTS 1
 /* Define to 1 if you have the `krb5_free_error_string' function. */
 /* Define to 1 if you have the `krb5_free_data_contents' function. */
 #define HAVE_KRB5_FREE_DATA_CONTENTS 1
 /* Define to 1 if you have the `krb5_free_error_string' function. */
-#define HAVE_KRB5_FREE_ERROR_STRING 1
+/* #undef HAVE_KRB5_FREE_ERROR_STRING */
+/* Define to 1 if you have the `krb5_free_error_message' function. */
+#define HAVE_KRB5_FREE_ERROR_MESSAGE 1
 /* Define to 1 if you have the `krb5_free_keytab_entry_contents' function. */
 /* #undef HAVE_KRB5_FREE_KEYTAB_ENTRY_CONTENTS */
 /* Define to 1 if you have the `krb5_free_ktypes' function. */
 /* Define to 1 if you have the `krb5_free_keytab_entry_contents' function. */
 /* #undef HAVE_KRB5_FREE_KEYTAB_ENTRY_CONTENTS */
 /* Define to 1 if you have the `krb5_free_ktypes' function. */
@@ -70,6 +72,8 @@
 #define HAVE_KRB5_GET_DEFAULT_IN_TKT_ETYPES 1
 /* Define to 1 if you have the `krb5_get_error_string' function. */
 #define HAVE_KRB5_GET_ERROR_STRING 1
 #define HAVE_KRB5_GET_DEFAULT_IN_TKT_ETYPES 1
 /* Define to 1 if you have the `krb5_get_error_string' function. */
 #define HAVE_KRB5_GET_ERROR_STRING 1
+/* Define to 1 if you have the `krb5_get_error_message' function. */
+#define HAVE_KRB5_GET_ERROR_MESSAGE 1
 /* Define to 1 if you have the `krb5_get_permitted_enctypes' function. */
 /* #undef HAVE_KRB5_GET_PERMITTED_ENCTYPES */
 /* Define to 1 if you have the `krb5_get_pw_salt' function. */
 /* Define to 1 if you have the `krb5_get_permitted_enctypes' function. */
 /* #undef HAVE_KRB5_GET_PERMITTED_ENCTYPES */
 /* Define to 1 if you have the `krb5_get_pw_salt' function. */
index bc3d05f529fd0244f2b7ac602b7865018169cc99..efcca3e269f59c136c426f40bc3eb9c9b336a100 100644 (file)
@@ -71,7 +71,6 @@ static int cli_credentials_set_from_ccache(struct cli_credentials *cred,
        krb5_principal princ;
        krb5_error_code ret;
        char *name;
        krb5_principal princ;
        krb5_error_code ret;
        char *name;
-       char **realm;
 
        if (cred->ccache_obtained > obtained) {
                return 0;
 
        if (cred->ccache_obtained > obtained) {
                return 0;
@@ -98,8 +97,6 @@ static int cli_credentials_set_from_ccache(struct cli_credentials *cred,
                return ret;
        }
 
                return ret;
        }
 
-       realm = krb5_princ_realm(ccache->smb_krb5_context->krb5_context, princ);
-
        cli_credentials_set_principal(cred, name, obtained);
 
        free(name);
        cli_credentials_set_principal(cred, name, obtained);
 
        free(name);
index aae04dffe2d3a104684f8cbc7501b3b1cc28c161..7129db72b86c99b5d7d018413b0d1cbfaaef9780 100644 (file)
@@ -170,6 +170,9 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security)
        gensec_gssapi_state->input_chan_bindings = GSS_C_NO_CHANNEL_BINDINGS;
        
        gensec_gssapi_state->want_flags = 0;
        gensec_gssapi_state->input_chan_bindings = GSS_C_NO_CHANNEL_BINDINGS;
        
        gensec_gssapi_state->want_flags = 0;
+       if (gensec_setting_bool(gensec_security->settings, "gensec_gssapi", "delegation_by_kdc_policy", true)) {
+               gensec_gssapi_state->want_flags |= GSS_C_DELEG_POLICY_FLAG;
+       }
        if (gensec_setting_bool(gensec_security->settings, "gensec_gssapi", "mutual", true)) {
                gensec_gssapi_state->want_flags |= GSS_C_MUTUAL_FLAG;
        }
        if (gensec_setting_bool(gensec_security->settings, "gensec_gssapi", "mutual", true)) {
                gensec_gssapi_state->want_flags |= GSS_C_MUTUAL_FLAG;
        }
index 68e7eb90cc19540198c3c1405ca17b80c9f0926d..3314cbc5910b15a6541d2cf1cacf4e4d78e4ddcc 100644 (file)
 {
        char *ret;
        
 {
        char *ret;
        
-#if defined(HAVE_KRB5_GET_ERROR_STRING) && defined(HAVE_KRB5_FREE_ERROR_STRING)        
-       char *context_error = krb5_get_error_string(context);
+#if defined(HAVE_KRB5_GET_ERROR_MESSAGE) && defined(HAVE_KRB5_FREE_ERROR_MESSAGE)      
+       const char *context_error = krb5_get_error_message(context, code);
        if (context_error) {
                ret = talloc_asprintf(mem_ctx, "%s: %s", error_message(code), context_error);
        if (context_error) {
                ret = talloc_asprintf(mem_ctx, "%s: %s", error_message(code), context_error);
-               krb5_free_error_string(context, context_error);
+               krb5_free_error_message(context, context_error);
                return ret;
        }
 #endif
                return ret;
        }
 #endif
index bf14ca0ee4e4bf32ca253ac2a43733fbe2f80868..a8d55a1287a91144a40da3563a0107bd6ee1e8de 100644 (file)
@@ -258,6 +258,8 @@ if test x"$with_krb5_support" != x"no"; then
        AC_CHECK_FUNC_EXT(krb5_enctypes_compatible_keys, $KRB5_LIBS)
        AC_CHECK_FUNC_EXT(krb5_get_error_string, $KRB5_LIBS)
        AC_CHECK_FUNC_EXT(krb5_free_error_string, $KRB5_LIBS)
        AC_CHECK_FUNC_EXT(krb5_enctypes_compatible_keys, $KRB5_LIBS)
        AC_CHECK_FUNC_EXT(krb5_get_error_string, $KRB5_LIBS)
        AC_CHECK_FUNC_EXT(krb5_free_error_string, $KRB5_LIBS)
+       AC_CHECK_FUNC_EXT(krb5_get_error_message, $KRB5_LIBS)
+       AC_CHECK_FUNC_EXT(krb5_free_error_message, $KRB5_LIBS)
        AC_CHECK_FUNC_EXT(krb5_initlog, $KRB5_LIBS)
        AC_CHECK_FUNC_EXT(krb5_addlog_func, $KRB5_LIBS)
        AC_CHECK_FUNC_EXT(krb5_set_warn_dest, $KRB5_LIBS)
        AC_CHECK_FUNC_EXT(krb5_initlog, $KRB5_LIBS)
        AC_CHECK_FUNC_EXT(krb5_addlog_func, $KRB5_LIBS)
        AC_CHECK_FUNC_EXT(krb5_set_warn_dest, $KRB5_LIBS)
index 1889dcab4dac573a7d3804b158813738988dd0f7..a0b21c891a1cc992aa541ebe37ee5bcecd697d76 100644 (file)
 {
        krb5_error_code code = 0;
        krb5_creds my_creds;
 {
        krb5_error_code code = 0;
        krb5_creds my_creds;
-       krb5_get_init_creds_opt options;
+       krb5_get_init_creds_opt *options;
 
 
-       krb5_get_init_creds_opt_init(&options);
+       if ((code = krb5_get_init_creds_opt_alloc(ctx, &options))) {
+               return code;
+       }
 
 
-       krb5_get_init_creds_opt_set_default_flags(ctx, NULL, NULL, &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,
 
        if ((code = krb5_get_init_creds_keyblock(ctx, &my_creds, principal, keyblock,
-                                                0, NULL, &options))) {
+                                                0, NULL, options))) {
                return code;
        }
        
        if ((code = krb5_cc_initialize(ctx, cc, principal))) {
                return code;
        }
        
        if ((code = krb5_cc_initialize(ctx, cc, principal))) {
+               krb5_get_init_creds_opt_free(ctx, options);
                krb5_free_cred_contents(ctx, &my_creds);
                return code;
        }
        
        if ((code = krb5_cc_store_cred(ctx, cc, &my_creds))) {
                krb5_free_cred_contents(ctx, &my_creds);
                return code;
        }
        
        if ((code = krb5_cc_store_cred(ctx, cc, &my_creds))) {
+               krb5_get_init_creds_opt_free(ctx, options);
                krb5_free_cred_contents(ctx, &my_creds);
                return code;
        }
                krb5_free_cred_contents(ctx, &my_creds);
                return code;
        }
@@ -69,6 +73,7 @@
                *kdc_time = (time_t) my_creds.times.starttime;
        }
 
                *kdc_time = (time_t) my_creds.times.starttime;
        }
 
+       krb5_get_init_creds_opt_free(ctx, options);
        krb5_free_cred_contents(ctx, &my_creds);
        
        return 0;
        krb5_free_cred_contents(ctx, &my_creds);
        
        return 0;
 {
        krb5_error_code code = 0;
        krb5_creds my_creds;
 {
        krb5_error_code code = 0;
        krb5_creds my_creds;
-       krb5_get_init_creds_opt options;
+       krb5_get_init_creds_opt *options;
 
 
-       krb5_get_init_creds_opt_init(&options);
+       if ((code = krb5_get_init_creds_opt_alloc(ctx, &options))) {
+               return code;
+       }
 
 
-       krb5_get_init_creds_opt_set_default_flags(ctx, NULL, NULL, &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, 
 
        if ((code = krb5_get_init_creds_password(ctx, &my_creds, principal, password, 
                                                 NULL, 
-                                                NULL, 0, NULL, &options))) {
+                                                NULL, 0, NULL, options))) {
                return code;
        }
        
        if ((code = krb5_cc_initialize(ctx, cc, principal))) {
                return code;
        }
        
        if ((code = krb5_cc_initialize(ctx, cc, principal))) {
+               krb5_get_init_creds_opt_free(ctx, options);
                krb5_free_cred_contents(ctx, &my_creds);
                return code;
        }
        
        if ((code = krb5_cc_store_cred(ctx, cc, &my_creds))) {
                krb5_free_cred_contents(ctx, &my_creds);
                return code;
        }
        
        if ((code = krb5_cc_store_cred(ctx, cc, &my_creds))) {
+               krb5_get_init_creds_opt_free(ctx, options);
                krb5_free_cred_contents(ctx, &my_creds);
                return code;
        }
                krb5_free_cred_contents(ctx, &my_creds);
                return code;
        }
                *kdc_time = (time_t) my_creds.times.starttime;
        }
 
                *kdc_time = (time_t) my_creds.times.starttime;
        }
 
+       krb5_get_init_creds_opt_free(ctx, options);
        krb5_free_cred_contents(ctx, &my_creds);
        
        return 0;
        krb5_free_cred_contents(ctx, &my_creds);
        
        return 0;
index 7a36c9ddea79a410c2c34575efd367289bdac16a..7a6d00856286c38a2e93568bdbb2149befe59148 100644 (file)
@@ -96,7 +96,7 @@ krb5_error_code check_pac_checksum(TALLOC_CTX *mem_ctx,
        krb5_principal client_principal_pac;
        int i;
 
        krb5_principal client_principal_pac;
        int i;
 
-       krb5_clear_error_string(context);
+       krb5_clear_error_message(context);
 
        if (k5ret) {
                *k5ret = KRB5_PARSE_MALFORMED;
 
        if (k5ret) {
                *k5ret = KRB5_PARSE_MALFORMED;
index 9bcb007358ed1f1010ee6676b85bf66b146c0ea0..d31311bd1dc03a978adc2605d04d6c2e0d76a5a6 100644 (file)
@@ -55,18 +55,18 @@ static WERROR dns_domain_from_principal(TALLOC_CTX *mem_ctx, struct smb_krb5_con
        krb5_error_code ret;
        krb5_principal principal;
        /* perhaps it's a principal with a realm, so return the right 'domain only' response */
        krb5_error_code ret;
        krb5_principal principal;
        /* perhaps it's a principal with a realm, so return the right 'domain only' response */
-       char **realm;
+       char *realm;
        ret = krb5_parse_name_flags(smb_krb5_context->krb5_context, name, 
        ret = krb5_parse_name_flags(smb_krb5_context->krb5_context, name, 
-                                   KRB5_PRINCIPAL_PARSE_MUST_REALM, &principal);
+                                   KRB5_PRINCIPAL_PARSE_REQUIRE_REALM, &principal);
        if (ret) {
                info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND;
                return WERR_OK;
        }
 
        /* This isn't an allocation assignemnt, so it is free'ed with the krb5_free_principal */
        if (ret) {
                info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND;
                return WERR_OK;
        }
 
        /* This isn't an allocation assignemnt, so it is free'ed with the krb5_free_principal */
-       realm = krb5_princ_realm(smb_krb5_context->krb5_context, principal);
+       realm = krb5_principal_get_realm(smb_krb5_context->krb5_context, principal);
        
        
-       info1->dns_domain_name  = talloc_strdup(mem_ctx, *realm);
+       info1->dns_domain_name  = talloc_strdup(mem_ctx, realm);
        krb5_free_principal(smb_krb5_context->krb5_context, principal);
        
        W_ERROR_HAVE_NO_MEMORY(info1->dns_domain_name);
        krb5_free_principal(smb_krb5_context->krb5_context, principal);
        
        W_ERROR_HAVE_NO_MEMORY(info1->dns_domain_name);
@@ -271,7 +271,7 @@ static WERROR DsCrackNameUPN(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx,
        const char *result_filter = NULL;
        krb5_error_code ret;
        krb5_principal principal;
        const char *result_filter = NULL;
        krb5_error_code ret;
        krb5_principal principal;
-       char **realm;
+       char *realm;
        char *unparsed_name_short;
        const char *domain_attrs[] = { NULL };
        struct ldb_result *domain_res = NULL;
        char *unparsed_name_short;
        const char *domain_attrs[] = { NULL };
        struct ldb_result *domain_res = NULL;
@@ -283,21 +283,21 @@ static WERROR DsCrackNameUPN(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx,
        }
 
        ret = krb5_parse_name_flags(smb_krb5_context->krb5_context, name, 
        }
 
        ret = krb5_parse_name_flags(smb_krb5_context->krb5_context, name, 
-                                   KRB5_PRINCIPAL_PARSE_MUST_REALM, &principal);
+                                   KRB5_PRINCIPAL_PARSE_REQUIRE_REALM, &principal);
        if (ret) {
                info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND;
                return WERR_OK;
        }
        
        if (ret) {
                info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND;
                return WERR_OK;
        }
        
-       realm = krb5_princ_realm(smb_krb5_context->krb5_context, principal);
+       realm = krb5_principal_get_realm(smb_krb5_context->krb5_context, principal);
 
        ldb_ret = ldb_search(sam_ctx, mem_ctx, &domain_res,
                                     samdb_partitions_dn(sam_ctx, mem_ctx), 
                                     LDB_SCOPE_ONELEVEL,
                                     domain_attrs,
                                     "(&(&(|(&(dnsRoot=%s)(nETBIOSName=*))(nETBIOSName=%s))(objectclass=crossRef))(ncName=*))",
 
        ldb_ret = ldb_search(sam_ctx, mem_ctx, &domain_res,
                                     samdb_partitions_dn(sam_ctx, mem_ctx), 
                                     LDB_SCOPE_ONELEVEL,
                                     domain_attrs,
                                     "(&(&(|(&(dnsRoot=%s)(nETBIOSName=*))(nETBIOSName=%s))(objectclass=crossRef))(ncName=*))",
-                                    ldb_binary_encode_string(mem_ctx, *realm), 
-                                    ldb_binary_encode_string(mem_ctx, *realm));
+                                    ldb_binary_encode_string(mem_ctx, realm), 
+                                    ldb_binary_encode_string(mem_ctx, realm));
 
        if (ldb_ret != LDB_SUCCESS) {
                DEBUG(2, ("DsCrackNameUPN domain ref search failed: %s", ldb_errstring(sam_ctx)));
 
        if (ldb_ret != LDB_SUCCESS) {
                DEBUG(2, ("DsCrackNameUPN domain ref search failed: %s", ldb_errstring(sam_ctx)));
index 3b938248fcb7c159523686182682d5b66263db41..f130698597c86861fce9d59cf180d2a553377f8e 100644 (file)
@@ -1,4 +1,3 @@
-$Id$
 
 Heimdal is a Kerberos 5 implementation.
 
 
 Heimdal is a Kerberos 5 implementation.
 
index b89ef790670b4b7fce0e306bc689e1359b4fd748..04733e12811d40531ee6040bc48fb27a55f790d2 100644 (file)
@@ -100,13 +100,16 @@ while(<>) {
        s/^\s*//;
        s/\s*$//;
        s/\s+/ /g;
        s/^\s*//;
        s/\s*$//;
        s/\s+/ /g;
-       if($_ =~ /\)$/){
+       if($_ =~ /\)$/ or $_ =~ /DEPRECATED$/){
            if(!/^static/ && !/^PRIVATE/){
            if(!/^static/ && !/^PRIVATE/){
-               if(/(.*)(__attribute__\s?\(.*\))/) {
-                   $attr = $2;
+               $attr = "";
+               if(m/(.*)(__attribute__\s?\(.*\))/) {
+                   $attr .= " $2";
+                   $_ = $1;
+               }
+               if(m/(.*)\s(\w+DEPRECATED)/) {
+                   $attr .= " $2";
                    $_ = $1;
                    $_ = $1;
-               } else {
-                   $attr = "";
                }
                # remove outer ()
                s/\s*\(/</;
                }
                # remove outer ()
                s/\s*\(/</;
@@ -308,7 +311,7 @@ extern \"C\" {
 if ($opt_E) {
     $public_h_header .= "#ifndef $opt_E
 #if defined(_WIN32)
 if ($opt_E) {
     $public_h_header .= "#ifndef $opt_E
 #if defined(_WIN32)
-#define ${opt_E}_FUNCTION _stdcall __declspec(dllimport)
+#define ${opt_E}_FUNCTION __stdcall __declspec(dllimport)
 #define ${opt_E}_VARIABLE __declspec(dllimport)
 #else
 #define ${opt_E}_FUNCTION
 #define ${opt_E}_VARIABLE __declspec(dllimport)
 #else
 #define ${opt_E}_FUNCTION
@@ -320,7 +323,7 @@ if ($opt_E) {
     
     $private_h_header .= "#ifndef $opt_E
 #if defined(_WIN32)
     
     $private_h_header .= "#ifndef $opt_E
 #if defined(_WIN32)
-#define ${opt_E}_FUNCTION _stdcall __declspec(dllimport)
+#define ${opt_E}_FUNCTION __stdcall __declspec(dllimport)
 #define ${opt_E}_VARIABLE __declspec(dllimport)
 #else
 #define ${opt_E}_FUNCTION
 #define ${opt_E}_VARIABLE __declspec(dllimport)
 #else
 #define ${opt_E}_FUNCTION
index b4045094d8026522e0dee0671f66379eb44ed372..49c868ab0ec6042ead5b2e3d0999d1c62a919348 100644 (file)
@@ -5,7 +5,7 @@ dnl
 
 AC_DEFUN([rk_RESOLV],[
 
 
 AC_DEFUN([rk_RESOLV],[
 
-AC_CHECK_HEADERS([arpa/nameser.h])
+AC_CHECK_HEADERS([arpa/nameser.h dns.h])
 
 AC_CHECK_HEADERS(resolv.h, , , [AC_INCLUDES_DEFAULT
 #ifdef HAVE_SYS_TYPES_H
 
 AC_CHECK_HEADERS(resolv.h, , , [AC_INCLUDES_DEFAULT
 #ifdef HAVE_SYS_TYPES_H
@@ -73,6 +73,15 @@ AC_FIND_FUNC(res_ndestroy, resolv,
 ],
 [0])
 
 ],
 [0])
 
+AC_FIND_FUNC_NO_LIBS(dns_search,,
+[
+#ifdef HAVE_DNS_H
+#include <dns.h>
+#endif
+],
+[0,0,0,0,0,0,0,0])
+
+
 AC_FIND_FUNC(dn_expand, resolv,
 [
 #include <stdio.h>
 AC_FIND_FUNC(dn_expand, resolv,
 [
 #include <stdio.h>
diff --git a/source4/heimdal/kdc/524.c b/source4/heimdal/kdc/524.c
deleted file mode 100644 (file)
index d153103..0000000
+++ /dev/null
@@ -1,400 +0,0 @@
-/*
- * 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 "kdc_locl.h"
-
-RCSID("$Id$");
-
-#include <krb5-v4compat.h>
-
-/*
- * fetch the server from `t', returning the name in malloced memory in
- * `spn' and the entry itself in `server'
- */
-
-static krb5_error_code
-fetch_server (krb5_context context,
-             krb5_kdc_configuration *config,
-             const Ticket *t,
-             char **spn,
-             hdb_entry_ex **server,
-             const char *from)
-{
-    krb5_error_code ret;
-    krb5_principal sprinc;
-
-    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));
-       return ret;
-    }
-    ret = krb5_unparse_name(context, sprinc, spn);
-    if (ret) {
-       krb5_free_principal(context, sprinc);
-       kdc_log(context, config, 0, "krb5_unparse_name: %s",
-               krb5_get_err_text(context, ret));
-       return ret;
-    }
-    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,
-       "Request to convert ticket from %s for unknown principal %s: %s",
-               from, *spn, krb5_get_err_text(context, ret));
-       if (ret == HDB_ERR_NOENTRY)
-           ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
-       return ret;
-    }
-    return 0;
-}
-
-static krb5_error_code
-log_524 (krb5_context context,
-        krb5_kdc_configuration *config,
-        const EncTicketPart *et,
-        const char *from,
-        const char *spn)
-{
-    krb5_principal client;
-    char *cpn;
-    krb5_error_code ret;
-
-    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));
-       return ret;
-    }
-    ret = krb5_unparse_name(context, client, &cpn);
-    if (ret) {
-       krb5_free_principal(context, client);
-       kdc_log(context, config, 0, "krb5_unparse_name: %s",
-               krb5_get_err_text (context, ret));
-       return ret;
-    }
-    kdc_log(context, config, 1, "524-REQ %s from %s for %s", cpn, from, spn);
-    free(cpn);
-    krb5_free_principal(context, client);
-    return 0;
-}
-
-static krb5_error_code
-verify_flags (krb5_context context,
-             krb5_kdc_configuration *config,
-             const EncTicketPart *et,
-             const char *spn)
-{
-    if(et->endtime < kdc_time){
-       kdc_log(context, config, 0, "Ticket expired (%s)", spn);
-       return KRB5KRB_AP_ERR_TKT_EXPIRED;
-    }
-    if(et->flags.invalid){
-       kdc_log(context, config, 0, "Ticket not valid (%s)", spn);
-       return KRB5KRB_AP_ERR_TKT_NYV;
-    }
-    return 0;
-}
-
-/*
- * set the `et->caddr' to the most appropriate address to use, where
- * `addr' is the address the request was received from.
- */
-
-static krb5_error_code
-set_address (krb5_context context,
-            krb5_kdc_configuration *config,
-            EncTicketPart *et,
-            struct sockaddr *addr,
-            const char *from)
-{
-    krb5_error_code ret;
-    krb5_address *v4_addr;
-
-    v4_addr = malloc (sizeof(*v4_addr));
-    if (v4_addr == NULL)
-       return ENOMEM;
-
-    ret = krb5_sockaddr2address(context, addr, v4_addr);
-    if(ret) {
-       free (v4_addr);
-       kdc_log(context, config, 0, "Failed to convert address (%s)", from);
-       return ret;
-    }
-       
-    if (et->caddr && !krb5_address_search (context, v4_addr, et->caddr)) {
-       kdc_log(context, config, 0, "Incorrect network address (%s)", from);
-       krb5_free_address(context, v4_addr);
-       free (v4_addr);
-       return KRB5KRB_AP_ERR_BADADDR;
-    }
-    if(v4_addr->addr_type == KRB5_ADDRESS_INET) {
-       /* we need to collapse the addresses in the ticket to a
-          single address; best guess is to use the address the
-          connection came from */
-       
-       if (et->caddr != NULL) {
-           free_HostAddresses(et->caddr);
-       } else {
-           et->caddr = malloc (sizeof (*et->caddr));
-           if (et->caddr == NULL) {
-               krb5_free_address(context, v4_addr);
-               free(v4_addr);
-               return ENOMEM;
-           }
-       }
-       et->caddr->val = v4_addr;
-       et->caddr->len = 1;
-    } else {
-       krb5_free_address(context, v4_addr);
-       free(v4_addr);
-    }
-    return 0;
-}
-
-
-static krb5_error_code
-encrypt_v4_ticket(krb5_context context,
-                 krb5_kdc_configuration *config,
-                 void *buf,
-                 size_t len,
-                 krb5_keyblock *skey,
-                 EncryptedData *reply)
-{
-    krb5_crypto crypto;
-    krb5_error_code ret;
-    ret = krb5_crypto_init(context, skey, ETYPE_DES_PCBC_NONE, &crypto);
-    if (ret) {
-       free(buf);
-       kdc_log(context, config, 0, "krb5_crypto_init failed: %s",
-               krb5_get_err_text(context, ret));
-       return ret;
-    }
-
-    ret = krb5_encrypt_EncryptedData(context,
-                                    crypto,
-                                    KRB5_KU_TICKET,
-                                    buf,
-                                    len,
-                                    0,
-                                    reply);
-    krb5_crypto_destroy(context, crypto);
-    if(ret) {
-       kdc_log(context, config, 0, "Failed to encrypt data: %s",
-               krb5_get_err_text(context, ret));
-       return ret;
-    }
-    return 0;
-}
-
-static krb5_error_code
-encode_524_response(krb5_context context,
-                   krb5_kdc_configuration *config,
-                   const char *spn, const EncTicketPart et,
-                   const Ticket *t, hdb_entry_ex *server,
-                   EncryptedData *ticket, int *kvno)
-{
-    krb5_error_code ret;
-    int use_2b;
-    size_t len;
-
-    use_2b = krb5_config_get_bool(context, NULL, "kdc", "use_2b", spn, NULL);
-    if(use_2b) {
-       ASN1_MALLOC_ENCODE(EncryptedData,
-                          ticket->cipher.data, ticket->cipher.length,
-                          &t->enc_part, &len, ret);
-       
-       if (ret) {
-           kdc_log(context, config, 0,
-                   "Failed to encode v4 (2b) ticket (%s)", spn);
-           return ret;
-       }
-       
-       ticket->etype = 0;
-       ticket->kvno = NULL;
-       *kvno = 213; /* 2b's use this magic kvno */
-    } else {
-       unsigned char buf[MAX_KTXT_LEN + 4 * 4];
-       Key *skey;
-       
-       if (!config->enable_v4_cross_realm && strcmp (et.crealm, t->realm) != 0) {
-           kdc_log(context, config, 0, "524 cross-realm %s -> %s disabled", et.crealm,
-                   t->realm);
-           return KRB5KDC_ERR_POLICY;
-       }
-
-       ret = _kdc_encode_v4_ticket(context, config,
-                                   buf + sizeof(buf) - 1, sizeof(buf),
-                                   &et, &t->sname, &len);
-       if(ret){
-           kdc_log(context, config, 0,
-                   "Failed to encode v4 ticket (%s)", spn);
-           return ret;
-       }
-       ret = _kdc_get_des_key(context, server, TRUE, FALSE, &skey);
-       if(ret){
-           kdc_log(context, config, 0,
-                   "no suitable DES key for server (%s)", spn);
-           return ret;
-       }
-       ret = encrypt_v4_ticket(context, config, buf + sizeof(buf) - len, len,
-                               &skey->key, ticket);
-       if(ret){
-           kdc_log(context, config, 0,
-                   "Failed to encrypt v4 ticket (%s)", spn);
-           return ret;
-       }
-       *kvno = server->entry.kvno;
-    }
-
-    return 0;
-}
-
-/*
- * process a 5->4 request, based on `t', and received `from, addr',
- * returning the reply in `reply'
- */
-
-krb5_error_code
-_kdc_do_524(krb5_context context,
-           krb5_kdc_configuration *config,
-           const Ticket *t, krb5_data *reply,
-           const char *from, struct sockaddr *addr)
-{
-    krb5_error_code ret = 0;
-    krb5_crypto crypto;
-    hdb_entry_ex *server = NULL;
-    Key *skey;
-    krb5_data et_data;
-    EncTicketPart et;
-    EncryptedData ticket;
-    krb5_storage *sp;
-    char *spn = NULL;
-    unsigned char buf[MAX_KTXT_LEN + 4 * 4];
-    size_t len;
-    int kvno = 0;
-
-    if(!config->enable_524) {
-       ret = KRB5KDC_ERR_POLICY;
-       kdc_log(context, config, 0,
-               "Rejected ticket conversion request from %s", from);
-       goto out;
-    }
-
-    ret = fetch_server (context, config, t, &spn, &server, from);
-    if (ret) {
-       goto out;
-    }
-
-    ret = hdb_enctype2key(context, &server->entry, t->enc_part.etype, &skey);
-    if(ret){
-       kdc_log(context, config, 0,
-               "No suitable key found for server (%s) from %s", spn, from);
-       goto out;
-    }
-    ret = krb5_crypto_init(context, &skey->key, 0, &crypto);
-    if (ret) {
-       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_TICKET,
-                                     &t->enc_part,
-                                     &et_data);
-    krb5_crypto_destroy(context, crypto);
-    if(ret){
-       kdc_log(context, config, 0,
-               "Failed to decrypt ticket from %s for %s", from, spn);
-       goto out;
-    }
-    ret = krb5_decode_EncTicketPart(context, et_data.data, et_data.length,
-                                   &et, &len);
-    krb5_data_free(&et_data);
-    if(ret){
-       kdc_log(context, config, 0,
-               "Failed to decode ticket from %s for %s", from, spn);
-       goto out;
-    }
-
-    ret = log_524 (context, config, &et, from, spn);
-    if (ret) {
-       free_EncTicketPart(&et);
-       goto out;
-    }
-
-    ret = verify_flags (context, config, &et, spn);
-    if (ret) {
-       free_EncTicketPart(&et);
-       goto out;
-    }
-
-    ret = set_address (context, config, &et, addr, from);
-    if (ret) {
-       free_EncTicketPart(&et);
-       goto out;
-    }
-
-    ret = encode_524_response(context, config, spn, et, t,
-                             server, &ticket, &kvno);
-    free_EncTicketPart(&et);
-
- out:
-    /* make reply */
-    memset(buf, 0, sizeof(buf));
-    sp = krb5_storage_from_mem(buf, sizeof(buf));
-    if (sp) {
-       krb5_store_int32(sp, ret);
-       if(ret == 0){
-           krb5_store_int32(sp, kvno);
-           krb5_store_data(sp, ticket.cipher);
-           /* Aargh! This is coded as a KTEXT_ST. */
-           krb5_storage_seek(sp, MAX_KTXT_LEN - ticket.cipher.length, SEEK_CUR);
-           krb5_store_int32(sp, 0); /* mbz */
-           free_EncryptedData(&ticket);
-       }
-       ret = krb5_storage_to_data(sp, reply);
-       reply->length = krb5_storage_seek(sp, 0, SEEK_CUR);
-       krb5_storage_free(sp);
-    } else
-       krb5_data_zero(reply);
-    if(spn)
-       free(spn);
-    if(server)
-       _kdc_free_ent (context, server);
-    return ret;
-}
index 60fbc92903ce926e035f8d35460d891f72419373..bf65af3cb9e3ea72f69c67e81474334d2b8f57c7 100644 (file)
@@ -84,6 +84,7 @@ krb5_kdc_get_config(krb5_context context, krb5_kdc_configuration **config)
        krb5_config_get_bool_default(context, NULL,
                                     c->enable_v4,
                                     "kdc", "enable-524", NULL);
        krb5_config_get_bool_default(context, NULL,
                                     c->enable_v4,
                                     "kdc", "enable-524", NULL);
+#ifdef DIGEST
     c->enable_digest =
        krb5_config_get_bool_default(context, NULL,
                                     FALSE,
     c->enable_digest =
        krb5_config_get_bool_default(context, NULL,
                                     FALSE,
@@ -110,7 +111,9 @@ krb5_kdc_get_config(krb5_context context, krb5_kdc_configuration **config)
            c->enable_digest = 0;
        }
     }
            c->enable_digest = 0;
        }
     }
+#endif
 
 
+#ifdef KX509
     c->enable_kx509 =
        krb5_config_get_bool_default(context, NULL,
                                     FALSE,
     c->enable_kx509 =
        krb5_config_get_bool_default(context, NULL,
                                     FALSE,
@@ -129,6 +132,7 @@ krb5_kdc_get_config(krb5_context context, krb5_kdc_configuration **config)
            c->enable_kx509 = FALSE;
        }
     }
            c->enable_kx509 = FALSE;
        }
     }
+#endif
 
     c->check_ticket_addresses =
        krb5_config_get_bool_default(context, NULL,
 
     c->check_ticket_addresses =
        krb5_config_get_bool_default(context, NULL,
@@ -220,7 +224,7 @@ krb5_kdc_get_config(krb5_context context, krb5_kdc_configuration **config)
                                     "enable-pkinit",
                                     NULL);
     if (c->enable_pkinit) {
                                     "enable-pkinit",
                                     NULL);
     if (c->enable_pkinit) {
-       const char *user_id, *anchors, *ocsp_file;
+       const char *user_id, *anchors, *file;
        char **pool_list, **revoke_list;
 
        user_id =
        char **pool_list, **revoke_list;
 
        user_id =
@@ -242,15 +246,23 @@ krb5_kdc_get_config(krb5_context context, krb5_kdc_configuration **config)
            krb5_config_get_strings(context, NULL,
                                    "kdc", "pkinit_revoke", NULL);
 
            krb5_config_get_strings(context, NULL,
                                    "kdc", "pkinit_revoke", NULL);
 
-       ocsp_file =
-           krb5_config_get_string(context, NULL,
-                                  "kdc", "pkinit_kdc_ocsp", NULL);
-       if (ocsp_file) {
-           c->pkinit_kdc_ocsp_file = strdup(ocsp_file);
+       file = krb5_config_get_string(context, NULL,
+                                     "kdc", "pkinit_kdc_ocsp", NULL);
+       if (file) {
+           c->pkinit_kdc_ocsp_file = strdup(file);
            if (c->pkinit_kdc_ocsp_file == NULL)
                krb5_errx(context, 1, "out of memory");
        }
 
            if (c->pkinit_kdc_ocsp_file == NULL)
                krb5_errx(context, 1, "out of memory");
        }
 
+       file = krb5_config_get_string(context, NULL,
+                                     "kdc", "pkinit_kdc_friendly_name", NULL);
+       if (file) {
+           c->pkinit_kdc_friendly_name = strdup(file);
+           if (c->pkinit_kdc_friendly_name == NULL)
+               krb5_errx(context, 1, "out of memory");
+       }
+
+
        _kdc_pk_initialize(context, c, user_id, anchors,
                           pool_list, revoke_list);
 
        _kdc_pk_initialize(context, c, user_id, anchors,
                           pool_list, revoke_list);
 
index 96986c1a877d3ab20582d884bb46967e10d7fc74..d13507fc1f80b8f55f5c8a70bab825b4f289ecfe 100644 (file)
@@ -34,7 +34,7 @@
 #include "kdc_locl.h"
 #include <hex.h>
 
 #include "kdc_locl.h"
 #include <hex.h>
 
-RCSID("$Id$");
+#ifdef DIGEST
 
 #define MS_CHAP_V2     0x20
 #define CHAP_MD5       0x10
 
 #define MS_CHAP_V2     0x20
 #define CHAP_MD5       0x10
@@ -201,7 +201,7 @@ get_password_entry(krb5_context context,
 krb5_error_code
 _kdc_do_digest(krb5_context context,
               krb5_kdc_configuration *config,
 krb5_error_code
 _kdc_do_digest(krb5_context context,
               krb5_kdc_configuration *config,
-              const DigestREQ *req, krb5_data *reply,
+              const struct DigestREQ *req, krb5_data *reply,
               const char *from, struct sockaddr *addr)
 {
     krb5_error_code ret = 0;
               const char *from, struct sockaddr *addr)
 {
     krb5_error_code ret = 0;
@@ -234,6 +234,7 @@ _kdc_do_digest(krb5_context context,
     memset(&ireq, 0, sizeof(ireq));
     memset(&r, 0, sizeof(r));
     memset(&rep, 0, sizeof(rep));
     memset(&ireq, 0, sizeof(ireq));
     memset(&r, 0, sizeof(r));
     memset(&rep, 0, sizeof(rep));
+    memset(&res, 0, sizeof(res));
 
     kdc_log(context, config, 0, "Digest request from %s", from);
 
 
     kdc_log(context, config, 0, "Digest request from %s", from);
 
@@ -487,6 +488,7 @@ _kdc_do_digest(krb5_context context,
 
        hex_encode(buf.data, buf.length, &r.u.initReply.opaque);
        free(buf.data);
 
        hex_encode(buf.data, buf.length, &r.u.initReply.opaque);
        free(buf.data);
+       krb5_data_zero(&buf);
        if (r.u.initReply.opaque == NULL) {
            krb5_clear_error_message(context);
            ret = ENOMEM;
        if (r.u.initReply.opaque == NULL) {
            krb5_clear_error_message(context);
            ret = ENOMEM;
@@ -539,8 +541,10 @@ _kdc_do_digest(krb5_context context,
 
        ret = decode_Checksum(buf.data, buf.length, &res, NULL);
        free(buf.data);
 
        ret = decode_Checksum(buf.data, buf.length, &res, NULL);
        free(buf.data);
+       krb5_data_zero(&buf);
        if (ret) {
        if (ret) {
-           krb5_set_error_message(context, ret, "Failed to decode digest Checksum");
+           krb5_set_error_message(context, ret,
+                                  "Failed to decode digest Checksum");
            goto out;
        }
        
            goto out;
        }
        
@@ -582,6 +586,8 @@ _kdc_do_digest(krb5_context context,
        ret = krb5_verify_checksum(context, crypto,
                                   KRB5_KU_DIGEST_OPAQUE,
                                   buf.data, buf.length, &res);
        ret = krb5_verify_checksum(context, crypto,
                                   KRB5_KU_DIGEST_OPAQUE,
                                   buf.data, buf.length, &res);
+       free_Checksum(&res);
+       krb5_data_free(&buf);
        krb5_crypto_destroy(context, crypto);
        crypto = NULL;
        if (ret)
        krb5_crypto_destroy(context, crypto);
        crypto = NULL;
        if (ret)
@@ -1165,6 +1171,8 @@ _kdc_do_digest(krb5_context context,
            krb5_set_error_message(context, ret, "NTLM storage read flags");
            goto out;
        }
            krb5_set_error_message(context, ret, "NTLM storage read flags");
            goto out;
        }
+       krb5_storage_free(sp);
+       sp = NULL;
        krb5_data_free(&buf);
 
        if ((flags & NTLM_NEG_NTLM) == 0) {
        krb5_data_free(&buf);
 
        if ((flags & NTLM_NEG_NTLM) == 0) {
@@ -1450,9 +1458,12 @@ _kdc_do_digest(krb5_context context,
        free (client_name);
     krb5_data_free(&buf);
     krb5_data_free(&serverNonce);
        free (client_name);
     krb5_data_free(&buf);
     krb5_data_free(&serverNonce);
+    free_Checksum(&res);
     free_DigestREP(&rep);
     free_DigestRepInner(&r);
     free_DigestReqInner(&ireq);
 
     return ret;
 }
     free_DigestREP(&rep);
     free_DigestRepInner(&r);
     free_DigestReqInner(&ireq);
 
     return ret;
 }
+
+#endif /* DIGEST */
index 3635d3c56a885b88150e2a18b71ffe325e864e00..2240336e31f3789aea4e38a31185da69937452af 100644 (file)
 #include <parse_units.h>
 #include <krb5.h>
 #include <krb5_locl.h>
 #include <parse_units.h>
 #include <krb5.h>
 #include <krb5_locl.h>
+#ifdef DIGEST
 #include <digest_asn1.h>
 #include <digest_asn1.h>
+#endif
+#ifdef KX509
 #include <kx509_asn1.h>
 #include <kx509_asn1.h>
+#endif
 #include <hdb.h>
 #include <hdb_err.h>
 #include <der.h>
 
 #include <hdb.h>
 #include <hdb_err.h>
 #include <der.h>
 
+#ifndef NO_NTLM
 #include <heimntlm.h>
 #include <heimntlm.h>
+#endif
 #include <windc_plugin.h>
 
 #undef ALLOC
 #include <windc_plugin.h>
 
 #undef ALLOC
index 9226ae115db0b9353679a6bf4d40bc20f3daae17..3702ab9281291836d18a78fa8bf31b6643edebd5 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "kdc_locl.h"
 
 
 #include "kdc_locl.h"
 
-RCSID("$Id$");
+#ifdef KRB4
 
 #include <krb5-v4compat.h>
 #include <rx.h>
 
 #include <krb5-v4compat.h>
 #include <rx.h>
@@ -949,3 +949,5 @@ out:
     krb5_storage_free (sp);
     return ret;
 }
     krb5_storage_free (sp);
     return ret;
 }
+
+#endif /* KRB4 */
index 843bd5fa5689df16cc789e437287a7d974259e8c..285a33af14ae32d75086c99c222c9f73747e29da 100644 (file)
@@ -75,8 +75,10 @@ typedef struct krb5_kdc_configuration {
     krb5_boolean enable_pkinit;
     krb5_boolean pkinit_princ_in_cert;
     char *pkinit_kdc_ocsp_file;
     krb5_boolean enable_pkinit;
     krb5_boolean pkinit_princ_in_cert;
     char *pkinit_kdc_ocsp_file;
+    char *pkinit_kdc_friendly_name;
     int pkinit_dh_min_bits;
     int pkinit_require_binding;
     int pkinit_dh_min_bits;
     int pkinit_require_binding;
+    int pkinit_allow_proxy_certs;
 
     krb5_log_facility *logf;
 
 
     krb5_log_facility *logf;
 
@@ -91,6 +93,20 @@ typedef struct krb5_kdc_configuration {
 
 } krb5_kdc_configuration;
 
 
 } krb5_kdc_configuration;
 
+struct krb5_kdc_service {
+    unsigned int flags;
+#define KS_KRB5                1
+#define KS_NO_LENGTH   2
+    krb5_error_code (*process)(krb5_context context,
+                              krb5_kdc_configuration *config,
+                              krb5_data *req_buffer,
+                              krb5_data *reply,
+                              const char *from,
+                              struct sockaddr *addr,
+                              int datagram_reply,
+                              int *claim);
+};
+
 #include <kdc-protos.h>
 
 #endif
 #include <kdc-protos.h>
 
 #endif
index 8e34c50049aa267b701c246494dec3b9ff713fab..9b291ac896511314b51cd1cdbde617c4a10098f7 100644 (file)
@@ -42,6 +42,8 @@
 #include "kdc.h"
 
 typedef struct pk_client_params pk_client_params;
 #include "kdc.h"
 
 typedef struct pk_client_params pk_client_params;
+struct DigestREQ;
+struct Kx509Request;
 #include <kdc-private.h>
 
 extern sig_atomic_t exit_flag;
 #include <kdc-private.h>
 
 extern sig_atomic_t exit_flag;
@@ -52,9 +54,12 @@ extern krb5_addresses explicit_addresses;
 
 extern int enable_http;
 
 
 extern int enable_http;
 
+#ifdef SUPPORT_DETACH
+
 #define DETACH_IS_DEFAULT FALSE
 
 extern int detach_from_console;
 #define DETACH_IS_DEFAULT FALSE
 
 extern int detach_from_console;
+#endif
 
 extern const struct units _kdc_digestunits[];
 
 
 extern const struct units _kdc_digestunits[];
 
diff --git a/source4/heimdal/kdc/kerberos4.c b/source4/heimdal/kdc/kerberos4.c
deleted file mode 100644 (file)
index 2bd2383..0000000
+++ /dev/null
@@ -1,794 +0,0 @@
-/*
- * 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"
-
-#include <krb5-v4compat.h>
-
-RCSID("$Id$");
-
-#ifndef swap32
-static uint32_t
-swap32(uint32_t x)
-{
-    return ((x << 24) & 0xff000000) |
-       ((x << 8) & 0xff0000) |
-       ((x >> 8) & 0xff00) |
-       ((x >> 24) & 0xff);
-}
-#endif /* swap32 */
-
-int
-_kdc_maybe_version4(unsigned char *buf, int len)
-{
-    return len > 0 && *buf == 4;
-}
-
-static void
-make_err_reply(krb5_context context, krb5_data *reply,
-              int code, const char *msg)
-{
-    _krb5_krb_cr_err_reply(context, "", "", "",
-                          kdc_time, code, msg, reply);
-}
-
-struct valid_princ_ctx {
-    krb5_kdc_configuration *config;
-    unsigned flags;
-};
-
-static krb5_boolean
-valid_princ(krb5_context context,
-           void *funcctx,
-           krb5_principal princ)
-{
-    struct valid_princ_ctx *ctx = funcctx;
-    krb5_error_code ret;
-    char *s;
-    hdb_entry_ex *ent;
-
-    ret = krb5_unparse_name(context, princ, &s);
-    if (ret)
-       return FALSE;
-    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));
-       free(s);
-       return FALSE;
-    }
-    kdc_log(context, ctx->config, 7, "Lookup %s succeeded", s);
-    free(s);
-    _kdc_free_ent(context, ent);
-    return TRUE;
-}
-
-krb5_error_code
-_kdc_db_fetch4(krb5_context context,
-              krb5_kdc_configuration *config,
-              const char *name, const char *instance, const char *realm,
-              unsigned flags,
-              hdb_entry_ex **ent)
-{
-    krb5_principal p;
-    krb5_error_code ret;
-    struct valid_princ_ctx ctx;
-
-    ctx.config = config;
-    ctx.flags = flags;
-
-    ret = krb5_425_conv_principal_ext2(context, name, instance, realm,
-                                      valid_princ, &ctx, 0, &p);
-    if(ret)
-       return ret;
-    ret = _kdc_db_fetch(context, config, p, flags, NULL, ent);
-    krb5_free_principal(context, p);
-    return ret;
-}
-
-#define RCHECK(X, L) if(X){make_err_reply(context, reply, KFAILURE, "Packet too short"); goto L;}
-
-/*
- * Process the v4 request in `buf, len' (received from `addr'
- * (with string `from').
- * Return an error code and a reply in `reply'.
- */
-
-krb5_error_code
-_kdc_do_version4(krb5_context context,
-                krb5_kdc_configuration *config,
-                unsigned char *buf,
-                size_t len,
-                krb5_data *reply,
-                const char *from,
-                struct sockaddr_in *addr)
-{
-    krb5_storage *sp;
-    krb5_error_code ret = EINVAL;
-    hdb_entry_ex *client = NULL, *server = NULL;
-    Key *ckey, *skey;
-    int8_t pvno;
-    int8_t msg_type;
-    int lsb;
-    char *name = NULL, *inst = NULL, *realm = NULL;
-    char *sname = NULL, *sinst = NULL;
-    int32_t req_time;
-    time_t max_life;
-    uint8_t life;
-    char client_name[256];
-    char server_name[256];
-
-    if(!config->enable_v4) {
-       kdc_log(context, config, 0,
-               "Rejected version 4 request from %s", from);
-       make_err_reply(context, reply, KRB4ET_KDC_GEN_ERR,
-                      "Function not enabled");
-       return 0;
-    }
-
-    sp = krb5_storage_from_mem(buf, len);
-    RCHECK(krb5_ret_int8(sp, &pvno), out);
-    if(pvno != 4){
-       kdc_log(context, config, 0,
-               "Protocol version mismatch (krb4) (%d)", pvno);
-       make_err_reply(context, reply, KRB4ET_KDC_PKT_VER, "protocol mismatch");
-       ret = KRB4ET_KDC_PKT_VER;
-       goto out;
-    }
-    RCHECK(krb5_ret_int8(sp, &msg_type), out);
-    lsb = msg_type & 1;
-    msg_type &= ~1;
-    switch(msg_type){
-    case AUTH_MSG_KDC_REQUEST: {
-       krb5_data ticket, cipher;
-       krb5_keyblock session;
-       
-       krb5_data_zero(&ticket);
-       krb5_data_zero(&cipher);
-
-       RCHECK(krb5_ret_stringz(sp, &name), out1);
-       RCHECK(krb5_ret_stringz(sp, &inst), out1);
-       RCHECK(krb5_ret_stringz(sp, &realm), out1);
-       RCHECK(krb5_ret_int32(sp, &req_time), out1);
-       if(lsb)
-           req_time = swap32(req_time);
-       RCHECK(krb5_ret_uint8(sp, &life), out1);
-       RCHECK(krb5_ret_stringz(sp, &sname), out1);
-       RCHECK(krb5_ret_stringz(sp, &sinst), out1);
-       snprintf (client_name, sizeof(client_name),
-                 "%s.%s@%s", name, inst, realm);
-       snprintf (server_name, sizeof(server_name),
-                 "%s.%s@%s", sname, sinst, config->v4_realm);
-       
-       kdc_log(context, config, 0, "AS-REQ (krb4) %s from %s for %s",
-               client_name, from, server_name);
-
-       ret = _kdc_db_fetch4(context, config, name, inst, realm,
-                            HDB_F_GET_CLIENT, &client);
-       if(ret) {
-           kdc_log(context, config, 0, "Client not found in database: %s: %s",
-                   client_name, krb5_get_err_text(context, ret));
-           make_err_reply(context, reply, KRB4ET_KDC_PR_UNKNOWN,
-                          "principal unknown");
-           goto out1;
-       }
-       ret = _kdc_db_fetch4(context, config, sname, sinst, config->v4_realm,
-                            HDB_F_GET_SERVER, &server);
-       if(ret){
-           kdc_log(context, config, 0, "Server not found in database: %s: %s",
-                   server_name, krb5_get_err_text(context, ret));
-           make_err_reply(context, reply, KRB4ET_KDC_PR_UNKNOWN,
-                          "principal unknown");
-           goto out1;
-       }
-
-       ret = _kdc_check_flags (context, config,
-                               client, client_name,
-                               server, server_name,
-                               TRUE);
-       if (ret) {
-           /* good error code? */
-           make_err_reply(context, reply, KRB4ET_KDC_NAME_EXP,
-                          "operation not allowed");
-           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, KRB4ET_KDC_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.
-        */
-
-       if (config->require_preauth
-           || client->entry.flags.require_preauth
-           || server->entry.flags.require_preauth) {
-           kdc_log(context, config, 0,
-                   "Pre-authentication required for v4-request: "
-                   "%s for %s",
-                   client_name, server_name);
-           make_err_reply(context, reply, KRB4ET_KDC_NULL_KEY,
-                          "preauth required");
-           goto out1;
-       }
-
-       ret = _kdc_get_des_key(context, client, FALSE, FALSE, &ckey);
-       if(ret){
-           kdc_log(context, config, 0, "no suitable DES key for client");
-           make_err_reply(context, reply, KRB4ET_KDC_NULL_KEY,
-                          "no suitable DES key for client");
-           goto out1;
-       }
-
-       ret = _kdc_get_des_key(context, server, TRUE, FALSE, &skey);
-       if(ret){
-           kdc_log(context, config, 0, "no suitable DES key for server");
-           make_err_reply(context, reply, KRB4ET_KDC_NULL_KEY,
-                          "no suitable DES key for server");
-           goto out1;
-       }
-
-       max_life = _krb5_krb_life_to_time(0, life);
-       if(client->entry.max_life)
-           max_life = min(max_life, *client->entry.max_life);
-       if(server->entry.max_life)
-           max_life = min(max_life, *server->entry.max_life);
-
-       life = krb_time_to_life(kdc_time, kdc_time + max_life);
-
-       ret = krb5_generate_random_keyblock(context,
-                                           ETYPE_DES_PCBC_NONE,
-                                           &session);
-       if (ret) {
-           make_err_reply(context, reply, KFAILURE,
-                          "Not enough random i KDC");
-           goto out1;
-       }
-       
-       ret = _krb5_krb_create_ticket(context,
-                                     0,
-                                     name,
-                                     inst,
-                                     config->v4_realm,
-                                     addr->sin_addr.s_addr,
-                                     &session,
-                                     life,
-                                     kdc_time,
-                                     sname,
-                                     sinst,
-                                     &skey->key,
-                                     &ticket);
-       if (ret) {
-           krb5_free_keyblock_contents(context, &session);
-           make_err_reply(context, reply, KFAILURE,
-                          "failed to create v4 ticket");
-           goto out1;
-       }
-
-       ret = _krb5_krb_create_ciph(context,
-                                   &session,
-                                   sname,
-                                   sinst,
-                                   config->v4_realm,
-                                   life,
-                                   server->entry.kvno % 255,
-                                   &ticket,
-                                   kdc_time,
-                                   &ckey->key,
-                                   &cipher);
-       krb5_free_keyblock_contents(context, &session);
-       krb5_data_free(&ticket);
-       if (ret) {
-           make_err_reply(context, reply, KFAILURE,
-                          "Failed to create v4 cipher");
-           goto out1;
-       }
-       
-       ret = _krb5_krb_create_auth_reply(context,
-                                         name,
-                                         inst,
-                                         realm,
-                                         req_time,
-                                         0,
-                                         client->entry.pw_end ? *client->entry.pw_end : 0,
-                                         client->entry.kvno % 256,
-                                         &cipher,
-                                         reply);
-       krb5_data_free(&cipher);
-
-    out1:
-       break;
-    }
-    case AUTH_MSG_APPL_REQUEST: {
-       struct _krb5_krb_auth_data ad;
-       int8_t kvno;
-       int8_t ticket_len;
-       int8_t req_len;
-       krb5_data auth;
-       int32_t address;
-       size_t pos;
-       krb5_principal tgt_princ = NULL;
-       hdb_entry_ex *tgt = NULL;
-       Key *tkey;
-       time_t max_end, actual_end, issue_time;
-       
-       memset(&ad, 0, sizeof(ad));
-       krb5_data_zero(&auth);
-
-       RCHECK(krb5_ret_int8(sp, &kvno), out2);
-       RCHECK(krb5_ret_stringz(sp, &realm), out2);
-       
-       ret = krb5_425_conv_principal(context, "krbtgt", realm,
-                                     config->v4_realm,
-                                     &tgt_princ);
-       if(ret){
-           kdc_log(context, config, 0,
-                   "Converting krbtgt principal (krb4): %s",
-                   krb5_get_err_text(context, ret));
-           make_err_reply(context, reply, KFAILURE,
-                          "Failed to convert v4 principal (krbtgt)");
-           goto out2;
-       }
-
-       ret = _kdc_db_fetch(context, config, tgt_princ,
-                           HDB_F_GET_KRBTGT, NULL, &tgt);
-       if(ret){
-           char *s;
-           s = kdc_log_msg(context, config, 0, "Ticket-granting ticket not "
-                           "found in database (krb4): krbtgt.%s@%s: %s",
-                           realm, config->v4_realm,
-                           krb5_get_err_text(context, ret));
-           make_err_reply(context, reply, KFAILURE, s);
-           free(s);
-           goto out2;
-       }
-       
-       if(tgt->entry.kvno % 256 != kvno){
-           kdc_log(context, config, 0,
-                   "tgs-req (krb4) with old kvno %d (current %d) for "
-                   "krbtgt.%s@%s", kvno, tgt->entry.kvno % 256,
-                   realm, config->v4_realm);
-           make_err_reply(context, reply, KRB4ET_KDC_AUTH_EXP,
-                          "old krbtgt kvno used");
-           goto out2;
-       }
-
-       ret = _kdc_get_des_key(context, tgt, TRUE, FALSE, &tkey);
-       if(ret){
-           kdc_log(context, config, 0,
-                   "no suitable DES key for krbtgt (krb4)");
-           make_err_reply(context, reply, KRB4ET_KDC_NULL_KEY,
-                          "no suitable DES key for krbtgt");
-           goto out2;
-       }
-
-       RCHECK(krb5_ret_int8(sp, &ticket_len), out2);
-       RCHECK(krb5_ret_int8(sp, &req_len), out2);
-       
-       pos = krb5_storage_seek(sp, ticket_len + req_len, SEEK_CUR);
-       
-       auth.data = buf;
-       auth.length = pos;
-
-       if (config->check_ticket_addresses)
-           address = addr->sin_addr.s_addr;
-       else
-           address = 0;
-
-       ret = _krb5_krb_rd_req(context, &auth, "krbtgt", realm,
-                              config->v4_realm,
-                              address, &tkey->key, &ad);
-       if(ret){
-           kdc_log(context, config, 0, "krb_rd_req: %d", ret);
-           make_err_reply(context, reply, ret, "failed to parse request");
-           goto out2;
-       }
-       
-       RCHECK(krb5_ret_int32(sp, &req_time), out2);
-       if(lsb)
-           req_time = swap32(req_time);
-       RCHECK(krb5_ret_uint8(sp, &life), out2);
-       RCHECK(krb5_ret_stringz(sp, &sname), out2);
-       RCHECK(krb5_ret_stringz(sp, &sinst), out2);
-       snprintf (server_name, sizeof(server_name),
-                 "%s.%s@%s",
-                 sname, sinst, config->v4_realm);
-       snprintf (client_name, sizeof(client_name),
-                 "%s.%s@%s",
-                 ad.pname, ad.pinst, ad.prealm);
-
-       kdc_log(context, config, 0, "TGS-REQ (krb4) %s from %s for %s",
-               client_name, from, server_name);
-       
-       if(strcmp(ad.prealm, realm)){
-           kdc_log(context, config, 0,
-                   "Can't hop realms (krb4) %s -> %s", realm, ad.prealm);
-           make_err_reply(context, reply, KRB4ET_KDC_PR_UNKNOWN,
-                          "Can't hop realms");
-           goto out2;
-       }
-
-       if (!config->enable_v4_cross_realm && strcmp(realm, config->v4_realm) != 0) {
-           kdc_log(context, config, 0,
-                   "krb4 Cross-realm %s -> %s disabled",
-                   realm, config->v4_realm);
-           make_err_reply(context, reply, KRB4ET_KDC_PR_UNKNOWN,
-                          "Can't hop realms");
-           goto out2;
-       }
-
-       if(strcmp(sname, "changepw") == 0){
-           kdc_log(context, config, 0,
-                   "Bad request for changepw ticket (krb4)");
-           make_err_reply(context, reply, KRB4ET_KDC_PR_UNKNOWN,
-                          "Can't authorize password change based on TGT");
-           goto out2;
-       }
-       
-       ret = _kdc_db_fetch4(context, config, ad.pname, ad.pinst, ad.prealm,
-                            HDB_F_GET_CLIENT, &client);
-       if(ret && ret != HDB_ERR_NOENTRY) {
-           char *s;
-           s = kdc_log_msg(context, config, 0,
-                           "Client not found in database: (krb4) %s: %s",
-                           client_name, krb5_get_err_text(context, ret));
-           make_err_reply(context, reply, KRB4ET_KDC_PR_UNKNOWN, s);
-           free(s);
-           goto out2;
-       }
-       if (client == NULL && strcmp(ad.prealm, config->v4_realm) == 0) {
-           char *s;
-           s = kdc_log_msg(context, config, 0,
-                           "Local client not found in database: (krb4) "
-                           "%s", client_name);
-           make_err_reply(context, reply, KRB4ET_KDC_PR_UNKNOWN, s);
-           free(s);
-           goto out2;
-       }
-
-       ret = _kdc_db_fetch4(context, config, sname, sinst, config->v4_realm,
-                            HDB_F_GET_SERVER, &server);
-       if(ret){
-           char *s;
-           s = kdc_log_msg(context, config, 0,
-                           "Server not found in database (krb4): %s: %s",
-                           server_name, krb5_get_err_text(context, ret));
-           make_err_reply(context, reply, KRB4ET_KDC_PR_UNKNOWN, s);
-           free(s);
-           goto out2;
-       }
-
-       ret = _kdc_check_flags (context, config,
-                               client, client_name,
-                               server, server_name,
-                               FALSE);
-       if (ret) {
-           make_err_reply(context, reply, KRB4ET_KDC_NAME_EXP,
-                          "operation not allowed");
-           goto out2;
-       }
-
-       ret = _kdc_get_des_key(context, server, TRUE, FALSE, &skey);
-       if(ret){
-           kdc_log(context, config, 0,
-                   "no suitable DES key for server (krb4)");
-           make_err_reply(context, reply, KRB4ET_KDC_NULL_KEY,
-                          "no suitable DES key for server");
-           goto out2;
-       }
-
-       max_end = _krb5_krb_life_to_time(ad.time_sec, ad.life);
-       max_end = min(max_end, _krb5_krb_life_to_time(kdc_time, life));
-       if(server->entry.max_life)
-           max_end = min(max_end, kdc_time + *server->entry.max_life);
-       if(client && client->entry.max_life)
-           max_end = min(max_end, kdc_time + *client->entry.max_life);
-       life = min(life, krb_time_to_life(kdc_time, max_end));
-       
-       issue_time = kdc_time;
-       actual_end = _krb5_krb_life_to_time(issue_time, life);
-       while (actual_end > max_end && life > 1) {
-           /* move them into the next earlier lifetime bracket */
-           life--;
-           actual_end = _krb5_krb_life_to_time(issue_time, life);
-       }
-       if (actual_end > max_end) {
-           /* if life <= 1 and it's still too long, backdate the ticket */
-           issue_time -= actual_end - max_end;
-       }
-
-       {
-           krb5_data ticket, cipher;
-           krb5_keyblock session;
-
-           krb5_data_zero(&ticket);
-           krb5_data_zero(&cipher);
-
-           ret = krb5_generate_random_keyblock(context,
-                                               ETYPE_DES_PCBC_NONE,
-                                               &session);
-           if (ret) {
-               make_err_reply(context, reply, KFAILURE,
-                              "Not enough random i KDC");
-               goto out2;
-           }
-       
-           ret = _krb5_krb_create_ticket(context,
-                                         0,
-                                         ad.pname,
-                                         ad.pinst,
-                                         ad.prealm,
-                                         addr->sin_addr.s_addr,
-                                         &session,
-                                         life,
-                                         issue_time,
-                                         sname,
-                                         sinst,
-                                         &skey->key,
-                                         &ticket);
-           if (ret) {
-               krb5_free_keyblock_contents(context, &session);
-               make_err_reply(context, reply, KFAILURE,
-                              "failed to create v4 ticket");
-               goto out2;
-           }
-
-           ret = _krb5_krb_create_ciph(context,
-                                       &session,
-                                       sname,
-                                       sinst,
-                                       config->v4_realm,
-                                       life,
-                                       server->entry.kvno % 255,
-                                       &ticket,
-                                       issue_time,
-                                       &ad.session,
-                                       &cipher);
-           krb5_free_keyblock_contents(context, &session);
-           if (ret) {
-               make_err_reply(context, reply, KFAILURE,
-                              "failed to create v4 cipher");
-               goto out2;
-           }
-       
-           ret = _krb5_krb_create_auth_reply(context,
-                                             ad.pname,
-                                             ad.pinst,
-                                             ad.prealm,
-                                             req_time,
-                                             0,
-                                             0,
-                                             0,
-                                             &cipher,
-                                             reply);
-           krb5_data_free(&cipher);
-       }
-    out2:
-       _krb5_krb_free_auth_data(context, &ad);
-       if(tgt_princ)
-           krb5_free_principal(context, tgt_princ);
-       if(tgt)
-           _kdc_free_ent(context, tgt);
-       break;
-    }
-    case AUTH_MSG_ERR_REPLY:
-       ret = EINVAL;
-       break;
-    default:
-       kdc_log(context, config, 0, "Unknown message type (krb4): %d from %s",
-               msg_type, from);
-       
-       make_err_reply(context, reply, KFAILURE, "Unknown message type");
-       ret = EINVAL;
-    }
- out:
-    if(name)
-       free(name);
-    if(inst)
-       free(inst);
-    if(realm)
-       free(realm);
-    if(sname)
-       free(sname);
-    if(sinst)
-       free(sinst);
-    if(client)
-       _kdc_free_ent(context, client);
-    if(server)
-       _kdc_free_ent(context, server);
-    krb5_storage_free(sp);
-    return ret;
-}
-
-krb5_error_code
-_kdc_encode_v4_ticket(krb5_context context,
-                     krb5_kdc_configuration *config,
-                     void *buf, size_t len, const EncTicketPart *et,
-                     const PrincipalName *service, size_t *size)
-{
-    krb5_storage *sp;
-    krb5_error_code ret;
-    char name[40], inst[40], realm[40];
-    char sname[40], sinst[40];
-
-    {
-       krb5_principal princ;
-       _krb5_principalname2krb5_principal(context,
-                                          &princ,
-                                          *service,
-                                          et->crealm);
-       ret = krb5_524_conv_principal(context,
-                                     princ,
-                                     sname,
-                                     sinst,
-                                     realm);
-       krb5_free_principal(context, princ);
-       if(ret)
-           return ret;
-
-       _krb5_principalname2krb5_principal(context,
-                                          &princ,
-                                          et->cname,
-                                          et->crealm);
-                               
-       ret = krb5_524_conv_principal(context,
-                                     princ,
-                                     name,
-                                     inst,
-                                     realm);
-       krb5_free_principal(context, princ);
-    }
-    if(ret)
-       return ret;
-
-    sp = krb5_storage_emem();
-
-    krb5_store_int8(sp, 0); /* flags */
-    krb5_store_stringz(sp, name);
-    krb5_store_stringz(sp, inst);
-    krb5_store_stringz(sp, realm);
-    {
-       unsigned char tmp[4] = { 0, 0, 0, 0 };
-       int i;
-       if(et->caddr){
-           for(i = 0; i < et->caddr->len; i++)
-               if(et->caddr->val[i].addr_type == AF_INET &&
-                  et->caddr->val[i].address.length == 4){
-                   memcpy(tmp, et->caddr->val[i].address.data, 4);
-                   break;
-               }
-       }
-       krb5_storage_write(sp, tmp, sizeof(tmp));
-    }
-
-    if((et->key.keytype != ETYPE_DES_CBC_MD5 &&
-       et->key.keytype != ETYPE_DES_CBC_MD4 &&
-       et->key.keytype != ETYPE_DES_CBC_CRC) ||
-       et->key.keyvalue.length != 8)
-       return -1;
-    krb5_storage_write(sp, et->key.keyvalue.data, 8);
-
-    {
-       time_t start = et->starttime ? *et->starttime : et->authtime;
-       krb5_store_int8(sp, krb_time_to_life(start, et->endtime));
-       krb5_store_int32(sp, start);
-    }
-
-    krb5_store_stringz(sp, sname);
-    krb5_store_stringz(sp, sinst);
-
-    {
-       krb5_data data;
-       krb5_storage_to_data(sp, &data);
-       krb5_storage_free(sp);
-       *size = (data.length + 7) & ~7; /* pad to 8 bytes */
-       if(*size > len)
-           return -1;
-       memset((unsigned char*)buf - *size + 1, 0, *size);
-       memcpy((unsigned char*)buf - *size + 1, data.data, data.length);
-       krb5_data_free(&data);
-    }
-    return 0;
-}
-
-krb5_error_code
-_kdc_get_des_key(krb5_context context,
-                hdb_entry_ex *principal, krb5_boolean is_server,
-                krb5_boolean prefer_afs_key, Key **ret_key)
-{
-    Key *v5_key = NULL, *v4_key = NULL, *afs_key = NULL, *server_key = NULL;
-    int i;
-    krb5_enctype etypes[] = { ETYPE_DES_CBC_MD5,
-                             ETYPE_DES_CBC_MD4,
-                             ETYPE_DES_CBC_CRC };
-
-    for(i = 0;
-       i < sizeof(etypes)/sizeof(etypes[0])
-           && (v5_key == NULL || v4_key == NULL ||
-               afs_key == NULL || server_key == NULL);
-       ++i) {
-       Key *key = NULL;
-       while(hdb_next_enctype2key(context, &principal->entry, etypes[i], &key) == 0) {
-           if(key->salt == NULL) {
-               if(v5_key == NULL)
-                   v5_key = key;
-           } else if(key->salt->type == hdb_pw_salt &&
-                     key->salt->salt.length == 0) {
-               if(v4_key == NULL)
-                   v4_key = key;
-           } else if(key->salt->type == hdb_afs3_salt) {
-               if(afs_key == NULL)
-                   afs_key = key;
-           } else if(server_key == NULL)
-               server_key = key;
-       }
-    }
-
-    if(prefer_afs_key) {
-       if(afs_key)
-           *ret_key = afs_key;
-       else if(v4_key)
-           *ret_key = v4_key;
-       else if(v5_key)
-           *ret_key = v5_key;
-       else if(is_server && server_key)
-           *ret_key = server_key;
-       else
-           return KRB4ET_KDC_NULL_KEY;
-    } else {
-       if(v4_key)
-           *ret_key = v4_key;
-       else if(afs_key)
-           *ret_key = afs_key;
-       else  if(v5_key)
-           *ret_key = v5_key;
-       else if(is_server && server_key)
-           *ret_key = server_key;
-       else
-           return KRB4ET_KDC_NULL_KEY;
-    }
-
-    if((*ret_key)->key.keyvalue.length == 0)
-       return KRB4ET_KDC_NULL_KEY;
-    return 0;
-}
-
index c715e0812f319c8aa7021a10637e5c5ad84366a4..941a2e0572e39be2de90228bea4c165e43627cc3 100644 (file)
@@ -90,7 +90,7 @@ _kdc_find_padata(const KDC_REQ *req, int *start, int type)
  */
 
 krb5_boolean
  */
 
 krb5_boolean
-_kdc_is_weak_expection(krb5_principal principal, krb5_enctype etype)
+_kdc_is_weak_exception(krb5_principal principal, krb5_enctype etype)
 {
     if (principal->name.name_string.len > 0 &&
        strcmp(principal->name.name_string.val[0], "afs") == 0 &&
 {
     if (principal->name.name_string.len > 0 &&
        strcmp(principal->name.name_string.val[0], "afs") == 0 &&
@@ -139,7 +139,7 @@ _kdc_find_etype(krb5_context context, const hdb_entry_ex *princ,
        Key *key = NULL;
 
        if (krb5_enctype_valid(context, etypes[i]) != 0 &&
        Key *key = NULL;
 
        if (krb5_enctype_valid(context, etypes[i]) != 0 &&
-           !_kdc_is_weak_expection(princ->entry.principal, etypes[i]))
+           !_kdc_is_weak_exception(princ->entry.principal, etypes[i]))
            continue;
 
        while (hdb_next_enctype2key(context, &princ->entry, etypes[i], &key) == 0) {
            continue;
 
        while (hdb_next_enctype2key(context, &princ->entry, etypes[i], &key) == 0) {
@@ -260,7 +260,7 @@ _kdc_encode_reply(krb5_context context,
                  KDC_REP *rep, const EncTicketPart *et, EncKDCRepPart *ek,
                  krb5_enctype etype,
                  int skvno, const EncryptionKey *skey,
                  KDC_REP *rep, const EncTicketPart *et, EncKDCRepPart *ek,
                  krb5_enctype etype,
                  int skvno, const EncryptionKey *skey,
-                 int ckvno, const EncryptionKey *ckey,
+                 int ckvno, const EncryptionKey *reply_key,
                  const char **e_text,
                  krb5_data *reply)
 {
                  const char **e_text,
                  krb5_data *reply)
 {
@@ -321,7 +321,7 @@ _kdc_encode_reply(krb5_context context,
        *e_text = "KDC internal error";
        return KRB5KRB_ERR_GENERIC;
     }
        *e_text = "KDC internal error";
        return KRB5KRB_ERR_GENERIC;
     }
-    ret = krb5_crypto_init(context, ckey, 0, &crypto);
+    ret = krb5_crypto_init(context, reply_key, 0, &crypto);
     if (ret) {
        free(buf);
        kdc_log(context, config, 0, "krb5_crypto_init failed: %s",
     if (ret) {
        free(buf);
        kdc_log(context, config, 0, "krb5_crypto_init failed: %s",
@@ -394,18 +394,6 @@ older_enctype(krb5_enctype enctype)
     }
 }
 
     }
 }
 
-static int
-only_older_enctype_p(const KDC_REQ *req)
-{
-    int i;
-
-    for(i = 0; i < req->req_body.etype.len; i++) {
-       if (!older_enctype(req->req_body.etype.val[i]))
-           return 0;
-    }
-    return 1;
-}
-
 /*
  *
  */
 /*
  *
  */
@@ -461,72 +449,23 @@ make_etype_info_entry(krb5_context context, ETYPE_INFO_ENTRY *ent, Key *key)
 static krb5_error_code
 get_pa_etype_info(krb5_context context,
                  krb5_kdc_configuration *config,
 static krb5_error_code
 get_pa_etype_info(krb5_context context,
                  krb5_kdc_configuration *config,
-                 METHOD_DATA *md, hdb_entry *client,
-                 ENCTYPE *etypes, unsigned int etypes_len)
+                 METHOD_DATA *md, Key *ckey)
 {
     krb5_error_code ret = 0;
 {
     krb5_error_code ret = 0;
-    int i, j;
-    unsigned int n = 0;
     ETYPE_INFO pa;
     unsigned char *buf;
     size_t len;
 
 
     ETYPE_INFO pa;
     unsigned char *buf;
     size_t len;
 
 
-    pa.len = client->keys.len;
-    if(pa.len > UINT_MAX/sizeof(*pa.val))
-       return ERANGE;
-    pa.val = malloc(pa.len * sizeof(*pa.val));
+    pa.len = 1;
+    pa.val = calloc(1, sizeof(pa.val[0]));
     if(pa.val == NULL)
        return ENOMEM;
     if(pa.val == NULL)
        return ENOMEM;
-    memset(pa.val, 0, pa.len * sizeof(*pa.val));
-
-    for(i = 0; i < client->keys.len; i++) {
-       for (j = 0; j < n; j++)
-           if (pa.val[j].etype == client->keys.val[i].key.keytype)
-               goto skip1;
-       for(j = 0; j < etypes_len; j++) {
-           if(client->keys.val[i].key.keytype == etypes[j]) {
-               if (krb5_enctype_valid(context, etypes[j]) != 0)
-                   continue;
-               if (!older_enctype(etypes[j]))
-                   continue;
-               if (n >= pa.len)
-                   krb5_abortx(context, "internal error: n >= p.len");
-               if((ret = make_etype_info_entry(context,
-                                               &pa.val[n++],
-                                               &client->keys.val[i])) != 0) {
-                   free_ETYPE_INFO(&pa);
-                   return ret;
-               }
-               break;
-           }
-       }
-    skip1:;
-    }
-    for(i = 0; i < client->keys.len; i++) {
-       /* already added? */
-       for(j = 0; j < etypes_len; j++) {
-           if(client->keys.val[i].key.keytype == etypes[j])
-               goto skip2;
-       }
-       if (krb5_enctype_valid(context, client->keys.val[i].key.keytype) != 0)
-           continue;
-       if (!older_enctype(etypes[j]))
-           continue;
-       if (n >= pa.len)
-           krb5_abortx(context, "internal error: n >= p.len");
-       if((ret = make_etype_info_entry(context,
-                                       &pa.val[n++],
-                                       &client->keys.val[i])) != 0) {
-           free_ETYPE_INFO(&pa);
-           return ret;
-       }
-    skip2:;
-    }
 
 
-    if(n < pa.len) {
-       /* stripped out dups, newer enctypes, and not valid enctypes */
-       pa.len = n;
+    ret = make_etype_info_entry(context, &pa.val[0], ckey);
+    if (ret) {
+       free_ETYPE_INFO(&pa);
+       return ret;
     }
 
     ASN1_MALLOC_ENCODE(ETYPE_INFO, buf, len, &pa, &len, ret);
     }
 
     ASN1_MALLOC_ENCODE(ETYPE_INFO, buf, len, &pa, &len, ret);
@@ -623,66 +562,22 @@ make_etype_info2_entry(ETYPE_INFO2_ENTRY *ent, Key *key)
 static krb5_error_code
 get_pa_etype_info2(krb5_context context,
                   krb5_kdc_configuration *config,
 static krb5_error_code
 get_pa_etype_info2(krb5_context context,
                   krb5_kdc_configuration *config,
-                  METHOD_DATA *md, hdb_entry *client,
-                  ENCTYPE *etypes, unsigned int etypes_len)
+                  METHOD_DATA *md, Key *ckey)
 {
     krb5_error_code ret = 0;
 {
     krb5_error_code ret = 0;
-    int i, j;
-    unsigned int n = 0;
     ETYPE_INFO2 pa;
     unsigned char *buf;
     size_t len;
 
     ETYPE_INFO2 pa;
     unsigned char *buf;
     size_t len;
 
-    pa.len = client->keys.len;
-    if(pa.len > UINT_MAX/sizeof(*pa.val))
-       return ERANGE;
-    pa.val = malloc(pa.len * sizeof(*pa.val));
+    pa.len = 1;
+    pa.val = calloc(1, sizeof(pa.val[0]));
     if(pa.val == NULL)
        return ENOMEM;
     if(pa.val == NULL)
        return ENOMEM;
-    memset(pa.val, 0, pa.len * sizeof(*pa.val));
-
-    for(i = 0; i < client->keys.len; i++) {
-       for (j = 0; j < n; j++)
-           if (pa.val[j].etype == client->keys.val[i].key.keytype)
-               goto skip1;
-       for(j = 0; j < etypes_len; j++) {
-           if(client->keys.val[i].key.keytype == etypes[j]) {
-               if (krb5_enctype_valid(context, etypes[j]) != 0)
-                   continue;
-               if (n >= pa.len)
-                   krb5_abortx(context, "internal error: n >= p.len");
-               if((ret = make_etype_info2_entry(&pa.val[n++],
-                                                &client->keys.val[i])) != 0) {
-                   free_ETYPE_INFO2(&pa);
-                   return ret;
-               }
-               break;
-           }
-       }
-    skip1:;
-    }
-    /* send enctypes that the client doesn't know about too */
-    for(i = 0; i < client->keys.len; i++) {
-       /* already added? */
-       for(j = 0; j < etypes_len; j++) {
-           if(client->keys.val[i].key.keytype == etypes[j])
-               goto skip2;
-       }
-       if (krb5_enctype_valid(context, client->keys.val[i].key.keytype) != 0)
-           continue;
-       if (n >= pa.len)
-           krb5_abortx(context, "internal error: n >= p.len");
-       if((ret = make_etype_info2_entry(&pa.val[n++],
-                                        &client->keys.val[i])) != 0) {
-           free_ETYPE_INFO2(&pa);
-           return ret;
-       }
-      skip2:;
-    }
 
 
-    if(n < pa.len) {
-       /* stripped out dups, and not valid enctypes */
-       pa.len = n;
+    ret = make_etype_info2_entry(&pa.val[0], ckey);
+    if (ret) {
+       free_ETYPE_INFO2(&pa);
+       return ret;
     }
 
     ASN1_MALLOC_ENCODE(ETYPE_INFO2, buf, len, &pa, &len, ret);
     }
 
     ASN1_MALLOC_ENCODE(ETYPE_INFO2, buf, len, &pa, &len, ret);
@@ -712,10 +607,12 @@ log_as_req(krb5_context context,
           const KDC_REQ_BODY *b)
 {
     krb5_error_code ret;
           const KDC_REQ_BODY *b)
 {
     krb5_error_code ret;
-    struct rk_strpool *p = NULL;
+    struct rk_strpool *p;
     char *str;
     int i;
 
     char *str;
     int i;
 
+    p = rk_strpoolprintf(NULL, "%s", "Client supported enctypes: ");
+
     for (i = 0; i < b->etype.len; i++) {
        ret = krb5_enctype_to_string(context, b->etype.val[i], &str);
        if (ret == 0) {
     for (i = 0; i < b->etype.len; i++) {
        ret = krb5_enctype_to_string(context, b->etype.val[i], &str);
        if (ret == 0) {
@@ -733,10 +630,6 @@ log_as_req(krb5_context context,
     if (p == NULL)
        p = rk_strpoolprintf(p, "no encryption types");
 
     if (p == NULL)
        p = rk_strpoolprintf(p, "no encryption types");
 
-    str = rk_strpoolcollect(p);
-    kdc_log(context, config, 0, "Client supported enctypes: %s", str);
-    free(str);
-
     {
        char *cet;
        char *set;
     {
        char *cet;
        char *set;
@@ -745,21 +638,26 @@ log_as_req(krb5_context context,
        if(ret == 0) {
            ret = krb5_enctype_to_string(context, setype, &set);
            if (ret == 0) {
        if(ret == 0) {
            ret = krb5_enctype_to_string(context, setype, &set);
            if (ret == 0) {
-               kdc_log(context, config, 5, "Using %s/%s", cet, set);
+               p = rk_strpoolprintf(p, ", using %s/%s", cet, set);
                free(set);
            }
            free(cet);
        }
        if (ret != 0)
                free(set);
            }
            free(cet);
        }
        if (ret != 0)
-           kdc_log(context, config, 5, "Using e-types %d/%d", cetype, setype);
+           p = rk_strpoolprintf(p, ", using enctypes %d/%d",
+                                cetype, setype);
     }
 
     }
 
+    str = rk_strpoolcollect(p);
+    kdc_log(context, config, 0, "%s", str);
+    free(str);
+
     {
        char fixedstr[128];
        unparse_flags(KDCOptions2int(b->kdc_options), asn1_KDCOptions_units(),
                      fixedstr, sizeof(fixedstr));
        if(*fixedstr)
     {
        char fixedstr[128];
        unparse_flags(KDCOptions2int(b->kdc_options), asn1_KDCOptions_units(),
                      fixedstr, sizeof(fixedstr));
        if(*fixedstr)
-           kdc_log(context, config, 2, "Requested flags: %s", fixedstr);
+           kdc_log(context, config, 0, "Requested flags: %s", fixedstr);
     }
 }
 
     }
 }
 
@@ -956,6 +854,17 @@ send_pac_p(krb5_context context, KDC_REQ *req)
     return TRUE;
 }
 
     return TRUE;
 }
 
+krb5_boolean
+_kdc_is_anonymous(krb5_context context, krb5_principal principal)
+{
+    if (principal->name.name_type != KRB5_NT_WELLKNOWN ||
+       principal->name.name_string.len != 2 ||
+       strcmp(principal->name.name_string.val[0], KRB5_WELLKNOWN_NAME) != 0 ||
+       strcmp(principal->name.name_string.val[1], KRB5_ANON_NAME) != 0)
+       return 0;
+    return 1;
+}
+
 /*
  *
  */
 /*
  *
  */
@@ -1039,6 +948,7 @@ _kdc_as_rep(krb5_context context,
            if (ret)
                goto out;
        }
            if (ret)
                goto out;
        }
+
        ret = krb5_unparse_name(context, client_princ, &client_name);
     }
     if (ret) {
        ret = krb5_unparse_name(context, client_princ, &client_name);
     }
     if (ret) {
@@ -1050,6 +960,28 @@ _kdc_as_rep(krb5_context context,
     kdc_log(context, config, 0, "AS-REQ %s from %s for %s",
            client_name, from, server_name);
 
     kdc_log(context, config, 0, "AS-REQ %s from %s for %s",
            client_name, from, server_name);
 
+    /*
+     *
+     */
+
+    if (_kdc_is_anonymous(context, client_princ)) {
+       if (!b->kdc_options.request_anonymous) {
+           kdc_log(context, config, 0, "Anonymous ticket w/o anonymous flag");
+           ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
+           goto out;
+       }
+    } else if (b->kdc_options.request_anonymous) {
+       kdc_log(context, config, 0, 
+               "Request for a anonymous ticket with non "
+               "anonymous client name: %s", client_name);
+       ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
+       goto out;
+    }
+
+    /*
+     *
+     */
+
     ret = _kdc_db_fetch(context, config, client_princ,
                        HDB_F_GET_CLIENT | flags, NULL, &client);
     if(ret){
     ret = _kdc_db_fetch(context, config, client_princ,
                        HDB_F_GET_CLIENT | flags, NULL, &client);
     if(ret){
@@ -1069,19 +1001,27 @@ _kdc_as_rep(krb5_context context,
        goto out;
     }
 
        goto out;
     }
 
-    ret = _kdc_windc_client_access(context, client, req, &e_data);
-    if(ret)
-       goto out;
+    memset(&et, 0, sizeof(et));
+    memset(&ek, 0, sizeof(ek));
 
 
-    ret = _kdc_check_flags(context, config,
-                          client, client_name,
-                          server, server_name,
-                          TRUE);
-    if(ret)
+    /*
+     * Find the client key for reply encryption and pa-type salt, Pick
+     * the client key upfront before the other keys because that is
+     * going to affect what enctypes we are going to use in
+     * ETYPE-INFO{,2}.
+     */
+
+    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;
        goto out;
+    }
 
 
-    memset(&et, 0, sizeof(et));
-    memset(&ek, 0, sizeof(ek));
+    /*
+     * Pre-auth processing
+     */
 
     if(req->padata){
        int i;
 
     if(req->padata){
        int i;
@@ -1097,17 +1037,15 @@ _kdc_as_rep(krb5_context context,
        e_text = "No PKINIT PA found";
 
        i = 0;
        e_text = "No PKINIT PA found";
 
        i = 0;
-       if ((pa = _kdc_find_padata(req, &i, KRB5_PADATA_PK_AS_REQ)))
-           ;
+       pa = _kdc_find_padata(req, &i, KRB5_PADATA_PK_AS_REQ);
        if (pa == NULL) {
            i = 0;
        if (pa == NULL) {
            i = 0;
-           if((pa = _kdc_find_padata(req, &i, KRB5_PADATA_PK_AS_REQ_WIN)))
-               ;
+           pa = _kdc_find_padata(req, &i, KRB5_PADATA_PK_AS_REQ_WIN);
        }
        if (pa) {
            char *client_cert = NULL;
 
        }
        if (pa) {
            char *client_cert = NULL;
 
-           ret = _kdc_pk_rd_padata(context, config, req, pa, &pkp);
+           ret = _kdc_pk_rd_padata(context, config, req, pa, client, &pkp);
            if (ret) {
                ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
                kdc_log(context, config, 5,
            if (ret) {
                ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
                kdc_log(context, config, 5,
@@ -1127,11 +1065,12 @@ _kdc_as_rep(krb5_context context,
                e_text = "PKINIT certificate not allowed to "
                    "impersonate principal";
                _kdc_pk_free_client_param(context, pkp);
                e_text = "PKINIT certificate not allowed to "
                    "impersonate principal";
                _kdc_pk_free_client_param(context, pkp);
-
+               
                kdc_log(context, config, 0, "%s", e_text);
                pkp = NULL;
                goto out;
            }
                kdc_log(context, config, 0, "%s", e_text);
                pkp = NULL;
                goto out;
            }
+
            found_pa = 1;
            et.flags.pre_authent = 1;
            kdc_log(context, config, 0,
            found_pa = 1;
            et.flags.pre_authent = 1;
            kdc_log(context, config, 0,
@@ -1158,6 +1097,12 @@ _kdc_as_rep(krb5_context context,
        
            found_pa = 1;
        
        
            found_pa = 1;
        
+           if (b->kdc_options.request_anonymous) {
+               ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
+               kdc_log(context, config, 0, "ENC-TS doesn't support anon");
+               goto out;
+           }
+
            ret = decode_EncryptedData(pa->padata_value.data,
                                       pa->padata_value.length,
                                       &enc_data,
            ret = decode_EncryptedData(pa->padata_value.data,
                                       pa->padata_value.length,
                                       &enc_data,
@@ -1206,6 +1151,11 @@ _kdc_as_rep(krb5_context context,
                                              &enc_data,
                                              &ts_data);
            krb5_crypto_destroy(context, crypto);
                                              &enc_data,
                                              &ts_data);
            krb5_crypto_destroy(context, crypto);
+           /*
+            * Since the user might have several keys with the same
+            * enctype but with diffrent salting, we need to try all
+            * the keys with the same enctype.
+            */
            if(ret){
                krb5_error_code ret2;
                ret2 = krb5_enctype_to_string(context,
            if(ret){
                krb5_error_code ret2;
                ret2 = krb5_enctype_to_string(context,
@@ -1298,6 +1248,7 @@ _kdc_as_rep(krb5_context context,
            goto out;
        }
     }else if (config->require_preauth
            goto out;
        }
     }else if (config->require_preauth
+             || b->kdc_options.request_anonymous /* hack to force anon */
              || client->entry.flags.require_preauth
              || server->entry.flags.require_preauth) {
        METHOD_DATA method_data;
              || client->entry.flags.require_preauth
              || server->entry.flags.require_preauth) {
        METHOD_DATA method_data;
@@ -1310,6 +1261,10 @@ _kdc_as_rep(krb5_context context,
        method_data.val = NULL;
 
        ret = realloc_method_data(&method_data);
        method_data.val = NULL;
 
        ret = realloc_method_data(&method_data);
+       if (ret) {
+           free_METHOD_DATA(&method_data);
+           goto out;
+       }
        pa = &method_data.val[method_data.len-1];
        pa->padata_type         = KRB5_PADATA_ENC_TIMESTAMP;
        pa->padata_value.length = 0;
        pa = &method_data.val[method_data.len-1];
        pa->padata_type         = KRB5_PADATA_ENC_TIMESTAMP;
        pa->padata_value.length = 0;
@@ -1317,12 +1272,20 @@ _kdc_as_rep(krb5_context context,
 
 #ifdef PKINIT
        ret = realloc_method_data(&method_data);
 
 #ifdef PKINIT
        ret = realloc_method_data(&method_data);
+       if (ret) {
+           free_METHOD_DATA(&method_data);
+           goto out;
+       }
        pa = &method_data.val[method_data.len-1];
        pa->padata_type         = KRB5_PADATA_PK_AS_REQ;
        pa->padata_value.length = 0;
        pa->padata_value.data   = NULL;
 
        ret = realloc_method_data(&method_data);
        pa = &method_data.val[method_data.len-1];
        pa->padata_type         = KRB5_PADATA_PK_AS_REQ;
        pa->padata_value.length = 0;
        pa->padata_value.data   = NULL;
 
        ret = realloc_method_data(&method_data);
+       if (ret) {
+           free_METHOD_DATA(&method_data);
+           goto out;
+       }
        pa = &method_data.val[method_data.len-1];
        pa->padata_type         = KRB5_PADATA_PK_AS_REQ_WIN;
        pa->padata_value.length = 0;
        pa = &method_data.val[method_data.len-1];
        pa->padata_type         = KRB5_PADATA_PK_AS_REQ_WIN;
        pa->padata_value.length = 0;
@@ -1330,22 +1293,37 @@ _kdc_as_rep(krb5_context context,
 #endif
 
        /*
 #endif
 
        /*
-        * RFC4120 requires:
-        * - If the client only knows about old enctypes, then send
-        *   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.
+        * If there is a client key, send ETYPE_INFO{,2}
         */
         */
-
-       /* XXX check ret */
-       if (only_older_enctype_p(req))
-           ret = get_pa_etype_info(context, config,
-                                   &method_data, &client->entry,
-                                   b->etype.val, b->etype.len);
-       /* XXX check ret */
-       ret = get_pa_etype_info2(context, config, &method_data,
-                                &client->entry, b->etype.val, b->etype.len);
-
+       if (ckey) {
+
+           /*
+            * RFC4120 requires:
+            * - If the client only knows about old enctypes, then send
+            *   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.
+            *
+            * Before we send the full list of etype-info data, we pick
+            * the client key we would have used anyway below, just pick
+            * that instead.
+            */
+
+           if (older_enctype(ckey->key.keytype)) {
+               ret = get_pa_etype_info(context, config,
+                                       &method_data, ckey);
+               if (ret) {
+                   free_METHOD_DATA(&method_data);
+                   goto out;
+               }
+           }
+           ret = get_pa_etype_info2(context, config,
+                                    &method_data, ckey);
+           if (ret) {
+               free_METHOD_DATA(&method_data);
+               goto out;
+           }
+       }
        
        ASN1_MALLOC_ENCODE(METHOD_DATA, buf, len, &method_data, &len, ret);
        free_METHOD_DATA(&method_data);
        
        ASN1_MALLOC_ENCODE(METHOD_DATA, buf, len, &method_data, &len, ret);
        free_METHOD_DATA(&method_data);
@@ -1363,20 +1341,26 @@ _kdc_as_rep(krb5_context context,
     }
 
     /*
     }
 
     /*
-     * 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.
+     * Verify flags after the user been required to prove its identity
+     * with in a preauth mech.
      */
 
      */
 
-    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);
+    ret = _kdc_check_flags(context, config,
+                          client, client_name,
+                          server, server_name,
+                          TRUE);
+    if(ret)
        goto out;
        goto out;
-    }
-       
+
+    ret = _kdc_windc_client_access(context, client, req, &e_data);
+    if(ret)
+       goto out;
+
+    /*
+     * Selelct the best encryption type for the KDC with out regard to
+     * the client since the client never needs to read that data.
+     */
+
     ret = _kdc_get_preferred_key(context, config,
                                 server, server_name,
                                 &setype, &skey);
     ret = _kdc_get_preferred_key(context, config,
                                 server, server_name,
                                 &setype, &skey);
@@ -1449,12 +1433,14 @@ _kdc_as_rep(krb5_context context,
 
     rep.pvno = 5;
     rep.msg_type = krb_as_rep;
 
     rep.pvno = 5;
     rep.msg_type = krb_as_rep;
-    copy_Realm(&client->entry.principal->realm, &rep.crealm);
-    if (f.request_anonymous)
-       _kdc_make_anonymous_principalname (&rep.cname);
-    else
-       _krb5_principal2principalname(&rep.cname,
-                                     client->entry.principal);
+
+    ret = copy_Realm(&client->entry.principal->realm, &rep.crealm);
+    if (ret)
+       goto out;
+    ret = _krb5_principal2principalname(&rep.cname, client->entry.principal);
+    if (ret)
+       goto out;
+
     rep.ticket.tkt_vno = 5;
     copy_Realm(&server->entry.principal->realm, &rep.ticket.realm);
     _krb5_principal2principalname(&rep.ticket.sname,
     rep.ticket.tkt_vno = 5;
     copy_Realm(&server->entry.principal->realm, &rep.ticket.realm);
     _krb5_principal2principalname(&rep.ticket.sname,
@@ -1500,11 +1486,12 @@ _kdc_as_rep(krb5_context context,
        goto out;
     }
 
        goto out;
     }
 
-    ret = krb5_generate_random_keyblock(context, sessionetype, &et.key);
+    ret = copy_PrincipalName(&rep.cname, &et.cname);
+    if (ret)
+       goto out;
+    ret = copy_Realm(&rep.crealm, &et.crealm);
     if (ret)
        goto out;
     if (ret)
        goto out;
-    copy_PrincipalName(&rep.cname, &et.cname);
-    copy_Realm(&rep.crealm, &et.crealm);
 
     {
        time_t start;
 
     {
        time_t start;
@@ -1568,8 +1555,6 @@ _kdc_as_rep(krb5_context context,
     et.transited.tr_type = DOMAIN_X500_COMPRESS;
     krb5_data_zero(&et.transited.contents);
 
     et.transited.tr_type = DOMAIN_X500_COMPRESS;
     krb5_data_zero(&et.transited.contents);
 
-    copy_EncryptionKey(&et.key, &ek.key);
-
     /* The MIT ASN.1 library (obviously) doesn't tell lengths encoded
      * as 0 and as 0x80 (meaning indefinite length) apart, and is thus
      * incapable of correctly decoding SEQUENCE OF's of zero length.
     /* The MIT ASN.1 library (obviously) doesn't tell lengths encoded
      * as 0 and as 0x80 (meaning indefinite length) apart, and is thus
      * incapable of correctly decoding SEQUENCE OF's of zero length.
@@ -1637,12 +1622,12 @@ _kdc_as_rep(krb5_context context,
     rep.padata->len = 0;
     rep.padata->val = NULL;
 
     rep.padata->len = 0;
     rep.padata->val = NULL;
 
-    reply_key = &ckey->key;
 #if PKINIT
     if (pkp) {
 #if PKINIT
     if (pkp) {
+        e_text = "Failed to build PK-INIT reply";
        ret = _kdc_pk_mk_pa_reply(context, config, pkp, client,
        ret = _kdc_pk_mk_pa_reply(context, config, pkp, client,
-                                 req, req_buffer,
-                                 &reply_key, rep.padata);
+                                 sessionetype, req, req_buffer,
+                                 &reply_key, &et.key, rep.padata);
        if (ret)
            goto out;
        ret = _kdc_add_inital_verified_cas(context,
        if (ret)
            goto out;
        ret = _kdc_add_inital_verified_cas(context,
@@ -1651,10 +1636,25 @@ _kdc_as_rep(krb5_context context,
                                           &et);
        if (ret)
            goto out;
                                           &et);
        if (ret)
            goto out;
-    }
+    } else
 #endif
 #endif
+    if (ckey) {
+       reply_key = &ckey->key;
+       ret = krb5_generate_random_keyblock(context, sessionetype, &et.key);
+       if (ret)
+           goto out;
+    } else {
+       e_text = "Client have no reply key";
+       ret = KRB5KDC_ERR_CLIENT_NOTYET;
+       goto out;
+    }
+
+    ret = copy_EncryptionKey(&et.key, &ek.key);
+    if (ret)
+       goto out;
 
 
-    set_salt_padata (rep.padata, ckey->salt);
+    if (ckey)
+       set_salt_padata (rep.padata, ckey->salt);
 
     /* Add signing of alias referral */
     if (f.canonicalize) {
 
     /* Add signing of alias referral */
     if (f.canonicalize) {
index 4cf93e5a54be2dc0691677b3d8794d3fb0cbe419..3abdb18ae487a53b521c6a401b7354c515036967 100644 (file)
@@ -107,7 +107,7 @@ _kdc_add_KRB5SignedPath(krb5_context context,
                        hdb_entry_ex *krbtgt,
                        krb5_enctype enctype,
                        krb5_const_principal server,
                        hdb_entry_ex *krbtgt,
                        krb5_enctype enctype,
                        krb5_const_principal server,
-                       KRB5SignedPathPrincipals *principals,
+                       krb5_principals principals,
                        EncTicketPart *tkt)
 {
     krb5_error_code ret;
                        EncTicketPart *tkt)
 {
     krb5_error_code ret;
@@ -117,7 +117,7 @@ _kdc_add_KRB5SignedPath(krb5_context context,
     size_t size;
 
     if (server && principals) {
     size_t size;
 
     if (server && principals) {
-       ret = add_KRB5SignedPathPrincipals(principals, server);
+       ret = add_Principals(principals, server);
        if (ret)
            return ret;
     }
        if (ret)
            return ret;
     }
@@ -186,7 +186,7 @@ check_KRB5SignedPath(krb5_context context,
                     krb5_kdc_configuration *config,
                     hdb_entry_ex *krbtgt,
                     EncTicketPart *tkt,
                     krb5_kdc_configuration *config,
                     hdb_entry_ex *krbtgt,
                     EncTicketPart *tkt,
-                    KRB5SignedPathPrincipals **delegated,
+                    krb5_principals *delegated,
                     int *signedpath)
 {
     krb5_error_code ret;
                     int *signedpath)
 {
     krb5_error_code ret;
@@ -255,7 +255,7 @@ check_KRB5SignedPath(krb5_context context,
                return ENOMEM;
            }
 
                return ENOMEM;
            }
 
-           ret = copy_KRB5SignedPathPrincipals(*delegated, sp.delegated);
+           ret = copy_Principals(*delegated, sp.delegated);
            if (ret) {
                free_KRB5SignedPath(&sp);
                free(*delegated);
            if (ret) {
                free_KRB5SignedPath(&sp);
                free(*delegated);
@@ -668,7 +668,7 @@ tgs_make_reply(krb5_context context,
               krb5_principal client_principal,
               hdb_entry_ex *krbtgt,
               krb5_enctype krbtgt_etype,
               krb5_principal client_principal,
               hdb_entry_ex *krbtgt,
               krb5_enctype krbtgt_etype,
-              KRB5SignedPathPrincipals *spp,
+              krb5_principals spp,
               const krb5_data *rspac,
               const METHOD_DATA *enc_pa_data,
               const char **e_text,
               const krb5_data *rspac,
               const METHOD_DATA *enc_pa_data,
               const char **e_text,
@@ -725,14 +725,13 @@ tgs_make_reply(krb5_context context,
                                    PRINCIPAL_ALLOW_DISABLE_TRANSITED_CHECK(server)) ||
                                   GLOBAL_ALLOW_DISABLE_TRANSITED_CHECK),
                                 &tgt->transited, &et,
                                    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));
+                                krb5_principal_get_realm(context, client_principal),
+                                krb5_principal_get_realm(context, server->entry.principal),
+                                krb5_principal_get_realm(context, krbtgt->entry.principal));
     if(ret)
        goto out;
 
     if(ret)
        goto out;
 
-    copy_Realm(krb5_princ_realm(context, server_principal),
-              &rep.ticket.realm);
+    copy_Realm(&server_principal->realm, &rep.ticket.realm);
     _krb5_principal2principalname(&rep.ticket.sname, server_principal);
     copy_Realm(&tgt_name->realm, &rep.crealm);
 /*
     _krb5_principal2principalname(&rep.ticket.sname, server_principal);
     copy_Realm(&tgt_name->realm, &rep.crealm);
 /*
@@ -888,7 +887,7 @@ tgs_make_reply(krb5_context context,
     }
 
     if (krb5_enctype_valid(context, et.key.keytype) != 0
     }
 
     if (krb5_enctype_valid(context, et.key.keytype) != 0
-       && _kdc_is_weak_expection(server->entry.principal, et.key.keytype))
+       && _kdc_is_weak_exception(server->entry.principal, et.key.keytype))
     {
        krb5_enctype_enable(context, et.key.keytype);
        is_weak = 1;
     {
        krb5_enctype_enable(context, et.key.keytype);
        is_weak = 1;
@@ -1035,7 +1034,7 @@ need_referral(krb5_context context, krb5_kdc_configuration *config,
 
     if (server->name.name_string.len == 1)
        name = server->name.name_string.val[0];
 
     if (server->name.name_string.len == 1)
        name = server->name.name_string.val[0];
-    if (server->name.name_string.len > 1)
+    else if (server->name.name_string.len > 1)
        name = server->name.name_string.val[1];
     else
        return FALSE;
        name = server->name.name_string.val[1];
     else
        return FALSE;
@@ -1205,9 +1204,7 @@ tgs_parse_request(krb5_context context,
        krb5_keyblock *subkey;
        krb5_data ad;
 
        krb5_keyblock *subkey;
        krb5_data ad;
 
-       ret = krb5_auth_con_getremotesubkey(context,
-                                           ac,
-                                           &subkey);
+       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",
        if(ret){
            krb5_auth_con_free(context, ac);
            kdc_log(context, config, 0, "Failed to get remote subkey: %s",
@@ -1232,6 +1229,7 @@ tgs_parse_request(krb5_context context,
            goto out;
        }
        ret = krb5_crypto_init(context, subkey, 0, &crypto);
            goto out;
        }
        ret = krb5_crypto_init(context, subkey, 0, &crypto);
+       krb5_free_keyblock(context, subkey);
        if (ret) {
            krb5_auth_con_free(context, ac);
            kdc_log(context, config, 0, "krb5_crypto_init failed: %s",
        if (ret) {
            krb5_auth_con_free(context, ac);
            kdc_log(context, config, 0, "krb5_crypto_init failed: %s",
@@ -1251,7 +1249,6 @@ tgs_parse_request(krb5_context context,
            ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */
            goto out;
        }
            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);
        ALLOC(*auth_data);
        if (*auth_data == NULL) {
            krb5_auth_con_free(context, ac);
@@ -1365,8 +1362,7 @@ tgs_build_reply(krb5_context context,
                const char *from,
                const char **e_text,
                AuthorizationData **auth_data,
                const char *from,
                const char **e_text,
                AuthorizationData **auth_data,
-               const struct sockaddr *from_addr,
-               int datagram_reply)
+               const struct sockaddr *from_addr)
 {
     krb5_error_code ret;
     krb5_principal cp = NULL, sp = NULL;
 {
     krb5_error_code ret;
     krb5_principal cp = NULL, sp = NULL;
@@ -1375,13 +1371,11 @@ tgs_build_reply(krb5_context context,
     hdb_entry_ex *server = NULL, *client = NULL;
     krb5_realm ref_realm = NULL;
     EncTicketPart *tgt = &ticket->ticket;
     hdb_entry_ex *server = NULL, *client = NULL;
     krb5_realm ref_realm = NULL;
     EncTicketPart *tgt = &ticket->ticket;
-    KRB5SignedPathPrincipals *spp = NULL;
-    Key *tkey;
+    krb5_principals spp = NULL;
     const EncryptionKey *ekey;
     krb5_keyblock sessionkey;
     krb5_kvno kvno;
     krb5_data rspac;
     const EncryptionKey *ekey;
     krb5_keyblock sessionkey;
     krb5_kvno kvno;
     krb5_data rspac;
-    int cross_realm = 0;
 
     METHOD_DATA enc_pa_data;
 
 
     METHOD_DATA enc_pa_data;
 
@@ -1392,6 +1386,8 @@ tgs_build_reply(krb5_context context,
     char opt_str[128];
     int signedpath = 0;
 
     char opt_str[128];
     int signedpath = 0;
 
+    Key *tkey;
+
     memset(&sessionkey, 0, sizeof(sessionkey));
     memset(&adtkt, 0, sizeof(adtkt));
     krb5_data_zero(&rspac);
     memset(&sessionkey, 0, sizeof(sessionkey));
     memset(&adtkt, 0, sizeof(adtkt));
     krb5_data_zero(&rspac);
@@ -1559,8 +1555,6 @@ server_lookup:
        
        kdc_log(context, config, 1, "Client not found in database: %s: %s",
                cpn, krb5_get_err_text(context, ret));
        
        kdc_log(context, config, 1, "Client not found in database: %s: %s",
                cpn, krb5_get_err_text(context, ret));
-
-       cross_realm = 1;
     }
 
     /*
     }
 
     /*
@@ -1578,9 +1572,10 @@ server_lookup:
                    break;
            if(i == b->etype.len) {
                kdc_log(context, config, 0,
                    break;
            if(i == b->etype.len) {
                kdc_log(context, config, 0,
-                       "Addition ticket have not matching etypes", spp);
+                       "Addition ticket have not matching etypes");
                krb5_clear_error_message(context);
                krb5_clear_error_message(context);
-               return KRB5KDC_ERR_ETYPE_NOSUPP;
+               ret = KRB5KDC_ERR_ETYPE_NOSUPP;
+               goto out;
            }
            etype = b->etype.val[i];
            kvno = 0;
            }
            etype = b->etype.val[i];
            kvno = 0;
@@ -1592,7 +1587,7 @@ server_lookup:
            if(ret) {
                kdc_log(context, config, 0,
                        "Server (%s) has no support for etypes", spn);
            if(ret) {
                kdc_log(context, config, 0,
                        "Server (%s) has no support for etypes", spn);
-               return ret;
+               goto out;
            }
            ekey = &skey->key;
            kvno = server->entry.kvno;
            }
            ekey = &skey->key;
            kvno = server->entry.kvno;
@@ -1603,10 +1598,6 @@ server_lookup:
            goto out;
     }
 
            goto out;
     }
 
-    /*
-     * Validate authoriation data
-     */
-
     /*
      * Check that service is in the same realm as the krbtgt. If it's
      * not the same, it's someone that is using a uni-directional trust
     /*
      * Check that service is in the same realm as the krbtgt. If it's
      * not the same, it's someone that is using a uni-directional trust
@@ -1628,13 +1619,15 @@ server_lookup:
        goto out;
     }
 
        goto out;
     }
 
-    /* check PAC if there is one */
+    /*
+     * Validate authoriation data
+     */
 
     ret = hdb_enctype2key(context, &krbtgt->entry,
                          krbtgt_etype, &tkey);
     if(ret) {
        kdc_log(context, config, 0,
 
     ret = hdb_enctype2key(context, &krbtgt->entry,
                          krbtgt_etype, &tkey);
     if(ret) {
        kdc_log(context, config, 0,
-               "Failed to find key for krbtgt PAC check");
+                   "Failed to find key for krbtgt PAC check");
        goto out;
     }
 
        goto out;
     }
 
@@ -1672,7 +1665,7 @@ server_lookup:
        const PA_DATA *sdata;
        int i = 0;
 
        const PA_DATA *sdata;
        int i = 0;
 
-       sdata = _kdc_find_padata(req, &i, KRB5_PADATA_S4U2SELF);
+       sdata = _kdc_find_padata(req, &i, KRB5_PADATA_FOR_USER);
        if (sdata) {
            krb5_crypto crypto;
            krb5_data datack;
        if (sdata) {
            krb5_crypto crypto;
            krb5_data datack;
@@ -2044,8 +2037,7 @@ _kdc_tgs_rep(krb5_context context,
                          from,
                          &e_text,
                          &auth_data,
                          from,
                          &e_text,
                          &auth_data,
-                         from_addr,
-                         datagram_reply);
+                         from_addr);
     if (ret) {
        kdc_log(context, config, 0,
                "Failed building TGS-REP to %s", from);
     if (ret) {
        kdc_log(context, config, 0,
                "Failed building TGS-REP to %s", from);
index 83e05b81c5952ed2d2f26240d7140eb2410c6df4..8f7f3a27fb0d71c46dab9eb30727496a7b807b87 100644 (file)
 #include <rfc2459_asn1.h>
 #include <hx509.h>
 
 #include <rfc2459_asn1.h>
 #include <hx509.h>
 
-RCSID("$Id$");
+#ifdef KX509
 
 /*
  *
  */
 
 krb5_error_code
 
 /*
  *
  */
 
 krb5_error_code
-_kdc_try_kx509_request(void *ptr, size_t len, Kx509Request *req, size_t *size)
+_kdc_try_kx509_request(void *ptr, size_t len, struct Kx509Request *req, size_t *size)
 {
     if (len < 4)
        return -1;
 {
     if (len < 4)
        return -1;
@@ -97,16 +97,15 @@ calculate_reply_hash(krb5_context context,
                     krb5_keyblock *key,
                     Kx509Response *rep)
 {
                     krb5_keyblock *key,
                     Kx509Response *rep)
 {
+    krb5_error_code ret;
     HMAC_CTX ctx;
 
     HMAC_CTX_init(&ctx);
 
     HMAC_CTX ctx;
 
     HMAC_CTX_init(&ctx);
 
-    HMAC_Init_ex(&ctx,
-                key->keyvalue.data, key->keyvalue.length,
+    HMAC_Init_ex(&ctx, key->keyvalue.data, key->keyvalue.length,
                 EVP_sha1(), NULL);
                 EVP_sha1(), NULL);
-    rep->hash->length = HMAC_size(&ctx);
-    rep->hash->data = malloc(rep->hash->length);
-    if (rep->hash->data == NULL) {
+    ret = krb5_data_alloc(rep->hash, HMAC_size(&ctx));
+    if (ret) {
        HMAC_CTX_cleanup(&ctx);
        krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
        HMAC_CTX_cleanup(&ctx);
        krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
@@ -208,7 +207,7 @@ build_certificate(krb5_context context,
        spki.subjectPublicKey.data = key->data;
        spki.subjectPublicKey.length = key->length * 8;
 
        spki.subjectPublicKey.data = key->data;
        spki.subjectPublicKey.length = key->length * 8;
 
-       ret = der_copy_oid(oid_id_pkcs1_rsaEncryption(),
+       ret = der_copy_oid(&asn1_oid_id_pkcs1_rsaEncryption,
                           &spki.algorithm.algorithm);
 
        any.data = "\x05\x00";
                           &spki.algorithm.algorithm);
 
        any.data = "\x05\x00";
@@ -289,7 +288,7 @@ out:
 krb5_error_code
 _kdc_do_kx509(krb5_context context,
              krb5_kdc_configuration *config,
 krb5_error_code
 _kdc_do_kx509(krb5_context context,
              krb5_kdc_configuration *config,
-             const Kx509Request *req, krb5_data *reply,
+             const struct Kx509Request *req, krb5_data *reply,
              const char *from, struct sockaddr *addr)
 {
     krb5_error_code ret;
              const char *from, struct sockaddr *addr)
 {
     krb5_error_code ret;
@@ -385,8 +384,10 @@ _kdc_do_kx509(krb5_context context,
        if (ret)
            goto out;
        free_RSAPublicKey(&key);
        if (ret)
            goto out;
        free_RSAPublicKey(&key);
-       if (size != req->pk_key.length)
-           ;
+       if (size != req->pk_key.length) {
+           ret = ASN1_EXTRA_DATA;
+           goto out;
+       }
     }
 
     ALLOC(rep.certificate);
     }
 
     ALLOC(rep.certificate);
@@ -458,3 +459,5 @@ out:
 
     return 0;
 }
 
     return 0;
 }
+
+#endif /* KX509 */
index 82358682d8d9f9cb5f6bf6a97794932bd7241107..22734be811e379f486bef3a01df6d80becfaa071 100644 (file)
@@ -47,14 +47,26 @@ RCSID("$Id$");
 
 struct pk_client_params {
     enum krb5_pk_type type;
 
 struct pk_client_params {
     enum krb5_pk_type type;
-    BIGNUM *dh_public_key;
+    enum { USE_RSA, USE_DH, USE_ECDH } keyex;
+    union {
+       struct {
+           BIGNUM *public_key;
+           DH *key;
+       } dh;
+#ifdef HAVE_OPENSSL
+       struct {
+           EC_KEY *public_key;
+           EC_KEY *key;
+       } ecdh;
+#endif
+    } u;
     hx509_cert cert;
     unsigned nonce;
     hx509_cert cert;
     unsigned nonce;
-    DH *dh;
     EncryptionKey reply_key;
     char *dh_group_name;
     hx509_peer_info peer;
     hx509_certs client_anchors;
     EncryptionKey reply_key;
     char *dh_group_name;
     hx509_peer_info peer;
     hx509_certs client_anchors;
+    hx509_verify_ctx verify_ctx;
 };
 
 struct pk_principal_mapping {
 };
 
 struct pk_principal_mapping {
@@ -155,29 +167,43 @@ out:
 }
 
 void
 }
 
 void
-_kdc_pk_free_client_param(krb5_context context,
-                         pk_client_params *client_params)
+_kdc_pk_free_client_param(krb5_context context, pk_client_params *cp)
 {
 {
-    if (client_params->cert)
-       hx509_cert_free(client_params->cert);
-    if (client_params->dh)
-       DH_free(client_params->dh);
-    if (client_params->dh_public_key)
-       BN_free(client_params->dh_public_key);
-    krb5_free_keyblock_contents(context, &client_params->reply_key);
-    if (client_params->dh_group_name)
-       free(client_params->dh_group_name);
-    if (client_params->peer)
-       hx509_peer_info_free(client_params->peer);
-    if (client_params->client_anchors)
-       hx509_certs_free(&client_params->client_anchors);
-    memset(client_params, 0, sizeof(*client_params));
-    free(client_params);
+    if (cp == NULL)
+        return;
+    if (cp->cert)
+       hx509_cert_free(cp->cert);
+    if (cp->verify_ctx)
+       hx509_verify_destroy_ctx(cp->verify_ctx);
+    if (cp->keyex == USE_DH) {
+       if (cp->u.dh.key)
+           DH_free(cp->u.dh.key);
+       if (cp->u.dh.public_key)
+           BN_free(cp->u.dh.public_key);
+    }
+#ifdef HAVE_OPENSSL
+    if (cp->keyex == USE_ECDH) {
+       if (cp->u.ecdh.key)
+           EC_KEY_free(cp->u.ecdh.key);
+       if (cp->u.ecdh.public_key)
+           EC_KEY_free(cp->u.ecdh.public_key);
+    }
+#endif
+    krb5_free_keyblock_contents(context, &cp->reply_key);
+    if (cp->dh_group_name)
+       free(cp->dh_group_name);
+    if (cp->peer)
+       hx509_peer_info_free(cp->peer);
+    if (cp->client_anchors)
+       hx509_certs_free(&cp->client_anchors);
+    memset(cp, 0, sizeof(*cp));
+    free(cp);
 }
 
 static krb5_error_code
 }
 
 static krb5_error_code
-generate_dh_keyblock(krb5_context context, pk_client_params *client_params,
-                     krb5_enctype enctype, krb5_keyblock *reply_key)
+generate_dh_keyblock(krb5_context context,
+                    pk_client_params *client_params,
+                     krb5_enctype enctype)
 {
     unsigned char *dh_gen_key = NULL;
     krb5_keyblock key;
 {
     unsigned char *dh_gen_key = NULL;
     krb5_keyblock key;
@@ -186,36 +212,84 @@ generate_dh_keyblock(krb5_context context, pk_client_params *client_params,
 
     memset(&key, 0, sizeof(key));
 
 
     memset(&key, 0, sizeof(key));
 
-    if (!DH_generate_key(client_params->dh)) {
-       ret = KRB5KRB_ERR_GENERIC;
-       krb5_set_error_message(context, ret, "Can't generate Diffie-Hellman keys");
-       goto out;
-    }
-    if (client_params->dh_public_key == NULL) {
-       ret = KRB5KRB_ERR_GENERIC;
-       krb5_set_error_message(context, ret, "dh_public_key");
-       goto out;
-    }
+    if (client_params->keyex == USE_DH) {
 
 
-    dh_gen_keylen = DH_size(client_params->dh);
-    size = BN_num_bytes(client_params->dh->p);
-    if (size < dh_gen_keylen)
-       size = dh_gen_keylen;
+       if (client_params->u.dh.public_key == NULL) {
+           ret = KRB5KRB_ERR_GENERIC;
+           krb5_set_error_message(context, ret, "public_key");
+           goto out;
+       }
 
 
-    dh_gen_key = malloc(size);
-    if (dh_gen_key == NULL) {
-       ret = ENOMEM;
-       krb5_set_error_message(context, ret, "malloc: out of memory");
-       goto out;
-    }
-    memset(dh_gen_key, 0, size - dh_gen_keylen);
+       if (!DH_generate_key(client_params->u.dh.key)) {
+           ret = KRB5KRB_ERR_GENERIC;
+           krb5_set_error_message(context, ret, 
+                                  "Can't generate Diffie-Hellman keys");
+           goto out;
+       }
+
+       dh_gen_keylen = DH_size(client_params->u.dh.key);
+       size = BN_num_bytes(client_params->u.dh.key->p);
+       if (size < dh_gen_keylen)
+           size = dh_gen_keylen;
+
+       dh_gen_key = malloc(size);
+       if (dh_gen_key == NULL) {
+           ret = ENOMEM;
+           krb5_set_error_message(context, ret, "malloc: out of memory");
+           goto out;
+       }
+       memset(dh_gen_key, 0, size - dh_gen_keylen);
+
+       dh_gen_keylen = DH_compute_key(dh_gen_key + (size - dh_gen_keylen),
+                                      client_params->u.dh.public_key,
+                                      client_params->u.dh.key);
+       if (dh_gen_keylen == -1) {
+           ret = KRB5KRB_ERR_GENERIC;
+           krb5_set_error_message(context, ret,
+                                  "Can't compute Diffie-Hellman key");
+           goto out;
+       }
+       ret = 0;
+#ifdef HAVE_OPENSSL
+    } else if (client_params->keyex == USE_ECDH) {
+
+       if (client_params->u.ecdh.public_key == NULL) {
+           ret = KRB5KRB_ERR_GENERIC;
+           krb5_set_error_message(context, ret, "public_key");
+           goto out;
+       }
+
+       client_params->u.ecdh.key = EC_KEY_new();
+       if (client_params->u.ecdh.key == NULL) {
+           ret = ENOMEM;
+           goto out;
+       }
+       EC_KEY_set_group(client_params->u.ecdh.key,
+                        EC_KEY_get0_group(client_params->u.ecdh.public_key));
 
 
-    dh_gen_keylen = DH_compute_key(dh_gen_key + (size - dh_gen_keylen),
-                                  client_params->dh_public_key,
-                                  client_params->dh);
-    if (dh_gen_keylen == -1) {
+       if (EC_KEY_generate_key(client_params->u.ecdh.key) != 1) {
+           ret = ENOMEM;
+           goto out;
+       }
+
+       size = (EC_GROUP_get_degree(EC_KEY_get0_group(client_params->u.ecdh.key)) + 7) / 8;
+       dh_gen_key = malloc(size);
+       if (dh_gen_key == NULL) {
+           ret = ENOMEM;
+           krb5_set_error_message(context, ret,
+                                  N_("malloc: out of memory", ""));
+           goto out;
+       }
+
+       dh_gen_keylen = ECDH_compute_key(dh_gen_key, size, 
+                                        EC_KEY_get0_public_key(client_params->u.ecdh.public_key),
+                                        client_params->u.ecdh.key, NULL);
+       ret = 0;
+#endif /* HAVE_OPENSSL */
+    } else {
        ret = KRB5KRB_ERR_GENERIC;
        ret = KRB5KRB_ERR_GENERIC;
-       krb5_set_error_message(context, ret, "Can't compute Diffie-Hellman key");
+       krb5_set_error_message(context, ret, 
+                              "Diffie-Hellman not selected keys");
        goto out;
     }
 
        goto out;
     }
 
@@ -223,7 +297,7 @@ generate_dh_keyblock(krb5_context context, pk_client_params *client_params,
                                   enctype,
                                   dh_gen_key, dh_gen_keylen,
                                   NULL, NULL,
                                   enctype,
                                   dh_gen_key, dh_gen_keylen,
                                   NULL, NULL,
-                                  reply_key);
+                                  &client_params->reply_key);
 
  out:
     if (dh_gen_key)
 
  out:
     if (dh_gen_key)
@@ -261,10 +335,12 @@ get_dh_param(krb5_context context,
 
     memset(&dhparam, 0, sizeof(dhparam));
 
 
     memset(&dhparam, 0, sizeof(dhparam));
 
-    if (der_heim_oid_cmp(&dh_key_info->algorithm.algorithm, oid_id_dhpublicnumber())) {
-       krb5_set_error_message(context, KRB5_BADMSGTYPE,
-                              "PKINIT invalid oid in clientPublicValue");
-       return KRB5_BADMSGTYPE;
+    if ((dh_key_info->subjectPublicKey.length % 8) != 0) {
+       ret = KRB5_BADMSGTYPE;
+       krb5_set_error_message(context, ret,
+                              "PKINIT: subjectPublicKey not aligned "
+                              "to 8 bit boundary");
+       goto out;
     }
 
     if (dh_key_info->algorithm.parameters == NULL) {
     }
 
     if (dh_key_info->algorithm.parameters == NULL) {
@@ -284,15 +360,6 @@ get_dh_param(krb5_context context,
        goto out;
     }
 
        goto out;
     }
 
-    if ((dh_key_info->subjectPublicKey.length % 8) != 0) {
-       ret = KRB5_BADMSGTYPE;
-       krb5_set_error_message(context, ret,
-                              "PKINIT: subjectPublicKey not aligned "
-                              "to 8 bit boundary");
-       goto out;
-    }
-
-
     ret = _krb5_dh_group_ok(context, config->pkinit_dh_min_bits,
                            &dhparam.p, &dhparam.g, &dhparam.q, moduli,
                            &client_params->dh_group_name);
     ret = _krb5_dh_group_ok(context, config->pkinit_dh_min_bits,
                            &dhparam.p, &dhparam.g, &dhparam.q, moduli,
                            &client_params->dh_group_name);
@@ -331,17 +398,17 @@ get_dh_param(krb5_context context,
            return ret;
        }
 
            return ret;
        }
 
-       client_params->dh_public_key = integer_to_BN(context,
-                                                    "subjectPublicKey",
-                                                    &glue);
+       client_params->u.dh.public_key = integer_to_BN(context,
+                                                      "subjectPublicKey",
+                                                      &glue);
        der_free_heim_integer(&glue);
        der_free_heim_integer(&glue);
-       if (client_params->dh_public_key == NULL) {
+       if (client_params->u.dh.public_key == NULL) {
            ret = KRB5_BADMSGTYPE;
            goto out;
        }
     }
 
            ret = KRB5_BADMSGTYPE;
            goto out;
        }
     }
 
-    client_params->dh = dh;
+    client_params->u.dh.key = dh;
     dh = NULL;
     ret = 0;
 
     dh = NULL;
     ret = 0;
 
@@ -352,20 +419,88 @@ get_dh_param(krb5_context context,
     return ret;
 }
 
     return ret;
 }
 
+#ifdef HAVE_OPENSSL
+
+static krb5_error_code
+get_ecdh_param(krb5_context context,
+              krb5_kdc_configuration *config,
+              SubjectPublicKeyInfo *dh_key_info,
+              pk_client_params *client_params)
+{
+    ECParameters ecp;
+    EC_KEY *public = NULL;
+    krb5_error_code ret;
+    const unsigned char *p;
+    size_t len;
+    int nid;
+
+    if (dh_key_info->algorithm.parameters == NULL) {
+       krb5_set_error_message(context, KRB5_BADMSGTYPE,
+                              "PKINIT missing algorithm parameter "
+                              "in clientPublicValue");
+       return KRB5_BADMSGTYPE;
+    }
+
+    memset(&ecp, 0, sizeof(ecp));
+
+    ret = decode_ECParameters(dh_key_info->algorithm.parameters->data,
+                             dh_key_info->algorithm.parameters->length, &ecp, &len);
+    if (ret)
+       goto out;
+
+    if (ecp.element != choice_ECParameters_namedCurve) {
+       ret = KRB5_BADMSGTYPE;
+       goto out;
+    }
+
+    if (der_heim_oid_cmp(&ecp.u.namedCurve, &asn1_oid_id_ec_group_secp256r1) == 0)
+       nid = NID_X9_62_prime256v1;
+    else {
+       ret = KRB5_BADMSGTYPE;
+       goto out;
+    }
+
+    /* XXX verify group is ok */
+
+    public = EC_KEY_new_by_curve_name(nid);
+
+    p = dh_key_info->subjectPublicKey.data;
+    len = dh_key_info->subjectPublicKey.length / 8;
+    if (o2i_ECPublicKey(&public, &p, len) == NULL) {
+       ret = KRB5_BADMSGTYPE;
+       krb5_set_error_message(context, ret,
+                              "PKINIT failed to decode ECDH key");
+       goto out;
+    }
+    client_params->u.ecdh.public_key = public;
+    public = NULL;
+
+ out:
+    if (public)
+       EC_KEY_free(public);
+    free_ECParameters(&ecp);
+    return ret;
+}
+
+#endif /* HAVE_OPENSSL */
+
 krb5_error_code
 _kdc_pk_rd_padata(krb5_context context,
                  krb5_kdc_configuration *config,
                  const KDC_REQ *req,
                  const PA_DATA *pa,
 krb5_error_code
 _kdc_pk_rd_padata(krb5_context context,
                  krb5_kdc_configuration *config,
                  const KDC_REQ *req,
                  const PA_DATA *pa,
+                 hdb_entry_ex *client,
                  pk_client_params **ret_params)
 {
                  pk_client_params **ret_params)
 {
-    pk_client_params *client_params;
+    pk_client_params *cp;
     krb5_error_code ret;
     heim_oid eContentType = { 0, NULL }, contentInfoOid = { 0, NULL };
     krb5_data eContent = { 0, NULL };
     krb5_data signed_content = { 0, NULL };
     const char *type = "unknown type";
     krb5_error_code ret;
     heim_oid eContentType = { 0, NULL }, contentInfoOid = { 0, NULL };
     krb5_data eContent = { 0, NULL };
     krb5_data signed_content = { 0, NULL };
     const char *type = "unknown type";
+    hx509_certs trust_anchors;
     int have_data = 0;
     int have_data = 0;
+    const HDB_Ext_PKINIT_cert *pc;
 
     *ret_params = NULL;
 
 
     *ret_params = NULL;
 
@@ -375,20 +510,73 @@ _kdc_pk_rd_padata(krb5_context context,
        return 0;
     }
 
        return 0;
     }
 
-    hx509_verify_set_time(kdc_identity->verify_ctx, kdc_time);
-
-    client_params = calloc(1, sizeof(*client_params));
-    if (client_params == NULL) {
+    cp = calloc(1, sizeof(*cp));
+    if (cp == NULL) {
        krb5_clear_error_message(context);
        ret = ENOMEM;
        goto out;
     }
 
        krb5_clear_error_message(context);
        ret = ENOMEM;
        goto out;
     }
 
+    ret = hx509_certs_init(kdc_identity->hx509ctx,
+                          "MEMORY:trust-anchors",
+                          0, NULL, &trust_anchors);
+    if (ret) {
+       krb5_set_error_message(context, ret, "failed to create trust anchors");
+       goto out;
+    }
+
+    ret = hx509_certs_merge(kdc_identity->hx509ctx, trust_anchors, 
+                           kdc_identity->anchors);
+    if (ret) {
+       hx509_certs_free(&trust_anchors);
+       krb5_set_error_message(context, ret, "failed to create verify context");
+       goto out;
+    }
+
+    /* Add any registered certificates for this client as trust anchors */
+    ret = hdb_entry_get_pkinit_cert(&client->entry, &pc);
+    if (ret == 0 && pc != NULL) {
+       hx509_cert cert;
+       unsigned int i;
+       
+       for (i = 0; i < pc->len; i++) {
+           ret = hx509_cert_init_data(kdc_identity->hx509ctx,
+                                      pc->val[i].cert.data,
+                                      pc->val[i].cert.length,
+                                      &cert);
+           if (ret)
+               continue;
+           hx509_certs_add(kdc_identity->hx509ctx, trust_anchors, cert);
+           hx509_cert_free(cert);
+       }
+    }
+
+    ret = hx509_verify_init_ctx(kdc_identity->hx509ctx, &cp->verify_ctx);
+    if (ret) {
+       hx509_certs_free(&trust_anchors);
+       krb5_set_error_message(context, ret, "failed to create verify context");
+       goto out;
+    }
+
+    hx509_verify_set_time(cp->verify_ctx, kdc_time);
+    hx509_verify_attach_anchors(cp->verify_ctx, trust_anchors);
+    hx509_certs_free(&trust_anchors);
+
+    if (config->pkinit_allow_proxy_certs)
+       hx509_verify_set_proxy_certificate(cp->verify_ctx, 1);
+
     if (pa->padata_type == KRB5_PADATA_PK_AS_REQ_WIN) {
        PA_PK_AS_REQ_Win2k r;
 
        type = "PK-INIT-Win2k";
 
     if (pa->padata_type == KRB5_PADATA_PK_AS_REQ_WIN) {
        PA_PK_AS_REQ_Win2k r;
 
        type = "PK-INIT-Win2k";
 
+       if (req->req_body.kdc_options.request_anonymous) {
+           ret = KRB5_KDC_ERR_PUBLIC_KEY_ENCRYPTION_NOT_SUPPORTED;
+           krb5_set_error_message(context, ret, 
+                                  "Anon not supported in RSA mode");
+           goto out;
+       }
+
        ret = decode_PA_PK_AS_REQ_Win2k(pa->padata_value.data,
                                        pa->padata_value.length,
                                        &r,
        ret = decode_PA_PK_AS_REQ_Win2k(pa->padata_value.data,
                                        pa->padata_value.length,
                                        &r,
@@ -406,7 +594,7 @@ _kdc_pk_rd_padata(krb5_context context,
        free_PA_PK_AS_REQ_Win2k(&r);
        if (ret) {
            krb5_set_error_message(context, ret,
        free_PA_PK_AS_REQ_Win2k(&r);
        if (ret) {
            krb5_set_error_message(context, ret,
-                                  "Can't decode PK-AS-REQ: %d", ret);
+                                  "Can't unwrap ContentInfo(win): %d", ret);
            goto out;
        }
 
            goto out;
        }
 
@@ -420,25 +608,35 @@ _kdc_pk_rd_padata(krb5_context context,
                                  &r,
                                  NULL);
        if (ret) {
                                  &r,
                                  NULL);
        if (ret) {
-           krb5_set_error_message(context, ret, "Can't decode PK-AS-REQ: %d", ret);
+           krb5_set_error_message(context, ret,
+                                  "Can't decode PK-AS-REQ: %d", ret);
            goto out;
        }
        
        /* XXX look at r.kdcPkId */
        if (r.trustedCertifiers) {
            ExternalPrincipalIdentifiers *edi = r.trustedCertifiers;
            goto out;
        }
        
        /* XXX look at r.kdcPkId */
        if (r.trustedCertifiers) {
            ExternalPrincipalIdentifiers *edi = r.trustedCertifiers;
-           unsigned int i;
+           unsigned int i, maxedi;
 
            ret = hx509_certs_init(kdc_identity->hx509ctx,
                                   "MEMORY:client-anchors",
                                   0, NULL,
 
            ret = hx509_certs_init(kdc_identity->hx509ctx,
                                   "MEMORY:client-anchors",
                                   0, NULL,
-                                  &client_params->client_anchors);
+                                  &cp->client_anchors);
            if (ret) {
            if (ret) {
-               krb5_set_error_message(context, ret, "Can't allocate client anchors: %d", ret);
+               krb5_set_error_message(context, ret,
+                                      "Can't allocate client anchors: %d", 
+                                      ret);
                goto out;
 
            }
                goto out;
 
            }
-           for (i = 0; i < edi->len; i++) {
+           /* 
+            * If the client sent more then 10 EDI, don't bother
+            * looking more then 10 of performance reasons.
+            */
+           maxedi = edi->len;
+           if (maxedi > 10)
+               maxedi = 10;
+           for (i = 0; i < maxedi; i++) {
                IssuerAndSerialNumber iasn;
                hx509_query *q;
                hx509_cert cert;
                IssuerAndSerialNumber iasn;
                hx509_query *q;
                hx509_cert cert;
@@ -464,8 +662,10 @@ _kdc_pk_rd_padata(krb5_context context,
                }
                ret = hx509_query_match_issuer_serial(q, &iasn.issuer, &iasn.serialNumber);
                free_IssuerAndSerialNumber(&iasn);
                }
                ret = hx509_query_match_issuer_serial(q, &iasn.issuer, &iasn.serialNumber);
                free_IssuerAndSerialNumber(&iasn);
-               if (ret)
+               if (ret) {
+                   hx509_query_free(kdc_identity->hx509ctx, q);
                    continue;
                    continue;
+               }
 
                ret = hx509_certs_find(kdc_identity->hx509ctx,
                                       kdc_identity->certs,
 
                ret = hx509_certs_find(kdc_identity->hx509ctx,
                                       kdc_identity->certs,
@@ -475,7 +675,7 @@ _kdc_pk_rd_padata(krb5_context context,
                if (ret)
                    continue;
                hx509_certs_add(kdc_identity->hx509ctx,
                if (ret)
                    continue;
                hx509_certs_add(kdc_identity->hx509ctx,
-                               client_params->client_anchors, cert);
+                               cp->client_anchors, cert);
                hx509_cert_free(cert);
            }
        }
                hx509_cert_free(cert);
            }
        }
@@ -497,7 +697,7 @@ _kdc_pk_rd_padata(krb5_context context,
        goto out;
     }
 
        goto out;
     }
 
-    ret = der_heim_oid_cmp(&contentInfoOid, oid_id_pkcs7_signedData());
+    ret = der_heim_oid_cmp(&contentInfoOid, &asn1_oid_id_pkcs7_signedData);
     if (ret != 0) {
        ret = KRB5KRB_ERR_GENERIC;
        krb5_set_error_message(context, ret,
     if (ret != 0) {
        ret = KRB5KRB_ERR_GENERIC;
        krb5_set_error_message(context, ret,
@@ -514,9 +714,14 @@ _kdc_pk_rd_padata(krb5_context context,
 
     {
        hx509_certs signer_certs;
 
     {
        hx509_certs signer_certs;
+       int flags = HX509_CMS_VS_ALLOW_DATA_OID_MISMATCH; /* BTMM */
+
+       if (req->req_body.kdc_options.request_anonymous)
+           flags |= HX509_CMS_VS_ALLOW_ZERO_SIGNER;
 
        ret = hx509_cms_verify_signed(kdc_identity->hx509ctx,
 
        ret = hx509_cms_verify_signed(kdc_identity->hx509ctx,
-                                     kdc_identity->verify_ctx,
+                                     cp->verify_ctx,
+                                     flags,
                                      signed_content.data,
                                      signed_content.length,
                                      NULL,
                                      signed_content.data,
                                      signed_content.length,
                                      NULL,
@@ -532,16 +737,18 @@ _kdc_pk_rd_padata(krb5_context context,
            goto out;
        }
 
            goto out;
        }
 
-       ret = hx509_get_one_cert(kdc_identity->hx509ctx, signer_certs,
-                                &client_params->cert);
-       hx509_certs_free(&signer_certs);
+       if (signer_certs) {
+           ret = hx509_get_one_cert(kdc_identity->hx509ctx, signer_certs,
+                                    &cp->cert);
+           hx509_certs_free(&signer_certs);
+       }
        if (ret)
            goto out;
     }
 
     /* Signature is correct, now verify the signed message */
        if (ret)
            goto out;
     }
 
     /* Signature is correct, now verify the signed message */
-    if (der_heim_oid_cmp(&eContentType, oid_id_pkcs7_data()) != 0 &&
-       der_heim_oid_cmp(&eContentType, oid_id_pkauthdata()) != 0)
+    if (der_heim_oid_cmp(&eContentType, &asn1_oid_id_pkcs7_data) != 0 &&
+       der_heim_oid_cmp(&eContentType, &asn1_oid_id_pkauthdata) != 0)
     {
        ret = KRB5_BADMSGTYPE;
        krb5_set_error_message(context, ret, "got wrong oid for pkauthdata");
     {
        ret = KRB5_BADMSGTYPE;
        krb5_set_error_message(context, ret, "got wrong oid for pkauthdata");
@@ -556,7 +763,8 @@ _kdc_pk_rd_padata(krb5_context context,
                                    &ap,
                                    NULL);
        if (ret) {
                                    &ap,
                                    NULL);
        if (ret) {
-           krb5_set_error_message(context, ret, "can't decode AuthPack: %d", ret);
+           krb5_set_error_message(context, ret,
+                                  "Can't decode AuthPack: %d", ret);
            goto out;
        }
 
            goto out;
        }
 
@@ -568,12 +776,13 @@ _kdc_pk_rd_padata(krb5_context context,
            goto out;
        }
 
            goto out;
        }
 
-       client_params->type = PKINIT_WIN2K;
-       client_params->nonce = ap.pkAuthenticator.nonce;
+       cp->type = PKINIT_WIN2K;
+       cp->nonce = ap.pkAuthenticator.nonce;
 
        if (ap.clientPublicValue) {
            ret = KRB5KRB_ERR_GENERIC;
 
        if (ap.clientPublicValue) {
            ret = KRB5KRB_ERR_GENERIC;
-           krb5_set_error_message(context, ret, "DH not supported for windows");
+           krb5_set_error_message(context, ret,
+                                  "DH not supported for windows");
            goto out;
        }
        free_AuthPack_Win2k(&ap);
            goto out;
        }
        free_AuthPack_Win2k(&ap);
@@ -586,11 +795,21 @@ _kdc_pk_rd_padata(krb5_context context,
                              &ap,
                              NULL);
        if (ret) {
                              &ap,
                              NULL);
        if (ret) {
-           krb5_set_error_message(context, ret, "can't decode AuthPack: %d", ret);
+           krb5_set_error_message(context, ret,
+                                  "Can't decode AuthPack: %d", ret);
            free_AuthPack(&ap);
            goto out;
        }
 
            free_AuthPack(&ap);
            goto out;
        }
 
+       if (req->req_body.kdc_options.request_anonymous &&
+           ap.clientPublicValue == NULL) {
+           free_AuthPack(&ap);
+           ret = KRB5_KDC_ERR_PUBLIC_KEY_ENCRYPTION_NOT_SUPPORTED;
+           krb5_set_error_message(context, ret, 
+                                  "Anon not supported in RSA mode");
+           goto out;
+       }
+
        ret = pk_check_pkauthenticator(context,
                                       &ap.pkAuthenticator,
                                       req);
        ret = pk_check_pkauthenticator(context,
                                       &ap.pkAuthenticator,
                                       req);
@@ -599,33 +818,55 @@ _kdc_pk_rd_padata(krb5_context context,
            goto out;
        }
 
            goto out;
        }
 
-       client_params->type = PKINIT_27;
-       client_params->nonce = ap.pkAuthenticator.nonce;
+       cp->type = PKINIT_27;
+       cp->nonce = ap.pkAuthenticator.nonce;
 
        if (ap.clientPublicValue) {
 
        if (ap.clientPublicValue) {
-           ret = get_dh_param(context, config,
-                              ap.clientPublicValue, client_params);
+           if (der_heim_oid_cmp(&ap.clientPublicValue->algorithm.algorithm, &asn1_oid_id_dhpublicnumber) == 0) {
+               cp->keyex = USE_DH;
+               ret = get_dh_param(context, config,
+                                  ap.clientPublicValue, cp);
+#ifdef HAVE_OPENSSL
+           } else if (der_heim_oid_cmp(&ap.clientPublicValue->algorithm.algorithm, &asn1_oid_id_ecPublicKey) == 0) {
+               cp->keyex = USE_ECDH;
+               ret = get_ecdh_param(context, config,
+                                    ap.clientPublicValue, cp);
+#endif /* HAVE_OPENSSL */
+           } else {
+               ret = KRB5_BADMSGTYPE;
+               krb5_set_error_message(context, ret, "PKINIT unknown DH mechanism");
+           }
            if (ret) {
                free_AuthPack(&ap);
                goto out;
            }
            if (ret) {
                free_AuthPack(&ap);
                goto out;
            }
-       }
+       } else
+           cp->keyex = USE_RSA;
 
 
+       ret = hx509_peer_info_alloc(kdc_identity->hx509ctx,
+                                       &cp->peer);
+       if (ret) {
+           free_AuthPack(&ap);
+           goto out;
+       }
+       
        if (ap.supportedCMSTypes) {
        if (ap.supportedCMSTypes) {
-           ret = hx509_peer_info_alloc(kdc_identity->hx509ctx,
-                                       &client_params->peer);
-           if (ret) {
-               free_AuthPack(&ap);
-               goto out;
-           }
            ret = hx509_peer_info_set_cms_algs(kdc_identity->hx509ctx,
            ret = hx509_peer_info_set_cms_algs(kdc_identity->hx509ctx,
-                                              client_params->peer,
+                                              cp->peer,
                                               ap.supportedCMSTypes->val,
                                               ap.supportedCMSTypes->len);
            if (ret) {
                free_AuthPack(&ap);
                goto out;
            }
                                               ap.supportedCMSTypes->val,
                                               ap.supportedCMSTypes->len);
            if (ret) {
                free_AuthPack(&ap);
                goto out;
            }
+       } else {
+           /* assume old client */
+           hx509_peer_info_add_cms_alg(kdc_identity->hx509ctx, cp->peer,
+                                       hx509_crypto_des_rsdi_ede3_cbc());
+           hx509_peer_info_add_cms_alg(kdc_identity->hx509ctx, cp->peer,
+                                       hx509_signature_rsa_with_sha1());
+           hx509_peer_info_add_cms_alg(kdc_identity->hx509ctx, cp->peer,
+                                       hx509_signature_sha1());
        }
        free_AuthPack(&ap);
     } else
        }
        free_AuthPack(&ap);
     } else
@@ -642,10 +883,10 @@ out:
     krb5_data_free(&eContent);
     der_free_oid(&eContentType);
     der_free_oid(&contentInfoOid);
     krb5_data_free(&eContent);
     der_free_oid(&eContentType);
     der_free_oid(&contentInfoOid);
-    if (ret)
-       _kdc_pk_free_client_param(context, client_params);
-    else
-       *ret_params = client_params;
+    if (ret) {
+        _kdc_pk_free_client_param(context, cp);
+    } else 
+       *ret_params = cp;
     return ret;
 }
 
     return ret;
 }
 
@@ -670,11 +911,12 @@ BN_to_integer(krb5_context context, BIGNUM *bn, heim_integer *integer)
 static krb5_error_code
 pk_mk_pa_reply_enckey(krb5_context context,
                      krb5_kdc_configuration *config,
 static krb5_error_code
 pk_mk_pa_reply_enckey(krb5_context context,
                      krb5_kdc_configuration *config,
-                     pk_client_params *client_params,
+                     pk_client_params *cp,
                      const KDC_REQ *req,
                      const krb5_data *req_buffer,
                      krb5_keyblock *reply_key,
                      const KDC_REQ *req,
                      const krb5_data *req_buffer,
                      krb5_keyblock *reply_key,
-                     ContentInfo *content_info)
+                     ContentInfo *content_info,
+                     hx509_cert *kdc_cert)
 {
     const heim_oid *envelopedAlg = NULL, *sdAlg = NULL, *evAlg = NULL;
     krb5_error_code ret;
 {
     const heim_oid *envelopedAlg = NULL, *sdAlg = NULL, *evAlg = NULL;
     krb5_error_code ret;
@@ -685,13 +927,15 @@ pk_mk_pa_reply_enckey(krb5_context context,
     krb5_data_zero(&buf);
     krb5_data_zero(&signed_data);
 
     krb5_data_zero(&buf);
     krb5_data_zero(&signed_data);
 
+    *kdc_cert = NULL;
+
     /*
      * If the message client is a win2k-type but it send pa data
      * 09-binding it expects a IETF (checksum) reply so there can be
      * no replay attacks.
      */
 
     /*
      * If the message client is a win2k-type but it send pa data
      * 09-binding it expects a IETF (checksum) reply so there can be
      * no replay attacks.
      */
 
-    switch (client_params->type) {
+    switch (cp->type) {
     case PKINIT_WIN2K: {
        int i = 0;
        if (_kdc_find_padata(req, &i, KRB5_PADATA_PK_AS_09_BINDING) == NULL
     case PKINIT_WIN2K: {
        int i = 0;
        if (_kdc_find_padata(req, &i, KRB5_PADATA_PK_AS_09_BINDING) == NULL
@@ -699,14 +943,14 @@ pk_mk_pa_reply_enckey(krb5_context context,
        {
            do_win2k = 1;
        }
        {
            do_win2k = 1;
        }
-       sdAlg = oid_id_pkcs7_data();
-       evAlg = oid_id_pkcs7_data();
-       envelopedAlg = oid_id_rsadsi_des_ede3_cbc();
+       sdAlg = &asn1_oid_id_pkcs7_data;
+       evAlg = &asn1_oid_id_pkcs7_data;
+       envelopedAlg = &asn1_oid_id_rsadsi_des_ede3_cbc;
        break;
     }
     case PKINIT_27:
        break;
     }
     case PKINIT_27:
-       sdAlg = oid_id_pkrkeydata();
-       evAlg = oid_id_pkcs7_signedData();
+       sdAlg = &asn1_oid_id_pkrkeydata;
+       evAlg = &asn1_oid_id_pkcs7_signedData;
        break;
     default:
        krb5_abortx(context, "internal pkinit error");
        break;
     default:
        krb5_abortx(context, "internal pkinit error");
@@ -721,7 +965,7 @@ pk_mk_pa_reply_enckey(krb5_context context,
            krb5_clear_error_message(context);
            goto out;
        }
            krb5_clear_error_message(context);
            goto out;
        }
-       kp.nonce = client_params->nonce;
+       kp.nonce = cp->nonce;
        
        ASN1_MALLOC_ENCODE(ReplyKeyPack_Win2k,
                           buf.data, buf.length,
        
        ASN1_MALLOC_ENCODE(ReplyKeyPack_Win2k,
                           buf.data, buf.length,
@@ -777,7 +1021,8 @@ pk_mk_pa_reply_enckey(krb5_context context,
            goto out;
        
        hx509_query_match_option(q, HX509_QUERY_OPTION_PRIVATE_KEY);
            goto out;
        
        hx509_query_match_option(q, HX509_QUERY_OPTION_PRIVATE_KEY);
-       hx509_query_match_option(q, HX509_QUERY_OPTION_KU_DIGITALSIGNATURE);
+       if (config->pkinit_kdc_friendly_name)
+           hx509_query_match_friendly_name(q, config->pkinit_kdc_friendly_name);
        
        ret = hx509_certs_find(kdc_identity->hx509ctx,
                               kdc_identity->certs,
        
        ret = hx509_certs_find(kdc_identity->hx509ctx,
                               kdc_identity->certs,
@@ -794,19 +1039,19 @@ pk_mk_pa_reply_enckey(krb5_context context,
                                        buf.length,
                                        NULL,
                                        cert,
                                        buf.length,
                                        NULL,
                                        cert,
-                                       client_params->peer,
-                                       client_params->client_anchors,
+                                       cp->peer,
+                                       cp->client_anchors,
                                        kdc_identity->certpool,
                                        &signed_data);
                                        kdc_identity->certpool,
                                        &signed_data);
-       hx509_cert_free(cert);
+       *kdc_cert = cert;
     }
 
     krb5_data_free(&buf);
     if (ret)
        goto out;
 
     }
 
     krb5_data_free(&buf);
     if (ret)
        goto out;
 
-    if (client_params->type == PKINIT_WIN2K) {
-       ret = hx509_cms_wrap_ContentInfo(oid_id_pkcs7_signedData(),
+    if (cp->type == PKINIT_WIN2K) {
+       ret = hx509_cms_wrap_ContentInfo(&asn1_oid_id_pkcs7_signedData,
                                         &signed_data,
                                         &buf);
        if (ret)
                                         &signed_data,
                                         &buf);
        if (ret)
@@ -816,8 +1061,8 @@ pk_mk_pa_reply_enckey(krb5_context context,
     }
 
     ret = hx509_cms_envelope_1(kdc_identity->hx509ctx,
     }
 
     ret = hx509_cms_envelope_1(kdc_identity->hx509ctx,
-                              0,
-                              client_params->cert,
+                              HX509_CMS_EV_NO_KU_CHECK,
+                              cp->cert,
                               signed_data.data, signed_data.length,
                               envelopedAlg,
                               evAlg, &buf);
                               signed_data.data, signed_data.length,
                               envelopedAlg,
                               evAlg, &buf);
@@ -826,9 +1071,14 @@ pk_mk_pa_reply_enckey(krb5_context context,
 
     ret = _krb5_pk_mk_ContentInfo(context,
                                  &buf,
 
     ret = _krb5_pk_mk_ContentInfo(context,
                                  &buf,
-                                 oid_id_pkcs7_envelopedData(),
+                                 &asn1_oid_id_pkcs7_envelopedData,
                                  content_info);
 out:
                                  content_info);
 out:
+    if (ret && *kdc_cert) {
+        hx509_cert_free(*kdc_cert);
+       *kdc_cert = NULL;
+    }
+      
     krb5_data_free(&buf);
     krb5_data_free(&signed_data);
     return ret;
     krb5_data_free(&buf);
     krb5_data_free(&signed_data);
     return ret;
@@ -840,9 +1090,8 @@ out:
 
 static krb5_error_code
 pk_mk_pa_reply_dh(krb5_context context,
 
 static krb5_error_code
 pk_mk_pa_reply_dh(krb5_context context,
-                  DH *kdc_dh,
-                 pk_client_params *client_params,
-                  krb5_keyblock *reply_key,
+                 krb5_kdc_configuration *config,
+                 pk_client_params *cp,
                  ContentInfo *content_info,
                  hx509_cert *kdc_cert)
 {
                  ContentInfo *content_info,
                  hx509_cert *kdc_cert)
 {
@@ -850,33 +1099,63 @@ pk_mk_pa_reply_dh(krb5_context context,
     krb5_data signed_data, buf;
     ContentInfo contentinfo;
     krb5_error_code ret;
     krb5_data signed_data, buf;
     ContentInfo contentinfo;
     krb5_error_code ret;
+    hx509_cert cert;
+    hx509_query *q;
     size_t size;
     size_t size;
-    heim_integer i;
 
     memset(&contentinfo, 0, sizeof(contentinfo));
     memset(&dh_info, 0, sizeof(dh_info));
 
     memset(&contentinfo, 0, sizeof(contentinfo));
     memset(&dh_info, 0, sizeof(dh_info));
-    krb5_data_zero(&buf);
     krb5_data_zero(&signed_data);
     krb5_data_zero(&signed_data);
+    krb5_data_zero(&buf);
 
     *kdc_cert = NULL;
 
 
     *kdc_cert = NULL;
 
-    ret = BN_to_integer(context, kdc_dh->pub_key, &i);
-    if (ret)
-       return ret;
+    if (cp->keyex == USE_DH) {
+       DH *kdc_dh = cp->u.dh.key;
+       heim_integer i;
 
 
-    ASN1_MALLOC_ENCODE(DHPublicKey, buf.data, buf.length, &i, &size, ret);
-    if (ret) {
-       krb5_set_error_message(context, ret, "ASN.1 encoding of "
-                              "DHPublicKey failed (%d)", ret);
-       return ret;
-    }
-    if (buf.length != size)
-       krb5_abortx(context, "Internal ASN.1 encoder error");
-
-    dh_info.subjectPublicKey.length = buf.length * 8;
-    dh_info.subjectPublicKey.data = buf.data;
+       ret = BN_to_integer(context, kdc_dh->pub_key, &i);
+       if (ret)
+           return ret;
+       
+       ASN1_MALLOC_ENCODE(DHPublicKey, buf.data, buf.length, &i, &size, ret);
+       der_free_heim_integer(&i);
+       if (ret) {
+           krb5_set_error_message(context, ret, "ASN.1 encoding of "
+                                  "DHPublicKey failed (%d)", ret);
+           return ret;
+       }
+       if (buf.length != size)
+           krb5_abortx(context, "Internal ASN.1 encoder error");
+       
+       dh_info.subjectPublicKey.length = buf.length * 8;
+       dh_info.subjectPublicKey.data = buf.data;
+       krb5_data_zero(&buf);
+#ifdef HAVE_OPENSSL
+    } else if (cp->keyex == USE_ECDH) {
+       unsigned char *p;
+       int len;
+
+       len = i2o_ECPublicKey(cp->u.ecdh.key, NULL);
+       if (len <= 0)
+           abort();
+
+       p = malloc(len);
+       if (p == NULL)
+           abort();
+
+       dh_info.subjectPublicKey.length = len * 8;
+       dh_info.subjectPublicKey.data = p;
+
+       len = i2o_ECPublicKey(cp->u.ecdh.key, &p);
+       if (len <= 0)
+           abort();
+#endif
+    } else
+       krb5_abortx(context, "no keyex selected ?");
 
 
-    dh_info.nonce = client_params->nonce;
+       
+    dh_info.nonce = cp->nonce;
 
     ASN1_MALLOC_ENCODE(KDCDHKeyInfo, buf.data, buf.length, &dh_info, &size,
                       ret);
 
     ASN1_MALLOC_ENCODE(KDCDHKeyInfo, buf.data, buf.length, &dh_info, &size,
                       ret);
@@ -893,44 +1172,42 @@ pk_mk_pa_reply_dh(krb5_context context,
      * filled in above
      */
 
      * filled in above
      */
 
-    {
-       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,
-                                       0,
-                                       oid_id_pkdhkeydata(),
-                                       buf.data,
-                                       buf.length,
-                                       NULL,
-                                       cert,
-                                       client_params->peer,
-                                       client_params->client_anchors,
-                                       kdc_identity->certpool,
-                                       &signed_data);
-       *kdc_cert = cert;
-    }
+    ret = hx509_query_alloc(kdc_identity->hx509ctx, &q);
+    if (ret)
+       goto out;
+    
+    hx509_query_match_option(q, HX509_QUERY_OPTION_PRIVATE_KEY);
+    if (config->pkinit_kdc_friendly_name)
+       hx509_query_match_friendly_name(q, config->pkinit_kdc_friendly_name);
+    
+    ret = hx509_certs_find(kdc_identity->hx509ctx,
+                          kdc_identity->certs,
+                          q,
+                          &cert);
+    hx509_query_free(kdc_identity->hx509ctx, q);
     if (ret)
        goto out;
     if (ret)
        goto out;
+    
+    ret = hx509_cms_create_signed_1(kdc_identity->hx509ctx,
+                                   0,
+                                   &asn1_oid_id_pkdhkeydata,
+                                   buf.data,
+                                   buf.length,
+                                   NULL,
+                                   cert,
+                                   cp->peer,
+                                   cp->client_anchors,
+                                   kdc_identity->certpool,
+                                   &signed_data);
+    if (ret) {
+       kdc_log(context, config, 0, "Failed signing the DH* reply: %d", ret);
+       goto out;
+    }
+    *kdc_cert = cert;
 
     ret = _krb5_pk_mk_ContentInfo(context,
                                  &signed_data,
 
     ret = _krb5_pk_mk_ContentInfo(context,
                                  &signed_data,
-                                 oid_id_pkcs7_signedData(),
+                                 &asn1_oid_id_pkcs7_signedData,
                                  content_info);
     if (ret)
        goto out;
                                  content_info);
     if (ret)
        goto out;
@@ -955,11 +1232,13 @@ pk_mk_pa_reply_dh(krb5_context context,
 krb5_error_code
 _kdc_pk_mk_pa_reply(krb5_context context,
                    krb5_kdc_configuration *config,
 krb5_error_code
 _kdc_pk_mk_pa_reply(krb5_context context,
                    krb5_kdc_configuration *config,
-                   pk_client_params *client_params,
+                   pk_client_params *cp,
                    const hdb_entry_ex *client,
                    const hdb_entry_ex *client,
+                   krb5_enctype sessionetype,
                    const KDC_REQ *req,
                    const krb5_data *req_buffer,
                    krb5_keyblock **reply_key,
                    const KDC_REQ *req,
                    const krb5_data *req_buffer,
                    krb5_keyblock **reply_key,
+                   krb5_keyblock *sessionkey,
                    METHOD_DATA *md)
 {
     krb5_error_code ret;
                    METHOD_DATA *md)
 {
     krb5_error_code ret;
@@ -989,7 +1268,7 @@ _kdc_pk_mk_pa_reply(krb5_context context,
     } else
        enctype = ETYPE_DES3_CBC_SHA1;
 
     } else
        enctype = ETYPE_DES3_CBC_SHA1;
 
-    if (client_params->type == PKINIT_27) {
+    if (cp->type == PKINIT_27) {
        PA_PK_AS_REP rep;
        const char *type, *other = "";
 
        PA_PK_AS_REP rep;
        const char *type, *other = "";
 
@@ -997,7 +1276,7 @@ _kdc_pk_mk_pa_reply(krb5_context context,
 
        pa_type = KRB5_PADATA_PK_AS_REP;
 
 
        pa_type = KRB5_PADATA_PK_AS_REP;
 
-       if (client_params->dh == NULL) {
+       if (cp->keyex == USE_RSA) {
            ContentInfo info;
 
            type = "enckey";
            ContentInfo info;
 
            type = "enckey";
@@ -1005,18 +1284,19 @@ _kdc_pk_mk_pa_reply(krb5_context context,
            rep.element = choice_PA_PK_AS_REP_encKeyPack;
 
            ret = krb5_generate_random_keyblock(context, enctype,
            rep.element = choice_PA_PK_AS_REP_encKeyPack;
 
            ret = krb5_generate_random_keyblock(context, enctype,
-                                               &client_params->reply_key);
+                                               &cp->reply_key);
            if (ret) {
                free_PA_PK_AS_REP(&rep);
                goto out;
            }
            ret = pk_mk_pa_reply_enckey(context,
                                        config,
            if (ret) {
                free_PA_PK_AS_REP(&rep);
                goto out;
            }
            ret = pk_mk_pa_reply_enckey(context,
                                        config,
-                                       client_params,
+                                       cp,
                                        req,
                                        req_buffer,
                                        req,
                                        req_buffer,
-                                       &client_params->reply_key,
-                                       &info);
+                                       &cp->reply_key,
+                                       &info,
+                                       &kdc_cert);
            if (ret) {
                free_PA_PK_AS_REP(&rep);
                goto out;
            if (ret) {
                free_PA_PK_AS_REP(&rep);
                goto out;
@@ -1034,32 +1314,52 @@ _kdc_pk_mk_pa_reply(krb5_context context,
            if (rep.u.encKeyPack.length != size)
                krb5_abortx(context, "Internal ASN.1 encoder error");
 
            if (rep.u.encKeyPack.length != size)
                krb5_abortx(context, "Internal ASN.1 encoder error");
 
+           ret = krb5_generate_random_keyblock(context, sessionetype, 
+                                               sessionkey);
+           if (ret) {
+               free_PA_PK_AS_REP(&rep);
+               goto out;
+           }
+
        } else {
            ContentInfo info;
 
        } else {
            ContentInfo info;
 
-           type = "dh";
-           if (client_params->dh_group_name)
-               other = client_params->dh_group_name;
+           switch (cp->keyex) {
+           case USE_DH: type = "dh"; break;
+#ifdef HAVE_OPENSSL
+           case USE_ECDH: type = "ecdh"; break;
+#endif
+           default: krb5_abortx(context, "unknown keyex"); break;
+           }
+
+           if (cp->dh_group_name)
+               other = cp->dh_group_name;
 
            rep.element = choice_PA_PK_AS_REP_dhInfo;
 
 
            rep.element = choice_PA_PK_AS_REP_dhInfo;
 
-           ret = generate_dh_keyblock(context, client_params, enctype,
-                                      &client_params->reply_key);
+           ret = generate_dh_keyblock(context, cp, enctype);
            if (ret)
                return ret;
 
            if (ret)
                return ret;
 
-           ret = pk_mk_pa_reply_dh(context, client_params->dh,
-                                   client_params,
-                                   &client_params->reply_key,
+           ret = pk_mk_pa_reply_dh(context, config,
+                                   cp,
                                    &info,
                                    &kdc_cert);
                                    &info,
                                    &kdc_cert);
+           if (ret) {
+               free_PA_PK_AS_REP(&rep);
+               krb5_set_error_message(context, ret,
+                                      "create pa-reply-dh "
+                                      "failed %d", ret);
+               goto out;
+           }
 
            ASN1_MALLOC_ENCODE(ContentInfo, rep.u.dhInfo.dhSignedData.data,
                               rep.u.dhInfo.dhSignedData.length, &info, &size,
                               ret);
            free_ContentInfo(&info);
            if (ret) {
 
            ASN1_MALLOC_ENCODE(ContentInfo, rep.u.dhInfo.dhSignedData.data,
                               rep.u.dhInfo.dhSignedData.length, &info, &size,
                               ret);
            free_ContentInfo(&info);
            if (ret) {
-               krb5_set_error_message(context, ret, "encoding of Key ContentInfo "
+               krb5_set_error_message(context, ret,
+                                      "encoding of Key ContentInfo "
                                       "failed %d", ret);
                free_PA_PK_AS_REP(&rep);
                goto out;
                                       "failed %d", ret);
                free_PA_PK_AS_REP(&rep);
                goto out;
@@ -1067,17 +1367,23 @@ _kdc_pk_mk_pa_reply(krb5_context context,
            if (rep.u.encKeyPack.length != size)
                krb5_abortx(context, "Internal ASN.1 encoder error");
 
            if (rep.u.encKeyPack.length != size)
                krb5_abortx(context, "Internal ASN.1 encoder error");
 
-       }
-       if (ret) {
-           free_PA_PK_AS_REP(&rep);
-           goto out;
+           /* XXX KRB-FX-CF2 */
+           ret = krb5_generate_random_keyblock(context, sessionetype, 
+                                               sessionkey);
+           if (ret) {
+               free_PA_PK_AS_REP(&rep);
+               goto out;
+           }
+
+           /* XXX Add PA-PKINIT-KX */
+
        }
 
        ASN1_MALLOC_ENCODE(PA_PK_AS_REP, buf, len, &rep, &size, ret);
        free_PA_PK_AS_REP(&rep);
        if (ret) {
        }
 
        ASN1_MALLOC_ENCODE(PA_PK_AS_REP, buf, len, &rep, &size, ret);
        free_PA_PK_AS_REP(&rep);
        if (ret) {
-           krb5_set_error_message(context, ret, "encode PA-PK-AS-REP failed %d",
-                                  ret);
+           krb5_set_error_message(context, ret,
+                                  "encode PA-PK-AS-REP failed %d", ret);
            goto out;
        }
        if (len != size)
            goto out;
        }
        if (len != size)
@@ -1085,13 +1391,14 @@ _kdc_pk_mk_pa_reply(krb5_context context,
 
        kdc_log(context, config, 0, "PK-INIT using %s %s", type, other);
 
 
        kdc_log(context, config, 0, "PK-INIT using %s %s", type, other);
 
-    } else if (client_params->type == PKINIT_WIN2K) {
+    } else if (cp->type == PKINIT_WIN2K) {
        PA_PK_AS_REP_Win2k rep;
        ContentInfo info;
 
        PA_PK_AS_REP_Win2k rep;
        ContentInfo info;
 
-       if (client_params->dh) {
+       if (cp->keyex != USE_RSA) {
            ret = KRB5KRB_ERR_GENERIC;
            ret = KRB5KRB_ERR_GENERIC;
-           krb5_set_error_message(context, ret, "Windows PK-INIT doesn't support DH");
+           krb5_set_error_message(context, ret,
+                                  "Windows PK-INIT doesn't support DH");
            goto out;
        }
 
            goto out;
        }
 
@@ -1101,18 +1408,19 @@ _kdc_pk_mk_pa_reply(krb5_context context,
        rep.element = choice_PA_PK_AS_REP_encKeyPack;
 
        ret = krb5_generate_random_keyblock(context, enctype,
        rep.element = choice_PA_PK_AS_REP_encKeyPack;
 
        ret = krb5_generate_random_keyblock(context, enctype,
-                                           &client_params->reply_key);
+                                           &cp->reply_key);
        if (ret) {
            free_PA_PK_AS_REP_Win2k(&rep);
            goto out;
        }
        ret = pk_mk_pa_reply_enckey(context,
                                    config,
        if (ret) {
            free_PA_PK_AS_REP_Win2k(&rep);
            goto out;
        }
        ret = pk_mk_pa_reply_enckey(context,
                                    config,
-                                   client_params,
+                                   cp,
                                    req,
                                    req_buffer,
                                    req,
                                    req_buffer,
-                                   &client_params->reply_key,
-                                   &info);
+                                   &cp->reply_key,
+                                   &info,
+                                   &kdc_cert);
        if (ret) {
            free_PA_PK_AS_REP_Win2k(&rep);
            goto out;
        if (ret) {
            free_PA_PK_AS_REP_Win2k(&rep);
            goto out;
@@ -1140,13 +1448,19 @@ _kdc_pk_mk_pa_reply(krb5_context context,
        if (len != size)
            krb5_abortx(context, "Internal ASN.1 encoder error");
 
        if (len != size)
            krb5_abortx(context, "Internal ASN.1 encoder error");
 
+       ret = krb5_generate_random_keyblock(context, sessionetype, 
+                                           sessionkey);
+       if (ret)
+           goto out;
+
     } else
        krb5_abortx(context, "PK-INIT internal error");
 
 
     ret = krb5_padata_add(context, md, pa_type, buf, len);
     if (ret) {
     } else
        krb5_abortx(context, "PK-INIT internal error");
 
 
     ret = krb5_padata_add(context, md, pa_type, buf, len);
     if (ret) {
-       krb5_set_error_message(context, ret, "failed adding PA-PK-AS-REP %d", ret);
+       krb5_set_error_message(context, ret,
+                              "Failed adding PA-PK-AS-REP %d", ret);
        free(buf);
        goto out;
     }
        free(buf);
        goto out;
     }
@@ -1232,7 +1546,7 @@ out:
        hx509_cert_free(kdc_cert);
 
     if (ret == 0)
        hx509_cert_free(kdc_cert);
 
     if (ret == 0)
-       *reply_key = &client_params->reply_key;
+       *reply_key = &cp->reply_key;
     return ret;
 }
 
     return ret;
 }
 
@@ -1250,7 +1564,7 @@ match_rfc_san(krb5_context context,
 
     ret = hx509_cert_find_subjectAltName_otherName(hx509ctx,
                                                   client_cert,
 
     ret = hx509_cert_find_subjectAltName_otherName(hx509ctx,
                                                   client_cert,
-                                                  oid_id_pkinit_san(),
+                                                  &asn1_oid_id_pkinit_san,
                                                   &list);
     if (ret)
        goto out;
                                                   &list);
     if (ret)
        goto out;
@@ -1311,7 +1625,7 @@ match_ms_upn_san(krb5_context context,
 
     ret = hx509_cert_find_subjectAltName_otherName(hx509ctx,
                                                   client_cert,
 
     ret = hx509_cert_find_subjectAltName_otherName(hx509ctx,
                                                   client_cert,
-                                                  oid_id_pkinit_ms_san(),
+                                                  &asn1_oid_id_pkinit_ms_san,
                                                   &list);
     if (ret)
        goto out;
                                                   &list);
     if (ret)
        goto out;
@@ -1363,16 +1677,25 @@ krb5_error_code
 _kdc_pk_check_client(krb5_context context,
                     krb5_kdc_configuration *config,
                     const hdb_entry_ex *client,
 _kdc_pk_check_client(krb5_context context,
                     krb5_kdc_configuration *config,
                     const hdb_entry_ex *client,
-                    pk_client_params *client_params,
+                    pk_client_params *cp,
                     char **subject_name)
 {
     const HDB_Ext_PKINIT_acl *acl;
                     char **subject_name)
 {
     const HDB_Ext_PKINIT_acl *acl;
+    const HDB_Ext_PKINIT_cert *pc;
     krb5_error_code ret;
     hx509_name name;
     int i;
 
     krb5_error_code ret;
     hx509_name name;
     int i;
 
+    if (cp->cert == NULL) {
+
+       *subject_name = strdup("anonymous client client");
+       if (*subject_name == NULL)
+           return ENOMEM;
+       return 0;
+    }
+
     ret = hx509_cert_get_base_subject(kdc_identity->hx509ctx,
     ret = hx509_cert_get_base_subject(kdc_identity->hx509ctx,
-                                     client_params->cert,
+                                     cp->cert,
                                      &name);
     if (ret)
        return ret;
                                      &name);
     if (ret)
        return ret;
@@ -1386,10 +1709,33 @@ _kdc_pk_check_client(krb5_context context,
            "Trying to authorize PK-INIT subject DN %s",
            *subject_name);
 
            "Trying to authorize PK-INIT subject DN %s",
            *subject_name);
 
+    ret = hdb_entry_get_pkinit_cert(&client->entry, &pc);
+    if (ret == 0 && pc) {
+       hx509_cert cert;
+       unsigned int i;
+       
+       for (i = 0; i < pc->len; i++) {
+           ret = hx509_cert_init_data(kdc_identity->hx509ctx,
+                                      pc->val[i].cert.data,
+                                      pc->val[i].cert.length,
+                                      &cert);
+           if (ret)
+               continue;
+           ret = hx509_cert_cmp(cert, cp->cert);
+           hx509_cert_free(cert);
+           if (ret == 0) {
+               kdc_log(context, config, 5,
+                       "Found matching PK-INIT cert in hdb");
+               return 0;
+           }
+       }
+    }
+
+
     if (config->pkinit_princ_in_cert) {
        ret = match_rfc_san(context, config,
                            kdc_identity->hx509ctx,
     if (config->pkinit_princ_in_cert) {
        ret = match_rfc_san(context, config,
                            kdc_identity->hx509ctx,
-                           client_params->cert,
+                           cp->cert,
                            client->entry.principal);
        if (ret == 0) {
            kdc_log(context, config, 5,
                            client->entry.principal);
        if (ret == 0) {
            kdc_log(context, config, 5,
@@ -1398,7 +1744,7 @@ _kdc_pk_check_client(krb5_context context,
        }
        ret = match_ms_upn_san(context, config,
                               kdc_identity->hx509ctx,
        }
        ret = match_ms_upn_san(context, config,
                               kdc_identity->hx509ctx,
-                              client_params->cert,
+                              cp->cert,
                               client->entry.principal);
        if (ret == 0) {
            kdc_log(context, config, 5,
                               client->entry.principal);
        if (ret == 0) {
            kdc_log(context, config, 5,
@@ -1493,7 +1839,7 @@ add_principal_mapping(krb5_context context,
 krb5_error_code
 _kdc_add_inital_verified_cas(krb5_context context,
                             krb5_kdc_configuration *config,
 krb5_error_code
 _kdc_add_inital_verified_cas(krb5_context context,
                             krb5_kdc_configuration *config,
-                            pk_client_params *params,
+                            pk_client_params *cp,
                             EncTicketPart *tkt)
 {
     AD_INITIAL_VERIFIED_CAS cas;
                             EncTicketPart *tkt)
 {
     AD_INITIAL_VERIFIED_CAS cas;
@@ -1594,6 +1940,7 @@ _kdc_pk_initialize(krb5_context context,
 
     ret = _krb5_pk_load_id(context,
                           &kdc_identity,
 
     ret = _krb5_pk_load_id(context,
                           &kdc_identity,
+                          0,
                           user_id,
                           anchors,
                           pool,
                           user_id,
                           anchors,
                           pool,
@@ -1618,7 +1965,8 @@ _kdc_pk_initialize(krb5_context context,
        }
        
        hx509_query_match_option(q, HX509_QUERY_OPTION_PRIVATE_KEY);
        }
        
        hx509_query_match_option(q, HX509_QUERY_OPTION_PRIVATE_KEY);
-       hx509_query_match_option(q, HX509_QUERY_OPTION_KU_DIGITALSIGNATURE);
+       if (config->pkinit_kdc_friendly_name)
+           hx509_query_match_friendly_name(q, config->pkinit_kdc_friendly_name);
        
        ret = hx509_certs_find(kdc_identity->hx509ctx,
                               kdc_identity->certs,
        
        ret = hx509_certs_find(kdc_identity->hx509ctx,
                               kdc_identity->certs,
@@ -1627,23 +1975,30 @@ _kdc_pk_initialize(krb5_context context,
        hx509_query_free(kdc_identity->hx509ctx, q);
        if (ret == 0) {
            if (hx509_cert_check_eku(kdc_identity->hx509ctx, cert,
        hx509_query_free(kdc_identity->hx509ctx, q);
        if (ret == 0) {
            if (hx509_cert_check_eku(kdc_identity->hx509ctx, cert,
-                                    oid_id_pkkdcekuoid(), 0))
-               krb5_warnx(context, "WARNING Found KDC certificate "
+                                    &asn1_oid_id_pkkdcekuoid, 0)) {
+               hx509_name name;
+               char *str;
+               ret = hx509_cert_get_subject(cert, &name);
+               hx509_name_to_string(name, &str);
+               krb5_warnx(context, "WARNING Found KDC certificate (%s)"
                           "is missing the PK-INIT KDC EKU, this is bad for "
                           "is missing the PK-INIT KDC EKU, this is bad for "
-                          "interoperability.");
+                          "interoperability.", str);
+               hx509_name_free(&name);
+               free(str);
+           }
            hx509_cert_free(cert);
        } else
            krb5_warnx(context, "PKINIT: failed to find a signing "
                       "certifiate with a public key");
     }
 
            hx509_cert_free(cert);
        } else
            krb5_warnx(context, "PKINIT: failed to find a signing "
                       "certifiate with a public key");
     }
 
-    ret = krb5_config_get_bool_default(context,
-                                      NULL,
-                                      FALSE,
-                                      "kdc",
-                                      "pkinit_allow_proxy_certificate",
-                                      NULL);
-    _krb5_pk_allow_proxy_certificate(kdc_identity, ret);
+    if (krb5_config_get_bool_default(context,
+                                    NULL,
+                                    FALSE,
+                                    "kdc",
+                                    "pkinit_allow_proxy_certificate",
+                                    NULL))
+       config->pkinit_allow_proxy_certs = 1;
 
     file = krb5_config_get_string(context,
                                  NULL,
 
     file = krb5_config_get_string(context,
                                  NULL,
index a27911914b52434fba48ae7463275a830335fb06..d3557ee6c9e45af0733ba5006d73f0c09bfcd251 100644 (file)
@@ -34,8 +34,6 @@
 
 #include "kdc_locl.h"
 
 
 #include "kdc_locl.h"
 
-RCSID("$Id$");
-
 /*
  *
  */
 /*
  *
  */
@@ -49,6 +47,209 @@ krb5_kdc_update_time(struct timeval *tv)
        _kdc_now = *tv;
 }
 
        _kdc_now = *tv;
 }
 
+static krb5_error_code 
+kdc_as_req(krb5_context context,
+          krb5_kdc_configuration *config,
+          krb5_data *req_buffer,
+          krb5_data *reply,
+          const char *from,
+          struct sockaddr *addr,
+          int datagram_reply,
+          int *claim)
+{
+    krb5_error_code ret;
+    KDC_REQ req;
+    size_t len;
+
+    ret = decode_AS_REQ(req_buffer->data, req_buffer->length, &req, &len);
+    if (ret)
+       return ret;
+
+    *claim = 1;
+
+    ret = _kdc_as_rep(context, config, &req, req_buffer,
+                     reply, from, addr, datagram_reply);
+    free_AS_REQ(&req);
+    return ret;
+}
+
+
+static krb5_error_code 
+kdc_tgs_req(krb5_context context,
+           krb5_kdc_configuration *config,
+           krb5_data *req_buffer,
+           krb5_data *reply,
+           const char *from,
+           struct sockaddr *addr,
+           int datagram_reply,
+           int *claim)
+{
+    krb5_error_code ret;
+    KDC_REQ req;
+    size_t len;
+
+    ret = decode_TGS_REQ(req_buffer->data, req_buffer->length, &req, &len);
+    if (ret)
+       return ret;
+    
+    *claim = 1;
+
+    ret = _kdc_tgs_rep(context, config, &req, reply, 
+                      from, addr, datagram_reply);
+    free_TGS_REQ(&req);
+    return ret;
+}
+
+#ifdef DIGEST
+
+static krb5_error_code 
+kdc_digest(krb5_context context,
+          krb5_kdc_configuration *config,
+          krb5_data *req_buffer,
+          krb5_data *reply,
+          const char *from,
+          struct sockaddr *addr,
+          int datagram_reply,
+          int *claim)
+{
+    DigestREQ digestreq;
+    krb5_error_code ret;
+    size_t len;
+
+    ret = decode_DigestREQ(req_buffer->data, req_buffer->length,
+                          &digestreq, &len);
+    if (ret)
+       return ret;
+
+    *claim = 1;
+
+    ret = _kdc_do_digest(context, config, &digestreq, reply, from, addr);
+    free_DigestREQ(&digestreq);
+    return ret;
+}
+
+#endif
+
+#ifdef KX509
+
+static krb5_error_code 
+kdc_kx509(krb5_context context,
+         krb5_kdc_configuration *config,
+         krb5_data *req_buffer,
+         krb5_data *reply,
+         const char *from,
+         struct sockaddr *addr,
+         int datagram_reply,
+         int *claim)
+{
+    Kx509Request kx509req;
+    krb5_error_code ret;
+    size_t len;
+
+    ret = _kdc_try_kx509_request(req_buffer->data, req_buffer->length,
+                                &kx509req, &len);
+    if (ret)
+       return ret;
+
+    *claim = 1;
+
+    ret = _kdc_do_kx509(context, config, &kx509req, reply, from, addr);
+    free_Kx509Request(&kx509req);
+    return ret;
+}
+
+#endif
+
+
+#ifdef KRB4
+
+static krb5_error_code 
+kdc_524(krb5_context context,
+       krb5_kdc_configuration *config,
+       krb5_data *req_buffer,
+       krb5_data *reply,
+       const char *from,
+       struct sockaddr *addr,
+       int datagram_reply,
+       int *claim)
+{
+    krb5_error_code ret;
+    Ticket ticket;
+    size_t len;
+
+    ret = decode_Ticket(req_buffer->data, req_buffer->length, &ticket, &len);
+    if (ret)
+       return ret;
+
+    *claim = 1;
+
+    ret = _kdc_do_524(context, config, &ticket, reply, from, addr);
+    free_Ticket(&ticket);
+    return ret;
+}
+
+static krb5_error_code 
+kdc_krb4(krb5_context context,
+        krb5_kdc_configuration *config,
+        krb5_data *req_buffer,
+        krb5_data *reply,
+        const char *from,
+        struct sockaddr *addr,
+        int datagram_reply,
+        int *claim)
+{
+    if (_kdc_maybe_version4(req_buffer->data, req_buffer->length) == 0)
+       return -1;
+
+    *claim = 1;
+
+    return _kdc_do_version4(context, config, 
+                          req_buffer->data, req_buffer->length, 
+                          reply, from,
+                          (struct sockaddr_in*)addr);
+}
+
+static krb5_error_code 
+kdc_kaserver(krb5_context context,
+            krb5_kdc_configuration *config,
+            krb5_data *req_buffer,
+            krb5_data *reply,
+            const char *from,
+            struct sockaddr *addr,
+            int datagram_reply,
+            int *claim)
+{
+    if (config->enable_kaserver == 0)
+       return -1;
+
+    *claim = 1;
+
+    return _kdc_do_kaserver(context, config, 
+                           req_buffer->data, req_buffer->length, 
+                           reply, from,
+                           (struct sockaddr_in*)addr);
+}
+
+#endif /* KRB4 */
+
+
+static struct krb5_kdc_service services[] =  {
+    { KS_KRB5,         kdc_as_req },
+    { KS_KRB5,         kdc_tgs_req },
+#ifdef DIGEST
+    { 0,               kdc_digest },
+#endif
+#ifdef KX509
+    { 0,               kdc_kx509 },
+#endif
+#ifdef KRB4
+    { 0,               kdc_524 },
+    { KS_NO_LENGTH,    kdc_krb4 },
+    { 0,               kdc_kaserver },
+#endif
+    { 0, NULL }
+};
+
 /*
  * handle the request in `buf, len', from `addr' (or `from' as a string),
  * sending a reply in `reply'.
 /*
  * handle the request in `buf, len', from `addr' (or `from' as a string),
  * sending a reply in `reply'.
@@ -65,50 +266,25 @@ krb5_kdc_process_request(krb5_context context,
                         struct sockaddr *addr,
                         int datagram_reply)
 {
                         struct sockaddr *addr,
                         int datagram_reply)
 {
-    KDC_REQ req;
-    Ticket ticket;
-    DigestREQ digestreq;
-    Kx509Request kx509req;
     krb5_error_code ret;
     krb5_error_code ret;
-    size_t i;
-
-    if(decode_AS_REQ(buf, len, &req, &i) == 0){
-       krb5_data req_buffer;
+    unsigned int i;
+    krb5_data req_buffer;
+    int claim = 0;
+    
+    req_buffer.data = buf;
+    req_buffer.length = len;
 
 
-       req_buffer.data = buf;
-       req_buffer.length = len;
-
-       ret = _kdc_as_rep(context, config, &req, &req_buffer,
-                         reply, from, addr, datagram_reply);
-       free_AS_REQ(&req);
-       return ret;
-    }else if(decode_TGS_REQ(buf, len, &req, &i) == 0){
-       ret = _kdc_tgs_rep(context, config, &req, reply, from, addr, datagram_reply);
-       free_TGS_REQ(&req);
-       return ret;
-    }else if(decode_Ticket(buf, len, &ticket, &i) == 0){
-       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_try_kx509_request(buf, len, &kx509req, &i) == 0) {
-       ret = _kdc_do_kx509(context, config, &kx509req, reply, from, addr);
-       free_Kx509Request(&kx509req);
-       return ret;
-    } else if(_kdc_maybe_version4(buf, len)){
-       *prependlength = FALSE; /* elbitapmoc sdrawkcab XXX */
-       ret = _kdc_do_version4(context, config, buf, len, reply, from,
-                              (struct sockaddr_in*)addr);
-       return ret;
-    } else if (config->enable_kaserver) {
-       ret = _kdc_do_kaserver(context, config, buf, len, reply, from,
-                              (struct sockaddr_in*)addr);
-       return ret;
+    for (i = 0; services[i].process != NULL; i++) {
+       ret = (*services[i].process)(context, config, &req_buffer,
+                                    reply, from, addr, datagram_reply,
+                                    &claim);
+       if (claim) {
+           if (services[i].flags & KS_NO_LENGTH)
+               *prependlength = 0;
+           return ret;
+       }
     }
     }
-                       
+
     return -1;
 }
 
     return -1;
 }
 
@@ -129,25 +305,24 @@ krb5_kdc_process_krb5_request(krb5_context context,
                              struct sockaddr *addr,
                              int datagram_reply)
 {
                              struct sockaddr *addr,
                              int datagram_reply)
 {
-    KDC_REQ req;
     krb5_error_code ret;
     krb5_error_code ret;
-    size_t i;
+    unsigned int i;
+    krb5_data req_buffer;
+    int claim = 0;
+    
+    req_buffer.data = buf;
+    req_buffer.length = len;
 
 
-    if(decode_AS_REQ(buf, len, &req, &i) == 0){
-       krb5_data req_buffer;
-
-       req_buffer.data = buf;
-       req_buffer.length = len;
-
-       ret = _kdc_as_rep(context, config, &req, &req_buffer,
-                         reply, from, addr, datagram_reply);
-       free_AS_REQ(&req);
-       return ret;
-    }else if(decode_TGS_REQ(buf, len, &req, &i) == 0){
-       ret = _kdc_tgs_rep(context, config, &req, reply, from, addr, datagram_reply);
-       free_TGS_REQ(&req);
-       return ret;
+    for (i = 0; services[i].process != NULL; i++) {
+       if ((services[i].flags & KS_KRB5) == 0)
+           continue;
+       ret = (*services[i].process)(context, config, &req_buffer,
+                                    reply, from, addr, datagram_reply,
+                                    &claim);
+       if (claim)
+           return ret;
     }
     }
+                       
     return -1;
 }
 
     return -1;
 }
 
index f67130a05242a088f3e1fafb5fce54bc669cf815..c2f980b25f0f145d297359bcaec68b173075529e 100644 (file)
@@ -153,9 +153,9 @@ main (int argc, char **argv)
        if (ret)
            krb5_err (context, 1, ret, "krb5_cc_resolve");
     } else {
        if (ret)
            krb5_err (context, 1, ret, "krb5_cc_resolve");
     } else {
-       ret = krb5_cc_gen_new(context, &krb5_mcc_ops, &id);
+       ret = krb5_cc_new_unique(context, krb5_cc_type_memory, NULL, &id);
        if (ret)
        if (ret)
-           krb5_err (context, 1, ret, "krb5_cc_gen_new");
+           krb5_err (context, 1, ret, "krb5_cc_new_unique");
     }
 
     if (cred_cache_str == NULL) {
     }
 
     if (cred_cache_str == NULL) {
index fbb2d2287bcd012b4b2d7cda162b98742b768ae7..350988dbac9667e06c091e9a2764c093851d8359 100644 (file)
  */
 
 #include "kuser_locl.h"
  */
 
 #include "kuser_locl.h"
-RCSID("$Id$");
 
 
+#ifndef HEIMDAL_SMALLER
 #include "krb5-v4compat.h"
 #include "krb5-v4compat.h"
+#endif
+
+struct krb5_dh_moduli;
+struct AlgorithmIdentifier;
+struct _krb5_krb_auth_data;
+#include <krb5-private.h>
 
 
+#ifndef NO_NTLM
 #include "heimntlm.h"
 #include "heimntlm.h"
+#endif
 
 int forwardable_flag   = -1;
 int proxiable_flag     = -1;
 
 int forwardable_flag   = -1;
 int proxiable_flag     = -1;
@@ -54,6 +62,7 @@ char *renew_life      = NULL;
 char *server_str       = NULL;
 char *cred_cache       = NULL;
 char *start_str                = NULL;
 char *server_str       = NULL;
 char *cred_cache       = NULL;
 char *start_str                = NULL;
+static int switch_cache_flags = 1;
 struct getarg_strings etype_str;
 int use_keytab         = 0;
 char *keytab_str       = NULL;
 struct getarg_strings etype_str;
 int use_keytab         = 0;
 char *keytab_str       = NULL;
@@ -66,13 +75,17 @@ static char *krb4_cc_name;
 int fcache_version;
 char *password_file    = NULL;
 char *pk_user_id       = NULL;
 int fcache_version;
 char *password_file    = NULL;
 char *pk_user_id       = NULL;
+int pk_enterprise_flag = 0;
 char *pk_x509_anchors  = NULL;
 int pk_use_enckey      = 0;
 static int canonicalize_flag = 0;
 char *pk_x509_anchors  = NULL;
 int pk_use_enckey      = 0;
 static int canonicalize_flag = 0;
+static int enterprise_flag = 0;
 static int ok_as_delegate_flag = 0;
 static int use_referrals_flag = 0;
 static int windows_flag = 0;
 static int ok_as_delegate_flag = 0;
 static int use_referrals_flag = 0;
 static int windows_flag = 0;
+#ifndef NO_NTLM
 static char *ntlm_domain;
 static char *ntlm_domain;
+#endif
 
 
 static struct getargs args[] = {
 
 
 static struct getargs args[] = {
@@ -154,7 +167,13 @@ static struct getargs args[] = {
 
     { "canonicalize",0,   arg_flag, &canonicalize_flag,
       NP_("canonicalize client principal", "") },
 
     { "canonicalize",0,   arg_flag, &canonicalize_flag,
       NP_("canonicalize client principal", "") },
+
+    { "enterprise",0,   arg_flag, &enterprise_flag,
+      NP_("parse principal as a KRB5-NT-ENTERPRISE name", "") },
 #ifdef PKINIT
 #ifdef PKINIT
+    { "pk-enterprise", 0,      arg_flag,       &pk_enterprise_flag,
+      NP_("use enterprise name from certificate", "") },
+
     { "pk-user",       'C',    arg_string,     &pk_user_id,
       NP_("principal's public/private/certificate identifier", ""), "id" },
 
     { "pk-user",       'C',    arg_string,     &pk_user_id,
       NP_("principal's public/private/certificate identifier", ""), "id" },
 
@@ -164,8 +183,13 @@ static struct getargs args[] = {
     { "pk-use-enckey", 0,  arg_flag, &pk_use_enckey,
       NP_("Use RSA encrypted reply (instead of DH)", "") },
 #endif
     { "pk-use-enckey", 0,  arg_flag, &pk_use_enckey,
       NP_("Use RSA encrypted reply (instead of DH)", "") },
 #endif
+#ifndef NO_NTLM
     { "ntlm-domain",   0,  arg_string, &ntlm_domain,
       NP_("NTLM domain", ""), "domain" },
     { "ntlm-domain",   0,  arg_string, &ntlm_domain,
       NP_("NTLM domain", ""), "domain" },
+#endif
+
+    { "change-default",  0,  arg_negative_flag, &switch_cache_flags,
+      NP_("switch the default cache to the new credentials cache", "") },
 
     { "ok-as-delegate",        0,  arg_flag, &ok_as_delegate_flag,
       NP_("honor ok-as-delegate on tickets", "") },
 
     { "ok-as-delegate",        0,  arg_flag, &ok_as_delegate_flag,
       NP_("honor ok-as-delegate on tickets", "") },
@@ -198,13 +222,13 @@ get_server(krb5_context context,
           const char *server,
           krb5_principal *princ)
 {
           const char *server,
           krb5_principal *princ)
 {
-    krb5_realm *client_realm;
+    krb5_const_realm realm;
     if(server)
        return krb5_parse_name(context, server, princ);
 
     if(server)
        return krb5_parse_name(context, server, princ);
 
-    client_realm = krb5_princ_realm (context, client);
-    return krb5_make_principal(context, princ, *client_realm,
-                              KRB5_TGS_NAME, *client_realm, NULL);
+    realm = krb5_principal_get_realm(context, client);
+    return krb5_make_principal(context, princ, realm,
+                              KRB5_TGS_NAME, realm, NULL);
 }
 
 #ifndef HEIMDAL_SMALLER
 }
 
 #ifndef HEIMDAL_SMALLER
@@ -301,7 +325,7 @@ renew_validate(krb5_context context,
     else if (out)
        flags.b.proxiable         = out->flags.b.proxiable;
 
     else if (out)
        flags.b.proxiable         = out->flags.b.proxiable;
 
-    if (anonymous_flag != -1)
+    if (anonymous_flag)
        flags.b.request_anonymous = anonymous_flag;
     if(life)
        in.times.endtime = time(NULL) + life;
        flags.b.request_anonymous = anonymous_flag;
     if(life)
        in.times.endtime = time(NULL) + life;
@@ -337,8 +361,10 @@ renew_validate(krb5_context context,
        if(get_v4_tgt)
            do_524init(context, cache, out, NULL);
 #endif
        if(get_v4_tgt)
            do_524init(context, cache, out, NULL);
 #endif
+#ifndef NO_AFS
        if(do_afslog && k_hasafs())
            krb5_afslog(context, cache, NULL, NULL);
        if(do_afslog && k_hasafs())
            krb5_afslog(context, cache, NULL, NULL);
+#endif
     }
 
     krb5_free_creds (context, out);
     }
 
     krb5_free_creds (context, out);
@@ -351,6 +377,8 @@ out:
     return ret;
 }
 
     return ret;
 }
 
+#ifndef NO_NTLM
+
 static krb5_error_code
 store_ntlmkey(krb5_context context, krb5_ccache id,
              const char *domain, struct ntlm_buf *buf)
 static krb5_error_code
 store_ntlmkey(krb5_context context, krb5_ccache id,
              const char *domain, struct ntlm_buf *buf)
@@ -372,6 +400,7 @@ store_ntlmkey(krb5_context context, krb5_ccache id,
     free(name);
     return ret;
 }
     free(name);
     return ret;
 }
+#endif
 
 static krb5_error_code
 get_new_tickets(krb5_context context,
 
 static krb5_error_code
 get_new_tickets(krb5_context context,
@@ -388,10 +417,11 @@ get_new_tickets(krb5_context context,
     krb5_deltat renew = 0;
     char *renewstr = NULL;
     krb5_enctype *enctype = NULL;
     krb5_deltat renew = 0;
     char *renewstr = NULL;
     krb5_enctype *enctype = NULL;
-    struct ntlm_buf ntlmkey;
     krb5_ccache tempccache;
     krb5_ccache tempccache;
-
+#ifndef NO_NTLM
+    struct ntlm_buf ntlmkey;
     memset(&ntlmkey, 0, sizeof(ntlmkey));
     memset(&ntlmkey, 0, sizeof(ntlmkey));
+#endif
     passwd[0] = '\0';
 
     if (password_file) {
     passwd[0] = '\0';
 
     if (password_file) {
@@ -428,21 +458,24 @@ get_new_tickets(krb5_context context,
        krb5_get_init_creds_opt_set_forwardable (opt, forwardable_flag);
     if(proxiable_flag != -1)
        krb5_get_init_creds_opt_set_proxiable (opt, proxiable_flag);
        krb5_get_init_creds_opt_set_forwardable (opt, forwardable_flag);
     if(proxiable_flag != -1)
        krb5_get_init_creds_opt_set_proxiable (opt, proxiable_flag);
-    if(anonymous_flag != -1)
+    if(anonymous_flag)
        krb5_get_init_creds_opt_set_anonymous (opt, anonymous_flag);
     if (pac_flag != -1)
        krb5_get_init_creds_opt_set_pac_request(context, opt,
                                                pac_flag ? TRUE : FALSE);
     if (canonicalize_flag)
        krb5_get_init_creds_opt_set_canonicalize(context, opt, TRUE);
        krb5_get_init_creds_opt_set_anonymous (opt, anonymous_flag);
     if (pac_flag != -1)
        krb5_get_init_creds_opt_set_pac_request(context, opt,
                                                pac_flag ? TRUE : FALSE);
     if (canonicalize_flag)
        krb5_get_init_creds_opt_set_canonicalize(context, opt, TRUE);
-    if (pk_user_id) {
+    if (pk_enterprise_flag && windows_flag)
+       krb5_get_init_creds_opt_set_win2k(context, opt, TRUE);
+    if (pk_user_id || anonymous_flag) {
        ret = krb5_get_init_creds_opt_set_pkinit(context, opt,
                                                 principal,
                                                 pk_user_id,
                                                 pk_x509_anchors,
                                                 NULL,
                                                 NULL,
        ret = krb5_get_init_creds_opt_set_pkinit(context, opt,
                                                 principal,
                                                 pk_user_id,
                                                 pk_x509_anchors,
                                                 NULL,
                                                 NULL,
-                                                pk_use_enckey ? 2 : 0,
+                                                pk_use_enckey ? 2 : 0 |
+                                                anonymous_flag ? 4 : 0,
                                                 krb5_prompter_posix,
                                                 NULL,
                                                 passwd);
                                                 krb5_prompter_posix,
                                                 NULL,
                                                 passwd);
@@ -510,7 +543,7 @@ get_new_tickets(krb5_context context,
                                          server_str,
                                          opt);
        krb5_kt_close(context, kt);
                                          server_str,
                                          opt);
        krb5_kt_close(context, kt);
-    } else if (pk_user_id) {
+    } else if (pk_user_id || anonymous_flag) {
        ret = krb5_get_init_creds_password (context,
                                            &cred,
                                            principal,
        ret = krb5_get_init_creds_password (context,
                                            &cred,
                                            principal,
@@ -552,8 +585,10 @@ get_new_tickets(krb5_context context,
                                            opt);
     }
     krb5_get_init_creds_opt_free(context, opt);
                                            opt);
     }
     krb5_get_init_creds_opt_free(context, opt);
+#ifndef NO_NTLM
     if (ntlm_domain && passwd[0])
        heim_ntlm_nt_key(passwd, &ntlmkey);
     if (ntlm_domain && passwd[0])
        heim_ntlm_nt_key(passwd, &ntlmkey);
+#endif
     memset(passwd, 0, sizeof(passwd));
 
     switch(ret){
     memset(passwd, 0, sizeof(passwd));
 
     switch(ret){
@@ -611,8 +646,13 @@ get_new_tickets(krb5_context context,
     if (ret)
        krb5_err (context, 1, ret, "krb5_cc_move");
 
     if (ret)
        krb5_err (context, 1, ret, "krb5_cc_move");
 
+    if (switch_cache_flags)
+       krb5_cc_switch(context, ccache);
+
+#ifndef NO_NTLM
     if (ntlm_domain && ntlmkey.data)
        store_ntlmkey(context, ccache, ntlm_domain, &ntlmkey);
     if (ntlm_domain && ntlmkey.data)
        store_ntlmkey(context, ccache, ntlm_domain, &ntlmkey);
+#endif
 
     if (ok_as_delegate_flag || windows_flag || use_referrals_flag) {
        unsigned char d = 0;
 
     if (ok_as_delegate_flag || windows_flag || use_referrals_flag) {
        unsigned char d = 0;
@@ -704,8 +744,10 @@ renew_func(void *ptr)
     if(get_v4_tgt || convert_524)
        do_524init(ctx->context, ctx->ccache, NULL, server_str);
 #endif
     if(get_v4_tgt || convert_524)
        do_524init(ctx->context, ctx->ccache, NULL, server_str);
 #endif
+#ifndef NO_AFS
     if(do_afslog && k_hasafs())
        krb5_afslog(ctx->context, ctx->ccache, NULL, NULL);
     if(do_afslog && k_hasafs())
        krb5_afslog(ctx->context, ctx->ccache, NULL, NULL);
+#endif
 
     expire = ticket_lifetime(ctx->context, ctx->ccache, ctx->principal,
                             server_str) / 2;
 
     expire = ticket_lifetime(ctx->context, ctx->ccache, ctx->principal,
                             server_str) / 2;
@@ -751,17 +793,35 @@ main (int argc, char **argv)
     argc -= optidx;
     argv += optidx;
 
     argc -= optidx;
     argv += optidx;
 
-    if (canonicalize_flag)
+    if (canonicalize_flag || enterprise_flag)
        parseflags |= KRB5_PRINCIPAL_PARSE_ENTERPRISE;
 
        parseflags |= KRB5_PRINCIPAL_PARSE_ENTERPRISE;
 
-    if (argv[0]) {
-       ret = krb5_parse_name_flags (context, argv[0], parseflags, &principal);
+    if (pk_enterprise_flag) {
+       ret = _krb5_pk_enterprise_cert(context, pk_user_id,
+                                      argv[0], &principal);
        if (ret)
        if (ret)
-           krb5_err (context, 1, ret, "krb5_parse_name");
-    } else {
-       ret = krb5_get_default_principal (context, &principal);
+           krb5_err(context, 1, ret, "krb5_pk_enterprise_certs");
+
+    } else if (anonymous_flag) {
+
+       ret = krb5_make_principal(context, &principal, argv[0],
+                                 KRB5_WELLKNOWN_NAME, KRB5_ANON_NAME, 
+                                 NULL);
        if (ret)
        if (ret)
-           krb5_err (context, 1, ret, "krb5_get_default_principal");
+           krb5_err(context, 1, ret, "krb5_build_principal");
+       krb5_principal_set_type(context, principal, KRB5_NT_WELLKNOWN);
+
+    } else {
+       if (argv[0]) {
+           ret = krb5_parse_name_flags (context, argv[0], parseflags,
+                                        &principal);
+           if (ret)
+               krb5_err (context, 1, ret, "krb5_parse_name");
+       } else {
+           ret = krb5_get_default_principal (context, &principal);
+           if (ret)
+               krb5_err (context, 1, ret, "krb5_get_default_principal");
+       }
     }
 
     if(fcache_version)
     }
 
     if(fcache_version)
@@ -788,7 +848,7 @@ main (int argc, char **argv)
     else {
        if(argc > 1) {
            char s[1024];
     else {
        if(argc > 1) {
            char s[1024];
-           ret = krb5_cc_gen_new(context, &krb5_fcc_ops, &ccache);
+           ret = krb5_cc_new_unique(context, NULL, NULL, &ccache);
            if(ret)
                krb5_err(context, 1, ret, "creating cred cache");
            snprintf(s, sizeof(s), "%s:%s",
            if(ret)
                krb5_err(context, 1, ret, "creating cred cache");
            snprintf(s, sizeof(s), "%s:%s",
@@ -818,8 +878,10 @@ main (int argc, char **argv)
     if (ret)
        krb5_err (context, 1, ret, N_("resolving credentials cache", ""));
 
     if (ret)
        krb5_err (context, 1, ret, N_("resolving credentials cache", ""));
 
+#ifndef NO_AFS
     if(argc > 1 && k_hasafs ())
        k_setpag();
     if(argc > 1 && k_hasafs ())
        k_setpag();
+#endif
 
     if (lifetime) {
        int tmp = parse_time (lifetime, "s");
 
     if (lifetime) {
        int tmp = parse_time (lifetime, "s");
@@ -863,8 +925,10 @@ main (int argc, char **argv)
     if(get_v4_tgt || convert_524)
        do_524init(context, ccache, NULL, server_str);
 #endif
     if(get_v4_tgt || convert_524)
        do_524init(context, ccache, NULL, server_str);
 #endif
+#ifndef NO_AFS
     if(do_afslog && k_hasafs())
        krb5_afslog(context, ccache, NULL, NULL);
     if(do_afslog && k_hasafs())
        krb5_afslog(context, ccache, NULL, NULL);
+#endif
     if(argc > 1) {
        struct renew_ctx ctx;
        time_t timeout;
     if(argc > 1) {
        struct renew_ctx ctx;
        time_t timeout;
@@ -889,8 +953,10 @@ main (int argc, char **argv)
 #ifndef HEIMDAL_SMALLER
        _krb5_krb_dest_tkt(context, krb4_cc_name);
 #endif
 #ifndef HEIMDAL_SMALLER
        _krb5_krb_dest_tkt(context, krb4_cc_name);
 #endif
+#ifndef NO_AFS
        if(k_hasafs())
            k_unlog();
        if(k_hasafs())
            k_unlog();
+#endif
     } else {
        krb5_cc_close (context, ccache);
        ret = 0;
     } else {
        krb5_cc_close (context, ccache);
        ret = 0;
index eed9e00af6bf9e05f437b9f73202c59d73c713b0..eafffe9bffc99897aa143c451821f65c2e67b6e3 100644 (file)
@@ -36,9 +36,7 @@
 #ifndef __KUSER_LOCL_H__
 #define __KUSER_LOCL_H__
 
 #ifndef __KUSER_LOCL_H__
 #define __KUSER_LOCL_H__
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-#endif
 
 #include <stdio.h>
 #include <stdlib.h>
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -81,7 +79,9 @@
 #ifdef HAVE_SYS_IOCCOM_H
 #include <sys/ioccom.h>
 #endif
 #ifdef HAVE_SYS_IOCCOM_H
 #include <sys/ioccom.h>
 #endif
+#ifndef NO_AFS
 #include <kafs.h>
 #include <kafs.h>
+#endif
 #include "crypto-headers.h" /* for UI_UTIL_read_pw_string */
 
 #ifdef HAVE_LOCALE_H
 #include "crypto-headers.h" /* for UI_UTIL_read_pw_string */
 
 #ifdef HAVE_LOCALE_H
index 26bda55c1900656ff985742544ced2d9b1eed666..f1a653b1f9ac929a2c9fe11661c10845c6f6b82c 100644 (file)
@@ -22,4 +22,6 @@ error_code BAD_CHARACTER,     "ASN.1 invalid character in string"
 error_code MIN_CONSTRAINT,     "ASN.1 too few elements"
 error_code MAX_CONSTRAINT,     "ASN.1 too many elements"
 error_code EXACT_CONSTRAINT,   "ASN.1 wrong number of elements"
 error_code MIN_CONSTRAINT,     "ASN.1 too few elements"
 error_code MAX_CONSTRAINT,     "ASN.1 too many elements"
 error_code EXACT_CONSTRAINT,   "ASN.1 wrong number of elements"
+error_code INDEF_OVERRUN,      "ASN.1 BER indefinte encoding overrun"
+error_code INDEF_UNDERRUN,     "ASN.1 BER indefinte encoding underun"
 end
 end
index e25f6d919e81367a06c891c6000f994f45d8e4a0..925cc72cb497c33f52d8b923447ef002a68261dc 100644 (file)
@@ -119,24 +119,24 @@ doit(const char *fn)
                                     &sz);
        if (ret)
            errx(1, "der_put_length_and_tag: %d", ret);
                                     &sz);
        if (ret)
            errx(1, "der_put_length_and_tag: %d", ret);
-       
+
        if (fwrite(p + sizeof(p) - sz , sz, 1, fout) != 1)
            err(1, "fwrite length/tag failed");
        offset += sz;
        if (fwrite(p + sizeof(p) - sz , sz, 1, fout) != 1)
            err(1, "fwrite length/tag failed");
        offset += sz;
-       
+
        if (data) {
            size_t datalen;
        if (data) {
            size_t datalen;
-       
+
            datalen = strlen(data) / 2;
            pdata = emalloc(sz);
            datalen = strlen(data) / 2;
            pdata = emalloc(sz);
-       
+
            if (hex_decode(data, pdata, datalen) != datalen)
                errx(1, "failed to decode data");
            if (hex_decode(data, pdata, datalen) != datalen)
                errx(1, "failed to decode data");
-       
+
            if (fwrite(pdata, datalen, 1, fout) != 1)
                err(1, "fwrite data failed");
            offset += datalen;
            if (fwrite(pdata, datalen, 1, fout) != 1)
                err(1, "fwrite data failed");
            offset += datalen;
-       
+
            free(pdata);
        }
     }
            free(pdata);
        }
     }
index 5c2690f9b68a17ba15657c1febe84883e26bb686..a335ee89e348f02115ed9894d8b26325dcf988b2 100644 (file)
@@ -7,7 +7,7 @@ CANTHANDLE DEFINITIONS ::= BEGIN
 -- Code the tag [2] but it should be primitive since KAKA3 is
 -- Workaround: use the INTEGER type directly
 
 -- Code the tag [2] but it should be primitive since KAKA3 is
 -- Workaround: use the INTEGER type directly
 
-Kaka2  ::= SEQUENCE { 
+Kaka2  ::= SEQUENCE {
         kaka2-1 [0] INTEGER
 }
 
         kaka2-1 [0] INTEGER
 }
 
similarity index 95%
rename from source4/heimdal/lib/asn1/CMS.asn1
rename to source4/heimdal/lib/asn1/cms.asn1
index 65a467521d798808a789740ae1123446300e9939..1c13d5f387e6f4bd95ed407b248d7d801fecd821 100644 (file)
@@ -18,8 +18,8 @@ id-pkcs7-digestedData OBJECT IDENTIFIER ::=           { id-pkcs7 5 }
 id-pkcs7-encryptedData OBJECT IDENTIFIER ::=           { id-pkcs7 6 }
 
 CMSVersion ::= INTEGER {
 id-pkcs7-encryptedData OBJECT IDENTIFIER ::=           { id-pkcs7 6 }
 
 CMSVersion ::= INTEGER {
-          CMSVersion_v0(0), 
-          CMSVersion_v1(1), 
+          CMSVersion_v0(0),
+          CMSVersion_v1(1),
           CMSVersion_v2(2),
           CMSVersion_v3(3),
           CMSVersion_v4(4)
           CMSVersion_v2(2),
           CMSVersion_v3(3),
           CMSVersion_v4(4)
@@ -34,7 +34,7 @@ MessageDigest ::= OCTET STRING
 
 ContentInfo ::= SEQUENCE {
        contentType ContentType,
 
 ContentInfo ::= SEQUENCE {
        contentType ContentType,
-       content [0] EXPLICIT heim_any OPTIONAL --  DEFINED BY contentType 
+       content [0] EXPLICIT heim_any OPTIONAL --  DEFINED BY contentType
 }
 
 EncapsulatedContentInfo ::= SEQUENCE {
 }
 
 EncapsulatedContentInfo ::= SEQUENCE {
@@ -53,7 +53,7 @@ IssuerAndSerialNumber ::= SEQUENCE {
        serialNumber CertificateSerialNumber
 }
 
        serialNumber CertificateSerialNumber
 }
 
--- RecipientIdentifier is same as SignerIdentifier, 
+-- RecipientIdentifier is same as SignerIdentifier,
 -- lets glue them togheter and save some bytes and share code for them
 
 CMSIdentifier ::= CHOICE {
 -- lets glue them togheter and save some bytes and share code for them
 
 CMSIdentifier ::= CHOICE {
@@ -67,7 +67,7 @@ RecipientIdentifier ::= CMSIdentifier
 --- CMSAttributes are the combined UnsignedAttributes and SignedAttributes
 --- to store space and share code
 
 --- CMSAttributes are the combined UnsignedAttributes and SignedAttributes
 --- to store space and share code
 
-CMSAttributes ::= SET OF Attribute             -- SIZE (1..MAX) 
+CMSAttributes ::= SET OF Attribute             -- SIZE (1..MAX)
 
 SignatureValue ::= OCTET STRING
 
 
 SignatureValue ::= OCTET STRING
 
@@ -79,7 +79,7 @@ SignerInfo ::= SEQUENCE {
                SET OF Attribute OPTIONAL,
        signatureAlgorithm SignatureAlgorithmIdentifier,
        signature SignatureValue,
                SET OF Attribute OPTIONAL,
        signatureAlgorithm SignatureAlgorithmIdentifier,
        signature SignatureValue,
-       unsignedAttrs [1] IMPLICIT -- CMSAttributes -- 
+       unsignedAttrs [1] IMPLICIT -- CMSAttributes --
                SET OF Attribute OPTIONAL
 }
 
                SET OF Attribute OPTIONAL
 }
 
diff --git a/source4/heimdal/lib/asn1/cms.opt b/source4/heimdal/lib/asn1/cms.opt
new file mode 100644 (file)
index 0000000..bf7d396
--- /dev/null
@@ -0,0 +1 @@
+--decode-dce-ber
index 3b6f30887c32d4b42aaf9f89b962cf13d1cd99ce..5b24b917d8aa5f9eed8cd81b88fdf32e7176367a 100644 (file)
@@ -52,7 +52,7 @@ typedef enum {PRIM = 0, CONS = 1} Der_type;
 enum {
     UT_EndOfContent    = 0,
     UT_Boolean         = 1,
 enum {
     UT_EndOfContent    = 0,
     UT_Boolean         = 1,
-    UT_Integer         = 2,    
+    UT_Integer         = 2,
     UT_BitString       = 3,
     UT_OctetString     = 4,
     UT_Null            = 5,
     UT_BitString       = 3,
     UT_OctetString     = 4,
     UT_Null            = 5,
index 8a709664133d3ab28990045a596afe6624a99cd8..8144639b9a940fb41f853eaa16e7f8a4a1c9f7ea 100644 (file)
 
 #include "der_locl.h"
 
 
 #include "der_locl.h"
 
-RCSID("$Id$");
-
-#include <version.h>
-
 /*
  * All decoding functions take a pointer `p' to first position in
  * which to read, from the left, `len' which means the maximum number
 /*
  * All decoding functions take a pointer `p' to first position in
  * which to read, from the left, `len' which means the maximum number
@@ -251,6 +247,75 @@ der_get_octet_string (const unsigned char *p, size_t len,
     return 0;
 }
 
     return 0;
 }
 
+int
+der_get_octet_string_ber (const unsigned char *p, size_t len,
+                         heim_octet_string *data, size_t *size)
+{
+    int e;
+    Der_type type;
+    Der_class class;
+    unsigned int tag, depth = 0;
+    size_t l, datalen, oldlen = len;
+
+    data->length = 0;
+    data->data = NULL;
+
+    while (len) {
+       e = der_get_tag (p, len, &class, &type, &tag, &l);
+       if (e) goto out;
+       if (class != ASN1_C_UNIV) {
+           e = ASN1_BAD_ID;
+           goto out;
+       }
+       if (type == PRIM && tag == UT_EndOfContent) {
+           if (depth == 0)
+               break;
+           depth--;
+       }
+       if (tag != UT_OctetString) {
+           e = ASN1_BAD_ID;
+           goto out;
+       }
+
+       p += l;
+       len -= l;
+       e = der_get_length (p, len, &datalen, &l);
+       if (e) goto out;
+       p += l;
+       len -= l;
+
+       if (datalen > len)
+           return ASN1_OVERRUN;
+
+       if (type == PRIM) {
+           void *ptr;
+
+           ptr = realloc(data->data, data->length + datalen);
+           if (ptr == NULL) {
+               e = ENOMEM;
+               goto out;
+           }
+           data->data = ptr;
+           memcpy(((unsigned char *)data->data) + data->length, p, datalen);
+           data->length += datalen;
+       } else
+           depth++;
+
+       p += datalen;
+       len -= datalen;
+    }
+    if (depth != 0)
+       return ASN1_INDEF_OVERRUN;
+    if(size) *size = oldlen - len;
+    return 0;
+ out:
+    free(data->data);
+    data->data = NULL;
+    data->length = 0;
+    return e;
+}
+
+
 int
 der_get_heim_integer (const unsigned char *p, size_t len,
                      heim_integer *data, size_t *size)
 int
 der_get_heim_integer (const unsigned char *p, size_t len,
                      heim_integer *data, size_t *size)
@@ -397,7 +462,7 @@ der_get_oid (const unsigned char *p, size_t len,
     ++p;
     for (n = 2; len > 0; ++n) {
        unsigned u = 0, u1;
     ++p;
     for (n = 2; len > 0; ++n) {
        unsigned u = 0, u1;
-       
+
        do {
            --len;
            u1 = u * 128 + (*p++ % 128);
        do {
            --len;
            u1 = u * 128 + (*p++ % 128);
@@ -456,16 +521,29 @@ int
 der_match_tag (const unsigned char *p, size_t len,
               Der_class class, Der_type type,
               unsigned int tag, size_t *size)
 der_match_tag (const unsigned char *p, size_t len,
               Der_class class, Der_type type,
               unsigned int tag, size_t *size)
+{
+    Der_type thistype;
+    int e;
+
+    e = der_match_tag2(p, len, class, &thistype, tag, size);
+    if (e) return e;
+    if (thistype != type) return ASN1_BAD_ID;
+    return 0;
+}
+
+int
+der_match_tag2 (const unsigned char *p, size_t len,
+               Der_class class, Der_type *type,
+               unsigned int tag, size_t *size)
 {
     size_t l;
     Der_class thisclass;
 {
     size_t l;
     Der_class thisclass;
-    Der_type thistype;
     unsigned int thistag;
     int e;
 
     unsigned int thistag;
     int e;
 
-    e = der_get_tag (p, len, &thisclass, &thistype, &thistag, &l);
+    e = der_get_tag (p, len, &thisclass, type, &thistag, &l);
     if (e) return e;
     if (e) return e;
-    if (class != thisclass || type != thistype)
+    if (class != thisclass)
        return ASN1_BAD_ID;
     if(tag > thistag)
        return ASN1_MISPLACED_FIELD;
        return ASN1_BAD_ID;
     if(tag > thistag)
        return ASN1_MISPLACED_FIELD;
@@ -477,26 +555,25 @@ der_match_tag (const unsigned char *p, size_t len,
 
 int
 der_match_tag_and_length (const unsigned char *p, size_t len,
 
 int
 der_match_tag_and_length (const unsigned char *p, size_t len,
-                         Der_class class, Der_type type, unsigned int tag,
+                         Der_class class, Der_type *type, unsigned int tag,
                          size_t *length_ret, size_t *size)
 {
     size_t l, ret = 0;
     int e;
 
                          size_t *length_ret, size_t *size)
 {
     size_t l, ret = 0;
     int e;
 
-    e = der_match_tag (p, len, class, type, tag, &l);
+    e = der_match_tag2 (p, len, class, type, tag, &l);
     if (e) return e;
     p += l;
     len -= l;
     ret += l;
     e = der_get_length (p, len, length_ret, &l);
     if (e) return e;
     if (e) return e;
     p += l;
     len -= l;
     ret += l;
     e = der_get_length (p, len, length_ret, &l);
     if (e) return e;
-    p += l;
-    len -= l;
-    ret += l;
-    if(size) *size = ret;
+    if(size) *size = ret + l;
     return 0;
 }
 
     return 0;
 }
 
+
+
 /*
  * Old versions of DCE was based on a very early beta of the MIT code,
  * which used MAVROS for ASN.1 encoding. MAVROS had the interesting
 /*
  * Old versions of DCE was based on a very early beta of the MIT code,
  * which used MAVROS for ASN.1 encoding. MAVROS had the interesting
@@ -539,8 +616,11 @@ der_get_bit_string (const unsigned char *p, size_t len,
     data->data = malloc(len - 1);
     if (data->data == NULL && (len - 1) != 0)
        return ENOMEM;
     data->data = malloc(len - 1);
     if (data->data == NULL && (len - 1) != 0)
        return ENOMEM;
-    memcpy (data->data, p + 1, len - 1);
-    data->length -= p[0];
+    /* copy data is there is data to copy */
+    if (len - 1 != 0) {
+      memcpy (data->data, p + 1, len - 1);
+      data->length -= p[0];
+    }
     if(size) *size = len;
     return 0;
 }
     if(size) *size = len;
     return 0;
 }
index f8a21de71c1d78ab7493bf230fd46d4fb253111d..1f27e7290304d2f6002c9dff31764f6db5df6cc1 100644 (file)
@@ -36,9 +36,9 @@
 #ifndef __DER_LOCL_H__
 #define __DER_LOCL_H__
 
 #ifndef __DER_LOCL_H__
 #define __DER_LOCL_H__
 
-#ifdef HAVE_CONFIG_H
+
 #include <config.h>
 #include <config.h>
-#endif
+
 #include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
index 5afddb1d05b0fed43cb8ba794bd1da77eeb8c04c..7e71443da5b36184bc56f86da364c4f4b4f21488 100644 (file)
@@ -384,7 +384,7 @@ der_put_tag (unsigned char *p, size_t len, Der_class class, Der_type type,
     } else {
        size_t ret = 0;
        unsigned int continuation = 0;
     } else {
        size_t ret = 0;
        unsigned int continuation = 0;
-       
+
        do {
            if (len < 1)
                return ASN1_OVERFLOW;
        do {
            if (len < 1)
                return ASN1_OVERFLOW;
index 1cf58b46380feef3bd458f1f33a748316e225c82..5ee5bd4a998f8316a67772af36abb5c278b5b87a 100644 (file)
@@ -139,7 +139,7 @@ DigestREP ::= [APPLICATION 129] SEQUENCE {
 -- qop == auth
 -- A2 = Method ":" digest-uri-value
 -- qop == auth-int
 -- qop == auth
 -- A2 = Method ":" digest-uri-value
 -- qop == auth-int
--- A2 = Method ":" digest-uri-value ":" H(entity-body) 
+-- 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))))
 
 -- request-digest  = HEX(KD(HEX(H(A1)),
 --    unq(nonce-value) ":" nc-value ":" unq(cnonce-value) ":" unq(qop-value) ":" HEX(H(A2))))
index 49240605c82a4bc8f6e8a4af7608dc5a88341ef9..b244dbb52a3075aa23f64117411f02b3e054ec68 100644 (file)
@@ -67,15 +67,21 @@ decode_heim_any(const unsigned char *p, size_t len,
        return ASN1_OVERFLOW;
     e = der_get_length(p + l, len - l, &length, &len_len);
     if (e) return e;
        return ASN1_OVERFLOW;
     e = der_get_length(p + l, len - l, &length, &len_len);
     if (e) return e;
-    if (length + len_len + l > len)
-       return ASN1_OVERFLOW;
-
+    if (length == ASN1_INDEFINITE) {
+        if (len < len_len + l)
+           return ASN1_OVERFLOW;
+       length = len - (len_len + l);
+    } else {
+       if (len < length + len_len + l)
+           return ASN1_OVERFLOW;
+    }
+   
     data->data = malloc(length + len_len + l);
     if (data->data == NULL)
        return ENOMEM;
     data->length = length + len_len + l;
     memcpy(data->data, p, length + len_len + l);
     data->data = malloc(length + len_len + l);
     if (data->data == NULL)
        return ENOMEM;
     data->length = length + len_len + l;
     memcpy(data->data, p, length + len_len + l);
-
+   
     if (size)
        *size = length + len_len + l;
 
     if (size)
        *size = length + len_len + l;
 
index 52fd0d393b7832cc609397d53adc3de9870b7835..e156c7cefb4809fa1facd6c01b6f2f4fe9ea90c9 100644 (file)
@@ -83,12 +83,19 @@ init_generate (const char *filename, const char *base)
        if (headerbase == NULL)
            errx(1, "strdup");
     }
        if (headerbase == NULL)
            errx(1, "strdup");
     }
+
+    /* public header file */
     asprintf(&header, "%s.h", headerbase);
     if (header == NULL)
        errx(1, "malloc");
     asprintf(&header, "%s.h", headerbase);
     if (header == NULL)
        errx(1, "malloc");
-    headerfile = fopen (header, "w");
+    asprintf(&fn, "%s.hx", headerbase);
+    if (fn == NULL)
+       errx(1, "malloc");
+    headerfile = fopen (fn, "w");
     if (headerfile == NULL)
     if (headerfile == NULL)
-       err (1, "open %s", header);
+       err (1, "open %s", fn);
+    free(fn);
+
     fprintf (headerfile,
             "/* Generated from %s */\n"
             "/* Do not edit */\n\n",
     fprintf (headerfile,
             "/* Generated from %s */\n"
             "/* Do not edit */\n\n",
@@ -229,7 +236,7 @@ gen_compare_defval(const char *var, struct value *val)
     }
 }
 
     }
 }
 
-static void
+void
 generate_header_of_codefile(const char *name)
 {
     char *filename;
 generate_header_of_codefile(const char *name)
 {
     char *filename;
@@ -267,7 +274,7 @@ generate_header_of_codefile(const char *name)
 
 }
 
 
 }
 
-static void
+void
 close_codefile(void)
 {
     if (codefile == NULL)
 close_codefile(void)
 {
     if (codefile == NULL)
@@ -296,7 +303,8 @@ generate_constant (const Symbol *s)
        struct objid *o, **list;
        unsigned int i, len;
 
        struct objid *o, **list;
        unsigned int i, len;
 
-       generate_header_of_codefile(s->gen_name);
+       if (!one_code_file)
+           generate_header_of_codefile(s->gen_name);
 
        len = 0;
        for (o = s->value->u.objectidentifiervalue; o != NULL; o = o->next)
 
        len = 0;
        for (o = s->value->u.objectidentifiervalue; o != NULL; o = o->next)
@@ -320,9 +328,13 @@ generate_constant (const Symbol *s)
        }
 
        fprintf (headerfile, "} */\n");
        }
 
        fprintf (headerfile, "} */\n");
-       fprintf (headerfile, "const heim_oid *oid_%s(void);\n\n",
+       fprintf (headerfile, "const heim_oid *oid_%s(void);\n",
+                s->gen_name);
+       fprintf (headerfile,
+                "extern const heim_oid asn1_oid_%s;\n\n",
                 s->gen_name);
 
                 s->gen_name);
 
+
        fprintf (codefile, "static unsigned oid_%s_variable_num[%d] =  {",
                 s->gen_name, len);
        for (i = len ; i > 0; i--) {
        fprintf (codefile, "static unsigned oid_%s_variable_num[%d] =  {",
                 s->gen_name, len);
        for (i = len ; i > 0; i--) {
@@ -330,17 +342,20 @@ generate_constant (const Symbol *s)
        }
        fprintf(codefile, "};\n");
 
        }
        fprintf(codefile, "};\n");
 
-       fprintf (codefile, "static const heim_oid oid_%s_variable = "
+       fprintf (codefile, "const heim_oid asn1_oid_%s = "
                 "{ %d, oid_%s_variable_num };\n\n",
                 s->gen_name, len, s->gen_name);
 
        fprintf (codefile, "const heim_oid *oid_%s(void)\n"
                 "{\n"
                 "{ %d, oid_%s_variable_num };\n\n",
                 s->gen_name, len, s->gen_name);
 
        fprintf (codefile, "const heim_oid *oid_%s(void)\n"
                 "{\n"
-                "return &oid_%s_variable;\n"
+                "return &asn1_oid_%s;\n"
                 "}\n\n",
                 s->gen_name, s->gen_name);
 
                 "}\n\n",
                 s->gen_name, s->gen_name);
 
-       close_codefile();
+       free(list);
+
+       if (!one_code_file)
+           close_codefile();
 
        break;
     }
 
        break;
     }
@@ -587,7 +602,7 @@ define_type (int level, const char *name, Type *t, int typedefp, int preservep)
            fprintf (headerfile, "struct %s {\n", typedefp ? name : "");
            ASN1_TAILQ_FOREACH(m, t->members, members) {
                char *n;
            fprintf (headerfile, "struct %s {\n", typedefp ? name : "");
            ASN1_TAILQ_FOREACH(m, t->members, members) {
                char *n;
-               
+       
                asprintf (&n, "%s:1", m->gen_name);
                if (n == NULL)
                    errx(1, "malloc");
                asprintf (&n, "%s:1", m->gen_name);
                if (n == NULL)
                    errx(1, "malloc");
@@ -787,7 +802,8 @@ generate_type_header (const Symbol *s)
 void
 generate_type (const Symbol *s)
 {
 void
 generate_type (const Symbol *s)
 {
-    generate_header_of_codefile(s->gen_name);
+    if (!one_code_file)
+       generate_header_of_codefile(s->gen_name);
 
     generate_type_header (s);
     generate_type_encode (s);
 
     generate_type_header (s);
     generate_type_encode (s);
@@ -798,5 +814,9 @@ generate_type (const Symbol *s)
     generate_type_seq (s);
     generate_glue (s->type, s->gen_name);
     fprintf(headerfile, "\n\n");
     generate_type_seq (s);
     generate_glue (s->type, s->gen_name);
     fprintf(headerfile, "\n\n");
-    close_codefile();
+
+    if (!one_code_file) {
+       fprintf(codefile, "\n\n");
+       close_codefile();
+       }
 }
 }
index 37c9304779be658ce75aac195d9497f4a3c54b7e..5042ed64ed27bd17ccf3e6a443f8c238a847666b 100644 (file)
@@ -149,7 +149,7 @@ copy_type (const char *from, const char *to, const Type *t, int preserve)
                        to, have_ellipsis->gen_name);
                used_fail++;
            }
                        to, have_ellipsis->gen_name);
                used_fail++;
            }
-           fprintf(codefile, "}\n");   
+           fprintf(codefile, "}\n");
        }
        break;
     }
        }
        break;
     }
index 2bd5acb47e82d727b3d5084d4454c2b06cb9840f..cf7f0b05dc06f47fe781563d99a0a85dc584e5ce 100644 (file)
@@ -230,7 +230,7 @@ range_check(const char *name,
 
 static int
 decode_type (const char *name, const Type *t, int optional,
 
 static int
 decode_type (const char *name, const Type *t, int optional,
-            const char *forwstr, const char *tmpstr)
+            const char *forwstr, const char *tmpstr, const char *dertype)
 {
     switch (t->type) {
     case TType: {
 {
     switch (t->type) {
     case TType: {
@@ -289,7 +289,17 @@ decode_type (const char *name, const Type *t, int optional,
        decode_primitive ("enumerated", name, forwstr);
        break;
     case TOctetString:
        decode_primitive ("enumerated", name, forwstr);
        break;
     case TOctetString:
+       if (dertype) {
+           fprintf(codefile,
+                   "if (%s == CONS) {\n",
+                   dertype);
+           decode_primitive("octet_string_ber", name, forwstr);
+           fprintf(codefile,
+                   "} else {\n");
+       }
        decode_primitive ("octet_string", name, forwstr);
        decode_primitive ("octet_string", name, forwstr);
+       if (dertype)
+           fprintf(codefile, "}\n");
        if (t->range)
            range_check(name, "length", forwstr, t->range);
        break;
        if (t->range)
            range_check(name, "length", forwstr, t->range);
        break;
@@ -340,10 +350,10 @@ decode_type (const char *name, const Type *t, int optional,
                      name, m->gen_name);
            if (s == NULL)
                errx(1, "malloc");
                      name, m->gen_name);
            if (s == NULL)
                errx(1, "malloc");
-           decode_type (s, m->type, m->optional, forwstr, m->gen_name);
+           decode_type (s, m->type, m->optional, forwstr, m->gen_name, NULL);
            free (s);
        }
            free (s);
        }
-       
+
        break;
     }
     case TSet: {
        break;
     }
     case TSet: {
@@ -382,7 +392,7 @@ decode_type (const char *name, const Type *t, int optional,
                        "%s = calloc(1, sizeof(*%s));\n"
                        "if (%s == NULL) { e = ENOMEM; %s; }\n",
                        s, s, s, forwstr);
                        "%s = calloc(1, sizeof(*%s));\n"
                        "if (%s == NULL) { e = ENOMEM; %s; }\n",
                        s, s, s, forwstr);
-           decode_type (s, m->type, 0, forwstr, m->gen_name);
+           decode_type (s, m->type, 0, forwstr, m->gen_name, NULL);
            free (s);
 
            fprintf(codefile, "members |= (1 << %d);\n", memno);
            free (s);
 
            fprintf(codefile, "members |= (1 << %d);\n", memno);
@@ -458,7 +468,7 @@ decode_type (const char *name, const Type *t, int optional,
        asprintf (&sname, "%s_s_of", tmpstr);
        if (sname == NULL)
            errx(1, "malloc");
        asprintf (&sname, "%s_s_of", tmpstr);
        if (sname == NULL)
            errx(1, "malloc");
-       decode_type (n, t->subtype, 0, forwstr, sname);
+       decode_type (n, t->subtype, 0, forwstr, sname, NULL);
        fprintf (codefile,
                 "(%s)->len++;\n"
                 "len = %s_origlen - ret;\n"
        fprintf (codefile,
                 "(%s)->len++;\n"
                 "len = %s_origlen - ret;\n"
@@ -480,21 +490,37 @@ decode_type (const char *name, const Type *t, int optional,
        decode_primitive ("general_string", name, forwstr);
        break;
     case TTag:{
        decode_primitive ("general_string", name, forwstr);
        break;
     case TTag:{
-       char *tname;
+       char *tname, *typestring;
+       char *ide = NULL;
+
+       asprintf(&typestring, "%s_type", tmpstr);
 
        fprintf(codefile,
                "{\n"
 
        fprintf(codefile,
                "{\n"
-               "size_t %s_datalen, %s_oldlen;\n",
-               tmpstr, tmpstr);
-       if(dce_fix)
+               "size_t %s_datalen, %s_oldlen;\n"
+               "Der_type %s;\n",
+               tmpstr, tmpstr, typestring);
+       if(support_ber)
            fprintf(codefile,
            fprintf(codefile,
-                   "int dce_fix;\n");
-       fprintf(codefile, "e = der_match_tag_and_length(p, len, %s, %s, %s, "
+                   "int is_indefinite;\n");
+
+       fprintf(codefile, "e = der_match_tag_and_length(p, len, %s, &%s, %s, "
                "&%s_datalen, &l);\n",
                classname(t->tag.tagclass),
                "&%s_datalen, &l);\n",
                classname(t->tag.tagclass),
-               is_primitive_type(t->subtype->type) ? "PRIM" : "CONS",
+               typestring,
                valuename(t->tag.tagclass, t->tag.tagvalue),
                tmpstr);
                valuename(t->tag.tagclass, t->tag.tagvalue),
                tmpstr);
+
+       /* XXX hardcode for now */
+       if (support_ber && t->subtype->type == TOctetString) {
+           ide = typestring;
+       } else {
+           fprintf(codefile,
+                   "if (e == 0 && %s != %s) { e = ASN1_BAD_ID; }\n",
+                   typestring,
+                   is_primitive_type(t->subtype->type) ? "PRIM" : "CONS");
+       }
+
        if(optional) {
            fprintf(codefile,
                    "if(e) {\n"
        if(optional) {
            fprintf(codefile,
                    "if(e) {\n"
@@ -510,11 +536,12 @@ decode_type (const char *name, const Type *t, int optional,
                 "p += l; len -= l; ret += l;\n"
                 "%s_oldlen = len;\n",
                 tmpstr);
                 "p += l; len -= l; ret += l;\n"
                 "%s_oldlen = len;\n",
                 tmpstr);
-       if(dce_fix)
+       if(support_ber)
            fprintf (codefile,
            fprintf (codefile,
-                    "if((dce_fix = _heim_fix_dce(%s_datalen, &len)) < 0)\n"
-                    "{ e = ASN1_BAD_FORMAT; %s; }\n",
-                    tmpstr, forwstr);
+                    "if((is_indefinite = _heim_fix_dce(%s_datalen, &len)) < 0)\n"
+                    "{ e = ASN1_BAD_FORMAT; %s; }\n"
+                    "if (is_indefinite) { if (len < 2) { e = ASN1_OVERRUN; %s; } len -= 2; }",
+                    tmpstr, forwstr, forwstr);
        else
            fprintf(codefile,
                    "if (%s_datalen > len) { e = ASN1_OVERRUN; %s; }\n"
        else
            fprintf(codefile,
                    "if (%s_datalen > len) { e = ASN1_OVERRUN; %s; }\n"
@@ -522,15 +549,22 @@ decode_type (const char *name, const Type *t, int optional,
        asprintf (&tname, "%s_Tag", tmpstr);
        if (tname == NULL)
            errx(1, "malloc");
        asprintf (&tname, "%s_Tag", tmpstr);
        if (tname == NULL)
            errx(1, "malloc");
-       decode_type (name, t->subtype, 0, forwstr, tname);
-       if(dce_fix)
+       decode_type (name, t->subtype, 0, forwstr, tname, ide);
+       if(support_ber)
            fprintf(codefile,
            fprintf(codefile,
-                   "if(dce_fix){\n"
-                   "e = der_match_tag_and_length (p, len, "
-                   "(Der_class)0,(Der_type)0, UT_EndOfContent, "
+                   "if(is_indefinite){\n"
+                   "len += 2;\n"
+                   "e = der_match_tag_and_length(p, len, "
+                   "(Der_class)0, &%s, UT_EndOfContent, "
                    "&%s_datalen, &l);\n"
                    "&%s_datalen, &l);\n"
-                   "if(e) %s;\np += l; len -= l; ret += l;\n"
-                   "} else \n", tmpstr, forwstr);
+                   "if(e) %s;\n"
+                   "p += l; len -= l; ret += l;\n"
+                   "if (%s != (Der_type)0) { e = ASN1_BAD_ID; %s; }\n"
+                   "} else \n",
+                   typestring,
+                   tmpstr,
+                   forwstr,
+                   typestring, forwstr);
        fprintf(codefile,
                "len = %s_oldlen - %s_datalen;\n",
                tmpstr, tmpstr);
        fprintf(codefile,
                "len = %s_oldlen - %s_datalen;\n",
                tmpstr, tmpstr);
@@ -540,6 +574,7 @@ decode_type (const char *name, const Type *t, int optional,
        fprintf(codefile,
                "}\n");
        free(tname);
        fprintf(codefile,
                "}\n");
        free(tname);
+       free(typestring);
        break;
     }
     case TChoice: {
        break;
     }
     case TChoice: {
@@ -555,7 +590,7 @@ decode_type (const char *name, const Type *t, int optional,
            Der_class cl;
            Der_type  ty;
            unsigned  tag;
            Der_class cl;
            Der_type  ty;
            unsigned  tag;
-       
+
            if (m->ellipsis) {
                have_ellipsis = m;
                continue;
            if (m->ellipsis) {
                have_ellipsis = m;
                continue;
@@ -573,7 +608,7 @@ decode_type (const char *name, const Type *t, int optional,
                      name, m->gen_name);
            if (s == NULL)
                errx(1, "malloc");
                      name, m->gen_name);
            if (s == NULL)
                errx(1, "malloc");
-           decode_type (s, m->type, m->optional, forwstr, m->gen_name);
+           decode_type (s, m->type, m->optional, forwstr, m->gen_name, NULL);
            fprintf(codefile,
                    "(%s)->element = %s;\n",
                    name, m->label);
            fprintf(codefile,
                    "(%s)->element = %s;\n",
                    name, m->label);
@@ -695,7 +730,7 @@ generate_type_decode (const Symbol *s)
        fprintf (codefile, "\n");
        fprintf (codefile, "memset(data, 0, sizeof(*data));\n"); /* hack to avoid `unused variable' */
 
        fprintf (codefile, "\n");
        fprintf (codefile, "memset(data, 0, sizeof(*data));\n"); /* hack to avoid `unused variable' */
 
-       decode_type ("data", s->type, 0, "goto fail", "Top");
+       decode_type ("data", s->type, 0, "goto fail", "Top", NULL);
        if (preserve)
            fprintf (codefile,
                     "data->_save.data = calloc(1, ret);\n"
        if (preserve)
            fprintf (codefile,
                     "data->_save.data = calloc(1, ret);\n"
index d80a2f8d1fff521f1006e354e33c2ff847ea5558..1f8078a0ee4261a0f6eda2efb53ecb8b43c3c052 100644 (file)
@@ -257,7 +257,7 @@ encode_type (const char *name, const Type *t, const char *tmpstr)
 
        if (t->members == NULL)
            break;
 
        if (t->members == NULL)
            break;
-       
+
        ASN1_TAILQ_FOREACH_REVERSE(m, t->members, memhead, members) {
            char *s;
 
        ASN1_TAILQ_FOREACH_REVERSE(m, t->members, memhead, members) {
            char *s;
 
@@ -388,7 +388,7 @@ encode_type (const char *name, const Type *t, const char *tmpstr)
        int c;
        asprintf (&tname, "%s_tag", tmpstr);
        if (tname == NULL)
        int c;
        asprintf (&tname, "%s_tag", tmpstr);
        if (tname == NULL)
-           errx(1, "malloc");  
+           errx(1, "malloc");
        c = encode_type (name, t->subtype, tname);
        fprintf (codefile,
                 "e = der_put_length_and_tag (p, len, ret, %s, %s, %s, &l);\n"
        c = encode_type (name, t->subtype, tname);
        fprintf (codefile,
                 "e = der_put_length_and_tag (p, len, ret, %s, %s, %s, &l);\n"
index 305d7de247c89d9b541dea927c29937fb0500125..fac1f6da5d5df3deff955a3f0a70594734fb5e0f 100644 (file)
@@ -110,7 +110,7 @@ free_type (const char *name, const Type *t, int preserve)
            if(t->type == TChoice)
                fprintf(codefile, "break;\n");
        }
            if(t->type == TChoice)
                fprintf(codefile, "break;\n");
        }
-       
+
        if(t->type == TChoice) {
            if (have_ellipsis)
                fprintf(codefile,
        if(t->type == TChoice) {
            if (have_ellipsis)
                fprintf(codefile,
index a1df4eef6bf9413e1fd27951c8c26fd97077dfb1..7f9755e2da3ed88816bfb745b3272a99feb411e5 100644 (file)
@@ -139,7 +139,7 @@ length_type (const char *name, const Type *t,
 
        ASN1_TAILQ_FOREACH(m, t->members, members) {
            char *s;
 
        ASN1_TAILQ_FOREACH(m, t->members, members) {
            char *s;
-       
+
            if (m->ellipsis) {
                have_ellipsis = m;
                continue;
            if (m->ellipsis) {
                have_ellipsis = m;
                continue;
index c8b38963141ac36d2b5f3c1649391d15aff75767..2bb64b5a38590c5cbc6f3241de3cbd6636a00c70 100644 (file)
@@ -36,9 +36,8 @@
 #ifndef __GEN_LOCL_H__
 #define __GEN_LOCL_H__
 
 #ifndef __GEN_LOCL_H__
 #define __GEN_LOCL_H__
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-#endif
+
 #include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -80,9 +79,14 @@ int yyparse(void);
 int preserve_type(const char *);
 int seq_type(const char *);
 
 int preserve_type(const char *);
 int seq_type(const char *);
 
+void generate_header_of_codefile(const char *);
+void close_codefile(void);
+
+
 extern FILE *headerfile, *codefile, *logfile;
 extern FILE *headerfile, *codefile, *logfile;
-extern int dce_fix;
+extern int support_ber;
 extern int rfc1510_bitstring;
 extern int rfc1510_bitstring;
+extern int one_code_file;
 
 extern int error_flag;
 
 
 extern int error_flag;
 
similarity index 86%
rename from source4/heimdal/lib/asn1/k5.asn1
rename to source4/heimdal/lib/asn1/krb5.asn1
index 9b36498161facf73dbea742d73dc8879aad5761f..8edb0fde69753c0bfb55f328798ae2677651312c 100644 (file)
@@ -13,6 +13,7 @@ NAME-TYPE ::= INTEGER {
        KRB5_NT_X500_PRINCIPAL(6), -- PKINIT
        KRB5_NT_SMTP_NAME(7),   -- Name in form of SMTP email name
        KRB5_NT_ENTERPRISE_PRINCIPAL(10), -- Windows 2000 UPN
        KRB5_NT_X500_PRINCIPAL(6), -- PKINIT
        KRB5_NT_SMTP_NAME(7),   -- Name in form of SMTP email name
        KRB5_NT_ENTERPRISE_PRINCIPAL(10), -- Windows 2000 UPN
+       KRB5_NT_WELLKNOWN(11),  -- Wellknown
        KRB5_NT_ENT_PRINCIPAL_AND_ID(-130), -- Windows 2000 UPN and SID
        KRB5_NT_MS_PRINCIPAL(-128), -- NT 4 style name
        KRB5_NT_MS_PRINCIPAL_AND_ID(-129) -- NT style name and SID
        KRB5_NT_ENT_PRINCIPAL_AND_ID(-130), -- Windows 2000 UPN and SID
        KRB5_NT_MS_PRINCIPAL(-128), -- NT 4 style name
        KRB5_NT_MS_PRINCIPAL_AND_ID(-129) -- NT style name and SID
@@ -64,6 +65,10 @@ PADATA-TYPE ::= INTEGER {
        KRB5-PADATA-GET-FROM-TYPED-DATA(22),
        KRB5-PADATA-SAM-ETYPE-INFO(23),
        KRB5-PADATA-SERVER-REFERRAL(25),
        KRB5-PADATA-GET-FROM-TYPED-DATA(22),
        KRB5-PADATA-SAM-ETYPE-INFO(23),
        KRB5-PADATA-SERVER-REFERRAL(25),
+       KRB5-PADATA-ALT-PRINC(24),              -- (crawdad@fnal.gov)
+       KRB5-PADATA-SAM-CHALLENGE2(30),         -- (kenh@pobox.com)
+       KRB5-PADATA-SAM-RESPONSE2(31),          -- (kenh@pobox.com)
+       KRB5-PA-EXTRA-TGT(41),                  -- Reserved extra TGT
        KRB5-PADATA-TD-KRB-PRINCIPAL(102),      -- PrincipalName
        KRB5-PADATA-PK-TD-TRUSTED-CERTIFIERS(104), -- PKINIT
        KRB5-PADATA-PK-TD-CERTIFICATE-INDEX(105), -- PKINIT
        KRB5-PADATA-TD-KRB-PRINCIPAL(102),      -- PrincipalName
        KRB5-PADATA-PK-TD-TRUSTED-CERTIFIERS(104), -- PKINIT
        KRB5-PADATA-PK-TD-CERTIFICATE-INDEX(105), -- PKINIT
@@ -71,13 +76,30 @@ 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-TD-REQ-NONCE(107),          -- INTEGER
        KRB5-PADATA-TD-REQ-SEQ(108),            -- INTEGER
        KRB5-PADATA-PA-PAC-REQUEST(128),        -- jbrezak@exchange.microsoft.com
-       KRB5-PADATA-S4U2SELF(129),
-       KRB5-PADATA-EPAC(130),                  -- EPAK
-       KRB5-PADATA-PK-AS-09-BINDING(132),      -- client send this to 
-                                               -- tell KDC that is supports 
+       KRB5-PADATA-FOR-USER(129),              -- MS-KILE
+       KRB5-PADATA-FOR-X509-USER(130),         -- MS-KILE
+       KRB5-PADATA-FOR-CHECK-DUPS(131),        -- MS-KILE
+       KRB5-PADATA-AS-CHECKSUM(132),           -- MS-KILE
+       KRB5-PADATA-PK-AS-09-BINDING(132),      -- client send this to
+                                               -- tell KDC that is supports
                                                -- the asCheckSum in the
                                                --  PK-AS-REP
                                                -- the asCheckSum in the
                                                --  PK-AS-REP
-       KRB5-PADATA-CLIENT-CANONICALIZED(133)   -- 
+       KRB5-PADATA-CLIENT-CANONICALIZED(133),  -- referals
+       KRB5-PADATA-FX-COOKIE(133),             -- krb-wg-preauth-framework
+       KRB5-PADATA-AUTHENTICATION-SET(134),    -- krb-wg-preauth-framework
+       KRB5-PADATA-AUTH-SET-SELECTED(135),     -- krb-wg-preauth-framework
+       KRB5-PADATA-FX-FAST(136),               -- krb-wg-preauth-framework
+       KRB5-PADATA-FX-ERROR(137),              -- krb-wg-preauth-framework
+       KRB5-PADATA-ENCRYPTED-CHALLENGE(138),   -- krb-wg-preauth-framework
+       KRB5-PADATA-OTP-CHALLENGE(141),         -- (gareth.richards@rsa.com)
+       KRB5-PADATA-OTP-REQUEST(142),           -- (gareth.richards@rsa.com)
+       KBB5-PADATA-OTP-CONFIRM(143),           -- (gareth.richards@rsa.com)
+       KRB5-PADATA-OTP-PIN-CHANGE(144),        -- (gareth.richards@rsa.com)
+       KRB5-PADATA-EPAK-AS-REQ(145),
+       KRB5-PADATA-EPAK-AS-REP(146),
+       KRB5-PADATA-PKINIT-KX(147),             -- krb-wg-anon
+       KRB5-PADATA-PKU2U-NAME(148),            -- zhu-pku2u
+       KRB5-PADATA-SUPPORTED-ETYPES(165)       -- MS-KILE
 }
 
 AUTHDATA-TYPE ::= INTEGER {
 }
 
 AUTHDATA-TYPE ::= INTEGER {
@@ -174,6 +196,8 @@ Principal ::= SEQUENCE {
        realm[1]                Realm
 }
 
        realm[1]                Realm
 }
 
+Principals ::= SEQUENCE OF Principal
+
 HostAddress ::= SEQUENCE  {
        addr-type[0]            krb5int32,
        address[1]              OCTET STRING
 HostAddress ::= SEQUENCE  {
        addr-type[0]            krb5int32,
        address[1]              OCTET STRING
@@ -387,7 +411,7 @@ PA-ENC-TS-ENC ::= SEQUENCE {
 
 -- draft-brezak-win2k-krb-authz-01
 PA-PAC-REQUEST ::= SEQUENCE {
 
 -- draft-brezak-win2k-krb-authz-01
 PA-PAC-REQUEST ::= SEQUENCE {
-       include-pac[0]          BOOLEAN -- Indicates whether a PAC 
+       include-pac[0]          BOOLEAN -- Indicates whether a PAC
                                        -- should be included or not
 }
 
                                        -- should be included or not
 }
 
@@ -618,21 +642,19 @@ PA-S4U2Self ::= SEQUENCE {
         auth[3]                GeneralString
 }
 
         auth[3]                GeneralString
 }
 
-KRB5SignedPathPrincipals ::= SEQUENCE OF Principal
-
 -- never encoded on the wire, just used to checksum over
 KRB5SignedPathData ::= SEQUENCE {
        encticket[0]    EncTicketPart,
 -- never encoded on the wire, just used to checksum over
 KRB5SignedPathData ::= SEQUENCE {
        encticket[0]    EncTicketPart,
-       delegated[1]    KRB5SignedPathPrincipals OPTIONAL
+       delegated[1]    Principals OPTIONAL
 }
 
 KRB5SignedPath ::= SEQUENCE {
        -- DERcoded KRB5SignedPathData
 }
 
 KRB5SignedPath ::= SEQUENCE {
        -- DERcoded KRB5SignedPathData
-       -- krbtgt key (etype), KeyUsage = XXX 
+       -- krbtgt key (etype), KeyUsage = XXX
        etype[0]        ENCTYPE,
        cksum[1]        Checksum,
        -- srvs delegated though
        etype[0]        ENCTYPE,
        cksum[1]        Checksum,
        -- srvs delegated though
-       delegated[2]    KRB5SignedPathPrincipals OPTIONAL
+       delegated[2]    Principals OPTIONAL
 }
 
 PA-ClientCanonicalizedNames ::= SEQUENCE{
 }
 
 PA-ClientCanonicalizedNames ::= SEQUENCE{
@@ -666,6 +688,63 @@ PA-ServerReferralData ::= SEQUENCE {
        ...
 }
 
        ...
 }
 
+FastOptions ::= BIT STRING {
+           reserved(0),
+           hide-client-names(1),
+           kdc-follow--referrals(16)
+}
+
+KrbFastReq ::= SEQUENCE {
+       fast-options [0] FastOptions,
+       padata       [1] SEQUENCE OF PA-DATA,
+       req-body     [2] KDC-REQ-BODY,
+       ...
+}
+
+KrbFastArmor ::= SEQUENCE {
+       armor-type   [0] krb5int32,
+       armor-value  [1] OCTET STRING,
+        ...
+}
+
+KrbFastArmoredReq ::= SEQUENCE {
+       armor        [0] KrbFastArmor OPTIONAL,
+       req-checksum [1] Checksum,
+       enc-fast-req [2] EncryptedData -- KrbFastReq --
+}
+
+PA-FX-FAST-REQUEST ::= CHOICE {
+       armored-data [0] KrbFastArmoredReq,
+       ...
+}
+
+KrbFastFinished ::= SEQUENCE {
+       timestamp   [0] KerberosTime,
+       usec        [1] krb5int32,
+       crealm      [2] Realm,
+       cname       [3] PrincipalName,
+       checksum    [4] Checksum,
+       ticket-checksum [5] Checksum,
+       ...
+}
+
+KrbFastResponse ::= SEQUENCE {
+       padata      [0] SEQUENCE OF PA-DATA,
+       rep-key     [1] EncryptionKey OPTIONAL,
+       finished    [2] KrbFastFinished OPTIONAL,
+       ...
+}
+
+KrbFastArmoredRep ::= SEQUENCE {
+       enc-fast-rep      [0] EncryptedData, -- KrbFastResponse --
+       ...
+}
+
+PA-FX-FAST-REPLY ::= CHOICE {
+       armored-data [0] KrbFastArmoredRep,
+       ...
+}
+
 END
 
 -- etags -r '/\([A-Za-z][-A-Za-z0-9]*\).*::=/\1/' k5.asn1
 END
 
 -- etags -r '/\([A-Za-z][-A-Za-z0-9]*\).*::=/\1/' k5.asn1
diff --git a/source4/heimdal/lib/asn1/krb5.opt b/source4/heimdal/lib/asn1/krb5.opt
new file mode 100644 (file)
index 0000000..1d6d5e8
--- /dev/null
@@ -0,0 +1,6 @@
+--encode-rfc1510-bit-string
+--sequence=Principals
+--sequence=AuthorizationData
+--sequence=METHOD-DATA
+--sequence=ETYPE-INFO
+--sequence=ETYPE-INFO2
index 820abc810687bf4d2d52b7a677aec540dbba56c0..14ebf50ecdbcbd73e18580d49437207ccb7773af 100644 (file)
@@ -3,6 +3,17 @@
 KX509 DEFINITIONS ::=
 BEGIN
 
 KX509 DEFINITIONS ::=
 BEGIN
 
+KX509-ERROR-CODE ::= INTEGER {
+       KX509-STATUS-GOOD(0),
+       KX509-STATUS-CLIENT-BAD(1),
+       KX509-STATUS-CLIENT-FIX(2),
+       KX509-STATUS-CLIENT-TEMP(3),
+       KX509-STATUS-SERVER-BAD(4),
+       KX509-STATUS-SERVER-TEMP(5),
+        -- 6 is used internally in the umich client, avoid that
+       KX509-STATUS-SERVER-KEY(7)
+}
+
 Kx509Request ::= SEQUENCE {
        authenticator OCTET STRING,
        pk-hash OCTET STRING,
 Kx509Request ::= SEQUENCE {
        authenticator OCTET STRING,
        pk-hash OCTET STRING,
index 1198ef16a689a6c3c54eda54543132001079b8eb..7bd442bc502abcee27b1ac4b969905e019282e1b 100644 (file)
@@ -46,7 +46,7 @@
 #endif
 #undef ECHO
 #include "symbol.h"
 #endif
 #undef ECHO
 #include "symbol.h"
-#include "parse.h"
+#include "asn1parse.h"
 #include "lex.h"
 #include "gen_locl.h"
 
 #include "lex.h"
 #include "gen_locl.h"
 
@@ -216,7 +216,7 @@ WITH                        { return kw_WITH; }
                            char *p = buf;
                            int f = 0;
                            int skip_ws = 0;
                            char *p = buf;
                            int f = 0;
                            int skip_ws = 0;
-                       
+               
                            while((c = input()) != EOF) {
                                if(isspace(c) && skip_ws) {
                                    if(c == '\n')
                            while((c = input()) != EOF) {
                                if(isspace(c) && skip_ws) {
                                    if(c == '\n')
@@ -224,7 +224,7 @@ WITH                        { return kw_WITH; }
                                    continue;
                                }
                                skip_ws = 0;
                                    continue;
                                }
                                skip_ws = 0;
-                               
+                       
                                if(c == '"') {
                                    if(f) {
                                        *p++ = '"';
                                if(c == '"') {
                                    if(f) {
                                        *p++ = '"';
index 6a9763431051ac42273fd8d44bddfa695ca43789..115c82a9c7d1d23cea019bb1979d4954c978dfde 100644 (file)
@@ -62,15 +62,20 @@ seq_type(const char *p)
     return 0;
 }
 
     return 0;
 }
 
-int dce_fix;
+int support_ber;
 int rfc1510_bitstring;
 int rfc1510_bitstring;
+int one_code_file;
+char *option_file;
 int version_flag;
 int help_flag;
 struct getargs args[] = {
     { "encode-rfc1510-bit-string", 0, arg_flag, &rfc1510_bitstring },
 int version_flag;
 int help_flag;
 struct getargs args[] = {
     { "encode-rfc1510-bit-string", 0, arg_flag, &rfc1510_bitstring },
-    { "decode-dce-ber", 0, arg_flag, &dce_fix },
+    { "decode-dce-ber", 0, arg_flag, &support_ber },
+    { "support-ber", 0, arg_flag, &support_ber },
     { "preserve-binary", 0, arg_strings, &preserve },
     { "sequence", 0, arg_strings, &seq },
     { "preserve-binary", 0, arg_strings, &preserve },
     { "sequence", 0, arg_strings, &seq },
+    { "one-code-file", 0, arg_flag, &one_code_file },
+    { "option-file", 0, arg_string, &option_file },
     { "version", 0, arg_flag, &version_flag },
     { "help", 0, arg_flag, &help_flag }
 };
     { "version", 0, arg_flag, &version_flag },
     { "help", 0, arg_flag, &help_flag }
 };
@@ -92,6 +97,8 @@ main(int argc, char **argv)
     const char *file;
     const char *name = NULL;
     int optidx = 0;
     const char *file;
     const char *name = NULL;
     int optidx = 0;
+    char **arg = NULL;
+    size_t len = 0, i;
 
     setprogname(argv[0]);
     if(getarg(args, num_args, argc, argv, &optidx))
 
     setprogname(argv[0]);
     if(getarg(args, num_args, argc, argv, &optidx))
@@ -121,7 +128,58 @@ main(int argc, char **argv)
            name = argv[optidx + 1];
     }
 
            name = argv[optidx + 1];
     }
 
+    /*
+     * Parse extra options file
+     */
+    if (option_file) {
+       char buf[1024];
+       FILE *opt;
+
+       opt = fopen(option_file, "r");
+       if (opt == NULL) {
+           perror("open");
+           exit(1);
+       }
+
+       arg = calloc(2, sizeof(arg[0]));
+       arg[0] = option_file;
+       arg[1] = NULL;
+       len = 1;
+
+       while (fgets(buf, sizeof(buf), opt) != NULL) {
+           buf[strcspn(buf, "\n\r")] = '\0';
+
+           arg = realloc(arg, (len + 2) * sizeof(arg[0]));
+           if (argv == NULL) {
+               perror("malloc");
+               exit(1);
+           }
+           arg[len] = strdup(buf);
+           if (arg[len] == NULL) {
+               perror("strdup");
+               exit(1);
+           }
+           arg[len + 1] = NULL;
+           len++;
+       }
+       fclose(opt);
+
+       optidx = 0;
+       if(getarg(args, num_args, len, arg, &optidx))
+           usage(1);
+
+       if (len != optidx) {
+           fprintf(stderr, "extra args");
+           exit(1);
+       }
+    }
+
+
     init_generate (file, name);
     init_generate (file, name);
+
+    if (one_code_file)
+       generate_header_of_codefile(name);
+
     initsym ();
     ret = yyparse ();
     if(ret != 0 || error_flag != 0)
     initsym ();
     ret = yyparse ();
     if(ret != 0 || error_flag != 0)
@@ -129,5 +187,15 @@ main(int argc, char **argv)
     close_generate ();
     if (argc != optidx)
        fclose(yyin);
     close_generate ();
     if (argc != optidx)
        fclose(yyin);
+
+    if (one_code_file)
+       close_codefile();
+
+    if (arg) {
+       for (i = 1; i < len; i++)
+           free(arg[i]);
+       free(arg);
+    }
+   
     return 0;
 }
     return 0;
 }
diff --git a/source4/heimdal/lib/asn1/parse.y b/source4/heimdal/lib/asn1/parse.y
deleted file mode 100644 (file)
index aca4a06..0000000
+++ /dev/null
@@ -1,1015 +0,0 @@
-/*
- * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden).
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * 3. Neither the name of the Institute nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/* $Id$ */
-
-%{
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "symbol.h"
-#include "lex.h"
-#include "gen_locl.h"
-#include "der.h"
-
-RCSID("$Id$");
-
-static Type *new_type (Typetype t);
-static struct constraint_spec *new_constraint_spec(enum ctype);
-static Type *new_tag(int tagclass, int tagvalue, int tagenv, Type *oldtype);
-void yyerror (const char *);
-static struct objid *new_objid(const char *label, int value);
-static void add_oid_to_tail(struct objid *, struct objid *);
-static void fix_labels(Symbol *s);
-
-struct string_list {
-    char *string;
-    struct string_list *next;
-};
-
-%}
-
-%union {
-    int constant;
-    struct value *value;
-    struct range *range;
-    char *name;
-    Type *type;
-    Member *member;
-    struct objid *objid;
-    char *defval;
-    struct string_list *sl;
-    struct tagtype tag;
-    struct memhead *members;
-    struct constraint_spec *constraint_spec;
-}
-
-%token kw_ABSENT
-%token kw_ABSTRACT_SYNTAX
-%token kw_ALL
-%token kw_APPLICATION
-%token kw_AUTOMATIC
-%token kw_BEGIN
-%token kw_BIT
-%token kw_BMPString
-%token kw_BOOLEAN
-%token kw_BY
-%token kw_CHARACTER
-%token kw_CHOICE
-%token kw_CLASS
-%token kw_COMPONENT
-%token kw_COMPONENTS
-%token kw_CONSTRAINED
-%token kw_CONTAINING
-%token kw_DEFAULT
-%token kw_DEFINITIONS
-%token kw_EMBEDDED
-%token kw_ENCODED
-%token kw_END
-%token kw_ENUMERATED
-%token kw_EXCEPT
-%token kw_EXPLICIT
-%token kw_EXPORTS
-%token kw_EXTENSIBILITY
-%token kw_EXTERNAL
-%token kw_FALSE
-%token kw_FROM
-%token kw_GeneralString
-%token kw_GeneralizedTime
-%token kw_GraphicString
-%token kw_IA5String
-%token kw_IDENTIFIER
-%token kw_IMPLICIT
-%token kw_IMPLIED
-%token kw_IMPORTS
-%token kw_INCLUDES
-%token kw_INSTANCE
-%token kw_INTEGER
-%token kw_INTERSECTION
-%token kw_ISO646String
-%token kw_MAX
-%token kw_MIN
-%token kw_MINUS_INFINITY
-%token kw_NULL
-%token kw_NumericString
-%token kw_OBJECT
-%token kw_OCTET
-%token kw_OF
-%token kw_OPTIONAL
-%token kw_ObjectDescriptor
-%token kw_PATTERN
-%token kw_PDV
-%token kw_PLUS_INFINITY
-%token kw_PRESENT
-%token kw_PRIVATE
-%token kw_PrintableString
-%token kw_REAL
-%token kw_RELATIVE_OID
-%token kw_SEQUENCE
-%token kw_SET
-%token kw_SIZE
-%token kw_STRING
-%token kw_SYNTAX
-%token kw_T61String
-%token kw_TAGS
-%token kw_TRUE
-%token kw_TYPE_IDENTIFIER
-%token kw_TeletexString
-%token kw_UNION
-%token kw_UNIQUE
-%token kw_UNIVERSAL
-%token kw_UTCTime
-%token kw_UTF8String
-%token kw_UniversalString
-%token kw_VideotexString
-%token kw_VisibleString
-%token kw_WITH
-
-%token RANGE
-%token EEQUAL
-%token ELLIPSIS
-
-%token <name> IDENTIFIER  referencename
-%token <name> STRING
-
-%token <constant> NUMBER
-%type <constant> SignedNumber
-%type <constant> Class tagenv
-
-%type <value> Value
-%type <value> BuiltinValue
-%type <value> IntegerValue
-%type <value> BooleanValue
-%type <value> ObjectIdentifierValue
-%type <value> CharacterStringValue
-%type <value> NullValue
-%type <value> DefinedValue
-%type <value> ReferencedValue
-%type <value> Valuereference
-
-%type <type> Type
-%type <type> BuiltinType
-%type <type> BitStringType
-%type <type> BooleanType
-%type <type> ChoiceType
-%type <type> ConstrainedType
-%type <type> EnumeratedType
-%type <type> IntegerType
-%type <type> NullType
-%type <type> OctetStringType
-%type <type> SequenceType
-%type <type> SequenceOfType
-%type <type> SetType
-%type <type> SetOfType
-%type <type> TaggedType
-%type <type> ReferencedType
-%type <type> DefinedType
-%type <type> UsefulType
-%type <type> ObjectIdentifierType
-%type <type> CharacterStringType
-%type <type> RestrictedCharactedStringType
-
-%type <tag> Tag
-
-%type <member> ComponentType
-%type <member> NamedBit
-%type <member> NamedNumber
-%type <member> NamedType
-%type <members> ComponentTypeList
-%type <members> Enumerations
-%type <members> NamedBitList
-%type <members> NamedNumberList
-
-%type <objid> objid objid_list objid_element objid_opt
-%type <range> range size
-
-%type <sl> referencenames
-
-%type <constraint_spec> Constraint
-%type <constraint_spec> ConstraintSpec
-%type <constraint_spec> GeneralConstraint
-%type <constraint_spec> ContentsConstraint
-%type <constraint_spec> UserDefinedConstraint
-
-
-
-%start ModuleDefinition
-
-%%
-
-ModuleDefinition: IDENTIFIER objid_opt kw_DEFINITIONS TagDefault ExtensionDefault
-                       EEQUAL kw_BEGIN ModuleBody kw_END
-               {
-                       checkundefined();
-               }
-               ;
-
-TagDefault     : kw_EXPLICIT kw_TAGS
-               | kw_IMPLICIT kw_TAGS
-                     { error_message("implicit tagging is not supported"); }
-               | kw_AUTOMATIC kw_TAGS
-                     { error_message("automatic tagging is not supported"); }
-               | /* empty */
-               ;
-
-ExtensionDefault: kw_EXTENSIBILITY kw_IMPLIED
-                     { error_message("no extensibility options supported"); }
-               | /* empty */
-               ;
-
-ModuleBody     : /* Exports */ Imports AssignmentList
-               | /* empty */
-               ;
-
-Imports                : kw_IMPORTS SymbolsImported ';'
-               | /* empty */
-               ;
-
-SymbolsImported        : SymbolsFromModuleList
-               | /* empty */
-               ;
-
-SymbolsFromModuleList: SymbolsFromModule
-               | SymbolsFromModuleList SymbolsFromModule
-               ;
-
-SymbolsFromModule: referencenames kw_FROM IDENTIFIER objid_opt
-               {
-                   struct string_list *sl;
-                   for(sl = $1; sl != NULL; sl = sl->next) {
-                       Symbol *s = addsym(sl->string);
-                       s->stype = Stype;
-                   }
-                   add_import($3);
-               }
-               ;
-
-AssignmentList : Assignment
-               | Assignment AssignmentList
-               ;
-
-Assignment     : TypeAssignment
-               | ValueAssignment
-               ;
-
-referencenames : IDENTIFIER ',' referencenames
-               {
-                   $$ = emalloc(sizeof(*$$));
-                   $$->string = $1;
-                   $$->next = $3;
-               }
-               | IDENTIFIER
-               {
-                   $$ = emalloc(sizeof(*$$));
-                   $$->string = $1;
-                   $$->next = NULL;
-               }
-               ;
-
-TypeAssignment : IDENTIFIER EEQUAL Type
-               {
-                   Symbol *s = addsym ($1);
-                   s->stype = Stype;
-                   s->type = $3;
-                   fix_labels(s);
-                   generate_type (s);
-               }
-               ;
-
-Type           : BuiltinType
-               | ReferencedType
-               | ConstrainedType
-               ;
-
-BuiltinType    : BitStringType
-               | BooleanType
-               | CharacterStringType
-               | ChoiceType
-               | EnumeratedType
-               | IntegerType
-               | NullType
-               | ObjectIdentifierType
-               | OctetStringType
-               | SequenceType
-               | SequenceOfType
-               | SetType
-               | SetOfType
-               | TaggedType
-               ;
-
-BooleanType    : kw_BOOLEAN
-               {
-                       $$ = new_tag(ASN1_C_UNIV, UT_Boolean,
-                                    TE_EXPLICIT, new_type(TBoolean));
-               }
-               ;
-
-range          : '(' Value RANGE Value ')'
-               {
-                   if($2->type != integervalue)
-                       error_message("Non-integer used in first part of range");
-                   if($2->type != integervalue)
-                       error_message("Non-integer in second part of range");
-                   $$ = ecalloc(1, sizeof(*$$));
-                   $$->min = $2->u.integervalue;
-                   $$->max = $4->u.integervalue;
-               }
-               | '(' Value RANGE kw_MAX ')'
-               {               
-                   if($2->type != integervalue)
-                       error_message("Non-integer in first part of range");
-                   $$ = ecalloc(1, sizeof(*$$));
-                   $$->min = $2->u.integervalue;
-                   $$->max = $2->u.integervalue - 1;
-               }
-               | '(' kw_MIN RANGE Value ')'
-               {               
-                   if($4->type != integervalue)
-                       error_message("Non-integer in second part of range");
-                   $$ = ecalloc(1, sizeof(*$$));
-                   $$->min = $4->u.integervalue + 2;
-                   $$->max = $4->u.integervalue;
-               }
-               | '(' Value ')'
-               {
-                   if($2->type != integervalue)
-                       error_message("Non-integer used in limit");
-                   $$ = ecalloc(1, sizeof(*$$));
-                   $$->min = $2->u.integervalue;
-                   $$->max = $2->u.integervalue;
-               }
-               ;
-
-
-IntegerType    : kw_INTEGER
-               {
-                       $$ = new_tag(ASN1_C_UNIV, UT_Integer,
-                                    TE_EXPLICIT, new_type(TInteger));
-               }
-               | kw_INTEGER range
-               {
-                       $$ = new_type(TInteger);
-                       $$->range = $2;
-                       $$ = new_tag(ASN1_C_UNIV, UT_Integer, TE_EXPLICIT, $$);
-               }
-               | kw_INTEGER '{' NamedNumberList '}'
-               {
-                 $$ = new_type(TInteger);
-                 $$->members = $3;
-                 $$ = new_tag(ASN1_C_UNIV, UT_Integer, TE_EXPLICIT, $$);
-               }
-               ;
-
-NamedNumberList        : NamedNumber
-               {
-                       $$ = emalloc(sizeof(*$$));
-                       ASN1_TAILQ_INIT($$);
-                       ASN1_TAILQ_INSERT_HEAD($$, $1, members);
-               }
-               | NamedNumberList ',' NamedNumber
-               {
-                       ASN1_TAILQ_INSERT_TAIL($1, $3, members);
-                       $$ = $1;
-               }
-               | NamedNumberList ',' ELLIPSIS
-                       { $$ = $1; } /* XXX used for Enumerations */
-               ;
-
-NamedNumber    : IDENTIFIER '(' SignedNumber ')'
-               {
-                       $$ = emalloc(sizeof(*$$));
-                       $$->name = $1;
-                       $$->gen_name = estrdup($1);
-                       output_name ($$->gen_name);
-                       $$->val = $3;
-                       $$->optional = 0;
-                       $$->ellipsis = 0;
-                       $$->type = NULL;
-               }
-               ;
-
-EnumeratedType : kw_ENUMERATED '{' Enumerations '}'
-               {
-                 $$ = new_type(TInteger);
-                 $$->members = $3;
-                 $$ = new_tag(ASN1_C_UNIV, UT_Enumerated, TE_EXPLICIT, $$);
-               }
-               ;
-
-Enumerations   : NamedNumberList /* XXX */
-               ;
-
-BitStringType  : kw_BIT kw_STRING
-               {
-                 $$ = new_type(TBitString);
-                 $$->members = emalloc(sizeof(*$$->members));
-                 ASN1_TAILQ_INIT($$->members);
-                 $$ = new_tag(ASN1_C_UNIV, UT_BitString, TE_EXPLICIT, $$);
-               }
-               | kw_BIT kw_STRING '{' NamedBitList '}'
-               {
-                 $$ = new_type(TBitString);
-                 $$->members = $4;
-                 $$ = new_tag(ASN1_C_UNIV, UT_BitString, TE_EXPLICIT, $$);
-               }
-               ;
-
-ObjectIdentifierType: kw_OBJECT kw_IDENTIFIER
-               {
-                       $$ = new_tag(ASN1_C_UNIV, UT_OID,
-                                    TE_EXPLICIT, new_type(TOID));
-               }
-               ;
-OctetStringType        : kw_OCTET kw_STRING size
-               {
-                   Type *t = new_type(TOctetString);
-                   t->range = $3;
-                   $$ = new_tag(ASN1_C_UNIV, UT_OctetString,
-                                TE_EXPLICIT, t);
-               }
-               ;
-
-NullType       : kw_NULL
-               {
-                       $$ = new_tag(ASN1_C_UNIV, UT_Null,
-                                    TE_EXPLICIT, new_type(TNull));
-               }
-               ;
-
-size           :
-               { $$ = NULL; }
-               | kw_SIZE range
-               { $$ = $2; }
-               ;
-
-
-SequenceType   : kw_SEQUENCE '{' /* ComponentTypeLists */ ComponentTypeList '}'
-               {
-                 $$ = new_type(TSequence);
-                 $$->members = $3;
-                 $$ = new_tag(ASN1_C_UNIV, UT_Sequence, TE_EXPLICIT, $$);
-               }
-               | kw_SEQUENCE '{' '}'
-               {
-                 $$ = new_type(TSequence);
-                 $$->members = NULL;
-                 $$ = new_tag(ASN1_C_UNIV, UT_Sequence, TE_EXPLICIT, $$);
-               }
-               ;
-
-SequenceOfType : kw_SEQUENCE size kw_OF Type
-               {
-                 $$ = new_type(TSequenceOf);
-                 $$->range = $2;
-                 $$->subtype = $4;
-                 $$ = new_tag(ASN1_C_UNIV, UT_Sequence, TE_EXPLICIT, $$);
-               }
-               ;
-
-SetType                : kw_SET '{' /* ComponentTypeLists */ ComponentTypeList '}'
-               {
-                 $$ = new_type(TSet);
-                 $$->members = $3;
-                 $$ = new_tag(ASN1_C_UNIV, UT_Set, TE_EXPLICIT, $$);
-               }
-               | kw_SET '{' '}'
-               {
-                 $$ = new_type(TSet);
-                 $$->members = NULL;
-                 $$ = new_tag(ASN1_C_UNIV, UT_Set, TE_EXPLICIT, $$);
-               }
-               ;
-
-SetOfType      : kw_SET kw_OF Type
-               {
-                 $$ = new_type(TSetOf);
-                 $$->subtype = $3;
-                 $$ = new_tag(ASN1_C_UNIV, UT_Set, TE_EXPLICIT, $$);
-               }
-               ;
-
-ChoiceType     : kw_CHOICE '{' /* AlternativeTypeLists */ ComponentTypeList '}'
-               {
-                 $$ = new_type(TChoice);
-                 $$->members = $3;
-               }
-               ;
-
-ReferencedType : DefinedType
-               | UsefulType
-               ;
-
-DefinedType    : IDENTIFIER
-               {
-                 Symbol *s = addsym($1);
-                 $$ = new_type(TType);
-                 if(s->stype != Stype && s->stype != SUndefined)
-                   error_message ("%s is not a type\n", $1);
-                 else
-                   $$->symbol = s;
-               }
-               ;
-
-UsefulType     : kw_GeneralizedTime
-               {
-                       $$ = new_tag(ASN1_C_UNIV, UT_GeneralizedTime,
-                                    TE_EXPLICIT, new_type(TGeneralizedTime));
-               }
-               | kw_UTCTime
-               {
-                       $$ = new_tag(ASN1_C_UNIV, UT_UTCTime,
-                                    TE_EXPLICIT, new_type(TUTCTime));
-               }
-               ;
-
-ConstrainedType        : Type Constraint
-               {
-                   /* if (Constraint.type == contentConstrant) {
-                      assert(Constraint.u.constraint.type == octetstring|bitstring-w/o-NamedBitList); // remember to check type reference too
-                      if (Constraint.u.constraint.type) {
-                        assert((Constraint.u.constraint.type.length % 8) == 0);
-                      }
-                     }
-                     if (Constraint.u.constraint.encoding) {
-                       type == der-oid|ber-oid
-                     }
-                   */
-               }
-               ;
-
-
-Constraint     : '(' ConstraintSpec ')'
-               {
-                   $$ = $2;
-               }
-               ;
-
-ConstraintSpec : GeneralConstraint
-               ;
-
-GeneralConstraint: ContentsConstraint
-               | UserDefinedConstraint
-               ;
-
-ContentsConstraint: kw_CONTAINING Type
-               {
-                   $$ = new_constraint_spec(CT_CONTENTS);
-                   $$->u.content.type = $2;
-                   $$->u.content.encoding = NULL;
-               }
-               | kw_ENCODED kw_BY Value
-               {
-                   if ($3->type != objectidentifiervalue)
-                       error_message("Non-OID used in ENCODED BY constraint");
-                   $$ = new_constraint_spec(CT_CONTENTS);
-                   $$->u.content.type = NULL;
-                   $$->u.content.encoding = $3;
-               }
-               | kw_CONTAINING Type kw_ENCODED kw_BY Value
-               {
-                   if ($5->type != objectidentifiervalue)
-                       error_message("Non-OID used in ENCODED BY constraint");
-                   $$ = new_constraint_spec(CT_CONTENTS);
-                   $$->u.content.type = $2;
-                   $$->u.content.encoding = $5;
-               }
-               ;
-
-UserDefinedConstraint: kw_CONSTRAINED kw_BY '{' '}'
-               {
-                   $$ = new_constraint_spec(CT_USER);
-               }
-               ;
-
-TaggedType     : Tag tagenv Type
-               {
-                       $$ = new_type(TTag);
-                       $$->tag = $1;
-                       $$->tag.tagenv = $2;
-                       if($3->type == TTag && $2 == TE_IMPLICIT) {
-                               $$->subtype = $3->subtype;
-                               free($3);
-                       } else
-                               $$->subtype = $3;
-               }
-               ;
-
-Tag            : '[' Class NUMBER ']'
-               {
-                       $$.tagclass = $2;
-                       $$.tagvalue = $3;
-                       $$.tagenv = TE_EXPLICIT;
-               }
-               ;
-
-Class          : /* */
-               {
-                       $$ = ASN1_C_CONTEXT;
-               }
-               | kw_UNIVERSAL
-               {
-                       $$ = ASN1_C_UNIV;
-               }
-               | kw_APPLICATION
-               {
-                       $$ = ASN1_C_APPL;
-               }
-               | kw_PRIVATE
-               {
-                       $$ = ASN1_C_PRIVATE;
-               }
-               ;
-
-tagenv         : /* */
-               {
-                       $$ = TE_EXPLICIT;
-               }
-               | kw_EXPLICIT
-               {
-                       $$ = TE_EXPLICIT;
-               }
-               | kw_IMPLICIT
-               {
-                       $$ = TE_IMPLICIT;
-               }
-               ;
-
-
-ValueAssignment        : IDENTIFIER Type EEQUAL Value
-               {
-                       Symbol *s;
-                       s = addsym ($1);
-
-                       s->stype = SValue;
-                       s->value = $4;
-                       generate_constant (s);
-               }
-               ;
-
-CharacterStringType: RestrictedCharactedStringType
-               ;
-
-RestrictedCharactedStringType: kw_GeneralString
-               {
-                       $$ = new_tag(ASN1_C_UNIV, UT_GeneralString,
-                                    TE_EXPLICIT, new_type(TGeneralString));
-               }
-               | kw_UTF8String
-               {
-                       $$ = new_tag(ASN1_C_UNIV, UT_UTF8String,
-                                    TE_EXPLICIT, new_type(TUTF8String));
-               }
-               | kw_PrintableString
-               {
-                       $$ = new_tag(ASN1_C_UNIV, UT_PrintableString,
-                                    TE_EXPLICIT, new_type(TPrintableString));
-               }
-               | kw_VisibleString
-               {
-                       $$ = new_tag(ASN1_C_UNIV, UT_VisibleString,
-                                    TE_EXPLICIT, new_type(TVisibleString));
-               }
-               | kw_IA5String
-               {
-                       $$ = new_tag(ASN1_C_UNIV, UT_IA5String,
-                                    TE_EXPLICIT, new_type(TIA5String));
-               }
-               | kw_BMPString
-               {
-                       $$ = new_tag(ASN1_C_UNIV, UT_BMPString,
-                                    TE_EXPLICIT, new_type(TBMPString));
-               }
-               | kw_UniversalString
-               {
-                       $$ = new_tag(ASN1_C_UNIV, UT_UniversalString,
-                                    TE_EXPLICIT, new_type(TUniversalString));
-               }
-
-               ;
-
-ComponentTypeList: ComponentType
-               {
-                       $$ = emalloc(sizeof(*$$));
-                       ASN1_TAILQ_INIT($$);
-                       ASN1_TAILQ_INSERT_HEAD($$, $1, members);
-               }
-               | ComponentTypeList ',' ComponentType
-               {
-                       ASN1_TAILQ_INSERT_TAIL($1, $3, members);
-                       $$ = $1;
-               }
-               | ComponentTypeList ',' ELLIPSIS
-               {
-                       struct member *m = ecalloc(1, sizeof(*m));
-                       m->name = estrdup("...");
-                       m->gen_name = estrdup("asn1_ellipsis");
-                       m->ellipsis = 1;
-                       ASN1_TAILQ_INSERT_TAIL($1, m, members);
-                       $$ = $1;
-               }
-               ;
-
-NamedType      : IDENTIFIER Type
-               {
-                 $$ = emalloc(sizeof(*$$));
-                 $$->name = $1;
-                 $$->gen_name = estrdup($1);
-                 output_name ($$->gen_name);
-                 $$->type = $2;
-                 $$->ellipsis = 0;
-               }
-               ;
-
-ComponentType  : NamedType
-               {
-                       $$ = $1;
-                       $$->optional = 0;
-                       $$->defval = NULL;
-               }
-               | NamedType kw_OPTIONAL
-               {
-                       $$ = $1;
-                       $$->optional = 1;
-                       $$->defval = NULL;
-               }
-               | NamedType kw_DEFAULT Value
-               {
-                       $$ = $1;
-                       $$->optional = 0;
-                       $$->defval = $3;
-               }
-               ;
-
-NamedBitList   : NamedBit
-               {
-                       $$ = emalloc(sizeof(*$$));
-                       ASN1_TAILQ_INIT($$);
-                       ASN1_TAILQ_INSERT_HEAD($$, $1, members);
-               }
-               | NamedBitList ',' NamedBit
-               {
-                       ASN1_TAILQ_INSERT_TAIL($1, $3, members);
-                       $$ = $1;
-               }
-               ;
-
-NamedBit       : IDENTIFIER '(' NUMBER ')'
-               {
-                 $$ = emalloc(sizeof(*$$));
-                 $$->name = $1;
-                 $$->gen_name = estrdup($1);
-                 output_name ($$->gen_name);
-                 $$->val = $3;
-                 $$->optional = 0;
-                 $$->ellipsis = 0;
-                 $$->type = NULL;
-               }
-               ;
-
-objid_opt      : objid
-               | /* empty */ { $$ = NULL; }
-               ;
-
-objid          : '{' objid_list '}'
-               {
-                       $$ = $2;
-               }
-               ;
-
-objid_list     :  /* empty */
-               {
-                       $$ = NULL;
-               }
-               | objid_element objid_list
-               {
-                       if ($2) {
-                               $$ = $2;
-                               add_oid_to_tail($2, $1);
-                       } else {
-                               $$ = $1;
-                       }
-               }
-               ;
-
-objid_element  : IDENTIFIER '(' NUMBER ')'
-               {
-                       $$ = new_objid($1, $3);
-               }
-               | IDENTIFIER
-               {
-                   Symbol *s = addsym($1);
-                   if(s->stype != SValue ||
-                      s->value->type != objectidentifiervalue) {
-                       error_message("%s is not an object identifier\n",
-                                     s->name);
-                       exit(1);
-                   }
-                   $$ = s->value->u.objectidentifiervalue;
-               }
-               | NUMBER
-               {
-                   $$ = new_objid(NULL, $1);
-               }
-               ;
-
-Value          : BuiltinValue
-               | ReferencedValue
-               ;
-
-BuiltinValue   : BooleanValue
-               | CharacterStringValue
-               | IntegerValue
-               | ObjectIdentifierValue
-               | NullValue
-               ;
-
-ReferencedValue        : DefinedValue
-               ;
-
-DefinedValue   : Valuereference
-               ;
-
-Valuereference : IDENTIFIER
-               {
-                       Symbol *s = addsym($1);
-                       if(s->stype != SValue)
-                               error_message ("%s is not a value\n",
-                                               s->name);
-                       else
-                               $$ = s->value;
-               }
-               ;
-
-CharacterStringValue: STRING
-               {
-                       $$ = emalloc(sizeof(*$$));
-                       $$->type = stringvalue;
-                       $$->u.stringvalue = $1;
-               }
-               ;
-
-BooleanValue   : kw_TRUE
-               {
-                       $$ = emalloc(sizeof(*$$));
-                       $$->type = booleanvalue;
-                       $$->u.booleanvalue = 0;
-               }
-               | kw_FALSE
-               {
-                       $$ = emalloc(sizeof(*$$));
-                       $$->type = booleanvalue;
-                       $$->u.booleanvalue = 0;
-               }
-               ;
-
-IntegerValue   : SignedNumber
-               {
-                       $$ = emalloc(sizeof(*$$));
-                       $$->type = integervalue;
-                       $$->u.integervalue = $1;
-               }
-               ;
-
-SignedNumber   : NUMBER
-               ;
-
-NullValue      : kw_NULL
-               {
-               }
-               ;
-
-ObjectIdentifierValue: objid
-               {
-                       $$ = emalloc(sizeof(*$$));
-                       $$->type = objectidentifiervalue;
-                       $$->u.objectidentifiervalue = $1;
-               }
-               ;
-
-%%
-
-void
-yyerror (const char *s)
-{
-     error_message ("%s\n", s);
-}
-
-static Type *
-new_tag(int tagclass, int tagvalue, int tagenv, Type *oldtype)
-{
-    Type *t;
-    if(oldtype->type == TTag && oldtype->tag.tagenv == TE_IMPLICIT) {
-       t = oldtype;
-       oldtype = oldtype->subtype; /* XXX */
-    } else
-       t = new_type (TTag);
-
-    t->tag.tagclass = tagclass;
-    t->tag.tagvalue = tagvalue;
-    t->tag.tagenv = tagenv;
-    t->subtype = oldtype;
-    return t;
-}
-
-static struct objid *
-new_objid(const char *label, int value)
-{
-    struct objid *s;
-    s = emalloc(sizeof(*s));
-    s->label = label;
-    s->value = value;
-    s->next = NULL;
-    return s;
-}
-
-static void
-add_oid_to_tail(struct objid *head, struct objid *tail)
-{
-    struct objid *o;
-    o = head;
-    while (o->next)
-       o = o->next;
-    o->next = tail;
-}
-
-static Type *
-new_type (Typetype tt)
-{
-    Type *t = ecalloc(1, sizeof(*t));
-    t->type = tt;
-    return t;
-}
-
-static struct constraint_spec *
-new_constraint_spec(enum ctype ct)
-{
-    struct constraint_spec *c = ecalloc(1, sizeof(*c));
-    c->ctype = ct;
-    return c;
-}
-
-static void fix_labels2(Type *t, const char *prefix);
-static void fix_labels1(struct memhead *members, const char *prefix)
-{
-    Member *m;
-
-    if(members == NULL)
-       return;
-    ASN1_TAILQ_FOREACH(m, members, members) {
-       asprintf(&m->label, "%s_%s", prefix, m->gen_name);
-       if (m->label == NULL)
-           errx(1, "malloc");
-       if(m->type != NULL)
-           fix_labels2(m->type, m->label);
-    }
-}
-
-static void fix_labels2(Type *t, const char *prefix)
-{
-    for(; t; t = t->subtype)
-       fix_labels1(t->members, prefix);
-}
-
-static void
-fix_labels(Symbol *s)
-{
-    char *p;
-    asprintf(&p, "choice_%s", s->gen_name);
-    if (p == NULL)
-       errx(1, "malloc");
-    fix_labels2(s->type, p);
-    free(p);
-}
index 4d6454a08fc39dc0705b2b76c5676ada529fa542..8b604c68d7e4ddd8aa2ff1f888623f32e72de648 100644 (file)
@@ -50,7 +50,7 @@ PKCS12-AuthenticatedSafe ::= SEQUENCE OF ContentInfo
 
 PKCS12-Attribute ::= SEQUENCE {
        attrId          OBJECT IDENTIFIER,
 
 PKCS12-Attribute ::= SEQUENCE {
        attrId          OBJECT IDENTIFIER,
-       attrValues      -- SET OF -- heim_any_set 
+       attrValues      -- SET OF -- heim_any_set
 }
 
 PKCS12-Attributes ::= SET OF PKCS12-Attribute
 }
 
 PKCS12-Attributes ::= SET OF PKCS12-Attribute
index 203d91eef8290712d3ebcbb479581a06b4f463ce..45a7d715dfce62f4a87ed10f36f669c3021750bb 100644 (file)
@@ -24,7 +24,7 @@ PKCS8EncryptedData ::= OCTET STRING
 
 PKCS8EncryptedPrivateKeyInfo ::= SEQUENCE {
     encryptionAlgorithm AlgorithmIdentifier,
 
 PKCS8EncryptedPrivateKeyInfo ::= SEQUENCE {
     encryptionAlgorithm AlgorithmIdentifier,
-    encryptedData PKCS8EncryptedData 
+    encryptedData PKCS8EncryptedData
 }
 
 END
 }
 
 END
index 758af6f86e8734879b75c562113762c993f4a239..f36ebf0b32fb5e99740727c842847c9683fcc230 100644 (file)
@@ -27,11 +27,11 @@ id-pkinit-san       OBJECT IDENTIFIER ::=
     x509-sanan(2) }
 
 id-pkinit-ms-eku OBJECT IDENTIFIER ::=
     x509-sanan(2) }
 
 id-pkinit-ms-eku OBJECT IDENTIFIER ::=
-  { iso(1) org(3) dod(6) internet(1) private(4) 
+  { iso(1) org(3) dod(6) internet(1) private(4)
     enterprise(1) microsoft(311) 20 2 2 }
 
 id-pkinit-ms-san OBJECT IDENTIFIER ::=
     enterprise(1) microsoft(311) 20 2 2 }
 
 id-pkinit-ms-san OBJECT IDENTIFIER ::=
-  { iso(1) org(3) dod(6) internet(1) private(4) 
+  { iso(1) org(3) dod(6) internet(1) private(4)
     enterprise(1) microsoft(311) 20 2 3 }
 
 MS-UPN-SAN ::= UTF8String
     enterprise(1) microsoft(311) 20 2 3 }
 
 MS-UPN-SAN ::= UTF8String
@@ -152,19 +152,18 @@ TrustedCA-Win2k ::= CHOICE {
        issuerAndSerial         [2] IssuerAndSerialNumber
 }
 
        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, 
+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 {
        encryption-cert         [4] IMPLICIT OCTET STRING OPTIONAL
 }
 
 PA-PK-AS-REP-Win2k ::= CHOICE {
-       dhSignedData            [0] IMPLICIT OCTET STRING, 
+       dhSignedData            [0] IMPLICIT OCTET STRING,
        encKeyPack              [1] IMPLICIT OCTET STRING
 }
 
        encKeyPack              [1] IMPLICIT OCTET STRING
 }
 
-
 KDCDHKeyInfo-Win2k ::= SEQUENCE {
        nonce                   [0] INTEGER (-2147483648..2147483647),
        subjectPublicKey        [2] BIT STRING
 KDCDHKeyInfo-Win2k ::= SEQUENCE {
        nonce                   [0] INTEGER (-2147483648..2147483647),
        subjectPublicKey        [2] BIT STRING
@@ -176,12 +175,18 @@ ReplyKeyPack-Win2k ::= SEQUENCE {
        ...
 }
 
        ...
 }
 
-PkinitSP80056AOtherInfo ::= SEQUENCE { 
-       algorithmID   AlgorithmIdentifier, 
-       partyUInfo     [0] OCTET STRING, 
-       partyVInfo     [1] OCTET STRING, 
-       suppPubInfo    [2] OCTET STRING OPTIONAL, 
-       suppPrivInfo   [3] OCTET STRING OPTIONAL 
+PA-PK-AS-REP-BTMM ::= SEQUENCE {
+       dhSignedData            [0] heim_any OPTIONAL,
+       encKeyPack              [1] heim_any OPTIONAL
+}
+
+
+PkinitSP80056AOtherInfo ::= SEQUENCE {
+       algorithmID   AlgorithmIdentifier,
+       partyUInfo     [0] OCTET STRING,
+       partyVInfo     [1] OCTET STRING,
+       suppPubInfo    [2] OCTET STRING OPTIONAL,
+       suppPrivInfo   [3] OCTET STRING OPTIONAL
 }
 
 PkinitSuppPubInfo ::= SEQUENCE {
 }
 
 PkinitSuppPubInfo ::= SEQUENCE {
index 8e24f0740b8a6b6f5a1f70b4bb4e4fcd37c484b8..51cac55cc032906ac76c7472420b77daa8aec9e1 100644 (file)
@@ -6,7 +6,7 @@ RFC2459 DEFINITIONS ::= BEGIN
 IMPORTS heim_any FROM heim;
 
 Version ::=  INTEGER {
 IMPORTS heim_any FROM heim;
 
 Version ::=  INTEGER {
-       rfc3280_version_1(0), 
+       rfc3280_version_1(0),
        rfc3280_version_2(1),
        rfc3280_version_3(2)
 }
        rfc3280_version_2(1),
        rfc3280_version_3(2)
 }
@@ -29,7 +29,7 @@ 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-pkcs2-md4 OBJECT IDENTIFIER ::=             { id-pkcs-2 4 }
 id-pkcs2-md5 OBJECT IDENTIFIER ::=             { id-pkcs-2 5 }
 
-id-rsa-digestAlgorithm OBJECT IDENTIFIER ::= 
+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 }
 { iso(1) member-body(2) us(840) rsadsi(113549) 2 }
 
 id-rsa-digest-md2 OBJECT IDENTIFIER ::= { id-rsa-digestAlgorithm 2 }
@@ -54,7 +54,7 @@ id-secsig-sha-1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3)
 
 id-nistAlgorithm OBJECT IDENTIFIER ::= {
    joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) 4 }
 
 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-nist-aes-algs OBJECT IDENTIFIER ::= { id-nistAlgorithm 1 }
 
 id-aes-128-cbc OBJECT IDENTIFIER ::=           { id-nist-aes-algs 2 }
@@ -72,9 +72,42 @@ id-dhpublicnumber OBJECT IDENTIFIER ::= {
         iso(1) member-body(2) us(840) ansi-x942(10046)
         number-type(2) 1 }
 
         iso(1) member-body(2) us(840) ansi-x942(10046)
         number-type(2) 1 }
 
+-- ECC
+
+id-ecPublicKey OBJECT IDENTIFIER ::= {
+       iso(1) member-body(2) us(840) ansi-X9-62(10045) keyType(2) 1 }
+
+id-ecDH OBJECT IDENTIFIER ::= {
+       iso(1) identified-organization(3) certicom(132) schemes(1)
+       ecdh(12) }
+
+id-ecMQV OBJECT IDENTIFIER ::= {
+       iso(1) identified-organization(3) certicom(132) schemes(1)
+       ecmqv(13) }
+
+id-ecdsa-with-SHA256 OBJECT IDENTIFIER ::= {
+     iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4)
+     ecdsa-with-SHA2(3) 2 }
+
+id-ecdsa-with-SHA1 OBJECT IDENTIFIER ::= {
+     iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4) 1 }
+
+-- some EC group ids
+
+id-ec-group-secp256r1 OBJECT IDENTIFIER ::= {
+       iso(1) member-body(2) us(840) ansi-X9-62(10045) curves(3)
+       prime(1) 7 }
+
+id-ec-group-secp160r1 OBJECT IDENTIFIER ::= {
+       iso(1) identified-organization(3) certicom(132) 0 8 }
+
+id-ec-group-secp160r2 OBJECT IDENTIFIER ::= {
+       iso(1) identified-organization(3) certicom(132) 0 30 }
+
+-- DSA
+
 id-x9-57 OBJECT IDENTIFIER ::= {
 id-x9-57 OBJECT IDENTIFIER ::= {
-        iso(1) member-body(2) us(840) ansi-x942(10046)
-       4 }
+        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 }
 
 id-dsa OBJECT IDENTIFIER ::=           { id-x9-57 1 }
 id-dsa-with-sha1 OBJECT IDENTIFIER ::=         { id-x9-57 3 }
@@ -256,8 +289,8 @@ KeyIdentifier ::= OCTET STRING
 
 AuthorityKeyIdentifier ::= SEQUENCE {
        keyIdentifier             [0] IMPLICIT OCTET STRING OPTIONAL,
 
 AuthorityKeyIdentifier ::= SEQUENCE {
        keyIdentifier             [0] IMPLICIT OCTET STRING OPTIONAL,
-       authorityCertIssuer       [1] IMPLICIT -- GeneralName -- 
-               SEQUENCE -- SIZE (1..MAX) -- OF GeneralName OPTIONAL, 
+       authorityCertIssuer       [1] IMPLICIT -- GeneralName --
+               SEQUENCE -- SIZE (1..MAX) -- OF GeneralName OPTIONAL,
        authorityCertSerialNumber [2] IMPLICIT INTEGER OPTIONAL
 }
 
        authorityCertSerialNumber [2] IMPLICIT INTEGER OPTIONAL
 }
 
@@ -269,7 +302,7 @@ id-x509-ce-basicConstraints OBJECT IDENTIFIER ::=  { id-x509-ce 19 }
 
 BasicConstraints ::= SEQUENCE {
        cA                      BOOLEAN OPTIONAL -- DEFAULT FALSE --,
 
 BasicConstraints ::= SEQUENCE {
        cA                      BOOLEAN OPTIONAL -- DEFAULT FALSE --,
-       pathLenConstraint       INTEGER (0..4294967295) OPTIONAL 
+       pathLenConstraint       INTEGER (0..4294967295) OPTIONAL
 }
 
 id-x509-ce-nameConstraints OBJECT IDENTIFIER ::=  { id-x509-ce 30 }
 }
 
 id-x509-ce-nameConstraints OBJECT IDENTIFIER ::=  { id-x509-ce 30 }
@@ -350,6 +383,21 @@ DSAParams  ::=  SEQUENCE {
        g       INTEGER
 }
 
        g       INTEGER
 }
 
+-- draft-ietf-pkix-ecc-subpubkeyinfo-11
+
+ECPoint ::= OCTET STRING
+
+ECParameters ::= CHOICE {
+       namedCurve         OBJECT IDENTIFIER
+       -- implicitCurve   NULL
+       -- specifiedCurve  SpecifiedECDomain
+}
+
+ECDSA-Sig-Value ::= SEQUENCE {
+     r  INTEGER,
+     s  INTEGER
+}
+
 -- really pkcs1
 
 RSAPublicKey ::= SEQUENCE {
 -- really pkcs1
 
 RSAPublicKey ::= SEQUENCE {
@@ -382,7 +430,7 @@ DigestInfo ::= SEQUENCE {
 
 -- szOID_CERTIFICATE_TEMPLATE "1.3.6.1.4.1.311.21.7" is Encoded as:
 
 
 -- szOID_CERTIFICATE_TEMPLATE "1.3.6.1.4.1.311.21.7" is Encoded as:
 
--- TemplateVersion ::= INTEGER (0..4294967295) 
+-- TemplateVersion ::= INTEGER (0..4294967295)
 
 -- CertificateTemplate ::= SEQUENCE {
 --     templateID OBJECT IDENTIFIER,
 
 -- CertificateTemplate ::= SEQUENCE {
 --     templateID OBJECT IDENTIFIER,
@@ -393,7 +441,7 @@ DigestInfo ::= SEQUENCE {
 
 --
 -- CRL
 
 --
 -- CRL
--- 
+--
 
 TBSCRLCertList ::=  SEQUENCE  {
        version                 Version OPTIONAL, -- if present, MUST be v2
 
 TBSCRLCertList ::=  SEQUENCE  {
        version                 Version OPTIONAL, -- if present, MUST be v2
@@ -489,16 +537,16 @@ id-uspkicommon-piv-interim OBJECT IDENTIFIER ::= { 2 16 840 1 101 3 6 9 1 }
 
 --- Netscape extentions
 
 
 --- Netscape extentions
 
-id-netscape OBJECT IDENTIFIER ::= 
+id-netscape OBJECT IDENTIFIER ::=
     { joint-iso-itu-t(2) country(16) us(840) organization(1) netscape(113730) }
 id-netscape-cert-comment OBJECT IDENTIFIER ::= { id-netscape 1 13 }
 
 --- MS extentions
 
     { joint-iso-itu-t(2) country(16) us(840) organization(1) netscape(113730) }
 id-netscape-cert-comment OBJECT IDENTIFIER ::= { id-netscape 1 13 }
 
 --- MS extentions
 
-id-ms-cert-enroll-domaincontroller OBJECT IDENTIFIER ::= 
+id-ms-cert-enroll-domaincontroller OBJECT IDENTIFIER ::=
     { 1 3 6 1 4 1 311 20 2 }
 
     { 1 3 6 1 4 1 311 20 2 }
 
-id-ms-client-authentication OBJECT IDENTIFIER ::= 
+id-ms-client-authentication OBJECT IDENTIFIER ::=
  { 1 3 6 1 5 5 7 3 2 }
 
 -- DER:1e:20:00:44:00:6f:00:6d:00:61:00:69:00:6e:00:43:00:6f:00:6e:00:74:00:72:00:6f:00:6c:00:6c:00:65:00:72
  { 1 3 6 1 5 5 7 3 2 }
 
 -- DER:1e:20:00:44:00:6f:00:6d:00:61:00:69:00:6e:00:43:00:6f:00:6e:00:74:00:72:00:6f:00:6c:00:6c:00:65:00:72
index d07bba6185be2d1437d4b24db5f406f0221abacc..f6237b85b8060e007e71c1e29984ffa75a75e74b 100644 (file)
@@ -20,12 +20,12 @@ TESTSeq ::= SEQUENCE {
 TESTChoice1 ::= CHOICE {
        i1[1]   INTEGER (-2147483648..2147483647),
        i2[2]   INTEGER (-2147483648..2147483647),
 TESTChoice1 ::= CHOICE {
        i1[1]   INTEGER (-2147483648..2147483647),
        i2[2]   INTEGER (-2147483648..2147483647),
-       ...     
+       ...
 }
 
 TESTChoice2 ::= CHOICE {
        i1[1]   INTEGER (-2147483648..2147483647),
 }
 
 TESTChoice2 ::= CHOICE {
        i1[1]   INTEGER (-2147483648..2147483647),
-       ...     
+       ...
 }
 
 TESTInteger ::= INTEGER (-2147483648..2147483647)
 }
 
 TESTInteger ::= INTEGER (-2147483648..2147483647)
@@ -35,7 +35,7 @@ TESTInteger3 ::= [5] IMPLICIT TESTInteger2
 
 TESTImplicit ::= SEQUENCE {
        ti1[0] IMPLICIT INTEGER (-2147483648..2147483647),
 
 TESTImplicit ::= SEQUENCE {
        ti1[0] IMPLICIT INTEGER (-2147483648..2147483647),
-       ti2[1] IMPLICIT SEQUENCE { 
+       ti2[1] IMPLICIT SEQUENCE {
                foo[127] INTEGER (-2147483648..2147483647)
        },
        ti3[2] IMPLICIT [5] IMPLICIT [4] IMPLICIT INTEGER (-2147483648..2147483647)
                foo[127] INTEGER (-2147483648..2147483647)
        },
        ti3[2] IMPLICIT [5] IMPLICIT [4] IMPLICIT INTEGER (-2147483648..2147483647)
@@ -59,19 +59,19 @@ TESTAlloc ::= SEQUENCE {
 
 
 TESTCONTAINING ::= OCTET STRING ( CONTAINING INTEGER )
 
 
 TESTCONTAINING ::= OCTET STRING ( CONTAINING INTEGER )
-TESTENCODEDBY ::= OCTET STRING ( ENCODED BY 
+TESTENCODEDBY ::= OCTET STRING ( ENCODED BY
   { joint-iso-itu-t(2) asn(1) ber-derived(2) distinguished-encoding(1) }
 )
 
   { joint-iso-itu-t(2) asn(1) ber-derived(2) distinguished-encoding(1) }
 )
 
-TESTDer OBJECT IDENTIFIER ::= { 
+TESTDer OBJECT IDENTIFIER ::= {
        joint-iso-itu-t(2) asn(1) ber-derived(2) distinguished-encoding(1)
 }
 
        joint-iso-itu-t(2) asn(1) ber-derived(2) distinguished-encoding(1)
 }
 
-TESTCONTAININGENCODEDBY ::= OCTET STRING ( CONTAINING INTEGER ENCODED BY 
+TESTCONTAININGENCODEDBY ::= OCTET STRING ( CONTAINING INTEGER ENCODED BY
   { joint-iso-itu-t(2) asn(1) ber-derived(2) distinguished-encoding(1) }
 )
 
   { joint-iso-itu-t(2) asn(1) ber-derived(2) distinguished-encoding(1) }
 )
 
-TESTCONTAININGENCODEDBY2 ::= OCTET STRING ( 
+TESTCONTAININGENCODEDBY2 ::= OCTET STRING (
        CONTAINING INTEGER ENCODED BY TESTDer
 )
 
        CONTAINING INTEGER ENCODED BY TESTDer
 )
 
index 89c8ab2c8958d39c8a01934cd1d47b5a1a1de3c4..a43d1e3e6cde5c01fa9e983c371615be6838c41a 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
+
 #include <config.h>
 #include <config.h>
-RCSID("$Id$");
-#endif
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
index 239617d1debafb4570da97b34d711090ad1427ec..a28e51f8da1003cb7744c6032825ebe99f908d10 100644 (file)
@@ -35,8 +35,6 @@
 #include "compile_et.h"
 #include <getarg.h>
 
 #include "compile_et.h"
 #include <getarg.h>
 
-RCSID("$Id$");
-
 #include <roken.h>
 #include <err.h>
 #include "parse.h"
 #include <roken.h>
 #include <err.h>
 #include "parse.h"
index 430405d9d545e19b98da96ef8c87d16c81572e10..b0b8e21da1662bfc6fb96037ce0a803a0eebf56b 100644 (file)
@@ -36,9 +36,7 @@
 #ifndef __COMPILE_ET_H__
 #define __COMPILE_ET_H__
 
 #ifndef __COMPILE_ET_H__
 #define __COMPILE_ET_H__
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-#endif
 
 #include <err.h>
 #include <stdio.h>
 
 #include <err.h>
 #include <stdio.h>
index d64225a758f3aeb60a09e3ed757079ee3b652ddf..6b12c00c7a22434a7b7e9f15f38417d7ae3909d9 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
+
 #include <config.h>
 #include <config.h>
-RCSID("$Id$");
-#endif
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
index 84356405ddf2370422aa8b4cce2f3a07e94c953f..b68814b21caa0993ae4b45acc31efb7118091543 100644 (file)
@@ -44,8 +44,6 @@
 #include "parse.h"
 #include "lex.h"
 
 #include "parse.h"
 #include "lex.h"
 
-RCSID("$Id$");
-
 static unsigned lineno = 1;
 static int getstring(void);
 
 static unsigned lineno = 1;
 static int getstring(void);
 
index 99dddbe1e146bc47cf1a1c59516abcb191002566..d64681d90234dc0434426f2508a92e5ee15ddee0 100644 (file)
@@ -35,8 +35,6 @@
 #include "compile_et.h"
 #include "lex.h"
 
 #include "compile_et.h"
 #include "lex.h"
 
-RCSID("$Id$");
-
 void yyerror (char *s);
 static long name2number(const char *str);
 
 void yyerror (char *s);
 static long name2number(const char *str);
 
index f8b599a6644b4b2f3286e58f76c6c121757d9a6d..9fe2bb8b46e182bc7ee2fbb18d2b2065e8ce000e 100644 (file)
 #endif
 #endif
 
 #endif
 #endif
 
+#ifndef GSSAPI_DEPRECATED
+#define GSSAPI_DEPRECATED __attribute__((deprecated))
+#endif
+
 /*
  * Now define the three implementation-dependent types.
  */
 /*
  * Now define the three implementation-dependent types.
  */
@@ -102,6 +106,11 @@ typedef struct gss_buffer_set_desc_struct {
       gss_buffer_desc *elements;
 } gss_buffer_set_desc, *gss_buffer_set_t;
 
       gss_buffer_desc *elements;
 } gss_buffer_set_desc, *gss_buffer_set_t;
 
+typedef struct gss_iov_buffer_desc_struct {
+    OM_uint32 type;
+    gss_buffer_desc buffer;
+} gss_iov_buffer_desc, *gss_iov_buffer_t;
+
 /*
  * For now, define a QOP-type as an OM_uint32
  */
 /*
  * For now, define a QOP-type as an OM_uint32
  */
@@ -178,6 +187,7 @@ typedef OM_uint32 gss_qop_t;
 #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}
 #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}
+#define GSS_C_NO_IOV_BUFFER ((gss_iov_buffer_t)0)
 
 /*
  * Some alternate names for a couple of the above
 
 /*
  * Some alternate names for a couple of the above
@@ -206,6 +216,27 @@ typedef OM_uint32 gss_qop_t;
  */
 #define GSS_C_INDEFINITE 0xfffffffful
 
  */
 #define GSS_C_INDEFINITE 0xfffffffful
 
+/*
+ * Type of gss_wrap_iov()/gss_unwrap_iov().
+ */
+
+#define GSS_IOV_BUFFER_TYPE_EMPTY 0
+#define GSS_IOV_BUFFER_TYPE_DATA 1
+#define GSS_IOV_BUFFER_TYPE_HEADER 2
+#define GSS_IOV_BUFFER_TYPE_MECH_PARAMS 3
+
+#define GSS_IOV_BUFFER_TYPE_TRAILER 7
+#define GSS_IOV_BUFFER_TYPE_PADDING 9
+#define GSS_IOV_BUFFER_TYPE_STREAM 10
+#define GSS_IOV_BUFFER_TYPE_SIGN_ONLY 11
+
+#define GSS_IOV_BUFFER_TYPE_FLAG_MASK 0xffff0000
+#define GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE 0x00010000
+#define GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATED 0x00020000
+
+#define GSS_IOV_BUFFER_TYPE(_t) ((_t) & ~GSS_IOV_BUFFER_TYPE_FLAG_MASK)
+#define GSS_IOV_BUFFER_FLAGS(_t) ((_t) & GSS_IOV_BUFFER_TYPE_FLAG_MASK)
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -311,12 +342,6 @@ extern GSSAPI_LIB_VARIABLE gss_OID GSS_C_NT_EXPORT_NAME;
 
 extern GSSAPI_LIB_VARIABLE gss_OID GSS_SASL_DIGEST_MD5_MECHANISM;
 
 
 extern GSSAPI_LIB_VARIABLE gss_OID GSS_SASL_DIGEST_MD5_MECHANISM;
 
-/*
- * NTLM mechanism
- */
-
-extern GSSAPI_LIB_VARIABLE gss_OID GSS_NTLM_MECHANISM;
-
 /* Major status codes */
 
 #define GSS_S_COMPLETE 0
 /* Major status codes */
 
 #define GSS_S_COMPLETE 0
@@ -743,6 +768,75 @@ gss_pseudo_random
         gss_buffer_t prf_out
        );
 
         gss_buffer_t prf_out
        );
 
+/*
+ * AEAD support
+ */
+
+OM_uint32 GSSAPI_LIB_FUNCTION
+gss_wrap_iov(OM_uint32 * /* minor_status */,
+            gss_ctx_id_t /* context_handle */,
+            int /* conf_req_flag */,
+            gss_qop_t /* qop_req */,
+            int * /* conf_state */,
+            gss_iov_buffer_desc * /*iov */,
+            int /* iov_count */);
+
+OM_uint32 GSSAPI_LIB_FUNCTION
+gss_unwrap_iov(OM_uint32 * /* minor_status */,
+              gss_ctx_id_t /* context_handle */,
+              int * /* conf_state */,
+              gss_qop_t * /* qop_state */,
+              gss_iov_buffer_desc * /* iov */,
+              int /* iov_count */);
+    
+OM_uint32  GSSAPI_LIB_FUNCTION
+gss_wrap_iov_length(OM_uint32 * /* minor_status */,
+                   gss_ctx_id_t /* context_handle */,
+                   int /* conf_req_flag */,
+                   gss_qop_t /* qop_req */,
+                   int * /* conf_state */,
+                   gss_iov_buffer_desc * /* iov */,
+                   int /* iov_count */);
+
+OM_uint32 GSSAPI_LIB_FUNCTION
+gss_release_iov_buffer(OM_uint32 * /* minor_status */,
+                      gss_iov_buffer_desc * /* iov */,
+                      int /* iov_count */);
+
+
+OM_uint32
+gss_store_cred(OM_uint32         * /* minor_status */,
+              gss_cred_id_t     /* input_cred_handle */,
+              gss_cred_usage_t  /* cred_usage */,
+              const gss_OID     /* desired_mech */,
+              OM_uint32         /* overwrite_cred */,
+              OM_uint32         /* default_cred */,
+              gss_OID_set       * /* elements_stored */,
+              gss_cred_usage_t  * /* cred_usage_stored */);
+
+
+/*
+ * Query functions
+ */
+
+typedef struct {
+    size_t header; /**< size of header */
+    size_t trailer; /**< size of trailer */
+    size_t max_msg_size; /**< maximum message size */
+    size_t buffers; /**< extra GSS_IOV_BUFFER_TYPE_EMPTY buffer to pass */
+    size_t blocksize; /**< Specificed optimal size of messages, also
+                        is the maximum padding size
+                        (GSS_IOV_BUFFER_TYPE_PADDING) */
+} gss_context_stream_sizes; 
+
+extern gss_OID GSSAPI_LIB_VARIABLE GSS_C_ATTR_STREAM_SIZES;
+
+
+OM_uint32 GSSAPI_LIB_FUNCTION
+gss_context_query_attributes(OM_uint32 * /* minor_status */,
+                            gss_OID /* attribute */,
+                            void * /*data*/,
+                            size_t /* len */);
 /*
  * The following routines are obsolete variants of gss_get_mic,
  * gss_verify_mic, gss_wrap and gss_unwrap.  They should be
 /*
  * The following routines are obsolete variants of gss_get_mic,
  * gss_verify_mic, gss_wrap and gss_unwrap.  They should be
@@ -754,7 +848,7 @@ gss_pseudo_random
  * obsolete versions of these routines and their current forms.
  */
 
  * obsolete versions of these routines and their current forms.
  */
 
-OM_uint32 GSSAPI_LIB_FUNCTION gss_sign
+OM_uint32 GSSAPI_LIB_FUNCTION GSSAPI_DEPRECATED gss_sign
            (OM_uint32 * /*minor_status*/,
             gss_ctx_id_t /*context_handle*/,
             int /*qop_req*/,
            (OM_uint32 * /*minor_status*/,
             gss_ctx_id_t /*context_handle*/,
             int /*qop_req*/,
@@ -762,7 +856,7 @@ OM_uint32 GSSAPI_LIB_FUNCTION gss_sign
             gss_buffer_t /*message_token*/
            );
 
             gss_buffer_t /*message_token*/
            );
 
-OM_uint32 GSSAPI_LIB_FUNCTION gss_verify
+OM_uint32 GSSAPI_LIB_FUNCTION GSSAPI_DEPRECATED gss_verify
            (OM_uint32 * /*minor_status*/,
             gss_ctx_id_t /*context_handle*/,
             gss_buffer_t /*message_buffer*/,
            (OM_uint32 * /*minor_status*/,
             gss_ctx_id_t /*context_handle*/,
             gss_buffer_t /*message_buffer*/,
@@ -770,7 +864,7 @@ OM_uint32 GSSAPI_LIB_FUNCTION gss_verify
             int * /*qop_state*/
            );
 
             int * /*qop_state*/
            );
 
-OM_uint32 GSSAPI_LIB_FUNCTION gss_seal
+OM_uint32 GSSAPI_LIB_FUNCTION GSSAPI_DEPRECATED gss_seal
            (OM_uint32 * /*minor_status*/,
             gss_ctx_id_t /*context_handle*/,
             int /*conf_req_flag*/,
            (OM_uint32 * /*minor_status*/,
             gss_ctx_id_t /*context_handle*/,
             int /*conf_req_flag*/,
@@ -780,7 +874,7 @@ OM_uint32 GSSAPI_LIB_FUNCTION gss_seal
             gss_buffer_t /*output_message_buffer*/
            );
 
             gss_buffer_t /*output_message_buffer*/
            );
 
-OM_uint32 GSSAPI_LIB_FUNCTION gss_unseal
+OM_uint32 GSSAPI_LIB_FUNCTION GSSAPI_DEPRECATED gss_unseal
            (OM_uint32 * /*minor_status*/,
             gss_ctx_id_t /*context_handle*/,
             gss_buffer_t /*input_message_buffer*/,
            (OM_uint32 * /*minor_status*/,
             gss_ctx_id_t /*context_handle*/,
             gss_buffer_t /*input_message_buffer*/,
@@ -809,7 +903,4 @@ gss_decapsulate_token(gss_buffer_t /* input_token */,
 }
 #endif
 
 }
 #endif
 
-#include <gssapi/gssapi_krb5.h>
-#include <gssapi/gssapi_spnego.h>
-
 #endif /* GSSAPI_GSSAPI_H_ */
 #endif /* GSSAPI_GSSAPI_H_ */
index a821f73d2a01c472654daf7a296ed553f7594cac..0baccf5098f65ad750363e8d0deace89393f070d 100644 (file)
@@ -36,7 +36,7 @@
 #ifndef GSSAPI_KRB5_H_
 #define GSSAPI_KRB5_H_
 
 #ifndef GSSAPI_KRB5_H_
 #define GSSAPI_KRB5_H_
 
-#include <gssapi/gssapi.h>
+#include <gssapi.h>
 
 #ifdef __cplusplus
 extern "C" {
 
 #ifdef __cplusplus
 extern "C" {
index b360de13fcaf53192de49fc62d6c719ef72610cb..6470df30a031c56c0c531444bea96782d25e8019 100644 (file)
@@ -307,7 +307,45 @@ typedef OM_uint32 _gss_pseudo_random(
               gss_buffer_t prf_out
               );
 
               gss_buffer_t prf_out
               );
 
-#define GMI_VERSION 1
+typedef OM_uint32
+_gss_wrap_iov_t(OM_uint32 *minor_status,
+               gss_ctx_id_t  context_handle,
+               int conf_req_flag,
+               gss_qop_t qop_req,
+               int * conf_state,
+               gss_iov_buffer_desc *iov,
+               int iov_count);
+
+typedef OM_uint32
+_gss_unwrap_iov_t(OM_uint32 *minor_status,
+                 gss_ctx_id_t context_handle,
+                 int *conf_state,
+                 gss_qop_t *qop_state,
+                 gss_iov_buffer_desc *iov,
+                 int iov_count);
+
+typedef OM_uint32
+_gss_wrap_iov_length_t(OM_uint32 * minor_status,
+                      gss_ctx_id_t context_handle,
+                      int conf_req_flag,
+                      gss_qop_t qop_req,
+                      int *conf_state,
+                      gss_iov_buffer_desc *iov,
+                      int iov_count);
+
+typedef OM_uint32
+_gss_store_cred_t(OM_uint32         *minor_status,
+                 gss_cred_id_t     input_cred_handle,
+                 gss_cred_usage_t  cred_usage,
+                 const gss_OID     desired_mech,
+                 OM_uint32         overwrite_cred,
+                 OM_uint32         default_cred,
+                 gss_OID_set       *elements_stored,
+                 gss_cred_usage_t  *cred_usage_stored);
+
+
+
+#define GMI_VERSION 2
 
 typedef struct gssapi_mech_interface_desc {
        unsigned                        gm_version;
 
 typedef struct gssapi_mech_interface_desc {
        unsigned                        gm_version;
@@ -347,6 +385,10 @@ typedef struct gssapi_mech_interface_desc {
        _gss_set_sec_context_option     *gm_set_sec_context_option;
        _gss_set_cred_option            *gm_set_cred_option;
        _gss_pseudo_random              *gm_pseudo_random;
        _gss_set_sec_context_option     *gm_set_sec_context_option;
        _gss_set_cred_option            *gm_set_cred_option;
        _gss_pseudo_random              *gm_pseudo_random;
+       _gss_wrap_iov_t                 *gm_wrap_iov;
+       _gss_unwrap_iov_t               *gm_unwrap_iov;
+       _gss_wrap_iov_length_t          *gm_wrap_iov_length;
+       _gss_store_cred_t               *gm_store_cred;
 } gssapi_mech_interface_desc, *gssapi_mech_interface;
 
 gssapi_mech_interface
 } gssapi_mech_interface_desc, *gssapi_mech_interface;
 
 gssapi_mech_interface
index 119d49a0c50c761919efa7c35d98f6557eaa7b33..f5181cc311b877cd50ed9a666bcda8db0d6b414c 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "krb5/gsskrb5_locl.h"
+#include "gsskrb5_locl.h"
 
 RCSID("$Id$");
 
 
 RCSID("$Id$");
 
index 626afa93843459ba2fabe2ddca470ec145219aa6..e0944852a7ea1749441b85c2c5d72a1ce6537914 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "krb5/gsskrb5_locl.h"
+#include "gsskrb5_locl.h"
 
 RCSID("$Id$");
 
 
 RCSID("$Id$");
 
@@ -74,12 +74,10 @@ _gsskrb5_register_acceptor_identity (const char *identity)
 }
 
 void
 }
 
 void
-_gsskrb5i_is_cfx(gsskrb5_ctx ctx, int *is_cfx)
+_gsskrb5i_is_cfx(krb5_context context, gsskrb5_ctx ctx, int acceptor)
 {
 {
+    krb5_error_code ret;
     krb5_keyblock *key;
     krb5_keyblock *key;
-    int acceptor = (ctx->more_flags & LOCAL) == 0;
-
-    *is_cfx = 0;
 
     if (acceptor) {
        if (ctx->auth_context->local_subkey)
 
     if (acceptor) {
        if (ctx->auth_context->local_subkey)
@@ -108,12 +106,16 @@ _gsskrb5i_is_cfx(gsskrb5_ctx ctx, int *is_cfx)
     case ETYPE_ARCFOUR_HMAC_MD5_56:
        break;
     default :
     case ETYPE_ARCFOUR_HMAC_MD5_56:
        break;
     default :
-       *is_cfx = 1;
+        ctx->more_flags |= IS_CFX;
+
        if ((acceptor && ctx->auth_context->local_subkey) ||
            (!acceptor && ctx->auth_context->remote_subkey))
            ctx->more_flags |= ACCEPTOR_SUBKEY;
        break;
     }
        if ((acceptor && ctx->auth_context->local_subkey) ||
            (!acceptor && ctx->auth_context->remote_subkey))
            ctx->more_flags |= ACCEPTOR_SUBKEY;
        break;
     }
+    if (ctx->crypto)
+        krb5_crypto_destroy(context, ctx->crypto);
+    ret = krb5_crypto_init(context, key, 0, &ctx->crypto);
 }
 
 
 }
 
 
@@ -136,7 +138,8 @@ gsskrb5_accept_delegated_token
        kret = krb5_cc_default (context, &ccache);
     } else {
        *delegated_cred_handle = NULL;
        kret = krb5_cc_default (context, &ccache);
     } else {
        *delegated_cred_handle = NULL;
-       kret = krb5_cc_gen_new (context, &krb5_mcc_ops, &ccache);
+       kret = krb5_cc_new_unique (context, krb5_cc_type_memory,
+                                  NULL, &ccache);
     }
     if (kret) {
        ctx->flags &= ~GSS_C_DELEG_FLAG;
     }
     if (kret) {
        ctx->flags &= ~GSS_C_DELEG_FLAG;
@@ -210,7 +213,8 @@ gsskrb5_acceptor_ready(OM_uint32 * minor_status,
                                  ctx->auth_context,
                                  &seq_number);
 
                                  ctx->auth_context,
                                  &seq_number);
 
-    _gsskrb5i_is_cfx(ctx, &is_cfx);
+    _gsskrb5i_is_cfx(context, ctx, 1);
+    is_cfx = (ctx->more_flags & IS_CFX);
 
     ret = _gssapi_msg_order_create(minor_status,
                                   &ctx->order,
 
     ret = _gssapi_msg_order_create(minor_status,
                                   &ctx->order,
@@ -381,7 +385,7 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status,
                               server,
                               in, &out);
        krb5_rd_req_in_ctx_free(context, in);
                               server,
                               in, &out);
        krb5_rd_req_in_ctx_free(context, in);
-       if (kret == KRB5KRB_AP_ERR_SKEW) {
+       if (kret == KRB5KRB_AP_ERR_SKEW || kret == KRB5KRB_AP_ERR_TKT_NYV) {
            /*
             * No reply in non-MUTUAL mode, but we don't know that its
             * non-MUTUAL mode yet, thats inside the 8003 checksum, so
            /*
             * No reply in non-MUTUAL mode, but we don't know that its
             * non-MUTUAL mode yet, thats inside the 8003 checksum, so
@@ -526,7 +530,8 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status,
        krb5_data outbuf;
        int use_subkey = 0;
        
        krb5_data outbuf;
        int use_subkey = 0;
        
-       _gsskrb5i_is_cfx(ctx, &is_cfx);
+       _gsskrb5i_is_cfx(context, ctx, 1);
+       is_cfx = (ctx->more_flags & IS_CFX);
        
        if (is_cfx || (ap_options & AP_OPTS_USE_SUBKEY)) {
            use_subkey = 1;
        
        if (is_cfx || (ap_options & AP_OPTS_USE_SUBKEY)) {
            use_subkey = 1;
index be680840f525d0906d86ae1211250b3448cbbc45..bfab5667beb5cd6403b9a5cf39f5a3dfaac9b549 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "krb5/gsskrb5_locl.h"
+#include "gsskrb5_locl.h"
 
 RCSID("$Id$");
 
 
 RCSID("$Id$");
 
@@ -187,7 +187,8 @@ static OM_uint32 acquire_initiator_cred
        krb5_get_init_creds_opt_free(context, opt);
        if (kret)
            goto end;
        krb5_get_init_creds_opt_free(context, opt);
        if (kret)
            goto end;
-       kret = krb5_cc_gen_new(context, &krb5_mcc_ops, &ccache);
+       kret = krb5_cc_new_unique(context, krb5_cc_type_memory,
+                                 NULL, &ccache);
        if (kret)
            goto end;
        kret = krb5_cc_initialize(context, ccache, cred.client);
        if (kret)
            goto end;
        kret = krb5_cc_initialize(context, ccache, cred.client);
index d6fd8f6f158144bbd0121c0398d621daf4bae0c8..aa96a45e451966da2d58690c7c1690adb9a44640 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "krb5/gsskrb5_locl.h"
+#include "gsskrb5_locl.h"
 
 RCSID("$Id$");
 
 
 RCSID("$Id$");
 
@@ -168,8 +168,8 @@ OM_uint32 _gsskrb5_add_cred (
            }
 
            if (strcmp(type, "MEMORY") == 0) {
            }
 
            if (strcmp(type, "MEMORY") == 0) {
-               ret = krb5_cc_gen_new(context, &krb5_mcc_ops,
-                                     &handle->ccache);
+               ret = krb5_cc_new_unique(context, type, 
+                                        NULL, &handle->ccache);
                if (ret) {
                    *minor_status = ret;
                    goto failure;
                if (ret) {
                    *minor_status = ret;
                    goto failure;
index ff0afdc05984b451c3405d7a001b3bf7707bb0d1..fa115d964a89a62c936f526b2b86c36afde2087a 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "krb5/gsskrb5_locl.h"
+#include "gsskrb5_locl.h"
 
 #include <roken.h>
 
 
 #include <roken.h>
 
diff --git a/source4/heimdal/lib/gssapi/krb5/aeap.c b/source4/heimdal/lib/gssapi/krb5/aeap.c
new file mode 100644 (file)
index 0000000..7dab787
--- /dev/null
@@ -0,0 +1,271 @@
+/*
+ * Copyright (c) 2008  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 "gsskrb5_locl.h"
+
+#include <roken.h>
+
+static OM_uint32
+iov_allocate(OM_uint32 *minor_status, gss_iov_buffer_desc *iov, int iov_count)
+{
+    unsigned int i;
+    
+    for (i = 0; i < iov_count; i++) {
+       if (GSS_IOV_BUFFER_FLAGS(iov[i].type) & GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE){
+           void *ptr = malloc(iov[i].buffer.length);
+           if (ptr == NULL)
+               abort();
+           if (iov[i].buffer.value)
+               memcpy(ptr, iov[i].buffer.value, iov[i].buffer.length);
+           iov[i].buffer.value = ptr;
+           iov[i].type |= GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATED;
+       }
+    }
+    return GSS_S_COMPLETE;
+}
+
+static OM_uint32
+iov_map(OM_uint32 *minor_status,
+       const gss_iov_buffer_desc *iov,
+       int iov_count,
+       krb5_crypto_iov *data)
+{
+    unsigned int i;
+
+    for (i = 0; i < iov_count; i++) {
+       switch(GSS_IOV_BUFFER_TYPE(iov[i].type)) {
+       case GSS_IOV_BUFFER_TYPE_EMPTY:
+           data[i].flags = KRB5_CRYPTO_TYPE_EMPTY;
+           break;
+       case GSS_IOV_BUFFER_TYPE_DATA:
+           data[i].flags = KRB5_CRYPTO_TYPE_DATA;
+           break;
+       case GSS_IOV_BUFFER_TYPE_SIGN_ONLY:
+           data[i].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY;
+           break;
+       case GSS_IOV_BUFFER_TYPE_HEADER:
+           data[i].flags = KRB5_CRYPTO_TYPE_HEADER;
+           break;
+       case GSS_IOV_BUFFER_TYPE_TRAILER:
+           data[i].flags = KRB5_CRYPTO_TYPE_TRAILER;
+           break;
+       case GSS_IOV_BUFFER_TYPE_PADDING:
+           data[i].flags = KRB5_CRYPTO_TYPE_PADDING;
+           break;
+       case GSS_IOV_BUFFER_TYPE_STREAM:
+           abort();
+           break;
+       default:
+           *minor_status = EINVAL;
+           return GSS_S_FAILURE;
+       }
+       data[i].data.data = iov[i].buffer.value;
+       data[i].data.length = iov[i].buffer.length;
+    }
+    return GSS_S_COMPLETE;
+}
+
+OM_uint32 GSSAPI_LIB_FUNCTION
+_gk_wrap_iov(OM_uint32 * minor_status,
+            gss_ctx_id_t  context_handle,
+            int conf_req_flag,
+            gss_qop_t qop_req,
+            int * conf_state,
+            gss_iov_buffer_desc *iov,
+            int iov_count)
+{
+    gsskrb5_ctx ctx = (gsskrb5_ctx) context_handle;
+    krb5_context context;
+    OM_uint32 major_status, junk;
+    krb5_crypto_iov *data;
+    krb5_error_code ret;
+    unsigned usage;
+
+    GSSAPI_KRB5_INIT (&context);
+
+    major_status = iov_allocate(minor_status, iov, iov_count);
+    if (major_status != GSS_S_COMPLETE)
+       return major_status;
+
+    data = calloc(iov_count, sizeof(data[0]));
+    if (data == NULL) {
+       gss_release_iov_buffer(&junk, iov, iov_count);
+       *minor_status = ENOMEM;
+       return GSS_S_FAILURE;
+    }
+
+    major_status = iov_map(minor_status, iov, iov_count, data);
+    if (major_status != GSS_S_COMPLETE) {
+       gss_release_iov_buffer(&junk, iov, iov_count);
+       free(data);
+       return major_status;
+    }
+
+    if (ctx->more_flags & LOCAL) {
+       usage = KRB5_KU_USAGE_ACCEPTOR_SIGN;
+    } else {
+       usage = KRB5_KU_USAGE_INITIATOR_SIGN;
+    }
+
+    ret = krb5_encrypt_iov_ivec(context, ctx->crypto, usage,
+                               data, iov_count, NULL);
+    free(data);
+    if (ret) {
+       gss_release_iov_buffer(&junk, iov, iov_count);
+        *minor_status = ret;
+       return GSS_S_FAILURE;
+    }
+
+    *minor_status = 0;
+    return GSS_S_COMPLETE;
+}
+
+OM_uint32 GSSAPI_LIB_FUNCTION
+_gk_unwrap_iov(OM_uint32 *minor_status,
+              gss_ctx_id_t context_handle,
+              int *conf_state,
+              gss_qop_t *qop_state,
+              gss_iov_buffer_desc *iov,
+              int iov_count)
+{
+    gsskrb5_ctx ctx = (gsskrb5_ctx) context_handle;
+    krb5_context context;
+    krb5_error_code ret;
+    OM_uint32 major_status, junk;
+    krb5_crypto_iov *data;
+    unsigned usage;
+
+    GSSAPI_KRB5_INIT (&context);
+
+    major_status = iov_allocate(minor_status, iov, iov_count);
+    if (major_status != GSS_S_COMPLETE)
+       return major_status;
+
+    data = calloc(iov_count, sizeof(data[0]));
+    if (data == NULL) {
+       gss_release_iov_buffer(&junk, iov, iov_count);
+       *minor_status = ENOMEM;
+       return GSS_S_FAILURE;
+    }
+
+    major_status = iov_map(minor_status, iov, iov_count, data);
+    if (major_status != GSS_S_COMPLETE) {
+       gss_release_iov_buffer(&junk, iov, iov_count);
+       free(data);
+       return major_status;
+    }
+
+    if (ctx->more_flags & LOCAL) {
+       usage = KRB5_KU_USAGE_INITIATOR_SIGN;
+    } else {
+       usage = KRB5_KU_USAGE_ACCEPTOR_SIGN;
+    }
+
+    ret = krb5_decrypt_iov_ivec(context, ctx->crypto, usage,
+                               data, iov_count, NULL);
+    free(data);
+    if (ret) {
+        *minor_status = ret;
+       gss_release_iov_buffer(&junk, iov, iov_count);
+       return GSS_S_FAILURE;
+    }
+
+    *minor_status = 0;
+    return GSS_S_COMPLETE;
+}
+
+OM_uint32  GSSAPI_LIB_FUNCTION
+_gk_wrap_iov_length(OM_uint32 * minor_status,
+                   gss_ctx_id_t context_handle,
+                   int conf_req_flag,
+                   gss_qop_t qop_req,
+                   int *conf_state,
+                   gss_iov_buffer_desc *iov,
+                   int iov_count)
+{
+    gsskrb5_ctx ctx = (gsskrb5_ctx) context_handle;
+    krb5_context context;
+    unsigned int i;
+    size_t size;
+    size_t *padding = NULL;
+
+    GSSAPI_KRB5_INIT (&context);
+    *minor_status = 0;
+
+    for (size = 0, i = 0; i < iov_count; i++) {
+       switch(GSS_IOV_BUFFER_TYPE(iov[i].type)) {
+       case GSS_IOV_BUFFER_TYPE_EMPTY:
+           break;
+       case GSS_IOV_BUFFER_TYPE_DATA:
+           size += iov[i].buffer.length;
+           break;
+       case GSS_IOV_BUFFER_TYPE_HEADER:
+           iov[i].buffer.length =
+             krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_HEADER);
+           size += iov[i].buffer.length;
+           break;
+       case GSS_IOV_BUFFER_TYPE_TRAILER:
+           iov[i].buffer.length =
+             krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_TRAILER);
+           size += iov[i].buffer.length;
+           break;
+       case GSS_IOV_BUFFER_TYPE_PADDING:
+           if (padding != NULL) {
+               *minor_status = 0;
+               return GSS_S_FAILURE;
+           }
+           padding = &iov[i].buffer.length;
+           break;
+       case GSS_IOV_BUFFER_TYPE_STREAM:
+           size += iov[i].buffer.length;
+           break;
+       case GSS_IOV_BUFFER_TYPE_SIGN_ONLY:
+           break;
+       default:
+           *minor_status = EINVAL;
+           return GSS_S_FAILURE;
+       }
+    }
+    if (padding) {
+       size_t pad = krb5_crypto_length(context, ctx->crypto,
+                                       KRB5_CRYPTO_TYPE_PADDING);
+       if (pad > 1) {
+           *padding = pad - (size % pad);
+           if (*padding == pad)
+               *padding = 0;
+       } else
+           *padding = 0;
+    }
+
+    return GSS_S_COMPLETE;
+}
index 7288b58493ef3ea0b863c2f9195c2905c5f18c95..b48cfebcf1b13b3d82864f6fc67d2df14b844264 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "krb5/gsskrb5_locl.h"
+#include "gsskrb5_locl.h"
 
 RCSID("$Id$");
 
 
 RCSID("$Id$");
 
index fa2258ce82f9151dbcdc765e198eacf8998f5a47..3a206b1be1b036195ba25e6cfb59ea54942d5d29 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "krb5/gsskrb5_locl.h"
+#include "gsskrb5_locl.h"
 
 RCSID("$Id$");
 
 
 RCSID("$Id$");
 
index d029f55ce4d27f45b4ac0bd1a895bb29e23dc921..7ae26e2e7a556ac6b1775afb4b5d1c5b5cf20ab8 100755 (executable)
@@ -30,7 +30,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "krb5/gsskrb5_locl.h"
+#include "gsskrb5_locl.h"
 
 RCSID("$Id$");
 
 
 RCSID("$Id$");
 
@@ -101,49 +101,47 @@ _gsskrb5cfx_wrap_length_cfx(const gsskrb5_ctx context_handle,
     return 0;
 }
 
     return 0;
 }
 
-krb5_error_code
-_gsskrb5cfx_max_wrap_length_cfx(krb5_context context,
-                               krb5_crypto crypto,
+OM_uint32 _gssapi_wrap_size_cfx(OM_uint32 *minor_status,
+                               const gsskrb5_ctx ctx,
+                               krb5_context context,
                                int conf_req_flag,
                                int conf_req_flag,
-                               size_t input_length,
-                               OM_uint32 *output_length)
+                               gss_qop_t qop_req,
+                               OM_uint32 req_output_size,
+                               OM_uint32 *max_input_size)
 {
     krb5_error_code ret;
 
 {
     krb5_error_code ret;
 
-    *output_length = 0;
+    *max_input_size = 0;
 
     /* 16-byte header is always first */
 
     /* 16-byte header is always first */
-    if (input_length < 16)
+    if (req_output_size < 16)
        return 0;
        return 0;
-    input_length -= 16;
+    req_output_size -= 16;
 
     if (conf_req_flag) {
        size_t wrapped_size, sz;
 
 
     if (conf_req_flag) {
        size_t wrapped_size, sz;
 
-       wrapped_size = input_length + 1;
+       wrapped_size = req_output_size + 1;
        do {
            wrapped_size--;
            sz = krb5_get_wrapped_length(context,
        do {
            wrapped_size--;
            sz = krb5_get_wrapped_length(context,
-                                        crypto, wrapped_size);
-       } while (wrapped_size && sz > input_length);
-       if (wrapped_size == 0) {
-           *output_length = 0;
+                                        ctx->crypto, wrapped_size);
+       } while (wrapped_size && sz > req_output_size);
+       if (wrapped_size == 0)
            return 0;
            return 0;
-       }
 
        /* inner header */
 
        /* inner header */
-       if (wrapped_size < 16) {
-           *output_length = 0;
+       if (wrapped_size < 16)
            return 0;
            return 0;
-       }
+
        wrapped_size -= 16;
 
        wrapped_size -= 16;
 
-       *output_length = wrapped_size;
+       *max_input_size = wrapped_size;
     } else {
        krb5_cksumtype type;
        size_t cksumsize;
 
     } else {
        krb5_cksumtype type;
        size_t cksumsize;
 
-       ret = krb5_crypto_get_checksum_type(context, crypto, &type);
+       ret = krb5_crypto_get_checksum_type(context, ctx->crypto, &type);
        if (ret)
            return ret;
 
        if (ret)
            return ret;
 
@@ -151,48 +149,16 @@ _gsskrb5cfx_max_wrap_length_cfx(krb5_context context,
        if (ret)
            return ret;
 
        if (ret)
            return ret;
 
-       if (input_length < cksumsize)
+       if (req_output_size < cksumsize)
            return 0;
 
        /* Checksum is concatenated with data */
            return 0;
 
        /* Checksum is concatenated with data */
-       *output_length = input_length - cksumsize;
+       *max_input_size = req_output_size - cksumsize;
     }
 
     return 0;
 }
 
     }
 
     return 0;
 }
 
-
-OM_uint32 _gssapi_wrap_size_cfx(OM_uint32 *minor_status,
-                               const gsskrb5_ctx context_handle,
-                               krb5_context context,
-                               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(context, key, 0, &crypto);
-    if (ret != 0) {
-       *minor_status = ret;
-       return GSS_S_FAILURE;
-    }
-
-    ret = _gsskrb5cfx_max_wrap_length_cfx(context, crypto, conf_req_flag,
-                                         req_output_size, max_input_size);
-    if (ret != 0) {
-       *minor_status = ret;
-       krb5_crypto_destroy(context, crypto);
-       return GSS_S_FAILURE;
-    }
-
-    krb5_crypto_destroy(context, crypto);
-
-    return GSS_S_COMPLETE;
-}
-
 /*
  * Rotate "rrc" bytes to the front or back
  */
 /*
  * Rotate "rrc" bytes to the front or back
  */
@@ -238,16 +204,14 @@ rrc_rotate(void *data, size_t len, uint16_t rrc, krb5_boolean unrotate)
 }
 
 OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
 }
 
 OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
-                          const gsskrb5_ctx context_handle,
+                          const gsskrb5_ctx ctx,
                           krb5_context context,
                           int conf_req_flag,
                           gss_qop_t qop_req,
                           const gss_buffer_t input_message_buffer,
                           int *conf_state,
                           krb5_context context,
                           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)
+                          gss_buffer_t output_message_buffer)
 {
 {
-    krb5_crypto crypto;
     gss_cfx_wrap_token token;
     krb5_error_code ret;
     unsigned usage;
     gss_cfx_wrap_token token;
     krb5_error_code ret;
     unsigned usage;
@@ -257,19 +221,12 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
     int32_t seq_number;
     u_char *p;
 
     int32_t seq_number;
     u_char *p;
 
-    ret = krb5_crypto_init(context, key, 0, &crypto);
-    if (ret != 0) {
-       *minor_status = ret;
-       return GSS_S_FAILURE;
-    }
-
-    ret = _gsskrb5cfx_wrap_length_cfx(context_handle, context,
-                                     crypto, conf_req_flag,
+    ret = _gsskrb5cfx_wrap_length_cfx(ctx, context,
+                                     ctx->crypto, conf_req_flag,
                                      input_message_buffer->length,
                                      &wrapped_len, &cksumsize, &padlength);
     if (ret != 0) {
        *minor_status = ret;
                                      input_message_buffer->length,
                                      &wrapped_len, &cksumsize, &padlength);
     if (ret != 0) {
        *minor_status = ret;
-       krb5_crypto_destroy(context, crypto);
        return GSS_S_FAILURE;
     }
 
        return GSS_S_FAILURE;
     }
 
@@ -280,7 +237,6 @@ 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;
     output_message_buffer->value = malloc(output_message_buffer->length);
     if (output_message_buffer->value == NULL) {
        *minor_status = ENOMEM;
-       krb5_crypto_destroy(context, crypto);
        return GSS_S_FAILURE;
     }
 
        return GSS_S_FAILURE;
     }
 
@@ -290,9 +246,9 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
     token->TOK_ID[1] = 0x04;
     token->Flags     = 0;
     token->Filler    = 0xFF;
     token->TOK_ID[1] = 0x04;
     token->Flags     = 0;
     token->Filler    = 0xFF;
-    if ((context_handle->more_flags & LOCAL) == 0)
+    if ((ctx->more_flags & LOCAL) == 0)
        token->Flags |= CFXSentByAcceptor;
        token->Flags |= CFXSentByAcceptor;
-    if (context_handle->more_flags & ACCEPTOR_SUBKEY)
+    if (ctx->more_flags & ACCEPTOR_SUBKEY)
        token->Flags |= CFXAcceptorSubkey;
     if (conf_req_flag) {
        /*
        token->Flags |= CFXAcceptorSubkey;
     if (conf_req_flag) {
        /*
@@ -329,16 +285,16 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
     token->RRC[0] = 0;
     token->RRC[1] = 0;
 
     token->RRC[0] = 0;
     token->RRC[1] = 0;
 
-    HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
+    HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
     krb5_auth_con_getlocalseqnumber(context,
     krb5_auth_con_getlocalseqnumber(context,
-                                   context_handle->auth_context,
+                                   ctx->auth_context,
                                    &seq_number);
     _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(context,
                                    &seq_number);
     _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(context,
-                                   context_handle->auth_context,
+                                   ctx->auth_context,
                                    ++seq_number);
                                    ++seq_number);
-    HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+    HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
 
     /*
      * If confidentiality is requested, the token header is
 
     /*
      * If confidentiality is requested, the token header is
@@ -349,7 +305,7 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
      * calculated over the plaintext concatenated with the
      * token header.
      */
      * calculated over the plaintext concatenated with the
      * token header.
      */
-    if (context_handle->more_flags & LOCAL) {
+    if (ctx->more_flags & LOCAL) {
        usage = KRB5_KU_USAGE_INITIATOR_SEAL;
     } else {
        usage = KRB5_KU_USAGE_ACCEPTOR_SEAL;
        usage = KRB5_KU_USAGE_INITIATOR_SEAL;
     } else {
        usage = KRB5_KU_USAGE_ACCEPTOR_SEAL;
@@ -370,14 +326,13 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
        memcpy(p + input_message_buffer->length + padlength,
               token, sizeof(*token));
 
        memcpy(p + input_message_buffer->length + padlength,
               token, sizeof(*token));
 
-       ret = krb5_encrypt(context, crypto,
+       ret = krb5_encrypt(context, ctx->crypto,
                           usage, p,
                           input_message_buffer->length + padlength +
                                sizeof(*token),
                           &cipher);
        if (ret != 0) {
            *minor_status = ret;
                           usage, p,
                           input_message_buffer->length + padlength +
                                sizeof(*token),
                           &cipher);
        if (ret != 0) {
            *minor_status = ret;
-           krb5_crypto_destroy(context, crypto);
            _gsskrb5_release_buffer(minor_status, output_message_buffer);
            return GSS_S_FAILURE;
        }
            _gsskrb5_release_buffer(minor_status, output_message_buffer);
            return GSS_S_FAILURE;
        }
@@ -389,14 +344,13 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
         * this is really ugly, but needed against windows
         * for DCERPC, as windows rotates by EC+RRC.
         */
         * this is really ugly, but needed against windows
         * for DCERPC, as windows rotates by EC+RRC.
         */
-       if (IS_DCE_STYLE(context_handle)) {
+       if (IS_DCE_STYLE(ctx)) {
                ret = rrc_rotate(cipher.data, cipher.length, rrc+padlength, FALSE);
        } else {
                ret = rrc_rotate(cipher.data, cipher.length, rrc, FALSE);
        }
        if (ret != 0) {
            *minor_status = ret;
                ret = rrc_rotate(cipher.data, cipher.length, rrc+padlength, FALSE);
        } else {
                ret = rrc_rotate(cipher.data, cipher.length, rrc, FALSE);
        }
        if (ret != 0) {
            *minor_status = ret;
-           krb5_crypto_destroy(context, crypto);
            _gsskrb5_release_buffer(minor_status, output_message_buffer);
            return GSS_S_FAILURE;
        }
            _gsskrb5_release_buffer(minor_status, output_message_buffer);
            return GSS_S_FAILURE;
        }
@@ -409,21 +363,19 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
        buf = malloc(input_message_buffer->length + sizeof(*token));
        if (buf == NULL) {
            *minor_status = ENOMEM;
        buf = malloc(input_message_buffer->length + sizeof(*token));
        if (buf == NULL) {
            *minor_status = ENOMEM;
-           krb5_crypto_destroy(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));
 
            _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(context, crypto,
+       ret = krb5_create_checksum(context, ctx->crypto,
                                   usage, 0, buf,
                                   input_message_buffer->length +
                                        sizeof(*token),
                                   &cksum);
        if (ret != 0) {
            *minor_status = ret;
                                   usage, 0, buf,
                                   input_message_buffer->length +
                                        sizeof(*token),
                                   &cksum);
        if (ret != 0) {
            *minor_status = ret;
-           krb5_crypto_destroy(context, crypto);
            _gsskrb5_release_buffer(minor_status, output_message_buffer);
            free(buf);
            return GSS_S_FAILURE;
            _gsskrb5_release_buffer(minor_status, output_message_buffer);
            free(buf);
            return GSS_S_FAILURE;
@@ -446,7 +398,6 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
            input_message_buffer->length + cksum.checksum.length, rrc, FALSE);
        if (ret != 0) {
            *minor_status = ret;
            input_message_buffer->length + cksum.checksum.length, rrc, FALSE);
        if (ret != 0) {
            *minor_status = ret;
-           krb5_crypto_destroy(context, crypto);
            _gsskrb5_release_buffer(minor_status, output_message_buffer);
            free_Checksum(&cksum);
            return GSS_S_FAILURE;
            _gsskrb5_release_buffer(minor_status, output_message_buffer);
            free_Checksum(&cksum);
            return GSS_S_FAILURE;
@@ -454,8 +405,6 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
        free_Checksum(&cksum);
     }
 
        free_Checksum(&cksum);
     }
 
-    krb5_crypto_destroy(context, crypto);
-
     if (conf_state != NULL) {
        *conf_state = conf_req_flag;
     }
     if (conf_state != NULL) {
        *conf_state = conf_req_flag;
     }
@@ -465,15 +414,13 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
 }
 
 OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status,
 }
 
 OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status,
-                            const gsskrb5_ctx context_handle,
+                            const gsskrb5_ctx ctx,
                             krb5_context context,
                             const gss_buffer_t input_message_buffer,
                             gss_buffer_t output_message_buffer,
                             int *conf_state,
                             krb5_context context,
                             const gss_buffer_t input_message_buffer,
                             gss_buffer_t output_message_buffer,
                             int *conf_state,
-                            gss_qop_t *qop_state,
-                            krb5_keyblock *key)
+                            gss_qop_t *qop_state)
 {
 {
-    krb5_crypto crypto;
     gss_cfx_wrap_token token;
     u_char token_flags;
     krb5_error_code ret;
     gss_cfx_wrap_token token;
     u_char token_flags;
     krb5_error_code ret;
@@ -503,11 +450,11 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status,
        (CFXSentByAcceptor | CFXSealed | CFXAcceptorSubkey);
 
     if (token_flags & CFXSentByAcceptor) {
        (CFXSentByAcceptor | CFXSealed | CFXAcceptorSubkey);
 
     if (token_flags & CFXSentByAcceptor) {
-       if ((context_handle->more_flags & LOCAL) == 0)
+       if ((ctx->more_flags & LOCAL) == 0)
            return GSS_S_DEFECTIVE_TOKEN;
     }
 
            return GSS_S_DEFECTIVE_TOKEN;
     }
 
-    if (context_handle->more_flags & ACCEPTOR_SUBKEY) {
+    if (ctx->more_flags & ACCEPTOR_SUBKEY) {
        if ((token_flags & CFXAcceptorSubkey) == 0)
            return GSS_S_DEFECTIVE_TOKEN;
     } else {
        if ((token_flags & CFXAcceptorSubkey) == 0)
            return GSS_S_DEFECTIVE_TOKEN;
     } else {
@@ -537,26 +484,21 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status,
        return GSS_S_UNSEQ_TOKEN;
     }
 
        return GSS_S_UNSEQ_TOKEN;
     }
 
-    HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
-    ret = _gssapi_msg_order_check(context_handle->order, seq_number_lo);
+    HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+    ret = _gssapi_msg_order_check(ctx->order, seq_number_lo);
     if (ret != 0) {
        *minor_status = 0;
     if (ret != 0) {
        *minor_status = 0;
-       HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+       HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
        _gsskrb5_release_buffer(minor_status, output_message_buffer);
        return ret;
     }
        _gsskrb5_release_buffer(minor_status, output_message_buffer);
        return ret;
     }
-    HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+    HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
 
     /*
      * Decrypt and/or verify checksum
      */
 
     /*
      * Decrypt and/or verify checksum
      */
-    ret = krb5_crypto_init(context, key, 0, &crypto);
-    if (ret != 0) {
-       *minor_status = ret;
-       return GSS_S_FAILURE;
-    }
 
 
-    if (context_handle->more_flags & LOCAL) {
+    if (ctx->more_flags & LOCAL) {
        usage = KRB5_KU_USAGE_ACCEPTOR_SEAL;
     } else {
        usage = KRB5_KU_USAGE_INITIATOR_SEAL;
        usage = KRB5_KU_USAGE_ACCEPTOR_SEAL;
     } else {
        usage = KRB5_KU_USAGE_INITIATOR_SEAL;
@@ -571,27 +513,24 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status,
         * this is really ugly, but needed against windows
         * for DCERPC, as windows rotates by EC+RRC.
         */
         * this is really ugly, but needed against windows
         * for DCERPC, as windows rotates by EC+RRC.
         */
-       if (IS_DCE_STYLE(context_handle)) {
+       if (IS_DCE_STYLE(ctx)) {
                *minor_status = rrc_rotate(p, len, rrc+ec, TRUE);
        } else {
                *minor_status = rrc_rotate(p, len, rrc, TRUE);
        }
        if (*minor_status != 0) {
                *minor_status = rrc_rotate(p, len, rrc+ec, TRUE);
        } else {
                *minor_status = rrc_rotate(p, len, rrc, TRUE);
        }
        if (*minor_status != 0) {
-           krb5_crypto_destroy(context, crypto);
            return GSS_S_FAILURE;
        }
 
            return GSS_S_FAILURE;
        }
 
-       ret = krb5_decrypt(context, crypto, usage,
+       ret = krb5_decrypt(context, ctx->crypto, usage,
            p, len, &data);
        if (ret != 0) {
            *minor_status = ret;
            p, len, &data);
        if (ret != 0) {
            *minor_status = ret;
-           krb5_crypto_destroy(context, crypto);
            return GSS_S_BAD_MIC;
        }
 
        /* Check that there is room for the pad and token header */
        if (data.length < ec + sizeof(*token)) {
            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(context, crypto);
            krb5_data_free(&data);
            return GSS_S_DEFECTIVE_TOKEN;
        }
            krb5_data_free(&data);
            return GSS_S_DEFECTIVE_TOKEN;
        }
@@ -604,7 +543,6 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status,
 
        /* Check the integrity of the header */
        if (memcmp(p, token, sizeof(*token)) != 0) {
 
        /* Check the integrity of the header */
        if (memcmp(p, token, sizeof(*token)) != 0) {
-           krb5_crypto_destroy(context, crypto);
            krb5_data_free(&data);
            return GSS_S_BAD_MIC;
        }
            krb5_data_free(&data);
            return GSS_S_BAD_MIC;
        }
@@ -617,16 +555,15 @@ 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) {
        /* 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(context, crypto);
            return GSS_S_FAILURE;
        }
 
        /* Determine checksum type */
        ret = krb5_crypto_get_checksum_type(context,
            return GSS_S_FAILURE;
        }
 
        /* Determine checksum type */
        ret = krb5_crypto_get_checksum_type(context,
-                                           crypto, &cksum.cksumtype);
+                                           ctx->crypto,
+                                           &cksum.cksumtype);
        if (ret != 0) {
            *minor_status = ret;
        if (ret != 0) {
            *minor_status = ret;
-           krb5_crypto_destroy(context, crypto);
            return GSS_S_FAILURE;
        }
 
            return GSS_S_FAILURE;
        }
 
@@ -635,7 +572,6 @@ 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;
        /* Check we have at least as much data as the checksum */
        if (len < cksum.checksum.length) {
            *minor_status = ERANGE;
-           krb5_crypto_destroy(context, crypto);
            return GSS_S_BAD_MIC;
        }
 
            return GSS_S_BAD_MIC;
        }
 
@@ -647,7 +583,6 @@ 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;
        output_message_buffer->value = malloc(len + sizeof(*token));
        if (output_message_buffer->value == NULL) {
            *minor_status = ENOMEM;
-           krb5_crypto_destroy(context, crypto);
            return GSS_S_FAILURE;
        }
 
            return GSS_S_FAILURE;
        }
 
@@ -664,21 +599,18 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status,
        token->RRC[0] = 0;
        token->RRC[1] = 0;
 
        token->RRC[0] = 0;
        token->RRC[1] = 0;
 
-       ret = krb5_verify_checksum(context, crypto,
+       ret = krb5_verify_checksum(context, ctx->crypto,
                                   usage,
                                   output_message_buffer->value,
                                   len + sizeof(*token),
                                   &cksum);
        if (ret != 0) {
            *minor_status = ret;
                                   usage,
                                   output_message_buffer->value,
                                   len + sizeof(*token),
                                   &cksum);
        if (ret != 0) {
            *minor_status = ret;
-           krb5_crypto_destroy(context, crypto);
            _gsskrb5_release_buffer(minor_status, output_message_buffer);
            return GSS_S_BAD_MIC;
        }
     }
 
            _gsskrb5_release_buffer(minor_status, output_message_buffer);
            return GSS_S_BAD_MIC;
        }
     }
 
-    krb5_crypto_destroy(context, crypto);
-
     if (qop_state != NULL) {
        *qop_state = GSS_C_QOP_DEFAULT;
     }
     if (qop_state != NULL) {
        *qop_state = GSS_C_QOP_DEFAULT;
     }
@@ -688,14 +620,12 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status,
 }
 
 OM_uint32 _gssapi_mic_cfx(OM_uint32 *minor_status,
 }
 
 OM_uint32 _gssapi_mic_cfx(OM_uint32 *minor_status,
-                         const gsskrb5_ctx context_handle,
+                         const gsskrb5_ctx ctx,
                          krb5_context context,
                          gss_qop_t qop_req,
                          const gss_buffer_t message_buffer,
                          krb5_context context,
                          gss_qop_t qop_req,
                          const gss_buffer_t message_buffer,
-                         gss_buffer_t message_token,
-                         krb5_keyblock *key)
+                         gss_buffer_t message_token)
 {
 {
-    krb5_crypto crypto;
     gss_cfx_mic_token token;
     krb5_error_code ret;
     unsigned usage;
     gss_cfx_mic_token token;
     krb5_error_code ret;
     unsigned usage;
@@ -704,17 +634,10 @@ OM_uint32 _gssapi_mic_cfx(OM_uint32 *minor_status,
     size_t len;
     int32_t seq_number;
 
     size_t len;
     int32_t seq_number;
 
-    ret = krb5_crypto_init(context, key, 0, &crypto);
-    if (ret != 0) {
-       *minor_status = ret;
-       return GSS_S_FAILURE;
-    }
-
     len = message_buffer->length + sizeof(*token);
     buf = malloc(len);
     if (buf == NULL) {
        *minor_status = ENOMEM;
     len = message_buffer->length + sizeof(*token);
     buf = malloc(len);
     if (buf == NULL) {
        *minor_status = ENOMEM;
-       krb5_crypto_destroy(context, crypto);
        return GSS_S_FAILURE;
     }
 
        return GSS_S_FAILURE;
     }
 
@@ -724,38 +647,36 @@ OM_uint32 _gssapi_mic_cfx(OM_uint32 *minor_status,
     token->TOK_ID[0] = 0x04;
     token->TOK_ID[1] = 0x04;
     token->Flags = 0;
     token->TOK_ID[0] = 0x04;
     token->TOK_ID[1] = 0x04;
     token->Flags = 0;
-    if ((context_handle->more_flags & LOCAL) == 0)
+    if ((ctx->more_flags & LOCAL) == 0)
        token->Flags |= CFXSentByAcceptor;
        token->Flags |= CFXSentByAcceptor;
-    if (context_handle->more_flags & ACCEPTOR_SUBKEY)
+    if (ctx->more_flags & ACCEPTOR_SUBKEY)
        token->Flags |= CFXAcceptorSubkey;
     memset(token->Filler, 0xFF, 5);
 
        token->Flags |= CFXAcceptorSubkey;
     memset(token->Filler, 0xFF, 5);
 
-    HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
+    HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
     krb5_auth_con_getlocalseqnumber(context,
     krb5_auth_con_getlocalseqnumber(context,
-                                   context_handle->auth_context,
+                                   ctx->auth_context,
                                    &seq_number);
     _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(context,
                                    &seq_number);
     _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(context,
-                                   context_handle->auth_context,
+                                   ctx->auth_context,
                                    ++seq_number);
                                    ++seq_number);
-    HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+    HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
 
 
-    if (context_handle->more_flags & LOCAL) {
+    if (ctx->more_flags & LOCAL) {
        usage = KRB5_KU_USAGE_INITIATOR_SIGN;
     } else {
        usage = KRB5_KU_USAGE_ACCEPTOR_SIGN;
     }
 
        usage = KRB5_KU_USAGE_INITIATOR_SIGN;
     } else {
        usage = KRB5_KU_USAGE_ACCEPTOR_SIGN;
     }
 
-    ret = krb5_create_checksum(context, crypto,
+    ret = krb5_create_checksum(context, ctx->crypto,
        usage, 0, buf, len, &cksum);
     if (ret != 0) {
        *minor_status = ret;
        usage, 0, buf, len, &cksum);
     if (ret != 0) {
        *minor_status = ret;
-       krb5_crypto_destroy(context, crypto);
        free(buf);
        return GSS_S_FAILURE;
     }
        free(buf);
        return GSS_S_FAILURE;
     }
-    krb5_crypto_destroy(context, crypto);
 
     /* Determine MIC length */
     message_token->length = sizeof(*token) + cksum.checksum.length;
 
     /* Determine MIC length */
     message_token->length = sizeof(*token) + cksum.checksum.length;
@@ -780,14 +701,12 @@ OM_uint32 _gssapi_mic_cfx(OM_uint32 *minor_status,
 }
 
 OM_uint32 _gssapi_verify_mic_cfx(OM_uint32 *minor_status,
 }
 
 OM_uint32 _gssapi_verify_mic_cfx(OM_uint32 *minor_status,
-                                const gsskrb5_ctx context_handle,
+                                const gsskrb5_ctx ctx,
                                 krb5_context context,
                                 const gss_buffer_t message_buffer,
                                 const gss_buffer_t token_buffer,
                                 krb5_context context,
                                 const gss_buffer_t message_buffer,
                                 const gss_buffer_t token_buffer,
-                                gss_qop_t *qop_state,
-                                krb5_keyblock *key)
+                                gss_qop_t *qop_state)
 {
 {
-    krb5_crypto crypto;
     gss_cfx_mic_token token;
     u_char token_flags;
     krb5_error_code ret;
     gss_cfx_mic_token token;
     u_char token_flags;
     krb5_error_code ret;
@@ -814,10 +733,10 @@ OM_uint32 _gssapi_verify_mic_cfx(OM_uint32 *minor_status,
     token_flags = token->Flags & (CFXSentByAcceptor | CFXAcceptorSubkey);
 
     if (token_flags & CFXSentByAcceptor) {
     token_flags = token->Flags & (CFXSentByAcceptor | CFXAcceptorSubkey);
 
     if (token_flags & CFXSentByAcceptor) {
-       if ((context_handle->more_flags & LOCAL) == 0)
+       if ((ctx->more_flags & LOCAL) == 0)
            return GSS_S_DEFECTIVE_TOKEN;
     }
            return GSS_S_DEFECTIVE_TOKEN;
     }
-    if (context_handle->more_flags & ACCEPTOR_SUBKEY) {
+    if (ctx->more_flags & ACCEPTOR_SUBKEY) {
        if ((token_flags & CFXAcceptorSubkey) == 0)
            return GSS_S_DEFECTIVE_TOKEN;
     } else {
        if ((token_flags & CFXAcceptorSubkey) == 0)
            return GSS_S_DEFECTIVE_TOKEN;
     } else {
@@ -839,36 +758,29 @@ OM_uint32 _gssapi_verify_mic_cfx(OM_uint32 *minor_status,
        return GSS_S_UNSEQ_TOKEN;
     }
 
        return GSS_S_UNSEQ_TOKEN;
     }
 
-    HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
-    ret = _gssapi_msg_order_check(context_handle->order, seq_number_lo);
+    HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+    ret = _gssapi_msg_order_check(ctx->order, seq_number_lo);
     if (ret != 0) {
        *minor_status = 0;
     if (ret != 0) {
        *minor_status = 0;
-       HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+       HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
        return ret;
     }
        return ret;
     }
-    HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+    HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
 
     /*
      * Verify checksum
      */
 
     /*
      * Verify checksum
      */
-    ret = krb5_crypto_init(context, key, 0, &crypto);
-    if (ret != 0) {
-       *minor_status = ret;
-       return GSS_S_FAILURE;
-    }
-
-    ret = krb5_crypto_get_checksum_type(context, crypto,
+    ret = krb5_crypto_get_checksum_type(context, ctx->crypto,
                                        &cksum.cksumtype);
     if (ret != 0) {
        *minor_status = ret;
                                        &cksum.cksumtype);
     if (ret != 0) {
        *minor_status = ret;
-       krb5_crypto_destroy(context, crypto);
        return GSS_S_FAILURE;
     }
 
     cksum.checksum.data = p + sizeof(*token);
     cksum.checksum.length = token_buffer->length - sizeof(*token);
 
        return GSS_S_FAILURE;
     }
 
     cksum.checksum.data = p + sizeof(*token);
     cksum.checksum.length = token_buffer->length - sizeof(*token);
 
-    if (context_handle->more_flags & LOCAL) {
+    if (ctx->more_flags & LOCAL) {
        usage = KRB5_KU_USAGE_ACCEPTOR_SIGN;
     } else {
        usage = KRB5_KU_USAGE_INITIATOR_SIGN;
        usage = KRB5_KU_USAGE_ACCEPTOR_SIGN;
     } else {
        usage = KRB5_KU_USAGE_INITIATOR_SIGN;
@@ -877,18 +789,16 @@ OM_uint32 _gssapi_verify_mic_cfx(OM_uint32 *minor_status,
     buf = malloc(message_buffer->length + sizeof(*token));
     if (buf == NULL) {
        *minor_status = ENOMEM;
     buf = malloc(message_buffer->length + sizeof(*token));
     if (buf == NULL) {
        *minor_status = ENOMEM;
-       krb5_crypto_destroy(context, crypto);
        return GSS_S_FAILURE;
     }
     memcpy(buf, message_buffer->value, message_buffer->length);
     memcpy(buf + message_buffer->length, token, sizeof(*token));
 
        return GSS_S_FAILURE;
     }
     memcpy(buf, message_buffer->value, message_buffer->length);
     memcpy(buf + message_buffer->length, token, sizeof(*token));
 
-    ret = krb5_verify_checksum(context, crypto,
+    ret = krb5_verify_checksum(context, ctx->crypto,
                               usage,
                               buf,
                               sizeof(*token) + message_buffer->length,
                               &cksum);
                               usage,
                               buf,
                               sizeof(*token) + message_buffer->length,
                               &cksum);
-    krb5_crypto_destroy(context, crypto);
     if (ret != 0) {
        *minor_status = ret;
        free(buf);
     if (ret != 0) {
        *minor_status = ret;
        free(buf);
index d92f3ef4059e1e2ccdbeb86e50fa47c42e48d2a5..fbb0f0218e7e1d15f27f63dc0fb641be73f67cb3 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "krb5/gsskrb5_locl.h"
+#include "gsskrb5_locl.h"
 
 RCSID("$Id$");
 
 
 RCSID("$Id$");
 
index ee0d07d98399b712e9c4c51fb983047447a187fb..012602c07441623b6841156f5331f4d9634b06f8 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "krb5/gsskrb5_locl.h"
+#include "gsskrb5_locl.h"
 
 RCSID("$Id$");
 
 
 RCSID("$Id$");
 
index 3854b687829f4eb35c5f407738bc668f2e78149b..323038993880670aa5b59d812d3bf93c3850c97e 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "krb5/gsskrb5_locl.h"
+#include "gsskrb5_locl.h"
 
 RCSID("$Id$");
 
 
 RCSID("$Id$");
 
index 8961642671bf7f8519b334735999d6d4220da08d..40a8fab1b7b42a3fde291b00a97018c105832945 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "krb5/gsskrb5_locl.h"
+#include "gsskrb5_locl.h"
 
 RCSID("$Id$");
 
 
 RCSID("$Id$");
 
index 22386fa737673062a4138d18a7cda69a52de11ff..a2a5de9fe75b87b286bceb04e5610308977619fc 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "krb5/gsskrb5_locl.h"
+#include "gsskrb5_locl.h"
 
 RCSID("$Id$");
 
 
 RCSID("$Id$");
 
index 5ccfe9d01533c11b32af443ee6dc592bb8b4f0c3..ea0831815a27f50ec1167590651914972005229f 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "krb5/gsskrb5_locl.h"
+#include "gsskrb5_locl.h"
 
 RCSID("$Id$");
 
 
 RCSID("$Id$");
 
@@ -74,6 +74,8 @@ _gsskrb5_delete_sec_context(OM_uint32 * minor_status,
     if (ctx->service_keyblock)
        krb5_free_keyblock (context, ctx->service_keyblock);
     krb5_data_free(&ctx->fwd_data);
     if (ctx->service_keyblock)
        krb5_free_keyblock (context, ctx->service_keyblock);
     krb5_data_free(&ctx->fwd_data);
+    if (ctx->crypto)
+       krb5_crypto_destroy(context, ctx->crypto);
 
     HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
     HEIMDAL_MUTEX_destroy(&ctx->ctx_id_mutex);
 
     HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
     HEIMDAL_MUTEX_destroy(&ctx->ctx_id_mutex);
index d1834ebaf8ade1e8175ea58a4e21593698df2272..0b377315108ab3782be025c29cddd894b49b5278 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "krb5/gsskrb5_locl.h"
+#include "gsskrb5_locl.h"
 
 RCSID("$Id$");
 
 
 RCSID("$Id$");
 
index 18622610d5dc90df69d7074ea1ca6697a355aa9c..4136c25e533c31a76be8ee73f5e99ad5846d6be0 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "krb5/gsskrb5_locl.h"
+#include "gsskrb5_locl.h"
 
 RCSID("$Id$");
 
 
 RCSID("$Id$");
 
index 6c281f43dea4db83c10481bc495b343de463af49..2b5e5c0ef48a781ec10ec379627040fb46f3da36 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "krb5/gsskrb5_locl.h"
+#include "gsskrb5_locl.h"
 
 RCSID("$Id$");
 
 
 RCSID("$Id$");
 
index 19c6ec8ca7fc0c9df4d48049e0e4f94875b3b15e..838a34d7db9a20f6d1c43d4222ec03e198edd6c4 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "krb5/gsskrb5_locl.h"
+#include "gsskrb5_locl.h"
 
 RCSID("$Id$");
 
 
 RCSID("$Id$");
 
index b28777ea2eb6ed6e2d6f7a2d87e36d9622a3f169..bad73611dc84a277854cc83bfb615c667e3a3aa3 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "krb5/gsskrb5_locl.h"
+#include "gsskrb5_locl.h"
 
 RCSID("$Id$");
 
 
 RCSID("$Id$");
 
index 842921fe5008175597a5d8494ade257171d378ad..305d5c334e64312ceaab52276fb57d06ab0f996c 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "krb5/gsskrb5_locl.h"
+#include "gsskrb5_locl.h"
 
 RCSID("$Id$");
 
 
 RCSID("$Id$");
 
index 4efa61fd70885cf8a09df053481e09beb9955e31..1c28f7c141d8f47ab54c83d9d8b51c4265466fde 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "krb5/gsskrb5_locl.h"
+#include "gsskrb5_locl.h"
 #include <gssapi_mech.h>
 
 RCSID("$Id$");
 #include <gssapi_mech.h>
 
 RCSID("$Id$");
@@ -469,7 +469,10 @@ static gssapi_mech_interface_desc krb5_mech = {
     _gsskrb5_inquire_cred_by_oid,
     _gsskrb5_set_sec_context_option,
     _gsskrb5_set_cred_option,
     _gsskrb5_inquire_cred_by_oid,
     _gsskrb5_set_sec_context_option,
     _gsskrb5_set_cred_option,
-    _gsskrb5_pseudo_random
+    _gsskrb5_pseudo_random,
+    _gk_wrap_iov,
+    _gk_unwrap_iov,
+    _gk_wrap_iov_length
 };
 
 gssapi_mech_interface
 };
 
 gssapi_mech_interface
index 199c414ef48780ba15f3432ad81f812c7ae0cd5d..66aaba44d67827dff7578f1179b3303b5934d7f0 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "krb5/gsskrb5_locl.h"
+#include "gsskrb5_locl.h"
 
 RCSID("$Id$");
 
 
 RCSID("$Id$");
 
@@ -284,6 +284,10 @@ OM_uint32 _gsskrb5_get_mic
 
   GSSAPI_KRB5_INIT (&context);
 
 
   GSSAPI_KRB5_INIT (&context);
 
+  if (ctx->more_flags & IS_CFX)
+      return _gssapi_mic_cfx (minor_status, ctx, context, qop_req,
+                             message_buffer, message_token);
+
   HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
   ret = _gsskrb5i_get_token_key(ctx, context, &key);
   HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
   HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
   ret = _gsskrb5i_get_token_key(ctx, context, &key);
   HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
@@ -308,8 +312,7 @@ OM_uint32 _gsskrb5_get_mic
                                     message_buffer, message_token, key);
       break;
   default :
                                     message_buffer, message_token, key);
       break;
   default :
-      ret = _gssapi_mic_cfx (minor_status, ctx, context, qop_req,
-                            message_buffer, message_token, key);
+      abort();
       break;
   }
   krb5_free_keyblock (context, key);
       break;
   }
   krb5_free_keyblock (context, key);
index 6db842395f711a6ac6105305ed04ec0cd225d328..aadb80db0d90ae7ccfd031a08a587484a8684673 100644 (file)
 #ifndef GSSKRB5_LOCL_H
 #define GSSKRB5_LOCL_H
 
 #ifndef GSSKRB5_LOCL_H
 #define GSSKRB5_LOCL_H
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-#endif
 
 #include <krb5_locl.h>
 #include <gkrb5_err.h>
 #include <gssapi.h>
 #include <gssapi_mech.h>
 
 #include <krb5_locl.h>
 #include <gkrb5_err.h>
 #include <gssapi.h>
 #include <gssapi_mech.h>
+#include <gssapi_krb5.h>
 #include <assert.h>
 
 #include "cfx.h"
 #include <assert.h>
 
 #include "cfx.h"
@@ -54,7 +53,7 @@
 
 struct gss_msg_order;
 
 
 struct gss_msg_order;
 
-typedef struct {
+typedef struct gsskrb5_ctx {
   struct krb5_auth_context_data *auth_context;
   krb5_principal source, target;
 #define IS_DCE_STYLE(ctx) (((ctx)->flags & GSS_C_DCE_STYLE) != 0)
   struct krb5_auth_context_data *auth_context;
   krb5_principal source, target;
 #define IS_DCE_STYLE(ctx) (((ctx)->flags & GSS_C_DCE_STYLE) != 0)
@@ -64,7 +63,8 @@ typedef struct {
          COMPAT_OLD_DES3_SELECTED = 8,
         ACCEPTOR_SUBKEY = 16,
         RETRIED = 32,
          COMPAT_OLD_DES3_SELECTED = 8,
         ACCEPTOR_SUBKEY = 16,
         RETRIED = 32,
-        CLOSE_CCACHE = 64
+        CLOSE_CCACHE = 64,
+        IS_CFX = 128
   } more_flags;
   enum gss_ctx_id_t_state {
       /* initiator states */
   } more_flags;
   enum gss_ctx_id_t_state {
       /* initiator states */
@@ -85,6 +85,7 @@ typedef struct {
   struct gss_msg_order *order;
   krb5_keyblock *service_keyblock;
   krb5_data fwd_data;
   struct gss_msg_order *order;
   krb5_keyblock *service_keyblock;
   krb5_data fwd_data;
+  krb5_crypto crypto;
 } *gsskrb5_ctx;
 
 typedef struct {
 } *gsskrb5_ctx;
 
 typedef struct {
@@ -119,7 +120,7 @@ struct gssapi_thr_context {
  * Prototypes
  */
 
  * Prototypes
  */
 
-#include <krb5/gsskrb5-private.h>
+#include <gsskrb5-private.h>
 
 #define GSSAPI_KRB5_INIT(ctx) do {                             \
     krb5_error_code kret_gss_init;                             \
 
 #define GSSAPI_KRB5_INIT(ctx) do {                             \
     krb5_error_code kret_gss_init;                             \
index 2f6b002f306c287f1290834df748db12405c96af..8f5387fe2b56b32fc8eea7b05ca1bb7cfd1a689a 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "krb5/gsskrb5_locl.h"
+#include "gsskrb5_locl.h"
 
 RCSID("$Id$");
 
 
 RCSID("$Id$");
 
index e1e8e551b416a88377bb4ae361c0b304ed7998b1..ba1a977d2dc6ee8aa7a2b3717d92fa64dbaf2d57 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "krb5/gsskrb5_locl.h"
+#include "gsskrb5_locl.h"
 
 RCSID("$Id$");
 
 
 RCSID("$Id$");
 
index 05b9447746dea7649222cd32dafcacdc3152ecbc..3702106e7903cbda61b4a14e0c2c825a7cf22140 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "krb5/gsskrb5_locl.h"
+#include "gsskrb5_locl.h"
 
 RCSID("$Id$");
 
 
 RCSID("$Id$");
 
index 6c1c5949e02dc678962961ac4783e2dfb9b5a615..b28e6a4c12b536e997a47895fd5b8d23ca0da8d2 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "krb5/gsskrb5_locl.h"
+#include "gsskrb5_locl.h"
 
 RCSID("$Id$");
 
 
 RCSID("$Id$");
 
index dfa0e935e6c700822d6ed75de8cfbbf8d024cef1..4b632bd95ac768852df380b9951eca4ace827468 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "krb5/gsskrb5_locl.h"
+#include "gsskrb5_locl.h"
 
 RCSID("$Id$");
 
 
 RCSID("$Id$");
 
@@ -131,6 +131,7 @@ _gsskrb5_create_ctx(
     krb5_data_zero(&ctx->fwd_data);
     ctx->lifetime              = GSS_C_INDEFINITE;
     ctx->order                 = NULL;
     krb5_data_zero(&ctx->fwd_data);
     ctx->lifetime              = GSS_C_INDEFINITE;
     ctx->order                 = NULL;
+    ctx->crypto                        = NULL;
     HEIMDAL_MUTEX_init(&ctx->ctx_id_mutex);
 
     kret = krb5_auth_con_init (context, &ctx->auth_context);
     HEIMDAL_MUTEX_init(&ctx->ctx_id_mutex);
 
     kret = krb5_auth_con_init (context, &ctx->auth_context);
@@ -257,7 +258,8 @@ gsskrb5_initiator_ready(
 
     krb5_auth_getremoteseqnumber (context, ctx->auth_context, &seq_number);
 
 
     krb5_auth_getremoteseqnumber (context, ctx->auth_context, &seq_number);
 
-    _gsskrb5i_is_cfx(ctx, &is_cfx);
+    _gsskrb5i_is_cfx(context, ctx, 0);
+    is_cfx = (ctx->more_flags & IS_CFX);
 
     ret = _gssapi_msg_order_create(minor_status,
                                   &ctx->order,
 
     ret = _gssapi_msg_order_create(minor_status,
                                   &ctx->order,
@@ -552,8 +554,10 @@ init_auth_restart
        flags |= GSS_C_REPLAY_FLAG;
     if (req_flags & GSS_C_SEQUENCE_FLAG)
        flags |= GSS_C_SEQUENCE_FLAG;
        flags |= GSS_C_REPLAY_FLAG;
     if (req_flags & GSS_C_SEQUENCE_FLAG)
        flags |= GSS_C_SEQUENCE_FLAG;
+#if 0
     if (req_flags & GSS_C_ANON_FLAG)
        ;                               /* XXX */
     if (req_flags & GSS_C_ANON_FLAG)
        ;                               /* XXX */
+#endif
     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;
     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;
@@ -686,7 +690,6 @@ repl_mutual
     krb5_error_code kret;
     krb5_data indata;
     krb5_ap_rep_enc_part *repl;
     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;
 
     output_token->length = 0;
     output_token->value = NULL;
@@ -759,20 +762,6 @@ repl_mutual
     krb5_free_ap_rep_enc_part (context,
                               repl);
 
     krb5_free_ap_rep_enc_part (context,
                               repl);
 
-    _gsskrb5i_is_cfx(ctx, &is_cfx);
-    if (is_cfx) {
-       krb5_keyblock *key = NULL;
-
-       kret = krb5_auth_con_getremotesubkey(context,
-                                            ctx->auth_context,
-                                            &key);
-       if (kret == 0 && key != NULL) {
-           ctx->more_flags |= ACCEPTOR_SUBKEY;
-           krb5_free_keyblock (context, key);
-       }
-    }
-
-
     *minor_status = 0;
     if (time_rec) {
        ret = _gsskrb5_lifetime_left(minor_status,
     *minor_status = 0;
     if (time_rec) {
        ret = _gsskrb5_lifetime_left(minor_status,
index e0aeb032cea4cf8cb1aea19fa908f6efe85c4ba8..188a6135a4b1cd14793c6a8a1e54d4a9663e0398 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "krb5/gsskrb5_locl.h"
+#include "gsskrb5_locl.h"
 
 RCSID("$Id$");
 
 
 RCSID("$Id$");
 
index bb75978adbbf22abed8b8fbc64719de8504b0203..27e3014923602ac1ebda43479267dea25db67869 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "krb5/gsskrb5_locl.h"
+#include "gsskrb5_locl.h"
 
 RCSID("$Id$");
 
 
 RCSID("$Id$");
 
index cdf05d79340a286b0fabb68f895d4289ba130bbd..1fd973394093638af1758247941574f5af84073b 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "krb5/gsskrb5_locl.h"
+#include "gsskrb5_locl.h"
 
 RCSID("$Id$");
 
 
 RCSID("$Id$");
 
index 2bcc17683b401aaf0dcc780264d5a7a962e2637a..5a35202a6a04d9a26c037f4327e01f2ed23df9dc 100644 (file)
@@ -30,7 +30,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "krb5/gsskrb5_locl.h"
+#include "gsskrb5_locl.h"
 
 RCSID("$Id$");
 
 
 RCSID("$Id$");
 
index 4fd730deab73346a777c421c240049a1ea743a84..5d54bd65086792eeef84a524809c5cd1c931e5f5 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "krb5/gsskrb5_locl.h"
+#include "gsskrb5_locl.h"
 
 RCSID("$Id$");
 
 
 RCSID("$Id$");
 
index a9d6495c7b516e78e813e4e5e7d3361ef6ead56b..9eba7b7f4ddc8586f9f5ac6df70bbd03a89b09ed 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "krb5/gsskrb5_locl.h"
+#include "gsskrb5_locl.h"
 
 RCSID("$Id$");
 
 
 RCSID("$Id$");
 
index 8d40706294554201b4d15e8c8fe9748f307c2c70..f8ef2a3aa4e0719dde8b1a21c4bdcdf15d352be9 100644 (file)
@@ -30,7 +30,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "krb5/gsskrb5_locl.h"
+#include "gsskrb5_locl.h"
 
 RCSID("$Id$");
 
 
 RCSID("$Id$");
 
@@ -242,7 +242,7 @@ static OM_uint32 inquire_sec_context_has_updated_spnego
      * mechanism.
      */
     HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
      * mechanism.
      */
     HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
-    _gsskrb5i_is_cfx(context_handle, &is_updated);
+    is_updated = (context_handle->more_flags & IS_CFX);
     if (is_updated == 0) {
        krb5_keyblock *acceptor_subkey;
 
     if (is_updated == 0) {
        krb5_keyblock *acceptor_subkey;
 
@@ -282,7 +282,7 @@ export_lucid_sec_context_v1(OM_uint32 *minor_status,
 
     HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
 
 
     HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
 
-    _gsskrb5i_is_cfx(context_handle, &is_cfx);
+    is_cfx = (context_handle->more_flags & IS_CFX);
 
     sp = krb5_storage_emem();
     if (sp == NULL) {
 
     sp = krb5_storage_emem();
     if (sp == NULL) {
@@ -445,6 +445,7 @@ get_service_keyblock
     HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
     if (ctx->service_keyblock == NULL) {
        HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
     HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
     if (ctx->service_keyblock == NULL) {
        HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+       krb5_storage_free(sp);
        _gsskrb5_set_status(EINVAL, "No service keyblock on gssapi context");
        *minor_status = EINVAL;
        return GSS_S_FAILURE;
        _gsskrb5_set_status(EINVAL, "No service keyblock on gssapi context");
        *minor_status = EINVAL;
        return GSS_S_FAILURE;
index 9cbe6034357f9031d463e306ef7ffdb9a20b15dd..9fd13f51bd27b7318417fb6e3af9aa1d593e0b38 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "krb5/gsskrb5_locl.h"
+#include "gsskrb5_locl.h"
 
 RCSID("$Id$");
 
 
 RCSID("$Id$");
 
index 6892d3ca604f592d76ecc98d00f6646c97378ff9..3229b36292b1007175ed5c8aaddc6c3c55b0ef99 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "krb5/gsskrb5_locl.h"
+#include "gsskrb5_locl.h"
 
 RCSID("$Id$");
 
 
 RCSID("$Id$");
 
@@ -44,15 +44,12 @@ OM_uint32 _gsskrb5_process_context_token (
     krb5_context context;
     OM_uint32 ret = GSS_S_FAILURE;
     gss_buffer_desc empty_buffer;
     krb5_context context;
     OM_uint32 ret = GSS_S_FAILURE;
     gss_buffer_desc empty_buffer;
-    gss_qop_t qop_state;
 
     empty_buffer.length = 0;
     empty_buffer.value = NULL;
 
     GSSAPI_KRB5_INIT (&context);
 
 
     empty_buffer.length = 0;
     empty_buffer.value = NULL;
 
     GSSAPI_KRB5_INIT (&context);
 
-    qop_state = GSS_C_QOP_DEFAULT;
-
     ret = _gsskrb5_verify_mic_internal(minor_status,
                                       (gsskrb5_ctx)context_handle,
                                       context,
     ret = _gsskrb5_verify_mic_internal(minor_status,
                                       (gsskrb5_ctx)context_handle,
                                       context,
index a0f37c06f4cf02e2c0a22394702f8f434bea3c7b..18e0279939730f958701f3889dffaf09414e0aba 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "krb5/gsskrb5_locl.h"
+#include "gsskrb5_locl.h"
 
 RCSID("$Id$");
 
 
 RCSID("$Id$");
 
index 5a0ec829d224e08c7e1c702ca036ecf7cdd47504..62674a1d530870c23d334cf0806009efad2c0a99 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "krb5/gsskrb5_locl.h"
+#include "gsskrb5_locl.h"
 
 RCSID("$Id$");
 
 
 RCSID("$Id$");
 
@@ -61,8 +61,6 @@ OM_uint32 _gsskrb5_release_cred
     if (cred->keytab != NULL)
        krb5_kt_close(context, cred->keytab);
     if (cred->ccache != NULL) {
     if (cred->keytab != NULL)
        krb5_kt_close(context, cred->keytab);
     if (cred->ccache != NULL) {
-       const krb5_cc_ops *ops;
-       ops = krb5_cc_get_ops(context, cred->ccache);
        if (cred->cred_flags & GSS_CF_DESTROY_CRED_ON_RELEASE)
            krb5_cc_destroy(context, cred->ccache);
        else
        if (cred->cred_flags & GSS_CF_DESTROY_CRED_ON_RELEASE)
            krb5_cc_destroy(context, cred->ccache);
        else
index d39c7054332a78d82b9767c33370840ef9a54385..5491052c59378b9b7608833db13fc1ec5d570490 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "krb5/gsskrb5_locl.h"
+#include "gsskrb5_locl.h"
 
 RCSID("$Id$");
 
 
 RCSID("$Id$");
 
index 61164ffec113e1fb821513bc13bfa82354ccfdd4..6391d44429d46be458003a0c04805dd6f2993aa9 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "krb5/gsskrb5_locl.h"
+#include "gsskrb5_locl.h"
 
 RCSID("$Id$");
 
 
 RCSID("$Id$");
 
index e47e6fdb6ce0bcfda6939edaeec0bec96f9ece7c..2a2390f8d1f3a86870c4d4a69ea2ac44a1eb2e53 100644 (file)
@@ -30,7 +30,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "krb5/gsskrb5_locl.h"
+#include "gsskrb5_locl.h"
 
 RCSID("$Id$");
 
 
 RCSID("$Id$");
 
index 6591ab04dd63027232f0ea6379a91b5d348cb80b..460cfe942ad2736e16dd4696b7c9730b7a70c222 100644 (file)
@@ -34,7 +34,7 @@
  *  glue routine for _gsskrb5_inquire_sec_context_by_oid
  */
 
  *  glue routine for _gsskrb5_inquire_sec_context_by_oid
  */
 
-#include "krb5/gsskrb5_locl.h"
+#include "gsskrb5_locl.h"
 
 RCSID("$Id$");
 
 
 RCSID("$Id$");
 
index f34f72542ea7e967a7230d5303fcd1cc0b19ee2f..0e87cb88b73d8682f897cbbb22239cca8551bf10 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "krb5/gsskrb5_locl.h"
+#include "gsskrb5_locl.h"
 
 RCSID("$Id$");
 
 
 RCSID("$Id$");
 
@@ -393,11 +393,16 @@ OM_uint32 _gsskrb5_unwrap
 
   output_message_buffer->value = NULL;
   output_message_buffer->length = 0;
 
   output_message_buffer->value = NULL;
   output_message_buffer->length = 0;
+  if (qop_state != NULL)
+      *qop_state = GSS_C_QOP_DEFAULT;
 
   GSSAPI_KRB5_INIT (&context);
 
 
   GSSAPI_KRB5_INIT (&context);
 
-  if (qop_state != NULL)
-      *qop_state = GSS_C_QOP_DEFAULT;
+  if (ctx->more_flags & IS_CFX)
+      return _gssapi_unwrap_cfx (minor_status, ctx, context,
+                                input_message_buffer, output_message_buffer,
+                                conf_state, qop_state);
+
   HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
   ret = _gsskrb5i_get_token_key(ctx, context, &key);
   HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
   HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
   ret = _gsskrb5i_get_token_key(ctx, context, &key);
   HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
@@ -427,9 +432,7 @@ OM_uint32 _gsskrb5_unwrap
                                    conf_state, qop_state, key);
       break;
   default :
                                    conf_state, qop_state, key);
       break;
   default :
-      ret = _gssapi_unwrap_cfx (minor_status, ctx, context,
-                               input_message_buffer, output_message_buffer,
-                               conf_state, qop_state, key);
+      abort();
       break;
   }
   krb5_free_keyblock (context, key);
       break;
   }
   krb5_free_keyblock (context, key);
index 1832d35b5afe8d6c6a6c5c83545134d10b0b49c1..6eb7ae4b089fee2f3aabc3b626ef1b5ebfda4753 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "krb5/gsskrb5_locl.h"
+#include "gsskrb5_locl.h"
 
 RCSID("$Id$");
 
 
 RCSID("$Id$");
 
@@ -266,7 +266,7 @@ retry:
 OM_uint32
 _gsskrb5_verify_mic_internal
            (OM_uint32 * minor_status,
 OM_uint32
 _gsskrb5_verify_mic_internal
            (OM_uint32 * minor_status,
-            const gsskrb5_ctx context_handle,
+            const gsskrb5_ctx ctx,
            krb5_context context,
             const gss_buffer_t message_buffer,
             const gss_buffer_t token_buffer,
            krb5_context context,
             const gss_buffer_t message_buffer,
             const gss_buffer_t token_buffer,
@@ -278,9 +278,14 @@ _gsskrb5_verify_mic_internal
     OM_uint32 ret;
     krb5_keytype keytype;
 
     OM_uint32 ret;
     krb5_keytype keytype;
 
-    HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
-    ret = _gsskrb5i_get_token_key(context_handle, context, &key);
-    HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+    if (ctx->more_flags & IS_CFX)
+        return _gssapi_verify_mic_cfx (minor_status, ctx,
+                                      context, message_buffer, token_buffer,
+                                      qop_state);
+
+    HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+    ret = _gsskrb5i_get_token_key(ctx, context, &key);
+    HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
     if (ret) {
        *minor_status = ret;
        return GSS_S_FAILURE;
     if (ret) {
        *minor_status = ret;
        return GSS_S_FAILURE;
@@ -289,28 +294,24 @@ _gsskrb5_verify_mic_internal
     krb5_enctype_to_keytype (context, key->keytype, &keytype);
     switch (keytype) {
     case KEYTYPE_DES :
     krb5_enctype_to_keytype (context, key->keytype, &keytype);
     switch (keytype) {
     case KEYTYPE_DES :
-       ret = verify_mic_des (minor_status, context_handle, context,
+       ret = verify_mic_des (minor_status, ctx, context,
                              message_buffer, token_buffer, qop_state, key,
                              type);
        break;
     case KEYTYPE_DES3 :
                              message_buffer, token_buffer, qop_state, key,
                              type);
        break;
     case KEYTYPE_DES3 :
-       ret = verify_mic_des3 (minor_status, context_handle, context,
+       ret = verify_mic_des3 (minor_status, ctx, context,
                               message_buffer, token_buffer, qop_state, key,
                               type);
        break;
     case KEYTYPE_ARCFOUR :
     case KEYTYPE_ARCFOUR_56 :
                               message_buffer, token_buffer, qop_state, key,
                               type);
        break;
     case KEYTYPE_ARCFOUR :
     case KEYTYPE_ARCFOUR_56 :
-       ret = _gssapi_verify_mic_arcfour (minor_status, context_handle,
+       ret = _gssapi_verify_mic_arcfour (minor_status, ctx,
                                          context,
                                          message_buffer, token_buffer,
                                          qop_state, key, type);
        break;
     default :
                                          context,
                                          message_buffer, token_buffer,
                                          qop_state, key, type);
        break;
     default :
-       ret = _gssapi_verify_mic_cfx (minor_status, context_handle,
-                                     context,
-                                     message_buffer, token_buffer, qop_state,
-                                     key);
-       break;
+        abort();
     }
     krb5_free_keyblock (context, key);
 
     }
     krb5_free_keyblock (context, key);
 
index ad21bcb57bd371a843f1ff2c03c56f9e69581f00..b9f4c237c767d540e124abb2c3e34aaa0593eb31 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "krb5/gsskrb5_locl.h"
+#include "gsskrb5_locl.h"
 
 RCSID("$Id$");
 
 
 RCSID("$Id$");
 
@@ -154,6 +154,11 @@ _gsskrb5_wrap_size_limit (
 
   GSSAPI_KRB5_INIT (&context);
 
 
   GSSAPI_KRB5_INIT (&context);
 
+  if (ctx->more_flags & IS_CFX)
+      return _gssapi_wrap_size_cfx(minor_status, ctx, context,
+                                  conf_req_flag, qop_req,
+                                  req_output_size, max_input_size);
+
   HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
   ret = _gsskrb5i_get_token_key(ctx, context, &key);
   HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
   HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
   ret = _gsskrb5i_get_token_key(ctx, context, &key);
   HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
@@ -177,9 +182,7 @@ _gsskrb5_wrap_size_limit (
       ret = sub_wrap_size(req_output_size, max_input_size, 8, 34);
       break;
   default :
       ret = sub_wrap_size(req_output_size, max_input_size, 8, 34);
       break;
   default :
-      ret = _gssapi_wrap_size_cfx(minor_status, ctx, context,
-                                 conf_req_flag, qop_req,
-                                 req_output_size, max_input_size, key);
+      abort();
       break;
   }
   krb5_free_keyblock (context, key);
       break;
   }
   krb5_free_keyblock (context, key);
@@ -530,8 +533,16 @@ OM_uint32 _gsskrb5_wrap
   krb5_keytype keytype;
   const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle;
 
   krb5_keytype keytype;
   const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle;
 
+  output_message_buffer->value = NULL;
+  output_message_buffer->length = 0;
+
   GSSAPI_KRB5_INIT (&context);
 
   GSSAPI_KRB5_INIT (&context);
 
+  if (ctx->more_flags & IS_CFX)
+      return _gssapi_wrap_cfx (minor_status, ctx, context, conf_req_flag,
+                              qop_req, input_message_buffer, conf_state,
+                              output_message_buffer);
+
   HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
   ret = _gsskrb5i_get_token_key(ctx, context, &key);
   HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
   HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
   ret = _gsskrb5i_get_token_key(ctx, context, &key);
   HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
@@ -559,9 +570,7 @@ OM_uint32 _gsskrb5_wrap
                                  output_message_buffer, key);
       break;
   default :
                                  output_message_buffer, key);
       break;
   default :
-      ret = _gssapi_wrap_cfx (minor_status, ctx, context, conf_req_flag,
-                             qop_req, input_message_buffer, conf_state,
-                             output_message_buffer, key);
+      abort();
       break;
   }
   krb5_free_keyblock (context, key);
       break;
   }
   krb5_free_keyblock (context, key);
index a06a1e9e37a7b5484ac508d337db00c6bc05b71c..b032d8aa0e1fe6e28f659ce075148174fcc22f37 100644 (file)
@@ -1,4 +1,4 @@
-#include "mech/mech_locl.h"
+#include "mech_locl.h"
 #include "heim_threads.h"
 
 RCSID("$Id$");
 #include "heim_threads.h"
 
 RCSID("$Id$");
index 50011a9b0d72c658f228187e2c5d6fe60cc4b093..134511f34b0106fde94011257d58a14c64f5b1c8 100644 (file)
@@ -260,7 +260,8 @@ OM_uint32 gss_accept_sec_context(OM_uint32 *minor_status,
        if (mech_ret_flags & GSS_C_DELEG_FLAG) {
                if (!delegated_cred_handle) {
                        m->gm_release_cred(minor_status, &delegated_mc);
        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;
+                       if (ret_flags)
+                               *ret_flags &= ~GSS_C_DELEG_FLAG;
                } else if (delegated_mc) {
                        struct _gss_cred *dcred;
                        struct _gss_mechanism_cred *dmc;
                } else if (delegated_mc) {
                        struct _gss_cred *dcred;
                        struct _gss_mechanism_cred *dmc;
index b21b3f62e842406de97c2edeec70fe6adf90c9b7..a8ebe644ab239c88d18e3b76f610e233e2bbe43c 100644 (file)
@@ -51,7 +51,7 @@ gss_acquire_cred(OM_uint32 *minor_status,
 
        *minor_status = 0;
        if (output_cred_handle)
 
        *minor_status = 0;
        if (output_cred_handle)
-           *output_cred_handle = GSS_C_NO_CREDENTIAL;
+           return GSS_S_CALL_INACCESSIBLE_READ;
        if (actual_mechs)
            *actual_mechs = GSS_C_NO_OID_SET;
        if (time_rec)
        if (actual_mechs)
            *actual_mechs = GSS_C_NO_OID_SET;
        if (time_rec)
diff --git a/source4/heimdal/lib/gssapi/mech/gss_aeap.c b/source4/heimdal/lib/gssapi/mech/gss_aeap.c
new file mode 100644 (file)
index 0000000..cbe0cd1
--- /dev/null
@@ -0,0 +1,184 @@
+/*
+ * AEAD support
+ */ 
+
+#include "mech_locl.h"
+RCSID("$Id$");
+
+/**
+ * Encrypts or sign the data.
+ *
+ * The maximum packet size is gss_context_stream_sizes.max_msg_size.
+ *
+ * The caller needs provide the folloing buffers:
+ *
+ * - HEADER (of size gss_context_stream_sizes.header)
+ *   SIGN_ONLY (optional, zero or more)
+ *   DATA
+ *   SIGN_ONLY (optional, zero or more)
+ *   PADDING (of size gss_context_stream_sizes.blocksize)
+ *   TRAILER (of size gss_context_stream_sizes.trailer)
+ *
+ * - on DCE-RPC mode, the caller can skip PADDING and TRAILER if the
+ *   DATA elements is padded to a block bountry.
+ *
+ * To generate gss_wrap() compatible packets, use: HEADER | DATA | PADDING | TRAILER
+ *
+ * The input sizes of HEADER, PADDING and TRAILER can be fetched using gss_wrap_iov_length() or
+ * gss_context_query_attributes().
+ *
+ * @ingroup gssapi
+ */
+
+
+OM_uint32 GSSAPI_LIB_FUNCTION
+gss_wrap_iov(OM_uint32 * minor_status,
+            gss_ctx_id_t  context_handle,
+            int conf_req_flag,
+            gss_qop_t qop_req,
+            int * conf_state,
+            gss_iov_buffer_desc *iov,
+            int iov_count)
+{
+       struct _gss_context *ctx = (struct _gss_context *) context_handle;
+       gssapi_mech_interface m;
+
+       if (minor_status)
+           *minor_status = 0;
+       if (conf_state)
+           *conf_state = 0;
+       if (ctx == NULL)
+           return GSS_S_NO_CONTEXT;
+       if (iov == NULL && iov_count != 0)
+           return GSS_S_CALL_INACCESSIBLE_READ;
+
+       m = ctx->gc_mech;
+
+       if (m->gm_wrap_iov == NULL) {
+           if (minor_status)
+               *minor_status = 0;
+           return GSS_S_UNAVAILABLE;
+       }
+
+       return (m->gm_wrap_iov)(minor_status, ctx->gc_ctx,
+                               conf_req_flag, qop_req, conf_state,
+                               iov, iov_count);
+}
+
+OM_uint32 GSSAPI_LIB_FUNCTION
+gss_unwrap_iov(OM_uint32 *minor_status,
+              gss_ctx_id_t context_handle,
+              int *conf_state,
+              gss_qop_t *qop_state,
+              gss_iov_buffer_desc *iov,
+              int iov_count)
+{
+       struct _gss_context *ctx = (struct _gss_context *) context_handle;
+       gssapi_mech_interface m;          
+
+       if (minor_status)
+           *minor_status = 0;
+       if (conf_state)
+           *conf_state = 0;
+       if (qop_state)
+           *qop_state = 0;
+       if (ctx == NULL)
+           return GSS_S_NO_CONTEXT;
+       if (iov == NULL && iov_count != 0)
+           return GSS_S_CALL_INACCESSIBLE_READ;
+
+       m = ctx->gc_mech;
+
+       if (m->gm_unwrap_iov == NULL) {
+           *minor_status = 0;
+           return GSS_S_UNAVAILABLE;
+       }
+
+       return (m->gm_unwrap_iov)(minor_status, ctx->gc_ctx,
+                                 conf_state, qop_state,
+                                 iov, iov_count);
+}
+
+OM_uint32  GSSAPI_LIB_FUNCTION
+gss_wrap_iov_length(OM_uint32 * minor_status,
+                   gss_ctx_id_t context_handle,
+                   int conf_req_flag,
+                   gss_qop_t qop_req,
+                   int *conf_state,
+                   gss_iov_buffer_desc *iov,
+                   int iov_count)
+{
+       struct _gss_context *ctx = (struct _gss_context *) context_handle;
+       gssapi_mech_interface m;
+
+       if (minor_status)
+           *minor_status = 0;
+       if (conf_state)
+           *conf_state = 0;
+       if (ctx == NULL)
+           return GSS_S_NO_CONTEXT;
+       if (iov == NULL && iov_count != 0)
+           return GSS_S_CALL_INACCESSIBLE_READ;
+
+       m = ctx->gc_mech;
+
+       if (m->gm_wrap_iov_length == NULL) {
+           *minor_status = 0;
+           return GSS_S_UNAVAILABLE;
+       }
+
+       return (m->gm_wrap_iov_length)(minor_status, ctx->gc_ctx,
+                                      conf_req_flag, qop_req, conf_state,
+                                      iov, iov_count);
+}
+
+OM_uint32 GSSAPI_LIB_FUNCTION
+gss_release_iov_buffer(OM_uint32 *minor_status,
+                      gss_iov_buffer_desc *iov,
+                      int iov_count)
+{
+    OM_uint32 junk;
+    size_t i;
+
+    if (minor_status)
+       *minor_status = 0;
+    if (iov == NULL && iov_count != 0)
+       return GSS_S_CALL_INACCESSIBLE_READ;
+
+    for (i = 0; i < iov_count; i++) {
+       if (iov[i].type & GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATED)
+           continue;
+       gss_release_buffer(&junk, &iov[i].buffer);
+    }
+    return GSS_S_COMPLETE;
+}
+
+/**
+ * Query the context for parameters.
+ *
+ * SSPI equivalent if this function is QueryContextAttributes.
+ *
+ * - GSS_C_ATTR_STREAM_SIZES data is a gss_context_stream_sizes.
+ */
+
+static gss_OID_desc gss_c_attr_stream_sizes_desc =
+    {10, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x03")};
+
+gss_OID GSSAPI_LIB_VARIABLE GSS_C_ATTR_STREAM_SIZES =
+    &gss_c_attr_stream_sizes_desc;
+
+OM_uint32 GSSAPI_LIB_FUNCTION
+gss_context_query_attributes(OM_uint32 *minor_status,
+                            gss_OID attribute,
+                            void *data,
+                            size_t len)
+{
+    *minor_status = 0;
+
+    if (gss_oid_equal(GSS_C_ATTR_STREAM_SIZES, attribute)) {
+       memset(data, 0, len);
+       return GSS_S_COMPLETE;
+    }
+
+    return GSS_S_FAILURE;
+}
index 91a08fb2bcb3e6d6352b1e10bf1a54a1c4222d2f..db976f2453ef33a349fd68c1dfdc07bb5880c1d9 100644 (file)
 #include "mech_locl.h"
 RCSID("$Id$");
 
 #include "mech_locl.h"
 RCSID("$Id$");
 
+/**
+ *  gss_canonicalize_name takes a Internal Name (IN) and converts in into a
+ *  mechanism specific Mechanism Name (MN).
+ *
+ *  The input name may multiple name, or generic name types.
+ *
+ *  If the input_name if of the GSS_C_NT_USER_NAME, and the Kerberos
+ *  mechanism is specified, the resulting MN type is a
+ *  GSS_KRB5_NT_PRINCIPAL_NAME.
+ *
+ *  For more information about @ref internalVSmechname.
+ *
+ *  @param minor_status minor status code.
+ *  @param input_name name to covert, unchanged by gss_canonicalize_name().
+ *  @param mech_type the type to convert Name too.
+ *  @param output_name the resulting type, release with
+ *         gss_release_name(), independent of input_name.
+ *
+ *  @returns a gss_error code, see gss_display_status() about printing
+ *         the error code.
+ *       
+ *  @ingroup gssapi
+ */
+
 OM_uint32 GSSAPI_LIB_FUNCTION
 gss_canonicalize_name(OM_uint32 *minor_status,
     const gss_name_t input_name,
 OM_uint32 GSSAPI_LIB_FUNCTION
 gss_canonicalize_name(OM_uint32 *minor_status,
     const gss_name_t input_name,
index 9cd5060fc941bf7e9786d1410093b1571a096243..3a0f3fb757b9ebb851a7dd8075531d5b21e545bc 100644 (file)
@@ -37,7 +37,7 @@ gss_get_mic(OM_uint32 *minor_status,
     gss_buffer_t message_token)
 {
        struct _gss_context *ctx = (struct _gss_context *) context_handle;
     gss_buffer_t message_token)
 {
        struct _gss_context *ctx = (struct _gss_context *) context_handle;
-       gssapi_mech_interface m = ctx->gc_mech;
+       gssapi_mech_interface m;
 
        _mg_buffer_zero(message_token);
        if (ctx == NULL) {
 
        _mg_buffer_zero(message_token);
        if (ctx == NULL) {
@@ -45,6 +45,8 @@ gss_get_mic(OM_uint32 *minor_status,
            return GSS_S_NO_CONTEXT;
        }
 
            return GSS_S_NO_CONTEXT;
        }
 
+       m = ctx->gc_mech;
+
        return (m->gm_get_mic(minor_status, ctx->gc_ctx, qop_req,
                    message_buffer, message_token));
 }
        return (m->gm_get_mic(minor_status, ctx->gc_ctx, qop_req,
                    message_buffer, message_token));
 }
index 040e2284105b95c2046decf4a204a7defd96097d..c1dffdc614cb7bd8991314cc09eb97dfcf8259a6 100644 (file)
@@ -145,9 +145,12 @@ gss_import_name(OM_uint32 *minor_status,
     const gss_OID input_name_type,
     gss_name_t *output_name)
 {
     const gss_OID input_name_type,
     gss_name_t *output_name)
 {
+        struct _gss_mechanism_name *mn;
        gss_OID                 name_type = input_name_type;
        gss_OID                 name_type = input_name_type;
-       OM_uint32               major_status;
+       OM_uint32               major_status, ms;
        struct _gss_name        *name;
        struct _gss_name        *name;
+        struct _gss_mech_switch        *m;
+       gss_name_t              rname;
 
        *output_name = GSS_C_NO_NAME;
 
 
        *output_name = GSS_C_NO_NAME;
 
@@ -156,6 +159,8 @@ gss_import_name(OM_uint32 *minor_status,
                return (GSS_S_BAD_NAME);
        }
 
                return (GSS_S_BAD_NAME);
        }
 
+       _gss_load_mech();
+
        /*
         * Use GSS_NT_USER_NAME as default name type.
         */
        /*
         * Use GSS_NT_USER_NAME as default name type.
         */
@@ -172,29 +177,15 @@ gss_import_name(OM_uint32 *minor_status,
                    input_name_buffer, output_name);
        }
 
                    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;
-               return (GSS_S_BAD_NAMETYPE);
-       }
 
        *minor_status = 0;
 
        *minor_status = 0;
-       name = malloc(sizeof(struct _gss_name));
+       name = calloc(1, sizeof(struct _gss_name));
        if (!name) {
                *minor_status = ENOMEM;
                return (GSS_S_FAILURE);
        }
        if (!name) {
                *minor_status = ENOMEM;
                return (GSS_S_FAILURE);
        }
-       memset(name, 0, sizeof(struct _gss_name));
+
+       SLIST_INIT(&name->gn_mn);
 
        major_status = _gss_copy_oid(minor_status,
            name_type, &name->gn_type);
 
        major_status = _gss_copy_oid(minor_status,
            name_type, &name->gn_type);
@@ -205,14 +196,62 @@ gss_import_name(OM_uint32 *minor_status,
 
        major_status = _gss_copy_buffer(minor_status,
            input_name_buffer, &name->gn_value);
 
        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);
+       if (major_status)
+               goto out;
+
+       /*
+        * Walk over the mechs and import the name into a mech name
+        * for those supported this nametype.
+        */
+
+       SLIST_FOREACH(m, &_gss_mechs, gm_link) {
+               int present = 0;
+
+               major_status = gss_test_oid_set_member(minor_status, 
+                   name_type, m->gm_name_types, &present);
+
+               if (major_status || present == 0)
+                       continue;
+
+               mn = malloc(sizeof(struct _gss_mechanism_name));
+               if (!mn) {
+                       *minor_status = ENOMEM;
+                       major_status = GSS_S_FAILURE;
+                       goto out;
+               }
+
+               major_status = (*m->gm_mech.gm_import_name)(minor_status,
+                   &name->gn_value,
+                   (name->gn_type.elements
+                       ? &name->gn_type : GSS_C_NO_OID),
+                   &mn->gmn_name);
+               if (major_status != GSS_S_COMPLETE) {
+                       _gss_mg_error(&m->gm_mech, major_status, *minor_status);
+                       free(mn);
+                       goto out;
+               }
+
+               mn->gmn_mech = &m->gm_mech;
+               mn->gmn_mech_oid = &m->gm_mech_oid;
+               SLIST_INSERT_HEAD(&name->gn_mn, mn, gmn_link);
        }
 
        }
 
-       SLIST_INIT(&name->gn_mn);
+       /*
+        * If we can't find a mn for the name, bail out already here.
+        */
+
+       mn = SLIST_FIRST(&name->gn_mn);
+       if (!mn) {
+               *minor_status = 0;
+               major_status = GSS_S_NAME_NOT_MN;
+               goto out;
+       }
 
        *output_name = (gss_name_t) name;
        return (GSS_S_COMPLETE);
 
        *output_name = (gss_name_t) name;
        return (GSS_S_COMPLETE);
+
+ out:
+       rname = (gss_name_t)name;
+       gss_release_name(&ms, &rname);
+       return major_status;
 }
 }
index 5318f6cdbaaaaf17328c9103e4fd1dda05cb7a20..5d883c45c2a9d98ffab9410a5cbeb4beff2459a5 100644 (file)
@@ -278,7 +278,7 @@ gss_krb5_export_lucid_sec_context(OM_uint32 *minor_status,
        || *context_handle == GSS_C_NO_CONTEXT
        || version != 1)
     {
        || *context_handle == GSS_C_NO_CONTEXT
        || version != 1)
     {
-       ret = EINVAL;
+       *minor_status = EINVAL;
        return GSS_S_FAILURE;
     }
 
        return GSS_S_FAILURE;
     }
 
@@ -715,7 +715,7 @@ gsskrb5_extract_key(OM_uint32 *minor_status,
     krb5_storage *sp = NULL;
 
     if (context_handle == GSS_C_NO_CONTEXT) {
     krb5_storage *sp = NULL;
 
     if (context_handle == GSS_C_NO_CONTEXT) {
-       ret = EINVAL;
+       *minor_status = EINVAL;
        return GSS_S_FAILURE;
     }
 
        return GSS_S_FAILURE;
     }
 
index fc2e8816c5fceea0632d0ed0d83ab88b61604af1..3321819d28fc1db6d45eaa0a116d9b3ab1f15fd7 100644 (file)
@@ -186,6 +186,15 @@ add_builtin(gssapi_mech_interface mech)
     gss_add_oid_set_member(&minor_status,
                           &m->gm_mech.gm_mech_oid, &_gss_mech_oids);
 
     gss_add_oid_set_member(&minor_status,
                           &m->gm_mech.gm_mech_oid, &_gss_mech_oids);
 
+    /* pick up the oid sets of names */
+
+    if (m->gm_mech.gm_inquire_names_for_mech) {
+       (*m->gm_mech.gm_inquire_names_for_mech)(&minor_status,
+           &m->gm_mech.gm_mech_oid, &m->gm_name_types);
+    } else {
+       gss_create_empty_oid_set(&minor_status, &m->gm_name_types);
+    }
+
     SLIST_INSERT_HEAD(&_gss_mechs, m, gm_link);
     return 0;
 }
     SLIST_INSERT_HEAD(&_gss_mechs, m, gm_link);
     return 0;
 }
@@ -221,9 +230,7 @@ _gss_load_mech(void)
 
        add_builtin(__gss_krb5_initialize());
        add_builtin(__gss_spnego_initialize());
 
        add_builtin(__gss_krb5_initialize());
        add_builtin(__gss_spnego_initialize());
-#ifndef HEIMDAL_SMALLER
        add_builtin(__gss_ntlm_initialize());
        add_builtin(__gss_ntlm_initialize());
-#endif
 
 #ifdef HAVE_DLOPEN
        fp = fopen(_PATH_GSS_MECH, "r");
 
 #ifdef HAVE_DLOPEN
        fp = fopen(_PATH_GSS_MECH, "r");
@@ -308,6 +315,9 @@ _gss_load_mech(void)
                OPTSYM(set_sec_context_option);
                OPTSYM(set_cred_option);
                OPTSYM(pseudo_random);
                OPTSYM(set_sec_context_option);
                OPTSYM(set_cred_option);
                OPTSYM(pseudo_random);
+               OPTSYM(wrap_iov);
+               OPTSYM(unwrap_iov);
+               OPTSYM(wrap_iov_length);
 
                SLIST_INSERT_HEAD(&_gss_mechs, m, gm_link);
                continue;
 
                SLIST_INSERT_HEAD(&_gss_mechs, m, gm_link);
                continue;
index b907f94038bbd82a30cad1e065e1a7616a8b3ad1..771efcb4342dd07b708cf70a267983d075e98367 100644 (file)
@@ -45,7 +45,7 @@ gss_pseudo_random(OM_uint32 *minor_status,
                  gss_buffer_t prf_out)
 {
     struct _gss_context *ctx = (struct _gss_context *) context;
                  gss_buffer_t prf_out)
 {
     struct _gss_context *ctx = (struct _gss_context *) context;
-    gssapi_mech_interface m = ctx->gc_mech;
+    gssapi_mech_interface m;
     OM_uint32 major_status;
 
     _mg_buffer_zero(prf_out);
     OM_uint32 major_status;
 
     _mg_buffer_zero(prf_out);
@@ -56,6 +56,8 @@ gss_pseudo_random(OM_uint32 *minor_status,
        return GSS_S_NO_CONTEXT;
     }
 
        return GSS_S_NO_CONTEXT;
     }
 
+    m = ctx->gc_mech;
+
     if (m->gm_pseudo_random == NULL)
        return GSS_S_UNAVAILABLE;
 
     if (m->gm_pseudo_random == NULL)
        return GSS_S_UNAVAILABLE;
 
index 1a411729c68ae3ea5d5fbb117fc021755fffcec0..60ef3bff85f1cf2206357633cb4222d37877b222 100644 (file)
@@ -37,7 +37,7 @@ gss_verify_mic(OM_uint32 *minor_status,
     gss_qop_t *qop_state)
 {
        struct _gss_context *ctx = (struct _gss_context *) context_handle;
     gss_qop_t *qop_state)
 {
        struct _gss_context *ctx = (struct _gss_context *) context_handle;
-       gssapi_mech_interface m = ctx->gc_mech;
+       gssapi_mech_interface m;
 
        if (qop_state)
            *qop_state = 0;
 
        if (qop_state)
            *qop_state = 0;
@@ -46,6 +46,8 @@ gss_verify_mic(OM_uint32 *minor_status,
            return GSS_S_NO_CONTEXT;
        }
 
            return GSS_S_NO_CONTEXT;
        }
 
+       m = ctx->gc_mech;
+
        return (m->gm_verify_mic(minor_status, ctx->gc_ctx,
                    message_buffer, token_buffer, qop_state));
 }
        return (m->gm_verify_mic(minor_status, ctx->gc_ctx,
                    message_buffer, token_buffer, qop_state));
 }
index b3363d3f207dbfd9457be6699d5ac030d6855f34..9476d01ddd898002c7d49b8caa08bffd9dc7e2f9 100644 (file)
@@ -39,7 +39,7 @@ gss_wrap(OM_uint32 *minor_status,
     gss_buffer_t output_message_buffer)
 {
        struct _gss_context *ctx = (struct _gss_context *) context_handle;
     gss_buffer_t output_message_buffer)
 {
        struct _gss_context *ctx = (struct _gss_context *) context_handle;
-       gssapi_mech_interface m = ctx->gc_mech;
+       gssapi_mech_interface m;
 
        if (conf_state)
            *conf_state = 0;
 
        if (conf_state)
            *conf_state = 0;
@@ -49,6 +49,8 @@ gss_wrap(OM_uint32 *minor_status,
            return GSS_S_NO_CONTEXT;
        }
 
            return GSS_S_NO_CONTEXT;
        }
 
+       m = ctx->gc_mech;
+
        return (m->gm_wrap(minor_status, ctx->gc_ctx,
                    conf_req_flag, qop_req, input_message_buffer,
                    conf_state, output_message_buffer));
        return (m->gm_wrap(minor_status, ctx->gc_ctx,
                    conf_req_flag, qop_req, input_message_buffer,
                    conf_state, output_message_buffer));
index 15b86a9367b4dcc547fcd95198a43dbb91a1a2c2..a5a80b21d7f0a440673beaba66bdf1021c04c3dc 100644 (file)
@@ -38,7 +38,7 @@ gss_wrap_size_limit(OM_uint32 *minor_status,
     OM_uint32 *max_input_size)
 {
        struct _gss_context *ctx = (struct _gss_context *) context_handle;
     OM_uint32 *max_input_size)
 {
        struct _gss_context *ctx = (struct _gss_context *) context_handle;
-       gssapi_mech_interface m = ctx->gc_mech;
+       gssapi_mech_interface m;
        
        *max_input_size = 0;
        if (ctx == NULL) {
        
        *max_input_size = 0;
        if (ctx == NULL) {
@@ -46,6 +46,8 @@ gss_wrap_size_limit(OM_uint32 *minor_status,
            return GSS_S_NO_CONTEXT;
        }
 
            return GSS_S_NO_CONTEXT;
        }
 
+       m = ctx->gc_mech;
+
        return (m->gm_wrap_size_limit(minor_status, ctx->gc_ctx,
                    conf_req_flag, qop_req, req_output_size, max_input_size));
 }
        return (m->gm_wrap_size_limit(minor_status, ctx->gc_ctx,
                    conf_req_flag, qop_req, req_output_size, max_input_size));
 }
index 42c069eb2d1f9e3c12fbefda39eb0a3e39373a1a..17721fd3ce6ed2b966085c7316e8fa92545ea2f5 100644 (file)
@@ -53,6 +53,7 @@
 
 #include <gssapi.h>
 #include <gssapi_mech.h>
 
 #include <gssapi.h>
 #include <gssapi_mech.h>
+#include <gssapi_krb5.h>
 
 #include "mechqueue.h"
 
 
 #include "mechqueue.h"
 
index e83a4c8a5aaffb40aa4b1c00e81e2ec297686753..56e3b7dea79a466592d05924ee2fa7f8ec562162 100644 (file)
@@ -32,6 +32,7 @@
 struct _gss_mech_switch {
        SLIST_ENTRY(_gss_mech_switch)   gm_link;
        gss_OID_desc                    gm_mech_oid;
 struct _gss_mech_switch {
        SLIST_ENTRY(_gss_mech_switch)   gm_link;
        gss_OID_desc                    gm_mech_oid;
+       gss_OID_set                     gm_name_types;
        void                            *gm_so;
        gssapi_mech_interface_desc      gm_mech;
 };
        void                            *gm_so;
        gssapi_mech_interface_desc      gm_mech;
 };
index cabd806fbfd0be62fe835da3aef45aecfa21bb2a..158126d99f96cd1c7876121cf0e42d1ececbc774 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "spnego/spnego_locl.h"
+#include "spnego_locl.h"
 
 RCSID("$Id$");
 
 
 RCSID("$Id$");
 
@@ -494,7 +494,7 @@ acceptor_complete(OM_uint32 * minor_status,
            *get_mic = 1;
        }
        
            *get_mic = 1;
        }
        
-       if (verify_mic || get_mic) {
+       if (verify_mic || *get_mic) {
            int eret;
            size_t buf_len;
        
            int eret;
            size_t buf_len;
        
@@ -512,7 +512,7 @@ acceptor_complete(OM_uint32 * minor_status,
        if (verify_mic) {
            ret = verify_mechlist_mic(minor_status, ctx, mech_buf, mic);
            if (ret) {
        if (verify_mic) {
            ret = verify_mechlist_mic(minor_status, ctx, mech_buf, mic);
            if (ret) {
-               if (get_mic)
+               if (*get_mic)
                    send_reject (minor_status, output_token);
                if (buf.value)
                    free(buf.value);
                    send_reject (minor_status, output_token);
                if (buf.value)
                    free(buf.value);
index 67d9b202a7309533dc9de724d4e624af69e1d91b..ee25b594358286cae977cda07a964a1eef74ae2c 100644 (file)
@@ -30,7 +30,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "spnego/spnego_locl.h"
+#include "spnego_locl.h"
 
 RCSID("$Id$");
 
 
 RCSID("$Id$");
 
index 5bc1a486563ae6ac00ed5b287fb98e92eaca3997..1998c44edf2588a812020278356923096bc7a28a 100644 (file)
@@ -30,7 +30,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "spnego/spnego_locl.h"
+#include "spnego_locl.h"
 
 RCSID("$Id$");
 
 
 RCSID("$Id$");
 
@@ -62,6 +62,7 @@ spnego_supported_mechs(OM_uint32 *minor_status, gss_OID_set *mechs)
            return ret;
        }
     }
            return ret;
        }
     }
+    gss_release_oid_set(&junk, &m);
     return ret;
 }
 
     return ret;
 }
 
@@ -598,7 +599,7 @@ out:
 
     gss_release_oid_set(&junk, &mechs);
 
 
     gss_release_oid_set(&junk, &mechs);
 
-    return GSS_S_COMPLETE;
+    return ret;
 }
 
 OM_uint32 _gss_spnego_inquire_mechs_for_name (
 }
 
 OM_uint32 _gss_spnego_inquire_mechs_for_name (
@@ -642,128 +643,6 @@ OM_uint32 _gss_spnego_duplicate_name (
     return gss_duplicate_name(minor_status, src_name, 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,
 #if 0
 OM_uint32 _gss_spnego_unwrap_ex
            (OM_uint32 * minor_status,
index f6b3fecaa016044747f6bac0a66ac30c2596e036..a3a984e22c3eb05137b7e569fd9b1ca64b7677f8 100644 (file)
@@ -30,7 +30,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "spnego/spnego_locl.h"
+#include "spnego_locl.h"
 
 RCSID("$Id$");
 
 
 RCSID("$Id$");
 
index 02404237a70c987cd1e0a5dba87b6efe51b8ca9e..2dc809bbbaa58af610b3e1d0c54064b36f69f560 100644 (file)
@@ -30,7 +30,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "spnego/spnego_locl.h"
+#include "spnego_locl.h"
 #include <gssapi_mech.h>
 
 RCSID("$Id$");
 #include <gssapi_mech.h>
 
 RCSID("$Id$");
@@ -71,7 +71,7 @@ static gssapi_mech_interface_desc spnego_mech = {
     _gss_spnego_inquire_cred_by_mech,
     _gss_spnego_export_sec_context,
     _gss_spnego_import_sec_context,
     _gss_spnego_inquire_cred_by_mech,
     _gss_spnego_export_sec_context,
     _gss_spnego_import_sec_context,
-    _gss_spnego_inquire_names_for_mech,
+    NULL /* _gss_spnego_inquire_names_for_mech */,
     _gss_spnego_inquire_mechs_for_name,
     _gss_spnego_canonicalize_name,
     _gss_spnego_duplicate_name,
     _gss_spnego_inquire_mechs_for_name,
     _gss_spnego_canonicalize_name,
     _gss_spnego_duplicate_name,
index 7a5814413b92340116c7fb55132f5b21804425aa..ac32432d550320e4b7db48961e5fbcea45e469ae 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "spnego/spnego_locl.h"
+#include "spnego_locl.h"
 
 RCSID("$Id$");
 
 
 RCSID("$Id$");
 
@@ -392,8 +392,7 @@ spnego_reply
     )
 {
     OM_uint32 ret, minor;
     )
 {
     OM_uint32 ret, minor;
-    NegTokenResp resp;
-    size_t len, taglen;
+    NegotiationToken resp;
     gss_OID_desc mech;
     int require_mic;
     size_t buf_len;
     gss_OID_desc mech;
     int require_mic;
     size_t buf_len;
@@ -414,27 +413,23 @@ spnego_reply
     mech_buf.value = NULL;
     mech_buf.length = 0;
 
     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);
+    ret = decode_NegotiationToken(input_token->value, input_token->length,
+                                 &resp, NULL);
     if (ret)
     if (ret)
-       return 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.element != choice_NegotiationToken_negTokenResp) {
+       free_NegotiationToken(&resp);
+       *minor_status = 0;
+       return GSS_S_BAD_MECH;
     }
 
     }
 
-    if (resp.negResult == NULL
-       || *(resp.negResult) == reject
-       /* || resp.supportedMech == NULL */
+    if (resp.u.negTokenResp.negResult == NULL
+       || *(resp.u.negTokenResp.negResult) == reject
+       /* || resp.u.negTokenResp.supportedMech == NULL */
        )
     {
        )
     {
-       free_NegTokenResp(&resp);
+       free_NegotiationToken(&resp);
        return GSS_S_BAD_MECH;
     }
 
        return GSS_S_BAD_MECH;
     }
 
@@ -445,16 +440,16 @@ spnego_reply
 
     HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
 
 
     HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
 
-    if (resp.supportedMech) {
+    if (resp.u.negTokenResp.supportedMech) {
 
        if (ctx->oidlen) {
 
        if (ctx->oidlen) {
-           free_NegTokenResp(&resp);
+           free_NegotiationToken(&resp);
            HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
            return GSS_S_BAD_MECH;
        }
        ret = der_put_oid(ctx->oidbuf + sizeof(ctx->oidbuf) - 1,
                          sizeof(ctx->oidbuf),
            HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
            return GSS_S_BAD_MECH;
        }
        ret = der_put_oid(ctx->oidbuf + sizeof(ctx->oidbuf) - 1,
                          sizeof(ctx->oidbuf),
-                         resp.supportedMech,
+                         resp.u.negTokenResp.supportedMech,
                          &ctx->oidlen);
        /* Avoid recursively embedded SPNEGO */
        if (ret || (ctx->oidlen == GSS_SPNEGO_MECHANISM->length &&
                          &ctx->oidlen);
        /* Avoid recursively embedded SPNEGO */
        if (ret || (ctx->oidlen == GSS_SPNEGO_MECHANISM->length &&
@@ -462,7 +457,7 @@ spnego_reply
                           GSS_SPNEGO_MECHANISM->elements,
                           ctx->oidlen) == 0))
        {
                           GSS_SPNEGO_MECHANISM->elements,
                           ctx->oidlen) == 0))
        {
-           free_NegTokenResp(&resp);
+           free_NegotiationToken(&resp);
            HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
            return GSS_S_BAD_MECH;
        }
            HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
            return GSS_S_BAD_MECH;
        }
@@ -478,19 +473,19 @@ spnego_reply
            ctx->negotiated_ctx_id = GSS_C_NO_CONTEXT;
        }
     } else if (ctx->oidlen == 0) {
            ctx->negotiated_ctx_id = GSS_C_NO_CONTEXT;
        }
     } else if (ctx->oidlen == 0) {
-       free_NegTokenResp(&resp);
+       free_NegotiationToken(&resp);
        HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
        return GSS_S_BAD_MECH;
     }
 
     /* if a token (of non zero length), or no context, pass to underlaying mech */
        HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
        return GSS_S_BAD_MECH;
     }
 
     /* if a token (of non zero length), or no context, pass to underlaying mech */
-    if ((resp.responseToken != NULL && resp.responseToken->length) ||
+    if ((resp.u.negTokenResp.responseToken != NULL && resp.u.negTokenResp.responseToken->length) ||
        ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
        gss_buffer_desc mech_input_token;
 
        ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
        gss_buffer_desc mech_input_token;
 
-       if (resp.responseToken) {
-           mech_input_token.length = resp.responseToken->length;
-           mech_input_token.value  = resp.responseToken->data;
+       if (resp.u.negTokenResp.responseToken) {
+           mech_input_token.length = resp.u.negTokenResp.responseToken->length;
+           mech_input_token.value  = resp.u.negTokenResp.responseToken->data;
        } else {
            mech_input_token.length = 0;
            mech_input_token.value = NULL;
        } else {
            mech_input_token.length = 0;
            mech_input_token.value = NULL;
@@ -518,7 +513,7 @@ spnego_reply
                                   &ctx->mech_time_rec);
        if (GSS_ERROR(ret)) {
            HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
                                   &ctx->mech_time_rec);
        if (GSS_ERROR(ret)) {
            HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
-           free_NegTokenResp(&resp);
+           free_NegotiationToken(&resp);
            gss_mg_collect_error(&mech, ret, minor);
            *minor_status = minor;
            return ret;
            gss_mg_collect_error(&mech, ret, minor);
            *minor_status = minor;
            return ret;
@@ -526,12 +521,12 @@ spnego_reply
        if (ret == GSS_S_COMPLETE) {
            ctx->open = 1;
        }
        if (ret == GSS_S_COMPLETE) {
            ctx->open = 1;
        }
-    } else if (*(resp.negResult) == accept_completed) {
+    } else if (*(resp.u.negTokenResp.negResult) == accept_completed) {
        if (ctx->maybe_open)
            ctx->open = 1;
     }
 
        if (ctx->maybe_open)
            ctx->open = 1;
     }
 
-    if (*(resp.negResult) == request_mic) {
+    if (*(resp.u.negTokenResp.negResult) == request_mic) {
        ctx->require_mic = 1;
     }
 
        ctx->require_mic = 1;
     }
 
@@ -540,14 +535,14 @@ spnego_reply
         * Verify the mechListMIC if one was provided or CFX was
         * used and a non-preferred mechanism was selected
         */
         * Verify the mechListMIC if one was provided or CFX was
         * used and a non-preferred mechanism was selected
         */
-       if (resp.mechListMIC != NULL) {
+       if (resp.u.negTokenResp.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);
            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);
+               free_NegotiationToken(&resp);
                gss_release_buffer(&minor, &mech_output_token);
                return ret;
            }
                gss_release_buffer(&minor, &mech_output_token);
                return ret;
            }
@@ -561,7 +556,7 @@ spnego_reply
                           &ctx->initiator_mech_types, &buf_len, ret);
        if (ret) {
            HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
                           &ctx->initiator_mech_types, &buf_len, ret);
        if (ret) {
            HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
-           free_NegTokenResp(&resp);
+           free_NegotiationToken(&resp);
            gss_release_buffer(&minor, &mech_output_token);
            *minor_status = ret;
            return GSS_S_FAILURE;
            gss_release_buffer(&minor, &mech_output_token);
            *minor_status = ret;
            return GSS_S_FAILURE;
@@ -569,15 +564,15 @@ spnego_reply
        if (mech_buf.length != buf_len)
            abort();
 
        if (mech_buf.length != buf_len)
            abort();
 
-       if (resp.mechListMIC == NULL) {
+       if (resp.u.negTokenResp.mechListMIC == NULL) {
            HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
            free(mech_buf.value);
            HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
            free(mech_buf.value);
-           free_NegTokenResp(&resp);
+           free_NegotiationToken(&resp);
            *minor_status = 0;
            return GSS_S_DEFECTIVE_TOKEN;
        }
            *minor_status = 0;
            return GSS_S_DEFECTIVE_TOKEN;
        }
-       mic_buf.length = resp.mechListMIC->length;
-       mic_buf.value  = resp.mechListMIC->data;
+       mic_buf.length = resp.u.negTokenResp.mechListMIC->length;
+       mic_buf.value  = resp.u.negTokenResp.mechListMIC->data;
 
        if (mech_output_token.length == 0) {
            ret = gss_verify_mic(minor_status,
 
        if (mech_output_token.length == 0) {
            ret = gss_verify_mic(minor_status,
@@ -589,7 +584,7 @@ spnego_reply
                HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
                free(mech_buf.value);
                gss_release_buffer(&minor, &mech_output_token);
                HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
                free(mech_buf.value);
                gss_release_buffer(&minor, &mech_output_token);
-               free_NegTokenResp(&resp);
+               free_NegotiationToken(&resp);
                return GSS_S_DEFECTIVE_TOKEN;
            }
            ctx->verified_mic = 1;
                return GSS_S_DEFECTIVE_TOKEN;
            }
            ctx->verified_mic = 1;
@@ -604,7 +599,7 @@ spnego_reply
     if (mech_buf.value != NULL)
        free(mech_buf.value);
 
     if (mech_buf.value != NULL)
        free(mech_buf.value);
 
-    free_NegTokenResp(&resp);
+    free_NegotiationToken(&resp);
     gss_release_buffer(&minor, &mech_output_token);
 
     if (actual_mech_type)
     gss_release_buffer(&minor, &mech_output_token);
 
     if (actual_mech_type)
index 8344e750ae78ab388c70b6d88a0eb3c8640633bd..44fa8b117d344e56f74748db683b60cc14b1f9df 100644 (file)
@@ -35,9 +35,7 @@
 #ifndef SPNEGO_LOCL_H
 #define SPNEGO_LOCL_H
 
 #ifndef SPNEGO_LOCL_H
 #define SPNEGO_LOCL_H
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-#endif
 
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
 
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
@@ -50,8 +48,9 @@
 #include <pthread.h>
 #endif
 
 #include <pthread.h>
 #endif
 
-#include <gssapi/gssapi_spnego.h>
 #include <gssapi.h>
 #include <gssapi.h>
+#include <gssapi_krb5.h>
+#include <gssapi_spnego.h>
 #include <assert.h>
 #include <stdlib.h>
 #include <string.h>
 #include <assert.h>
 #include <stdlib.h>
 #include <string.h>
@@ -67,7 +66,7 @@
 #include <gssapi_mech.h>
 
 #include "spnego_asn1.h"
 #include <gssapi_mech.h>
 
 #include "spnego_asn1.h"
-#include "mech/utils.h"
+#include "utils.h"
 #include <der.h>
 
 #include <roken.h>
 #include <der.h>
 
 #include <roken.h>
@@ -109,6 +108,6 @@ typedef struct {
 extern gss_OID_desc _gss_spnego_mskrb_mechanism_oid_desc;
 extern gss_OID_desc _gss_spnego_krb5_mechanism_oid_desc;
 
 extern gss_OID_desc _gss_spnego_mskrb_mechanism_oid_desc;
 extern gss_OID_desc _gss_spnego_krb5_mechanism_oid_desc;
 
-#include <spnego/spnego-private.h>
+#include <spnego-private.h>
 
 #endif /* SPNEGO_LOCL_H */
 
 #endif /* SPNEGO_LOCL_H */
index b91a65a7bfc6f21dd11d0e0c01dc4911de476e75..179595ae5cd3ee62bb908db1456cf906cce5b6f2 100644 (file)
@@ -443,3 +443,91 @@ BN_GENCB_call(BN_GENCB *cb, int a, int b)
        return 1;
     return cb->cb.cb_2(a, b, cb);
 }
        return 1;
     return cb->cb.cb_2(a, b, cb);
 }
+
+/*
+ *
+ */
+
+struct BN_CTX {
+    struct {
+       BIGNUM **val;
+       size_t used;
+       size_t len;
+    } bn;
+    struct {
+       size_t *val;
+       size_t used;
+       size_t len;
+    } stack;
+};
+
+BN_CTX *
+BN_CTX_new(void)
+{
+    struct BN_CTX *c;
+    c = calloc(1, sizeof(*c));
+    return c;
+}
+
+void
+BN_CTX_free(BN_CTX *c)
+{
+    size_t i;
+    for (i = 0; i < c->bn.len; i++)
+       BN_free(c->bn.val[i]);
+    free(c->bn.val);
+    free(c->stack.val);
+}
+
+BIGNUM *
+BN_CTX_get(BN_CTX *c)
+{
+    if (c->bn.used == c->bn.len) {
+       void *ptr;
+       size_t i;
+       c->bn.len += 16;
+       ptr = realloc(c->bn.val, c->bn.len * sizeof(c->bn.val[0]));
+       if (ptr == NULL)
+           return NULL;
+       c->bn.val = ptr;
+       for (i = c->bn.used; i < c->bn.len; i++) {
+           c->bn.val[i] = BN_new();
+           if (c->bn.val[i] == NULL) {
+               c->bn.len = i;
+               return NULL;
+           }
+       }
+    }
+    return c->bn.val[c->bn.used++];
+}
+
+void
+BN_CTX_start(BN_CTX *c)
+{
+    if (c->stack.used == c->stack.len) {
+       void *ptr;
+       c->stack.len += 16;
+       ptr = realloc(c->stack.val, c->stack.len * sizeof(c->stack.val[0]));
+       if (ptr == NULL)
+           abort();
+       c->stack.val = ptr;
+    }
+    c->stack.val[c->stack.used++] = c->bn.used;
+}
+
+void
+BN_CTX_end(BN_CTX *c)
+{
+    const size_t prev = c->stack.val[c->stack.used - 1];
+    size_t i;
+
+    if (c->stack.used == 0)
+       abort();
+
+    for (i = prev; i < c->bn.used; i++)
+       BN_clear(c->bn.val[i]);
+
+    c->stack.used--;
+    c->bn.used = prev;
+}
+
index aac770b5a8c666bc21eccece03e532c9ba8197af..2fa25ac1a08a191d10990df21ecad2580dc1547d 100644 (file)
 #define BN_set_negative hc_BN_set_negative
 #define BN_set_word hc_BN_set_word
 #define BN_uadd hc_BN_uadd
 #define BN_set_negative hc_BN_set_negative
 #define BN_set_word hc_BN_set_word
 #define BN_uadd hc_BN_uadd
+#define BN_CTX_new hc_BN_CTX_new
+#define BN_CTX_free hc_BN_CTX_free
+#define BN_CTX_get hc_BN_CTX_get
+#define BN_CTX_start hc_BN_CTX_start
+#define BN_CTX_end hc_BN_CTX_end
 
 /*
  *
  */
 
 
 /*
  *
  */
 
-typedef void BIGNUM;
+typedef struct BIGNUM BIGNUM;
 typedef struct BN_GENCB BN_GENCB;
 typedef struct BN_GENCB BN_GENCB;
-typedef void BN_CTX;
-typedef void BN_MONT_CTX;
-typedef void BN_BLINDING;
+typedef struct BN_CTX BN_CTX;
+typedef struct BN_MONT_CTX BN_MONT_CTX;
+typedef struct BN_BLINDING BN_BLINDING;
 
 struct BN_GENCB {
     unsigned int ver;
 
 struct BN_GENCB {
     unsigned int ver;
@@ -118,4 +123,10 @@ int        BN_rand(BIGNUM *, int, int, int);
 void   BN_GENCB_set(BN_GENCB *, int (*)(int, int, BN_GENCB *), void *);
 int    BN_GENCB_call(BN_GENCB *, int, int);
 
 void   BN_GENCB_set(BN_GENCB *, int (*)(int, int, BN_GENCB *), void *);
 int    BN_GENCB_call(BN_GENCB *, int, int);
 
+BN_CTX *BN_CTX_new(void);
+void   BN_CTX_free(BN_CTX *);
+BIGNUM *BN_CTX_get(BN_CTX *);
+void   BN_CTX_start(BN_CTX *);
+void   BN_CTX_end(BN_CTX *);
+
 #endif
 #endif
index 685dcac18b4e3b19e86fb583ac0f95ef0717ec0b..66f87982c00b44f93a5e3486db2c5fba68fcec9d 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-#endif
-
-RCSID("$Id$");
 
 #define HC_DEPRECATED
 
 
 #define HC_DEPRECATED
 
index 517ca2a2bc08782bfee762c6415ef17f79b24f27..ac6cac972af06865832b355e39eac1c973a1bfb0 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
+ * Copyright (c) 2006 - 2008 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden).
  * All rights reserved.
  *
  * (Royal Institute of Technology, Stockholm, Sweden).
  * All rights reserved.
  *
@@ -35,8 +35,6 @@
 #include <config.h>
 #endif
 
 #include <config.h>
 #endif
 
-RCSID("$Id$");
-
 #define HC_DEPRECATED
 #define HC_DEPRECATED_CRYPTO
 
 #define HC_DEPRECATED
 #define HC_DEPRECATED_CRYPTO
 
@@ -512,13 +510,6 @@ EVP_md_null(void)
     return &null;
 }
 
     return &null;
 }
 
-#if 0
-int    EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type);
-int    EVP_DigestFinal(EVP_MD_CTX *ctx,unsigned char *md,unsigned int *s);
-int    EVP_SignFinal(EVP_MD_CTX *, void *, size_t *, EVP_PKEY *);
-int    EVP_VerifyFinal(EVP_MD_CTX *, const void *, size_t, EVP_PKEY *);
-#endif
-
 /**
  * Return the block size of the cipher.
  *
 /**
  * Return the block size of the cipher.
  *
@@ -1650,6 +1641,11 @@ EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, void *key)
 /**
  * Perform a operation on a ctx
  *
 /**
  * Perform a operation on a ctx
  *
+ * @param ctx context to perform operation on.
+ * @param type type of operation.
+ * @param arg argument to operation.
+ * @param data addition data to operation.
+
  * @return 1 for success, 0 for failure.
  *
  * @ingroup hcrypto_core
  * @return 1 for success, 0 for failure.
  *
  * @ingroup hcrypto_core
index 0c2185776c873700fc0db73e40ecd28b4de00acb..07d81eb62041a45ec150da1ec45a3829a1a2e508 100644 (file)
@@ -40,11 +40,15 @@ RCSID("$Id$");
 #include <stdio.h>
 #include <stdlib.h>
 #include <rand.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <rand.h>
+#include <heim_threads.h>
 
 #include <roken.h>
 
 #include "randi.h"
 
 
 #include <roken.h>
 
 #include "randi.h"
 
+static int random_fd = -1;
+static HEIMDAL_MUTEX random_mutex = HEIMDAL_MUTEX_INITIALIZER;
+
 /*
  * Unix /dev/random
  */
 /*
  * Unix /dev/random
  */
@@ -88,31 +92,47 @@ unix_seed(const void *indata, int size)
 
 }
 
 
 }
 
+
 static int
 unix_bytes(unsigned char *outdata, int size)
 {
     ssize_t count;
 static int
 unix_bytes(unsigned char *outdata, int size)
 {
     ssize_t count;
-    int fd;
+    int once = 0;
 
     if (size <= 0)
        return 0;
 
 
     if (size <= 0)
        return 0;
 
-    fd = get_device_fd(O_RDONLY);
-    if (fd < 0)
-       return 0;
+    HEIMDAL_MUTEX_lock(&random_mutex);
+    if (random_fd == -1) {
+    retry:
+       random_fd = get_device_fd(O_RDONLY);
+       if (random_fd < 0) {
+           HEIMDAL_MUTEX_unlock(&random_mutex);
+           return 0;
+       }
+    }
 
     while (size > 0) {
 
     while (size > 0) {
-       count = read (fd, outdata, size);
-       if (count < 0 && errno == EINTR)
-           continue;
-       else if (count <= 0) {
-           close(fd);
+       HEIMDAL_MUTEX_unlock(&random_mutex);
+       count = read (random_fd, outdata, size);
+       HEIMDAL_MUTEX_lock(&random_mutex);
+       if (random_fd < 0) {
+           if (errno == EINTR)
+               continue;
+           else if (errno == EBADF && once++ == 0) {
+               close(random_fd);
+               random_fd = -1;
+               goto retry;
+           }
+           return 0;
+       } else if (count <= 0) {
+           HEIMDAL_MUTEX_unlock(&random_mutex);
            return 0;
        }
        outdata += count;
        size -= count;
     }
            return 0;
        }
        outdata += count;
        size -= count;
     }
-    close(fd);
+    HEIMDAL_MUTEX_unlock(&random_mutex);
 
     return 1;
 }
 
     return 1;
 }
index b8ac2155d11b2685017a38e21fd37f23c2a6d5ba..a61c9cdfb2d993c2260319a0adea8c28f71dbc8b 100644 (file)
@@ -62,7 +62,11 @@ init_method(void)
 {
     if (selected_meth != NULL)
        return;
 {
     if (selected_meth != NULL)
        return;
+#ifdef __APPLE__
+    selected_meth = &hc_rand_unix_method;
+#else
     selected_meth = &hc_rand_fortuna_method;
     selected_meth = &hc_rand_fortuna_method;
+#endif
 }
 
 /**
 }
 
 /**
index 2121577bb1224d96c852117453bf8706a7e0d7b8..7e2961c61438610c62d1f1b2d6e61603fc701989 100644 (file)
@@ -228,10 +228,12 @@ hdb_free_dbinfo(krb5_context context, struct hdb_dbinfo **dbp)
 
     for(di = *dbp; di != NULL; di = ndi) {
        ndi = di->next;
 
     for(di = *dbp; di != NULL; di = ndi) {
        ndi = di->next;
+       free (di->label);
        free (di->realm);
        free (di->dbname);
        free (di->realm);
        free (di->dbname);
-       if (di->mkey_file)
-           free (di->mkey_file);
+       free (di->mkey_file);
+       free (di->acl_file);
+       free (di->log_file);
        free(di);
     }
     *dbp = NULL;
        free(di);
     }
     *dbp = NULL;
index f792b85c096d15dcc9bcb0a3b2df49a0247b7835..9053fd66335c1d56e7516b0ebdac2c66a4b9b0fa 100644 (file)
@@ -234,6 +234,20 @@ hdb_entry_get_pkinit_hash(const hdb_entry *entry, const HDB_Ext_PKINIT_hash **a)
     return 0;
 }
 
     return 0;
 }
 
+krb5_error_code
+hdb_entry_get_pkinit_cert(const hdb_entry *entry, const HDB_Ext_PKINIT_cert **a)
+{
+    const HDB_extension *ext;
+
+    ext = hdb_find_extension(entry, choice_HDB_extension_data_pkinit_cert);
+    if (ext)
+       *a = &ext->data.u.pkinit_cert;
+    else
+       *a = NULL;
+
+    return 0;
+}
+
 krb5_error_code
 hdb_entry_get_pw_change_time(const hdb_entry *entry, time_t *t)
 {
 krb5_error_code
 hdb_entry_get_pw_change_time(const hdb_entry *entry, time_t *t)
 {
index 5cddf8f1d0536d2d26dabcab87f9692c10a61a84..c2abd4af73ee78b71984f33d75ba5899e12c9f77 100644 (file)
@@ -13,7 +13,8 @@ hdb-afs3-salt INTEGER ::= 10
 
 Salt ::= SEQUENCE {
        type[0]         INTEGER (0..4294967295),
 
 Salt ::= SEQUENCE {
        type[0]         INTEGER (0..4294967295),
-       salt[1]         OCTET STRING
+       salt[1]         OCTET STRING,
+       opaque[2]       OCTET STRING OPTIONAL
 }
 
 Key ::= SEQUENCE {
 }
 
 Key ::= SEQUENCE {
@@ -64,6 +65,10 @@ HDB-Ext-PKINIT-hash ::= SEQUENCE OF SEQUENCE {
        digest[1] OCTET STRING
 }
 
        digest[1] OCTET STRING
 }
 
+HDB-Ext-PKINIT-cert ::= SEQUENCE OF SEQUENCE {
+       cert[0] OCTET STRING
+}
+
 HDB-Ext-Constrained-delegation-acl ::= SEQUENCE OF Principal
 
 -- hdb-ext-referrals ::= PA-SERVER-REFERRAL-DATA
 HDB-Ext-Constrained-delegation-acl ::= SEQUENCE OF Principal
 
 -- hdb-ext-referrals ::= PA-SERVER-REFERRAL-DATA
@@ -94,6 +99,7 @@ HDB-extension ::= SEQUENCE {
                password[5]                     HDB-Ext-Password,
                aliases[6]                      HDB-Ext-Aliases,
                last-pw-change[7]               KerberosTime,
                password[5]                     HDB-Ext-Password,
                aliases[6]                      HDB-Ext-Aliases,
                last-pw-change[7]               KerberosTime,
+               pkinit-cert[8]                  HDB-Ext-PKINIT-cert,
                ...
        },
        ...
                ...
        },
        ...
@@ -101,6 +107,10 @@ HDB-extension ::= SEQUENCE {
 
 HDB-extensions ::= SEQUENCE OF HDB-extension
 
 
 HDB-extensions ::= SEQUENCE OF HDB-extension
 
+hdb_keyset ::= SEQUENCE {
+       kvno[1]         INTEGER (0..4294967295),
+       keys[0]         SEQUENCE OF Key
+}
 
 hdb_entry ::= SEQUENCE {
        principal[0]    Principal  OPTIONAL, -- this is optional only 
 
 hdb_entry ::= SEQUENCE {
        principal[0]    Principal  OPTIONAL, -- this is optional only 
index ad2c35a43a58a9dbfc68f72979df15a84afc6e22..e55b0bed03ce286d51f8ed1f66db1c3bcf142217 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden).
  * All rights reserved.
  *
  * (Royal Institute of Technology, Stockholm, Sweden).
  * All rights reserved.
  *
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "krb5.h"
 #include "krb5_locl.h"
 #include "hdb_locl.h"
 RCSID("$Id$");
 #include "krb5_locl.h"
 #include "hdb_locl.h"
 RCSID("$Id$");
@@ -44,24 +39,49 @@ RCSID("$Id$");
 #include <dlfcn.h>
 #endif
 
 #include <dlfcn.h>
 #endif
 
+/*! @mainpage Heimdal database backend library
+ *
+ * @section intro Introduction
+ *
+ * Heimdal libhdb library provides the backend support for Heimdal kdc
+ * and kadmind. Its here where plugins for diffrent database engines
+ * can be pluged in and extend support for here Heimdal get the
+ * principal and policy data from.
+ *
+ * Example of Heimdal backend are:
+ * - Berkeley DB 1.85
+ * - Berkeley DB 3.0
+ * - Berkeley DB 4.0
+ * - New Berkeley DB
+ * - LDAP
+ *
+ *
+ * The project web page: http://www.h5l.org/
+ *
+ */
+
+
+
 static struct hdb_method methods[] = {
 #if HAVE_DB1 || HAVE_DB3
 static struct hdb_method methods[] = {
 #if HAVE_DB1 || HAVE_DB3
-    {HDB_INTERFACE_VERSION, "db:",     hdb_db_create},
+    { HDB_INTERFACE_VERSION, "db:",    hdb_db_create},
 #endif
 #if HAVE_NDBM
 #endif
 #if HAVE_NDBM
-    {HDB_INTERFACE_VERSION, "ndbm:",   hdb_ndbm_create},
+    { HDB_INTERFACE_VERSION, "ndbm:",  hdb_ndbm_create},
 #endif
 #if defined(OPENLDAP) && !defined(OPENLDAP_MODULE)
 #endif
 #if defined(OPENLDAP) && !defined(OPENLDAP_MODULE)
-    {HDB_INTERFACE_VERSION, "ldap:",   hdb_ldap_create},
-    {HDB_INTERFACE_VERSION, "ldapi:",  hdb_ldapi_create},
+    { HDB_INTERFACE_VERSION, "ldap:",  hdb_ldap_create},
+    { HDB_INTERFACE_VERSION, "ldapi:", hdb_ldapi_create},
 #endif
     {0, NULL,  NULL}
 };
 
 #if HAVE_DB1 || HAVE_DB3
 #endif
     {0, NULL,  NULL}
 };
 
 #if HAVE_DB1 || HAVE_DB3
-static struct hdb_method dbmetod = {"",        hdb_db_create };
+static struct hdb_method dbmetod =
+    { HDB_INTERFACE_VERSION, "", hdb_db_create };
 #elif defined(HAVE_NDBM)
 #elif defined(HAVE_NDBM)
-static struct hdb_method dbmetod = {"",        hdb_ndbm_create };
+static struct hdb_method dbmetod =
+    { HDB_INTERFACE_VERSION, "", hdb_ndbm_create };
 #endif
 
 
 #endif
 
 
@@ -265,9 +285,10 @@ find_dynamic_method (krb5_context context,
     len = p - filename;
     *rest = filename + len + 1;
 
     len = p - filename;
     *rest = filename + len + 1;
 
-    prefix = strndup(filename, len);
+    prefix = malloc(len + 1);
     if (prefix == NULL)
        krb5_errx(context, 1, "out of memory");
     if (prefix == NULL)
        krb5_errx(context, 1, "out of memory");
+    strlcpy(prefix, filename, len + 1);
 
     if (asprintf(&path, LIBDIR "/hdb_%s.so", prefix) == -1)
        krb5_errx(context, 1, "out of memory");
 
     if (asprintf(&path, LIBDIR "/hdb_%s.so", prefix) == -1)
        krb5_errx(context, 1, "out of memory");
@@ -390,6 +411,14 @@ hdb_list_builtin(krb5_context context, char **list)
     return 0;
 }
 
     return 0;
 }
 
+/**
+ * Create a handle for a Kerberos database
+ *
+ * Create a handle for a Kerberos database backend specified by a
+ * filename.  Doesn't create a file if its doesn't exists, you have to
+ * use O_CREAT to tell the backend to create the file.
+ */
+
 krb5_error_code
 hdb_create(krb5_context context, HDB **db, const char *filename)
 {
 krb5_error_code
 hdb_create(krb5_context context, HDB **db, const char *filename)
 {
index 53b1defc96088163f3cd66df393c9896baacae38..ce219153b34436015ab1fcf0dc068bd592e4c458 100644 (file)
@@ -66,65 +66,122 @@ typedef struct hdb_entry_ex {
 } hdb_entry_ex;
 
 
 } hdb_entry_ex;
 
 
+/**
+ * HDB backend function pointer structure
+ *
+ * The HDB structure is what the KDC and kadmind framework uses to
+ * query the backend database when talking about principals.
+ */
+
 typedef struct HDB{
     void *hdb_db;
 typedef struct HDB{
     void *hdb_db;
-    void *hdb_dbc;
+    void *hdb_dbc; /** don't use, only for DB3 */
     char *hdb_name;
     int hdb_master_key_set;
     hdb_master_key hdb_master_key;
     int hdb_openp;
 
     char *hdb_name;
     int hdb_master_key_set;
     hdb_master_key hdb_master_key;
     int hdb_openp;
 
-    krb5_error_code (*hdb_open)(krb5_context,
-                               struct HDB*,
-                               int,
-                               mode_t);
-    krb5_error_code (*hdb_close)(krb5_context,
-                                struct HDB*);
-    void           (*hdb_free)(krb5_context,
-                               struct HDB*,
-                               hdb_entry_ex*);
-    krb5_error_code (*hdb_fetch)(krb5_context,
-                                struct HDB*,
-                                krb5_const_principal,
-                                unsigned,
-                                hdb_entry_ex*);
-    krb5_error_code (*hdb_store)(krb5_context,
-                                struct HDB*,
-                                unsigned,
+    /**
+     * Open (or create) the a Kerberos database.
+     *
+     * Open (or create) the a Kerberos database that was resolved with
+     * hdb_create(). The third and fourth flag to the function are the
+     * same as open(), thus passing O_CREAT will create the data base
+     * if it doesn't exists.
+     *
+     * Then done the caller should call hdb_close(), and to release
+     * all resources hdb_destroy().
+     */
+    krb5_error_code (*hdb_open)(krb5_context, struct HDB*, int, mode_t);
+    /**
+     * Close the database for transaction
+     *
+     * Closes the database for further transactions, wont release any
+     * permanant resources. the database can be ->hdb_open-ed again.
+     */
+    krb5_error_code (*hdb_close)(krb5_context, struct HDB*);
+    /**
+     * Free an entry after use.
+     */
+    void           (*hdb_free)(krb5_context, struct HDB*, hdb_entry_ex*);
+    /**
+     * Fetch an entry from the backend
+     *
+     * Fetch an entry from the backend, flags are what type of entry
+     * should be fetch: client, server, krbtgt.
+     */
+    krb5_error_code (*hdb_fetch)(krb5_context, struct HDB*,
+                                krb5_const_principal, unsigned,
                                 hdb_entry_ex*);
                                 hdb_entry_ex*);
-    krb5_error_code (*hdb_remove)(krb5_context,
-                                 struct HDB*,
+    /**
+     * Store an entry to database
+     */
+    krb5_error_code (*hdb_store)(krb5_context, struct HDB*,
+                                unsigned, hdb_entry_ex*);
+    /**
+     * Remove an entry from the database.
+     */
+    krb5_error_code (*hdb_remove)(krb5_context, struct HDB*,
                                  krb5_const_principal);
                                  krb5_const_principal);
-    krb5_error_code (*hdb_firstkey)(krb5_context,
-                                   struct HDB*,
-                                   unsigned,
-                                   hdb_entry_ex*);
-    krb5_error_code (*hdb_nextkey)(krb5_context,
-                                  struct HDB*,
-                                  unsigned,
-                                  hdb_entry_ex*);
-    krb5_error_code (*hdb_lock)(krb5_context,
-                               struct HDB*,
-                               int operation);
-    krb5_error_code (*hdb_unlock)(krb5_context,
-                                 struct HDB*);
-    krb5_error_code (*hdb_rename)(krb5_context,
-                                 struct HDB*,
-                                 const char*);
-    krb5_error_code (*hdb__get)(krb5_context,
-                               struct HDB*,
-                               krb5_data,
-                               krb5_data*);
-    krb5_error_code (*hdb__put)(krb5_context,
-                               struct HDB*,
-                               int,
-                               krb5_data,
-                               krb5_data);
-    krb5_error_code (*hdb__del)(krb5_context,
-                               struct HDB*,
-                               krb5_data);
-    krb5_error_code (*hdb_destroy)(krb5_context,
-                                  struct HDB*);
+    /**
+     * As part of iteration, fetch one entry
+     */
+    krb5_error_code (*hdb_firstkey)(krb5_context, struct HDB*,
+                                   unsigned, hdb_entry_ex*);
+    /**
+     * As part of iteration, fetch next entry
+     */
+    krb5_error_code (*hdb_nextkey)(krb5_context, struct HDB*, 
+                                  unsigned, hdb_entry_ex*);
+    /**
+     * Lock database
+     *
+     * A lock can only be held by one consumers. Transaction can still
+     * happen on the database while the lock is held, so the entry is
+     * only useful for syncroning creation of the database and renaming of the database.
+     */
+    krb5_error_code (*hdb_lock)(krb5_context, struct HDB*, int);
+    /**
+     * Unlock database
+     */
+    krb5_error_code (*hdb_unlock)(krb5_context, struct HDB*);
+    /**
+     * Rename the data base.
+     */
+    krb5_error_code (*hdb_rename)(krb5_context, struct HDB*, const char*);
+    /**
+     * Get an hdb_entry from a classical DB backend
+     *
+     * If the database is a classical DB (ie BDB, NDBM, GDBM, etc)
+     * backend, this function will take a principal key (krb5_data)
+     * and return all data related to principal in the return
+     * krb5_data. The returned encoded entry is of type hdb_entry or
+     * hdb_entry_alias.
+     */
+    krb5_error_code (*hdb__get)(krb5_context, struct HDB*,
+                               krb5_data, krb5_data*);
+    /**
+     * Store an hdb_entry from a classical DB backend
+     *
+     * Same discussion as in @ref HDB::hdb__get
+     */
+    krb5_error_code (*hdb__put)(krb5_context, struct HDB*, int,
+                               krb5_data, krb5_data);
+    /**
+     * Delete and hdb_entry from a classical DB backend
+     *
+     * Same discussion as in @ref HDB::hdb__get
+     */
+    krb5_error_code (*hdb__del)(krb5_context, struct HDB*, krb5_data);
+    /**
+     * Destroy the handle to the database.
+     *
+     * Destroy the handle to the database, deallocate all memory and
+     * related resources. Does not remove any permanent data. Its the
+     * logical reverse of hdb_create() function that is the entry
+     * point for the module.
+     */
+    krb5_error_code (*hdb_destroy)(krb5_context, struct HDB*);
 }HDB;
 
 #define HDB_INTERFACE_VERSION  4
 }HDB;
 
 #define HDB_INTERFACE_VERSION  4
index b9f294e2eb01eda3ba805a3277457233a8353570..50fe7d7fda531b69b945a67d9f89521f2c3affe0 100644 (file)
@@ -1,3 +1,4 @@
+
 /*
  * Copyright (c) 1997 - 2001, 2003 - 2004 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden).
 /*
  * Copyright (c) 1997 - 2001, 2003 - 2004 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden).
@@ -172,8 +173,8 @@ parse_key_set(krb5_context context, const char *key,
        if(salt->salttype == KRB5_PW_SALT)
            ret = krb5_get_pw_salt(context, principal, salt);
        else if(salt->salttype == KRB5_AFS3_SALT) {
        if(salt->salttype == KRB5_PW_SALT)
            ret = krb5_get_pw_salt(context, principal, salt);
        else if(salt->salttype == KRB5_AFS3_SALT) {
-           krb5_realm *realm = krb5_princ_realm(context, principal);
-           salt->saltvalue.data = strdup(*realm);
+           krb5_const_realm realm = krb5_principal_get_realm(context, principal);
+           salt->saltvalue.data = strdup(realm);
            if(salt->saltvalue.data == NULL) {
                krb5_set_error_message(context, ENOMEM,
                                       "out of memory while "
            if(salt->saltvalue.data == NULL) {
                krb5_set_error_message(context, ENOMEM,
                                       "out of memory while "
@@ -181,7 +182,7 @@ parse_key_set(krb5_context context, const char *key,
                return ENOMEM;
            }
            strlwr(salt->saltvalue.data);
                return ENOMEM;
            }
            strlwr(salt->saltvalue.data);
-           salt->saltvalue.length = strlen(*realm);
+           salt->saltvalue.length = strlen(realm);
        }
     }
 
        }
     }
 
@@ -217,7 +218,7 @@ add_enctype_to_key_set(Key **key_set, size_t *nkeyset,
     key.key.keyvalue.data = NULL;
 
     if (salt) {
     key.key.keyvalue.data = NULL;
 
     if (salt) {
-       key.salt = malloc(sizeof(*key.salt));
+       key.salt = calloc(1, sizeof(*key.salt));
        if (key.salt == NULL) {
            free_Key(&key);
            return ENOMEM;
        if (key.salt == NULL) {
            free_Key(&key);
            return ENOMEM;
@@ -259,7 +260,6 @@ hdb_generate_key_set(krb5_context context, krb5_principal principal,
     Key *k, *key_set;
     int i, j;
     char *default_keytypes[] = {
     Key *k, *key_set;
     int i, j;
     char *default_keytypes[] = {
-       "des:pw-salt",
        "aes256-cts-hmac-sha1-96:pw-salt",
        "des3-cbc-sha1:pw-salt",
        "arcfour-hmac-md5:pw-salt",
        "aes256-cts-hmac-sha1-96:pw-salt",
        "des3-cbc-sha1:pw-salt",
        "arcfour-hmac-md5:pw-salt",
@@ -271,9 +271,6 @@ hdb_generate_key_set(krb5_context context, krb5_principal principal,
     if (ktypes == NULL)
        ktypes = default_keytypes;
 
     if (ktypes == NULL)
        ktypes = default_keytypes;
 
-    if (ktypes == NULL)
-       abort();
-
     *ret_key_set = key_set = NULL;
     *nkeyset = 0;
 
     *ret_key_set = key_set = NULL;
     *nkeyset = 0;
 
index a890ba62cd8a51ee1d4bdf76950bb7084401836c..97989a97641a1f3e6d0c5357d25ec602aad792dc 100644 (file)
@@ -59,7 +59,7 @@ hdb_resolve(krb5_context context, const char *name, krb5_keytab id)
        return ENOMEM;
     }
     db = name;
        return ENOMEM;
     }
     db = name;
-    mkey = strrchr(name, ':');
+    mkey = strchr(name, ':');
     if(mkey == NULL || mkey[1] == '\0') {
        if(*name == '\0')
            d->dbname = NULL;
     if(mkey == NULL || mkey[1] == '\0') {
        if(*name == '\0')
            d->dbname = NULL;
@@ -147,7 +147,7 @@ find_db (krb5_context context,
     const krb5_config_binding *top_bind = NULL;
     const krb5_config_binding *default_binding = NULL;
     const krb5_config_binding *db;
     const krb5_config_binding *top_bind = NULL;
     const krb5_config_binding *default_binding = NULL;
     const krb5_config_binding *db;
-    krb5_realm *prealm = krb5_princ_realm(context, rk_UNCONST(principal));
+    krb5_const_realm realm = krb5_principal_get_realm(context, principal);
 
     *dbname = *mkey = NULL;
 
 
     *dbname = *mkey = NULL;
 
@@ -169,7 +169,7 @@ find_db (krb5_context context,
                krb5_warnx(context, "WARNING: using the first encountered");
            } else
                default_binding = db;
                krb5_warnx(context, "WARNING: using the first encountered");
            } else
                default_binding = db;
-       } else if (strcmp (*prealm, p) == 0) {
+       } else if (strcmp (realm, p) == 0) {
            set_config (context, db, dbname, mkey);
            break;
        }
            set_config (context, db, dbname, mkey);
            break;
        }
@@ -263,6 +263,7 @@ krb5_kt_ops hdb_kt_ops = {
     hdb_resolve,
     hdb_get_name,
     hdb_close,
     hdb_resolve,
     hdb_get_name,
     hdb_close,
+    NULL,              /* destroy */
     hdb_get_entry,
     NULL,              /* start_seq_get */
     NULL,              /* next_entry */
     hdb_get_entry,
     NULL,              /* start_seq_get */
     NULL,              /* next_entry */
index ce1aa9aff15c476895006ff0eb4961b93bf171e3..1520c4f7e9a06641afcb71da5ab5a58035e03e91 100644 (file)
@@ -169,23 +169,24 @@ read_master_mit(krb5_context context, const char *filename,
        return errno;
     }
     krb5_storage_set_flags(sp, KRB5_STORAGE_HOST_BYTEORDER);
        return errno;
     }
     krb5_storage_set_flags(sp, KRB5_STORAGE_HOST_BYTEORDER);
-#if 0
     /* could possibly use ret_keyblock here, but do it with more
        checks for now */
     /* could possibly use ret_keyblock here, but do it with more
        checks for now */
-    ret = krb5_ret_keyblock(sp, &key);
-#else
-    ret = krb5_ret_int16(sp, &enctype);
-    if((htons(enctype) & 0xff00) == 0x3000) {
-       ret = HEIM_ERR_BAD_MKEY;
-       krb5_set_error_message(context, ret, "unknown keytype in %s: %#x, expected %#x",
-                              filename, htons(enctype), 0x3000);
-       goto out;
+    {
+       ret = krb5_ret_int16(sp, &enctype);
+       if (ret)
+           goto out;
+       if((htons(enctype) & 0xff00) == 0x3000) {
+           ret = HEIM_ERR_BAD_MKEY;
+           krb5_set_error_message(context, ret, "unknown keytype in %s: "
+                                  "%#x, expected %#x",
+                                  filename, htons(enctype), 0x3000);
+           goto out;
+       }
+       key.keytype = enctype;
+       ret = krb5_ret_data(sp, &key.keyvalue);
+       if(ret)
+           goto out;
     }
     }
-    key.keytype = enctype;
-    ret = krb5_ret_data(sp, &key.keyvalue);
-    if(ret)
-       goto out;
-#endif
     ret = hdb_process_master_key(context, 0, &key, 0, mkey);
     krb5_free_keyblock_contents(context, &key);
   out:
     ret = hdb_process_master_key(context, 0, &key, 0, mkey);
     krb5_free_keyblock_contents(context, &key);
   out:
index e71125c61fb10c15992799a91880ad8aefa97922..1e9df8165202b2cd85a693d5d50349c9b40517c2 100644 (file)
@@ -53,9 +53,7 @@ struct ndbm_db {
 static krb5_error_code
 NDBM_destroy(krb5_context context, HDB *db)
 {
 static krb5_error_code
 NDBM_destroy(krb5_context context, HDB *db)
 {
-    krb5_error_code ret;
-
-    ret = hdb_clear_master_key (context, db);
+    hdb_clear_master_key (context, db);
     free(db->hdb_name);
     free(db);
     return 0;
     free(db->hdb_name);
     free(db);
     return 0;
index cbd58ebd019b347f940b6b56693ceb0c9f2b9084..624d74289df701332a286aae4bbe474cf5911543 100644 (file)
@@ -33,7 +33,6 @@
 
 #include "hx_locl.h"
 #include <pkinit_asn1.h>
 
 #include "hx_locl.h"
 #include <pkinit_asn1.h>
-RCSID("$Id$");
 
 /**
  * @page page_ca Hx509 CA functions
 
 /**
  * @page page_ca Hx509 CA functions
@@ -672,7 +671,7 @@ hx509_ca_tbs_add_san_pkinit(hx509_context context,
 
     ret = hx509_ca_tbs_add_san_otherName(context,
                                         tbs,
 
     ret = hx509_ca_tbs_add_san_otherName(context,
                                         tbs,
-                                        oid_id_pkinit_san(),
+                                        &asn1_oid_id_pkinit_san,
                                         &os);
     free(os.data);
 out:
                                         &os);
     free(os.data);
 out:
@@ -736,7 +735,7 @@ hx509_ca_tbs_add_san_ms_upn(hx509_context context,
                            hx509_ca_tbs tbs,
                            const char *principal)
 {
                            hx509_ca_tbs tbs,
                            const char *principal)
 {
-    return add_utf8_san(context, tbs, oid_id_pkinit_ms_san(), principal);
+    return add_utf8_san(context, tbs, &asn1_oid_id_pkinit_ms_san, principal);
 }
 
 /**
 }
 
 /**
@@ -757,7 +756,7 @@ hx509_ca_tbs_add_san_jid(hx509_context context,
                         hx509_ca_tbs tbs,
                         const char *jid)
 {
                         hx509_ca_tbs tbs,
                         const char *jid)
 {
-    return add_utf8_san(context, tbs, oid_id_pkix_on_xmppAddr(), jid);
+    return add_utf8_san(context, tbs, &asn1_oid_id_pkix_on_xmppAddr, jid);
 }
 
 
 }
 
 
@@ -926,7 +925,7 @@ build_proxy_prefix(hx509_context context, const Name *issuer, Name *subject)
        return ENOMEM;
     }
     /* prefix with CN=<ts>,...*/
        return ENOMEM;
     }
     /* prefix with CN=<ts>,...*/
-    ret = _hx509_name_modify(context, subject, 1, oid_id_at_commonName(), tstr);
+    ret = _hx509_name_modify(context, subject, 1, &asn1_oid_id_at_commonName, tstr);
     free(tstr);
     if (ret)
        free_Name(subject);
     free(tstr);
     if (ret)
        free_Name(subject);
@@ -1110,7 +1109,7 @@ ca_sign(hx509_context context,
        data.length = 34;
 
        ret = add_extension(context, tbsc, 0,
        data.length = 34;
 
        ret = add_extension(context, tbsc, 0,
-                           oid_id_ms_cert_enroll_domaincontroller(),
+                           &asn1_oid_id_ms_cert_enroll_domaincontroller,
                            &data);
        if (ret)
            goto out;
                            &data);
        if (ret)
            goto out;
@@ -1129,7 +1128,7 @@ ca_sign(hx509_context context,
        if (size != data.length)
            _hx509_abort("internal ASN.1 encoder error");
        ret = add_extension(context, tbsc, 1,
        if (size != data.length)
            _hx509_abort("internal ASN.1 encoder error");
        ret = add_extension(context, tbsc, 1,
-                           oid_id_x509_ce_keyUsage(), &data);
+                           &asn1_oid_id_x509_ce_keyUsage, &data);
        free(data.data);
        if (ret)
            goto out;
        free(data.data);
        if (ret)
            goto out;
@@ -1146,7 +1145,7 @@ ca_sign(hx509_context context,
        if (size != data.length)
            _hx509_abort("internal ASN.1 encoder error");
        ret = add_extension(context, tbsc, 0,
        if (size != data.length)
            _hx509_abort("internal ASN.1 encoder error");
        ret = add_extension(context, tbsc, 0,
-                           oid_id_x509_ce_extKeyUsage(), &data);
+                           &asn1_oid_id_x509_ce_extKeyUsage, &data);
        free(data.data);
        if (ret)
            goto out;
        free(data.data);
        if (ret)
            goto out;
@@ -1163,7 +1162,7 @@ ca_sign(hx509_context context,
        if (size != data.length)
            _hx509_abort("internal ASN.1 encoder error");
        ret = add_extension(context, tbsc, 0,
        if (size != data.length)
            _hx509_abort("internal ASN.1 encoder error");
        ret = add_extension(context, tbsc, 0,
-                           oid_id_x509_ce_subjectAltName(),
+                           &asn1_oid_id_x509_ce_subjectAltName,
                            &data);
        free(data.data);
        if (ret)
                            &data);
        free(data.data);
        if (ret)
@@ -1181,7 +1180,7 @@ ca_sign(hx509_context context,
        if (size != data.length)
            _hx509_abort("internal ASN.1 encoder error");
        ret = add_extension(context, tbsc, 0,
        if (size != data.length)
            _hx509_abort("internal ASN.1 encoder error");
        ret = add_extension(context, tbsc, 0,
-                           oid_id_x509_ce_authorityKeyIdentifier(),
+                           &asn1_oid_id_x509_ce_authorityKeyIdentifier,
                            &data);
        free(data.data);
        if (ret)
                            &data);
        free(data.data);
        if (ret)
@@ -1214,7 +1213,7 @@ ca_sign(hx509_context context,
        if (size != data.length)
            _hx509_abort("internal ASN.1 encoder error");
        ret = add_extension(context, tbsc, 0,
        if (size != data.length)
            _hx509_abort("internal ASN.1 encoder error");
        ret = add_extension(context, tbsc, 0,
-                           oid_id_x509_ce_subjectKeyIdentifier(),
+                           &asn1_oid_id_x509_ce_subjectKeyIdentifier,
                            &data);
        free(data.data);
        if (ret)
                            &data);
        free(data.data);
        if (ret)
@@ -1247,7 +1246,7 @@ ca_sign(hx509_context context,
            _hx509_abort("internal ASN.1 encoder error");
        /* Critical if this is a CA */
        ret = add_extension(context, tbsc, tbs->flags.ca,
            _hx509_abort("internal ASN.1 encoder error");
        /* Critical if this is a CA */
        ret = add_extension(context, tbsc, tbs->flags.ca,
-                           oid_id_x509_ce_basicConstraints(),
+                           &asn1_oid_id_x509_ce_basicConstraints,
                            &data);
        free(data.data);
        if (ret)
                            &data);
        free(data.data);
        if (ret)
@@ -1271,7 +1270,7 @@ ca_sign(hx509_context context,
            *info.pCPathLenConstraint = tbs->pathLenConstraint;
        }
 
            *info.pCPathLenConstraint = tbs->pathLenConstraint;
        }
 
-       ret = der_copy_oid(oid_id_pkix_ppl_inheritAll(),
+       ret = der_copy_oid(&asn1_oid_id_pkix_ppl_inheritAll,
                           &info.proxyPolicy.policyLanguage);
        if (ret) {
            free_ProxyCertInfo(&info);
                           &info.proxyPolicy.policyLanguage);
        if (ret) {
            free_ProxyCertInfo(&info);
@@ -1289,7 +1288,7 @@ ca_sign(hx509_context context,
        if (size != data.length)
            _hx509_abort("internal ASN.1 encoder error");
        ret = add_extension(context, tbsc, 0,
        if (size != data.length)
            _hx509_abort("internal ASN.1 encoder error");
        ret = add_extension(context, tbsc, 0,
-                           oid_id_pkix_pe_proxyCertInfo(),
+                           &asn1_oid_id_pkix_pe_proxyCertInfo,
                            &data);
        free(data.data);
        if (ret)
                            &data);
        free(data.data);
        if (ret)
@@ -1307,7 +1306,7 @@ ca_sign(hx509_context context,
        if (size != data.length)
            _hx509_abort("internal ASN.1 encoder error");
        ret = add_extension(context, tbsc, FALSE,
        if (size != data.length)
            _hx509_abort("internal ASN.1 encoder error");
        ret = add_extension(context, tbsc, FALSE,
-                           oid_id_x509_ce_cRLDistributionPoints(),
+                           &asn1_oid_id_x509_ce_cRLDistributionPoints,
                            &data);
        free(data.data);
        if (ret)
                            &data);
        free(data.data);
        if (ret)
@@ -1399,8 +1398,7 @@ get_AuthorityKeyIdentifier(hx509_context context,
         */
 
        ret = copy_Name(&certificate->tbsCertificate.subject, &name);
         */
 
        ret = copy_Name(&certificate->tbsCertificate.subject, &name);
-       if (ai->authorityCertSerialNumber == NULL) {
-           ret = ENOMEM;
+       if (ret) {
            hx509_set_error_string(context, 0, ret, "Out of memory");
            goto out;
        }
            hx509_set_error_string(context, 0, ret, "Out of memory");
            goto out;
        }
index 121847faaaa238104743be56fa8c0097021564a9..cd9ae01fac06ac23bf693296e3b52d9e50c94807 100644 (file)
@@ -32,7 +32,6 @@
  */
 
 #include "hx_locl.h"
  */
 
 #include "hx_locl.h"
-RCSID("$Id$");
 #include "crypto-headers.h"
 #include <rtbl.h>
 
 #include "crypto-headers.h"
 #include <rtbl.h>
 
@@ -59,6 +58,7 @@ struct hx509_verify_ctx_data {
 #define HX509_VERIFY_CTX_F_REQUIRE_RFC3280             4
 #define HX509_VERIFY_CTX_F_CHECK_TRUST_ANCHORS         8
 #define HX509_VERIFY_CTX_F_NO_DEFAULT_ANCHORS          16
 #define HX509_VERIFY_CTX_F_REQUIRE_RFC3280             4
 #define HX509_VERIFY_CTX_F_CHECK_TRUST_ANCHORS         8
 #define HX509_VERIFY_CTX_F_NO_DEFAULT_ANCHORS          16
+#define HX509_VERIFY_CTX_F_NO_BEST_BEFORE_CHECK                32
     time_t time_now;
     unsigned int max_depth;
 #define HX509_VERIFY_MAX_DEPTH 30
     time_t time_now;
     unsigned int max_depth;
 #define HX509_VERIFY_MAX_DEPTH 30
@@ -432,6 +432,7 @@ hx509_verify_destroy_ctx(hx509_verify_ctx ctx)
  * Set the trust anchors in the verification context, makes an
  * reference to the keyset, so the consumer can free the keyset
  * independent of the destruction of the verification context (ctx).
  * Set the trust anchors in the verification context, makes an
  * reference to the keyset, so the consumer can free the keyset
  * independent of the destruction of the verification context (ctx).
+ * If there already is a keyset attached, it's released.
  *
  * @param ctx a verification context
  * @param set a keyset containing the trust anchors.
  *
  * @param ctx a verification context
  * @param set a keyset containing the trust anchors.
@@ -442,6 +443,8 @@ hx509_verify_destroy_ctx(hx509_verify_ctx ctx)
 void
 hx509_verify_attach_anchors(hx509_verify_ctx ctx, hx509_certs set)
 {
 void
 hx509_verify_attach_anchors(hx509_verify_ctx ctx, hx509_certs set)
 {
+    if (ctx->trust_anchors)
+       hx509_certs_free(&ctx->trust_anchors);
     ctx->trust_anchors = _hx509_certs_ref(set);
 }
 
     ctx->trust_anchors = _hx509_certs_ref(set);
 }
 
@@ -569,6 +572,16 @@ hx509_verify_ctx_f_allow_default_trustanchors(hx509_verify_ctx ctx, int boolean)
        ctx->flags |= HX509_VERIFY_CTX_F_NO_DEFAULT_ANCHORS;
 }
 
        ctx->flags |= HX509_VERIFY_CTX_F_NO_DEFAULT_ANCHORS;
 }
 
+void
+hx509_verify_ctx_f_allow_best_before_signature_algs(hx509_context ctx, 
+                                                   int boolean)
+{
+    if (boolean)
+       ctx->flags &= ~HX509_VERIFY_CTX_F_NO_BEST_BEFORE_CHECK;
+    else
+       ctx->flags |= HX509_VERIFY_CTX_F_NO_BEST_BEFORE_CHECK;
+}
+
 static const Extension *
 find_extension(const Certificate *cert, const heim_oid *oid, int *idx)
 {
 static const Extension *
 find_extension(const Certificate *cert, const heim_oid *oid, int *idx)
 {
@@ -594,7 +607,7 @@ find_extension_auth_key_id(const Certificate *subject,
 
     memset(ai, 0, sizeof(*ai));
 
 
     memset(ai, 0, sizeof(*ai));
 
-    e = find_extension(subject, oid_id_x509_ce_authorityKeyIdentifier(), &i);
+    e = find_extension(subject, &asn1_oid_id_x509_ce_authorityKeyIdentifier, &i);
     if (e == NULL)
        return HX509_EXTENSION_NOT_FOUND;
 
     if (e == NULL)
        return HX509_EXTENSION_NOT_FOUND;
 
@@ -613,7 +626,7 @@ _hx509_find_extension_subject_key_id(const Certificate *issuer,
 
     memset(si, 0, sizeof(*si));
 
 
     memset(si, 0, sizeof(*si));
 
-    e = find_extension(issuer, oid_id_x509_ce_subjectKeyIdentifier(), &i);
+    e = find_extension(issuer, &asn1_oid_id_x509_ce_subjectKeyIdentifier, &i);
     if (e == NULL)
        return HX509_EXTENSION_NOT_FOUND;
 
     if (e == NULL)
        return HX509_EXTENSION_NOT_FOUND;
 
@@ -632,7 +645,7 @@ find_extension_name_constraints(const Certificate *subject,
 
     memset(nc, 0, sizeof(*nc));
 
 
     memset(nc, 0, sizeof(*nc));
 
-    e = find_extension(subject, oid_id_x509_ce_nameConstraints(), &i);
+    e = find_extension(subject, &asn1_oid_id_x509_ce_nameConstraints, &i);
     if (e == NULL)
        return HX509_EXTENSION_NOT_FOUND;
 
     if (e == NULL)
        return HX509_EXTENSION_NOT_FOUND;
 
@@ -650,7 +663,7 @@ find_extension_subject_alt_name(const Certificate *cert, int *i,
 
     memset(sa, 0, sizeof(*sa));
 
 
     memset(sa, 0, sizeof(*sa));
 
-    e = find_extension(cert, oid_id_x509_ce_subjectAltName(), i);
+    e = find_extension(cert, &asn1_oid_id_x509_ce_subjectAltName, i);
     if (e == NULL)
        return HX509_EXTENSION_NOT_FOUND;
 
     if (e == NULL)
        return HX509_EXTENSION_NOT_FOUND;
 
@@ -668,7 +681,7 @@ find_extension_eku(const Certificate *cert, ExtKeyUsage *eku)
 
     memset(eku, 0, sizeof(*eku));
 
 
     memset(eku, 0, sizeof(*eku));
 
-    e = find_extension(cert, oid_id_x509_ce_extKeyUsage(), &i);
+    e = find_extension(cert, &asn1_oid_id_x509_ce_extKeyUsage, &i);
     if (e == NULL)
        return HX509_EXTENSION_NOT_FOUND;
 
     if (e == NULL)
        return HX509_EXTENSION_NOT_FOUND;
 
@@ -748,8 +761,7 @@ hx509_cert_find_subjectAltName_otherName(hx509_context context,
        ret = find_extension_subject_alt_name(_hx509_get_cert(cert), &i, &sa);
        i++;
        if (ret == HX509_EXTENSION_NOT_FOUND) {
        ret = find_extension_subject_alt_name(_hx509_get_cert(cert), &i, &sa);
        i++;
        if (ret == HX509_EXTENSION_NOT_FOUND) {
-           ret = 0;
-           break;
+           return 0;
        } else if (ret != 0) {
            hx509_set_error_string(context, 0, ret, "Error searching for SAN");
            hx509_free_octet_string_list(list);
        } else if (ret != 0) {
            hx509_set_error_string(context, 0, ret, "Error searching for SAN");
            hx509_free_octet_string_list(list);
@@ -773,7 +785,6 @@ hx509_cert_find_subjectAltName_otherName(hx509_context context,
        }
        free_GeneralNames(&sa);
     }
        }
        free_GeneralNames(&sa);
     }
-    return 0;
 }
 
 
 }
 
 
@@ -790,7 +801,7 @@ check_key_usage(hx509_context context, const Certificate *cert,
     if (_hx509_cert_get_version(cert) < 3)
        return 0;
 
     if (_hx509_cert_get_version(cert) < 3)
        return 0;
 
-    e = find_extension(cert, oid_id_x509_ce_keyUsage(), &i);
+    e = find_extension(cert, &asn1_oid_id_x509_ce_keyUsage, &i);
     if (e == NULL) {
        if (req_present) {
            hx509_set_error_string(context, 0, HX509_KU_CERT_MISSING,
     if (e == NULL) {
        if (req_present) {
            hx509_set_error_string(context, 0, HX509_KU_CERT_MISSING,
@@ -847,7 +858,7 @@ check_basic_constraints(hx509_context context, const Certificate *cert,
     if (_hx509_cert_get_version(cert) < 3)
        return 0;
 
     if (_hx509_cert_get_version(cert) < 3)
        return 0;
 
-    e = find_extension(cert, oid_id_x509_ce_basicConstraints(), &i);
+    e = find_extension(cert, &asn1_oid_id_x509_ce_basicConstraints, &i);
     if (e == NULL) {
        switch(type) {
        case PROXY_CERT:
     if (e == NULL) {
        switch(type) {
        case PROXY_CERT:
@@ -1134,7 +1145,7 @@ is_proxy_cert(hx509_context context,
     if (rinfo)
        memset(rinfo, 0, sizeof(*rinfo));
 
     if (rinfo)
        memset(rinfo, 0, sizeof(*rinfo));
 
-    e = find_extension(cert, oid_id_pkix_pe_proxyCertInfo(), &i);
+    e = find_extension(cert, &asn1_oid_id_pkix_pe_proxyCertInfo, &i);
     if (e == NULL) {
        hx509_clear_error_string(context);
        return HX509_EXTENSION_NOT_FOUND;
     if (e == NULL) {
        hx509_clear_error_string(context);
        return HX509_EXTENSION_NOT_FOUND;
@@ -1472,7 +1483,9 @@ hx509_cert_get_SPKI(hx509_context context, hx509_cert p, SubjectPublicKeyInfo *s
  * @param context a hx509 context.
  * @param p a hx509 certificate object.
  * @param alg AlgorithmIdentifier, should be freed with
  * @param context a hx509 context.
  * @param p a hx509 certificate object.
  * @param alg AlgorithmIdentifier, should be freed with
- * free_AlgorithmIdentifier().
+ *            free_AlgorithmIdentifier(). The algorithmidentifier is
+ *            typicly rsaEncryption, or id-ecPublicKey, or some other
+ *            public key mechanism.
  *
  * @return An hx509 error code, see hx509_get_error_string().
  *
  *
  * @return An hx509 error code, see hx509_get_error_string().
  *
@@ -2003,7 +2016,7 @@ hx509_verify_path(hx509_context context,
                free_ProxyCertInfo(&info);
                
                j = 0;
                free_ProxyCertInfo(&info);
                
                j = 0;
-               if (find_extension(c, oid_id_x509_ce_subjectAltName(), &j)) {
+               if (find_extension(c, &asn1_oid_id_x509_ce_subjectAltName, &j)) {
                    ret = HX509_PROXY_CERT_INVALID;
                    hx509_set_error_string(context, 0, ret,
                                           "Proxy certificate have explicity "
                    ret = HX509_PROXY_CERT_INVALID;
                    hx509_set_error_string(context, 0, ret,
                                           "Proxy certificate have explicity "
@@ -2012,7 +2025,7 @@ hx509_verify_path(hx509_context context,
                }
 
                j = 0;
                }
 
                j = 0;
-               if (find_extension(c, oid_id_x509_ce_issuerAltName(), &j)) {
+               if (find_extension(c, &asn1_oid_id_x509_ce_issuerAltName, &j)) {
                    ret = HX509_PROXY_CERT_INVALID;
                    hx509_set_error_string(context, 0, ret,
                                           "Proxy certificate have explicity "
                    ret = HX509_PROXY_CERT_INVALID;
                    hx509_set_error_string(context, 0, ret,
                                           "Proxy certificate have explicity "
@@ -2053,7 +2066,7 @@ hx509_verify_path(hx509_context context,
                if (proxy_issuer.u.rdnSequence.len < 2
                    || proxy_issuer.u.rdnSequence.val[j - 1].len > 1
                    || der_heim_oid_cmp(&proxy_issuer.u.rdnSequence.val[j - 1].val[0].type,
                if (proxy_issuer.u.rdnSequence.len < 2
                    || proxy_issuer.u.rdnSequence.val[j - 1].len > 1
                    || der_heim_oid_cmp(&proxy_issuer.u.rdnSequence.val[j - 1].val[0].type,
-                                       oid_id_at_commonName()))
+                                       &asn1_oid_id_at_commonName))
                {
                    ret = HX509_PROXY_CERT_NAME_WRONG;
                    hx509_set_error_string(context, 0, ret,
                {
                    ret = HX509_PROXY_CERT_NAME_WRONG;
                    hx509_set_error_string(context, 0, ret,
@@ -2263,6 +2276,24 @@ hx509_verify_path(hx509_context context,
                                   "Failed to verify signature of certificate");
            goto out;
        }
                                   "Failed to verify signature of certificate");
            goto out;
        }
+       /* 
+        * Verify that the sigature algorithm "best-before" date is
+        * before the creation date of the certificate, do this for
+        * trust anchors too, since any trust anchor that is created
+        * after a algorithm is known to be bad deserved to be invalid.
+        *
+        * Skip the leaf certificate for now...
+        */
+
+       if (i != 0 && (ctx->flags & HX509_VERIFY_CTX_F_NO_BEST_BEFORE_CHECK) == 0) {
+           time_t notBefore = 
+               _hx509_Time2time_t(&c->tbsCertificate.validity.notBefore);
+           ret = _hx509_signature_best_before(context,
+                                              &c->signatureAlgorithm,
+                                              notBefore);
+           if (ret)
+               goto out;
+       }
     }
 
 out:
     }
 
 out:
@@ -2329,6 +2360,7 @@ hx509_verify_hostname(hx509_context context,
                      /* XXX krb5_socklen_t */ int sa_size)
 {
     GeneralNames san;
                      /* XXX krb5_socklen_t */ int sa_size)
 {
     GeneralNames san;
+    const Name *name;
     int ret, i, j;
 
     if (sa && sa_size <= 0)
     int ret, i, j;
 
     if (sa && sa_size <= 0)
@@ -2339,11 +2371,10 @@ hx509_verify_hostname(hx509_context context,
     i = 0;
     do {
        ret = find_extension_subject_alt_name(cert->data, &i, &san);
     i = 0;
     do {
        ret = find_extension_subject_alt_name(cert->data, &i, &san);
-       if (ret == HX509_EXTENSION_NOT_FOUND) {
-           ret = 0;
-           break;
-       } else if (ret != 0)
+       if (ret == HX509_EXTENSION_NOT_FOUND)
            break;
            break;
+       else if (ret != 0)
+           return HX509_PARSING_NAME_FAILED;
 
        for (j = 0; j < san.len; j++) {
            switch (san.val[j].element) {
 
        for (j = 0; j < san.len; j++) {
            switch (san.val[j].element) {
@@ -2360,31 +2391,31 @@ hx509_verify_hostname(hx509_context context,
        free_GeneralNames(&san);
     } while (1);
 
        free_GeneralNames(&san);
     } while (1);
 
-    {
-       const Name *name = &cert->data->tbsCertificate.subject;
-
-       /* match if first component is a CN= */
-       if (name->u.rdnSequence.len > 0
-           && name->u.rdnSequence.val[0].len == 1
-           && der_heim_oid_cmp(&name->u.rdnSequence.val[0].val[0].type,
-                               oid_id_at_commonName()) == 0)
-       {
-           DirectoryString *ds = &name->u.rdnSequence.val[0].val[0].value;
-
-           switch (ds->element) {
-           case choice_DirectoryString_printableString:
-               if (strcasecmp(ds->u.printableString, hostname) == 0)
-                   return 0;
-               break;
-           case choice_DirectoryString_ia5String:
-               if (strcasecmp(ds->u.ia5String, hostname) == 0)
+    name = &cert->data->tbsCertificate.subject;
+
+    /* Find first CN= in the name, and try to match the hostname on that */
+    for (ret = 0, i = name->u.rdnSequence.len - 1; ret == 0 && i >= 0; i--) {
+       for (j = 0; ret == 0 && j < name->u.rdnSequence.val[i].len; j++) {
+           AttributeTypeAndValue *n = &name->u.rdnSequence.val[i].val[j];
+
+           if (der_heim_oid_cmp(&n->type, &asn1_oid_id_at_commonName) == 0) {
+               DirectoryString *ds = &n->value;
+               switch (ds->element) {
+               case choice_DirectoryString_printableString:
+                   if (strcasecmp(ds->u.printableString, hostname) == 0)
+                       return 0;
+                   break;
+               case choice_DirectoryString_ia5String:
+                   if (strcasecmp(ds->u.ia5String, hostname) == 0)
                    return 0;
                    return 0;
-               break;
-           case choice_DirectoryString_utf8String:
-               if (strcasecmp(ds->u.utf8String, hostname) == 0)
-                   return 0;
-           default:
-               break;
+                   break;
+               case choice_DirectoryString_utf8String:
+                   if (strcasecmp(ds->u.utf8String, hostname) == 0)
+                       return 0;
+               default:
+                   break;
+               }
+               ret = HX509_NAME_CONSTRAINT_ERROR;
            }
        }
     }
            }
        }
     }
@@ -2495,7 +2526,7 @@ hx509_cert_get_friendly_name(hx509_cert cert)
     if (cert->friendlyname)
        return cert->friendlyname;
 
     if (cert->friendlyname)
        return cert->friendlyname;
 
-    a = hx509_cert_get_attribute(cert, oid_id_pkcs_9_at_friendlyName());
+    a = hx509_cert_get_attribute(cert, &asn1_oid_id_pkcs_9_at_friendlyName);
     if (a == NULL) {
        hx509_name name;
 
     if (a == NULL) {
        hx509_name name;
 
@@ -2746,7 +2777,7 @@ hx509_query_match_expr(hx509_context context, hx509_query *q, const char *expr)
 
 int
 hx509_query_match_cmp_func(hx509_query *q,
 
 int
 hx509_query_match_cmp_func(hx509_query *q,
-                          int (*func)(void *, hx509_cert),
+                          int (*func)(hx509_context, hx509_cert, void *),
                           void *ctx)
 {
     if (func)
                           void *ctx)
 {
     if (func)
@@ -2869,7 +2900,7 @@ _hx509_query_match_cert(hx509_context context, const hx509_query *q, hx509_cert
     if (q->match & HX509_QUERY_MATCH_LOCAL_KEY_ID) {
        hx509_cert_attribute a;
 
     if (q->match & HX509_QUERY_MATCH_LOCAL_KEY_ID) {
        hx509_cert_attribute a;
 
-       a = hx509_cert_get_attribute(cert, oid_id_pkcs_9_at_localKeyId());
+       a = hx509_cert_get_attribute(cert, &asn1_oid_id_pkcs_9_at_localKeyId);
        if (a == NULL)
            return 0;
        if (der_heim_octet_string_cmp(&a->data, q->local_key_id) != 0)
        if (a == NULL)
            return 0;
        if (der_heim_octet_string_cmp(&a->data, q->local_key_id) != 0)
@@ -2891,7 +2922,7 @@ _hx509_query_match_cert(hx509_context context, const hx509_query *q, hx509_cert
            return 0;
     }
     if (q->match & HX509_QUERY_MATCH_FUNCTION) {
            return 0;
     }
     if (q->match & HX509_QUERY_MATCH_FUNCTION) {
-       ret = (*q->cmp_func)(q->cmp_func_ctx, cert);
+       ret = (*q->cmp_func)(context, cert, q->cmp_func_ctx);
        if (ret != 0)
            return 0;
     }
        if (ret != 0)
            return 0;
     }
@@ -3163,7 +3194,7 @@ _hx509_cert_get_keyusage(hx509_context context,
     if (_hx509_cert_get_version(cert) < 3)
        return 0;
 
     if (_hx509_cert_get_version(cert) < 3)
        return 0;
 
-    e = find_extension(cert, oid_id_x509_ce_keyUsage(), &i);
+    e = find_extension(cert, &asn1_oid_id_x509_ce_keyUsage, &i);
     if (e == NULL)
        return HX509_KU_CERT_MISSING;
 
     if (e == NULL)
        return HX509_KU_CERT_MISSING;
 
@@ -3348,6 +3379,46 @@ _hx509_cert_to_env(hx509_context context, hx509_cert cert, hx509_env *env)
        }
     }
 
        }
     }
 
+    {
+       Certificate *c = _hx509_get_cert(cert);
+        heim_octet_string os, sig;
+       hx509_env envhash = NULL;
+       char *buf;
+
+       os.data = c->tbsCertificate.subjectPublicKeyInfo.subjectPublicKey.data;
+       os.length =
+         c->tbsCertificate.subjectPublicKeyInfo.subjectPublicKey.length / 8;
+
+       ret = _hx509_create_signature(context,
+                                     NULL,
+                                     hx509_signature_sha1(),
+                                     &os,
+                                     NULL,
+                                     &sig);
+       if (ret != 0)
+           goto out;
+
+       ret = hex_encode(sig.data, sig.length, &buf);
+       der_free_octet_string(&sig);
+       if (ret < 0) {
+           ret = ENOMEM;
+           hx509_set_error_string(context, 0, ret,
+                                  "Out of memory");
+           goto out;
+       }
+       
+       ret = hx509_env_add(context, &envhash, "sha1", buf);
+       free(buf);
+       if (ret) 
+           goto out;
+
+       ret = hx509_env_add_binding(context, &envcert, "hash", envhash);
+       if (ret) {
+         hx509_env_free(&envhash);
+         goto out;
+       }
+    }
+
     ret = hx509_env_add_binding(context, env, "certificate", envcert);
     if (ret)
        goto out;
     ret = hx509_env_add_binding(context, env, "certificate", envcert);
     if (ret)
        goto out;
index ba1800ddf2fe8174f2269d6567d0ee226dd5b48c..4766c346552966a3aa139d001d7348eac29bf545 100644 (file)
@@ -32,7 +32,6 @@
  */
 
 #include "hx_locl.h"
  */
 
 #include "hx_locl.h"
-RCSID("$Id$");
 
 /**
  * @page page_cms CMS/PKCS7 message functions.
 
 /**
  * @page page_cms CMS/PKCS7 message functions.
@@ -474,6 +473,9 @@ hx509_cms_unenvelope(hx509_context context,
        if (ret)
            goto out;
        
        if (ret)
            goto out;
        
+       if (flags & HX509_CMS_UE_ALLOW_WEAK)
+           hx509_crypto_allow_weak(crypto);
+
        if (params) {
            ret = hx509_crypto_set_params(context, crypto, params, &ivec);
            if (ret) {
        if (params) {
            ret = hx509_crypto_set_params(context, crypto, params, &ivec);
            if (ret) {
@@ -527,7 +529,9 @@ out:
  * used to RSA.
  *
  * @param context A hx509 context.
  * used to RSA.
  *
  * @param context A hx509 context.
- * @param flags flags to control the behavior, no flags today
+ * @param flags flags to control the behavior.
+ *    - HX509_CMS_EV_NO_KU_CHECK - Dont check KU on certificate
+ *    - HX509_CMS_EV_ALLOW_WEAK - Allow weak crytpo
  * @param cert Certificate to encrypt the EnvelopedData encryption key
  * with.
  * @param data pointer the data to encrypt.
  * @param cert Certificate to encrypt the EnvelopedData encryption key
  * with.
  * @param data pointer the data to encrypt.
@@ -565,16 +569,21 @@ hx509_cms_envelope_1(hx509_context context,
     memset(content, 0, sizeof(*content));
 
     if (encryption_type == NULL)
     memset(content, 0, sizeof(*content));
 
     if (encryption_type == NULL)
-       encryption_type = oid_id_aes_256_cbc();
+       encryption_type = &asn1_oid_id_aes_256_cbc;
 
 
-    ret = _hx509_check_key_usage(context, cert, 1 << 2, TRUE);
-    if (ret)
-       goto out;
+    if ((flags & HX509_CMS_EV_NO_KU_CHECK) == 0) {
+       ret = _hx509_check_key_usage(context, cert, 1 << 2, TRUE);
+       if (ret)
+           goto out;
+    }
 
     ret = hx509_crypto_init(context, NULL, encryption_type, &crypto);
     if (ret)
        goto out;
 
 
     ret = hx509_crypto_init(context, NULL, encryption_type, &crypto);
     if (ret)
        goto out;
 
+    if (flags & HX509_CMS_EV_ALLOW_WEAK)
+       hx509_crypto_allow_weak(crypto);
+
     ret = hx509_crypto_set_random_key(crypto, &key);
     if (ret) {
        hx509_set_error_string(context, 0, ret,
     ret = hx509_crypto_set_random_key(crypto, &key);
     if (ret) {
        hx509_set_error_string(context, 0, ret,
@@ -738,12 +747,16 @@ find_attribute(const CMSAttributes *attr, const heim_oid *oid)
  * Decode SignedData and verify that the signature is correct.
  *
  * @param context A hx509 context.
  * Decode SignedData and verify that the signature is correct.
  *
  * @param context A hx509 context.
- * @param ctx a hx509 version context
- * @param data
+ * @param ctx a hx509 verify context.
+ * @param flags to control the behaivor of the function.
+ *    - HX509_CMS_VS_NO_KU_CHECK - Don't check KeyUsage
+ *    - HX509_CMS_VS_ALLOW_DATA_OID_MISMATCH - allow oid mismatch
+ *    - HX509_CMS_VS_ALLOW_ZERO_SIGNER - no signer, see below.
+ * @param data pointer to CMS SignedData encoded data.
  * @param length length of the data that data point to.
  * @param length length of the data that data point to.
- * @param signedContent
+ * @param signedContent external data used for signature.
  * @param pool certificate pool to build certificates paths.
  * @param pool certificate pool to build certificates paths.
- * @param contentType free with der_free_oid()
+ * @param contentType free with der_free_oid().
  * @param content the output of the function, free with
  * der_free_octet_string().
  * @param signer_certs list of the cerficates used to sign this
  * @param content the output of the function, free with
  * der_free_octet_string().
  * @param signer_certs list of the cerficates used to sign this
@@ -755,6 +768,7 @@ find_attribute(const CMSAttributes *attr, const heim_oid *oid)
 int
 hx509_cms_verify_signed(hx509_context context,
                        hx509_verify_ctx ctx,
 int
 hx509_cms_verify_signed(hx509_context context,
                        hx509_verify_ctx ctx,
+                       unsigned int flags,
                        const void *data,
                        size_t length,
                        const heim_octet_string *signedContent,
                        const void *data,
                        size_t length,
                        const heim_octet_string *signedContent,
@@ -797,8 +811,15 @@ hx509_cms_verify_signed(hx509_context context,
                               "Both external and internal SignedData");
        goto out;
     }
                               "Both external and internal SignedData");
        goto out;
     }
+
     if (sd.encapContentInfo.eContent)
     if (sd.encapContentInfo.eContent)
-       signedContent = sd.encapContentInfo.eContent;
+       ret = der_copy_octet_string(sd.encapContentInfo.eContent, content);
+    else
+       ret = der_copy_octet_string(signedContent, content);
+    if (ret) {
+       hx509_set_error_string(context, 0, ret, "malloc: out of memory");
+       goto out;
+    }
 
     ret = hx509_certs_init(context, "MEMORY:cms-cert-buffer",
                           0, NULL, &certs);
 
     ret = hx509_certs_init(context, "MEMORY:cms-cert-buffer",
                           0, NULL, &certs);
@@ -823,7 +844,7 @@ hx509_cms_verify_signed(hx509_context context,
     }
 
     for (found_valid_sig = 0, i = 0; i < sd.signerInfos.len; i++) {
     }
 
     for (found_valid_sig = 0, i = 0; i < sd.signerInfos.len; i++) {
-       heim_octet_string *signed_data;
+       heim_octet_string signed_data;
        const heim_oid *match_oid;
        heim_oid decode_oid;
 
        const heim_oid *match_oid;
        heim_oid decode_oid;
 
@@ -841,8 +862,22 @@ hx509_cms_verify_signed(hx509_context context,
        ret = find_CMSIdentifier(context, &signer_info->sid, certs,
                                 _hx509_verify_get_time(ctx), &cert,
                                 HX509_QUERY_KU_DIGITALSIGNATURE);
        ret = find_CMSIdentifier(context, &signer_info->sid, certs,
                                 _hx509_verify_get_time(ctx), &cert,
                                 HX509_QUERY_KU_DIGITALSIGNATURE);
-       if (ret)
-           continue;
+       if (ret) {
+           /**
+            * If HX509_CMS_VS_NO_KU_CHECK is set, allow more liberal
+            * search for matching certificates by not considering
+            * KeyUsage bits on the certificates.
+            */
+           if ((flags & HX509_CMS_VS_NO_KU_CHECK) == 0)
+               continue;
+
+           ret = find_CMSIdentifier(context, &signer_info->sid, certs,
+                                    _hx509_verify_get_time(ctx), &cert,
+                                    0);
+           if (ret)
+               continue;
+
+       }
 
        if (signer_info->signedAttrs) {
            const Attribute *attr;
 
        if (signer_info->signedAttrs) {
            const Attribute *attr;
@@ -854,7 +889,7 @@ hx509_cms_verify_signed(hx509_context context,
            sa.len = signer_info->signedAttrs->len;
 
            /* verify that sigature exists */
            sa.len = signer_info->signedAttrs->len;
 
            /* verify that sigature exists */
-           attr = find_attribute(&sa, oid_id_pkcs9_messageDigest());
+           attr = find_attribute(&sa, &asn1_oid_id_pkcs9_messageDigest);
            if (attr == NULL) {
                ret = HX509_CRYPTO_SIGNATURE_MISSING;
                hx509_set_error_string(context, 0, ret,
            if (attr == NULL) {
                ret = HX509_CRYPTO_SIGNATURE_MISSING;
                hx509_set_error_string(context, 0, ret,
@@ -885,7 +920,7 @@ hx509_cms_verify_signed(hx509_context context,
            ret = _hx509_verify_signature(context,
                                          NULL,
                                          &signer_info->digestAlgorithm,
            ret = _hx509_verify_signature(context,
                                          NULL,
                                          &signer_info->digestAlgorithm,
-                                         signedContent,
+                                         content,
                                          &os);
            der_free_octet_string(&os);
            if (ret) {
                                          &os);
            der_free_octet_string(&os);
            if (ret) {
@@ -898,9 +933,9 @@ hx509_cms_verify_signed(hx509_context context,
             * Fetch content oid inside signedAttrs or set it to
             * id-pkcs7-data.
             */
             * Fetch content oid inside signedAttrs or set it to
             * id-pkcs7-data.
             */
-           attr = find_attribute(&sa, oid_id_pkcs9_contentType());
+           attr = find_attribute(&sa, &asn1_oid_id_pkcs9_contentType);
            if (attr == NULL) {
            if (attr == NULL) {
-               match_oid = oid_id_pkcs7_data();
+               match_oid = &asn1_oid_id_pkcs7_data;
            } else {
                if (attr->value.len != 1) {
                    ret = HX509_CMS_DATA_OID_MISMATCH;
            } else {
                if (attr->value.len != 1) {
                    ret = HX509_CMS_DATA_OID_MISMATCH;
@@ -922,36 +957,36 @@ hx509_cms_verify_signed(hx509_context context,
                match_oid = &decode_oid;
            }
 
                match_oid = &decode_oid;
            }
 
-           ALLOC(signed_data, 1);
-           if (signed_data == NULL) {
-               if (match_oid == &decode_oid)
-                   der_free_oid(&decode_oid);
-               ret = ENOMEM;
-               hx509_clear_error_string(context);
-               goto next_sigature;
-           }
-       
            ASN1_MALLOC_ENCODE(CMSAttributes,
            ASN1_MALLOC_ENCODE(CMSAttributes,
-                              signed_data->data,
-                              signed_data->length,
+                              signed_data.data,
+                              signed_data.length,
                               &sa,
                               &size, ret);
            if (ret) {
                if (match_oid == &decode_oid)
                    der_free_oid(&decode_oid);
                               &sa,
                               &size, ret);
            if (ret) {
                if (match_oid == &decode_oid)
                    der_free_oid(&decode_oid);
-               free(signed_data);
                hx509_clear_error_string(context);
                goto next_sigature;
            }
                hx509_clear_error_string(context);
                goto next_sigature;
            }
-           if (size != signed_data->length)
+           if (size != signed_data.length)
                _hx509_abort("internal ASN.1 encoder error");
 
        } else {
                _hx509_abort("internal ASN.1 encoder error");
 
        } else {
-           signed_data = rk_UNCONST(signedContent);
-           match_oid = oid_id_pkcs7_data();
+           signed_data.data = content->data;
+           signed_data.length = content->length;
+           match_oid = &asn1_oid_id_pkcs7_data;
        }
 
        }
 
-       if (der_heim_oid_cmp(match_oid, &sd.encapContentInfo.eContentType)) {
+       /**
+        * If HX509_CMS_VS_ALLOW_DATA_OID_MISMATCH, allow
+        * encapContentInfo mismatch with the oid in signedAttributes
+        * (or if no signedAttributes where use, pkcs7-data oid).
+        * This is only needed to work with broken CMS implementations
+        * that doesn't follow CMS signedAttributes rules.
+        */
+
+       if (der_heim_oid_cmp(match_oid, &sd.encapContentInfo.eContentType) &&
+           (flags & HX509_CMS_VS_ALLOW_DATA_OID_MISMATCH) == 0) {
            ret = HX509_CMS_DATA_OID_MISMATCH;
            hx509_set_error_string(context, 0, ret,
                                   "Oid in message mismatch from the expected");
            ret = HX509_CMS_DATA_OID_MISMATCH;
            hx509_set_error_string(context, 0, ret,
                                   "Oid in message mismatch from the expected");
@@ -963,23 +998,28 @@ hx509_cms_verify_signed(hx509_context context,
            ret = hx509_verify_signature(context,
                                         cert,
                                         &signer_info->signatureAlgorithm,
            ret = hx509_verify_signature(context,
                                         cert,
                                         &signer_info->signatureAlgorithm,
-                                        signed_data,
+                                        &signed_data,
                                         &signer_info->signature);
            if (ret)
                hx509_set_error_string(context, HX509_ERROR_APPEND, ret,
                                         &signer_info->signature);
            if (ret)
                hx509_set_error_string(context, HX509_ERROR_APPEND, ret,
-                                      "Failed to verify sigature in "
+                                      "Failed to verify signature in "
                                       "CMS SignedData");
        }
                                       "CMS SignedData");
        }
-       if (signed_data != signedContent) {
-           der_free_octet_string(signed_data);
-           free(signed_data);
-       }
+        if (signer_info->signedAttrs)
+           free(signed_data.data);
        if (ret)
            goto next_sigature;
 
        if (ret)
            goto next_sigature;
 
-       ret = hx509_verify_path(context, ctx, cert, certs);
-       if (ret)
-           goto next_sigature;
+       /** 
+        * If HX509_CMS_VS_NO_VALIDATE flags is set, do not verify the
+        * signing certificates and leave that up to the caller.
+        */
+
+       if ((flags & HX509_CMS_VS_NO_VALIDATE) == 0) {
+           ret = hx509_verify_path(context, ctx, cert, certs);
+           if (ret)
+               goto next_sigature;
+       }
 
        ret = hx509_certs_add(context, *signer_certs, cert);
        if (ret)
 
        ret = hx509_certs_add(context, *signer_certs, cert);
        if (ret)
@@ -992,7 +1032,18 @@ hx509_cms_verify_signed(hx509_context context,
            hx509_cert_free(cert);
        cert = NULL;
     }
            hx509_cert_free(cert);
        cert = NULL;
     }
-    if (found_valid_sig == 0) {
+    /**
+     * If HX509_CMS_VS_ALLOW_ZERO_SIGNER is set, allow empty
+     * SignerInfo (no signatures). If SignedData have no signatures,
+     * the function will return 0 with signer_certs set to NULL. Zero
+     * signers is allowed by the standard, but since its only useful
+     * in corner cases, it make into a flag that the caller have to
+     * turn on.
+     */
+    if (sd.signerInfos.len == 0 && (flags & HX509_CMS_VS_ALLOW_ZERO_SIGNER)) {
+       if (*signer_certs)
+           hx509_certs_free(signer_certs);
+    } else if (found_valid_sig == 0) {
        if (ret == 0) {
            ret = HX509_CMS_SIGNER_NOT_FOUND;
            hx509_set_error_string(context, 0, ret,
        if (ret == 0) {
            ret = HX509_CMS_SIGNER_NOT_FOUND;
            hx509_set_error_string(context, 0, ret,
@@ -1007,20 +1058,13 @@ hx509_cms_verify_signed(hx509_context context,
        goto out;
     }
 
        goto out;
     }
 
-    content->data = malloc(signedContent->length);
-    if (content->data == NULL) {
-       hx509_clear_error_string(context);
-       ret = ENOMEM;
-       goto out;
-    }
-    content->length = signedContent->length;
-    memcpy(content->data, signedContent->data, content->length);
-
 out:
     free_SignedData(&sd);
     if (certs)
        hx509_certs_free(&certs);
     if (ret) {
 out:
     free_SignedData(&sd);
     if (certs)
        hx509_certs_free(&certs);
     if (ret) {
+       if (content->data)
+           der_free_octet_string(content);
        if (*signer_certs)
            hx509_certs_free(signer_certs);
        der_free_oid(contentType);
        if (*signer_certs)
            hx509_certs_free(signer_certs);
        der_free_oid(contentType);
@@ -1097,26 +1141,55 @@ hx509_cms_create_signed_1(hx509_context context,
                          hx509_certs pool,
                          heim_octet_string *signed_data)
 {
                          hx509_certs pool,
                          heim_octet_string *signed_data)
 {
-    AlgorithmIdentifier digest;
-    hx509_name name;
-    SignerInfo *signer_info;
-    heim_octet_string buf, content, sigdata = { 0, NULL };
+    hx509_certs certs;
+    int ret = 0;
+
+    signed_data->data = NULL;
+    signed_data->length = 0;
+
+    ret = hx509_certs_init(context, "MEMORY:certs", 0, NULL, &certs);
+    if (ret)
+       return ret;
+    ret = hx509_certs_add(context, certs, cert);
+    if (ret)
+       goto out;
+
+    ret = hx509_cms_create_signed(context, flags, eContentType, data, length,
+                                 digest_alg, certs, peer, anchors, pool,
+                                 signed_data);
+
+ out:
+    hx509_certs_free(&certs);
+    return ret;
+}
+
+struct sigctx {
     SignedData sd;
     SignedData sd;
-    int ret;
+    const AlgorithmIdentifier *digest_alg;
+    const heim_oid *eContentType;
+    heim_octet_string content;
+    hx509_peer_info peer;
+    int cmsidflag;
+    hx509_certs certs;
+    hx509_certs anchors;
+    hx509_certs pool;
+};
+
+static int
+sig_process(hx509_context context, void *ctx, hx509_cert cert)
+{
+    struct sigctx *sigctx = ctx;
+    heim_octet_string buf, sigdata = { 0, NULL };
+    SignerInfo *signer_info = NULL;
+    AlgorithmIdentifier digest;
     size_t size;
     size_t size;
+    void *ptr;
+    int ret;
+    SignedData *sd = &sigctx->sd;
     hx509_path path;
     hx509_path path;
-    int cmsidflag = CMS_ID_SKI;
 
 
-    memset(&sd, 0, sizeof(sd));
-    memset(&name, 0, sizeof(name));
-    memset(&path, 0, sizeof(path));
     memset(&digest, 0, sizeof(digest));
     memset(&digest, 0, sizeof(digest));
-
-    content.data = rk_UNCONST(data);
-    content.length = length;
-
-    if (flags & HX509_CMS_SIGATURE_ID_NAME)
-       cmsidflag = CMS_ID_NAME;
+    memset(&path, 0, sizeof(path));
 
     if (_hx509_cert_private_key(cert) == NULL) {
        hx509_set_error_string(context, 0, HX509_PRIVATE_KEY_MISSING,
 
     if (_hx509_cert_private_key(cert) == NULL) {
        hx509_set_error_string(context, 0, HX509_PRIVATE_KEY_MISSING,
@@ -1124,55 +1197,37 @@ hx509_cms_create_signed_1(hx509_context context,
        return HX509_PRIVATE_KEY_MISSING;
     }
 
        return HX509_PRIVATE_KEY_MISSING;
     }
 
-    if (digest_alg == NULL) {
-       ret = hx509_crypto_select(context, HX509_SELECT_DIGEST,
-                                 _hx509_cert_private_key(cert), peer, &digest);
-    } else {
-       ret = copy_AlgorithmIdentifier(digest_alg, &digest);
+    if (sigctx->digest_alg) {
+       ret = copy_AlgorithmIdentifier(sigctx->digest_alg, &digest);
        if (ret)
            hx509_clear_error_string(context);
        if (ret)
            hx509_clear_error_string(context);
+    } else {
+       ret = hx509_crypto_select(context, HX509_SELECT_DIGEST,
+                                 _hx509_cert_private_key(cert), 
+                                 sigctx->peer, &digest);
     }
     if (ret)
        goto out;
 
     }
     if (ret)
        goto out;
 
-    sd.version = CMSVersion_v3;
-
-    if (eContentType == NULL)
-       eContentType = oid_id_pkcs7_data();
-
-    der_copy_oid(eContentType, &sd.encapContentInfo.eContentType);
-
-    /* */
-    if ((flags & HX509_CMS_SIGATURE_DETACHED) == 0) {
-       ALLOC(sd.encapContentInfo.eContent, 1);
-       if (sd.encapContentInfo.eContent == NULL) {
-           hx509_clear_error_string(context);
-           ret = ENOMEM;
-           goto out;
-       }
-       
-       sd.encapContentInfo.eContent->data = malloc(length);
-       if (sd.encapContentInfo.eContent->data == NULL) {
-           hx509_clear_error_string(context);
-           ret = ENOMEM;
-           goto out;
-       }
-       memcpy(sd.encapContentInfo.eContent->data, data, length);
-       sd.encapContentInfo.eContent->length = length;
-    }
+    /*
+     * Allocate on more signerInfo and do the signature processing
+     */
 
 
-    ALLOC_SEQ(&sd.signerInfos, 1);
-    if (sd.signerInfos.val == NULL) {
-       hx509_clear_error_string(context);
+    ptr = realloc(sd->signerInfos.val,
+                 (sd->signerInfos.len + 1) * sizeof(sd->signerInfos.val[0]));
+    if (ptr == NULL) {
        ret = ENOMEM;
        goto out;
     }
        ret = ENOMEM;
        goto out;
     }
+    sd->signerInfos.val = ptr;
 
 
-    signer_info = &sd.signerInfos.val[0];
+    signer_info = &sd->signerInfos.val[sd->signerInfos.len];
+
+    memset(signer_info, 0, sizeof(*signer_info));
 
     signer_info->version = 1;
 
 
     signer_info->version = 1;
 
-    ret = fill_CMSIdentifier(cert, cmsidflag, &signer_info->sid);
+    ret = fill_CMSIdentifier(cert, sigctx->cmsidflag, &signer_info->sid);
     if (ret) {
        hx509_clear_error_string(context);
        goto out;
     if (ret) {
        hx509_clear_error_string(context);
        goto out;
@@ -1181,7 +1236,6 @@ hx509_cms_create_signed_1(hx509_context context,
     signer_info->signedAttrs = NULL;
     signer_info->unsignedAttrs = NULL;
 
     signer_info->signedAttrs = NULL;
     signer_info->unsignedAttrs = NULL;
 
-
     ret = copy_AlgorithmIdentifier(&digest, &signer_info->digestAlgorithm);
     if (ret) {
        hx509_clear_error_string(context);
     ret = copy_AlgorithmIdentifier(&digest, &signer_info->digestAlgorithm);
     if (ret) {
        hx509_clear_error_string(context);
@@ -1192,7 +1246,7 @@ hx509_cms_create_signed_1(hx509_context context,
      * If it isn't pkcs7-data send signedAttributes
      */
 
      * If it isn't pkcs7-data send signedAttributes
      */
 
-    if (der_heim_oid_cmp(eContentType, oid_id_pkcs7_data()) != 0) {
+    if (der_heim_oid_cmp(sigctx->eContentType, &asn1_oid_id_pkcs7_data) != 0) {
        CMSAttributes sa;       
        heim_octet_string sig;
 
        CMSAttributes sa;       
        heim_octet_string sig;
 
@@ -1205,7 +1259,7 @@ hx509_cms_create_signed_1(hx509_context context,
        ret = _hx509_create_signature(context,
                                      NULL,
                                      &digest,
        ret = _hx509_create_signature(context,
                                      NULL,
                                      &digest,
-                                     &content,
+                                     &sigctx->content,
                                      NULL,
                                      &sig);
        if (ret)
                                      NULL,
                                      &sig);
        if (ret)
@@ -1227,9 +1281,10 @@ hx509_cms_create_signed_1(hx509_context context,
 
        ret = add_one_attribute(&signer_info->signedAttrs->val,
                                &signer_info->signedAttrs->len,
 
        ret = add_one_attribute(&signer_info->signedAttrs->val,
                                &signer_info->signedAttrs->len,
-                               oid_id_pkcs9_messageDigest(),
+                               &asn1_oid_id_pkcs9_messageDigest,
                                &buf);
        if (ret) {
                                &buf);
        if (ret) {
+           free(buf.data);
            hx509_clear_error_string(context);
            goto out;
        }
            hx509_clear_error_string(context);
            goto out;
        }
@@ -1238,7 +1293,7 @@ hx509_cms_create_signed_1(hx509_context context,
        ASN1_MALLOC_ENCODE(ContentType,
                           buf.data,
                           buf.length,
        ASN1_MALLOC_ENCODE(ContentType,
                           buf.data,
                           buf.length,
-                          eContentType,
+                          sigctx->eContentType,
                           &size,
                           ret);
        if (ret)
                           &size,
                           ret);
        if (ret)
@@ -1248,9 +1303,10 @@ hx509_cms_create_signed_1(hx509_context context,
 
        ret = add_one_attribute(&signer_info->signedAttrs->val,
                                &signer_info->signedAttrs->len,
 
        ret = add_one_attribute(&signer_info->signedAttrs->val,
                                &signer_info->signedAttrs->len,
-                               oid_id_pkcs9_contentType(),
+                               &asn1_oid_id_pkcs9_contentType,
                                &buf);
        if (ret) {
                                &buf);
        if (ret) {
+           free(buf.data);
            hx509_clear_error_string(context);
            goto out;
        }
            hx509_clear_error_string(context);
            goto out;
        }
@@ -1271,16 +1327,15 @@ hx509_cms_create_signed_1(hx509_context context,
        if (size != sigdata.length)
            _hx509_abort("internal ASN.1 encoder error");
     } else {
        if (size != sigdata.length)
            _hx509_abort("internal ASN.1 encoder error");
     } else {
-       sigdata.data = content.data;
-       sigdata.length = content.length;
+       sigdata.data = sigctx->content.data;
+       sigdata.length = sigctx->content.length;
     }
 
     }
 
-
     {
        AlgorithmIdentifier sigalg;
 
        ret = hx509_crypto_select(context, HX509_SELECT_PUBLIC_SIG,
     {
        AlgorithmIdentifier sigalg;
 
        ret = hx509_crypto_select(context, HX509_SELECT_PUBLIC_SIG,
-                                 _hx509_cert_private_key(cert), peer,
+                                 _hx509_cert_private_key(cert), sigctx->peer,
                                  &sigalg);
        if (ret)
            goto out;
                                  &sigalg);
        if (ret)
            goto out;
@@ -1296,54 +1351,165 @@ hx509_cms_create_signed_1(hx509_context context,
            goto out;
     }
 
            goto out;
     }
 
-    ALLOC_SEQ(&sd.digestAlgorithms, 1);
-    if (sd.digestAlgorithms.val == NULL) {
-       ret = ENOMEM;
-       hx509_clear_error_string(context);
-       goto out;
-    }
-
-    ret = copy_AlgorithmIdentifier(&digest, &sd.digestAlgorithms.val[0]);
-    if (ret) {
-       hx509_clear_error_string(context);
-       goto out;
-    }
+    sigctx->sd.signerInfos.len++;
+    signer_info = NULL;
 
     /*
      * Provide best effort path
      */
 
     /*
      * Provide best effort path
      */
-    if (pool) {
-       _hx509_calculate_path(context,
-                             HX509_CALCULATE_PATH_NO_ANCHOR,                   
-                             time(NULL),
-                             anchors,
-                             0,
-                             cert,
-                             pool,
-                             &path);
-    } else
-       _hx509_path_append(context, &path, cert);
+    if (sigctx->certs) {
+       unsigned int i;
+
+       if (sigctx->pool) {
+           _hx509_calculate_path(context,
+                                 HX509_CALCULATE_PATH_NO_ANCHOR,
+                                 time(NULL),
+                                 sigctx->anchors,
+                                 0,
+                                 cert,
+                                 sigctx->pool,
+                                 &path);
+       } else
+           _hx509_path_append(context, &path, cert);
+
+       for (i = 0; i < path.len; i++) {
+           /* XXX remove dups */
+           ret = hx509_certs_add(context, sigctx->certs, path.val[i]);
+           if (ret) {
+               hx509_clear_error_string(context);
+               goto out;
+           }
+       }
+    }
+
+ out:
+    if (signer_info)
+       free_SignerInfo(signer_info);
+    if (sigdata.data != sigctx->content.data)
+       der_free_octet_string(&sigdata);
+    _hx509_path_free(&path);
+    free_AlgorithmIdentifier(&digest);
+
+    return ret;
+}
+
+static int
+cert_process(hx509_context context, void *ctx, hx509_cert cert)
+{
+    struct sigctx *sigctx = ctx;
+    const unsigned int i = sigctx->sd.certificates->len;
+    void *ptr;
+    int ret;
+    
+    ptr = realloc(sigctx->sd.certificates->val,
+                 (i + 1) * sizeof(sigctx->sd.certificates->val[0]));
+    if (ptr == NULL)
+       return ENOMEM;
+    sigctx->sd.certificates->val = ptr;
+
+    ret = hx509_cert_binary(context, cert,
+                           &sigctx->sd.certificates->val[i]);
+    if (ret == 0)
+       sigctx->sd.certificates->len++;
+
+    return ret;
+}
+
+int
+hx509_cms_create_signed(hx509_context context,
+                       int flags,
+                       const heim_oid *eContentType,
+                       const void *data, size_t length,
+                       const AlgorithmIdentifier *digest_alg,
+                       hx509_certs certs,
+                       hx509_peer_info peer,
+                       hx509_certs anchors,
+                       hx509_certs pool,
+                       heim_octet_string *signed_data)
+{
+    unsigned int i;
+    hx509_name name;
+    int ret;
+    size_t size;
+    struct sigctx sigctx;
+
+    memset(&sigctx, 0, sizeof(sigctx));
+    memset(&name, 0, sizeof(name));
+
+    if (eContentType == NULL)
+       eContentType = &asn1_oid_id_pkcs7_data;
+
+    sigctx.digest_alg = digest_alg;
+    sigctx.content.data = rk_UNCONST(data);
+    sigctx.content.length = length;
+    sigctx.eContentType = eContentType;
+    sigctx.peer = peer;
+    /**
+     * Use HX509_CMS_SIGNATURE_ID_NAME to preferred use of issuer name
+     * and serial number if possible. Otherwise subject key identifier
+     * will preferred.
+     */
+    if (flags & HX509_CMS_SIGNATURE_ID_NAME)
+       sigctx.cmsidflag = CMS_ID_NAME;
+    else
+       sigctx.cmsidflag = CMS_ID_SKI;
+
+    ret = hx509_certs_init(context, "MEMORY:certs", 0, NULL, &sigctx.certs);
+    if (ret)
+       return ret;
+
+    sigctx.anchors = anchors;
+    sigctx.pool = pool;
 
 
+    sigctx.sd.version = CMSVersion_v3;
 
 
-    if (path.len) {
-       int i;
+    der_copy_oid(eContentType, &sigctx.sd.encapContentInfo.eContentType);
 
 
-       ALLOC(sd.certificates, 1);
-       if (sd.certificates == NULL) {
+    /**
+     * Use HX509_CMS_SIGNATURE_DETACHED to create detached signatures.
+     */
+    if ((flags & HX509_CMS_SIGNATURE_DETACHED) == 0) {
+       ALLOC(sigctx.sd.encapContentInfo.eContent, 1);
+       if (sigctx.sd.encapContentInfo.eContent == NULL) {
            hx509_clear_error_string(context);
            ret = ENOMEM;
            goto out;
        }
            hx509_clear_error_string(context);
            ret = ENOMEM;
            goto out;
        }
-       ALLOC_SEQ(sd.certificates, path.len);
-       if (sd.certificates->val == NULL) {
+       
+       sigctx.sd.encapContentInfo.eContent->data = malloc(length);
+       if (sigctx.sd.encapContentInfo.eContent->data == NULL) {
            hx509_clear_error_string(context);
            ret = ENOMEM;
            goto out;
        }
            hx509_clear_error_string(context);
            ret = ENOMEM;
            goto out;
        }
+       memcpy(sigctx.sd.encapContentInfo.eContent->data, data, length);
+       sigctx.sd.encapContentInfo.eContent->length = length;
+    }
 
 
-       for (i = 0; i < path.len; i++) {
-           ret = hx509_cert_binary(context, path.val[i],
-                                   &sd.certificates->val[i]);
+    /**
+     * Use HX509_CMS_SIGNATURE_NO_SIGNER to create no sigInfo (no
+     * signatures).
+     */
+    if ((flags & HX509_CMS_SIGNATURE_NO_SIGNER) == 0) {
+       ret = hx509_certs_iter(context, certs, sig_process, &sigctx);
+       if (ret)
+           goto out;
+    }
+
+    if (sigctx.sd.signerInfos.len) {
+       ALLOC_SEQ(&sigctx.sd.digestAlgorithms, sigctx.sd.signerInfos.len);
+       if (sigctx.sd.digestAlgorithms.val == NULL) {
+           ret = ENOMEM;
+           hx509_clear_error_string(context);
+           goto out;
+       }
+       
+       /* XXX remove dups */
+       for (i = 0; i < sigctx.sd.signerInfos.len; i++) {
+           AlgorithmIdentifier *di =
+               &sigctx.sd.signerInfos.val[i].digestAlgorithm;
+           ret = copy_AlgorithmIdentifier(di,
+                                          &sigctx.sd.digestAlgorithms.val[i]);
            if (ret) {
                hx509_clear_error_string(context);
                goto out;
            if (ret) {
                hx509_clear_error_string(context);
                goto out;
@@ -1351,9 +1517,22 @@ hx509_cms_create_signed_1(hx509_context context,
        }
     }
 
        }
     }
 
+    if (sigctx.certs) {
+       ALLOC(sigctx.sd.certificates, 1);
+       if (sigctx.sd.certificates == NULL) {
+           hx509_clear_error_string(context);
+           ret = ENOMEM;
+           goto out;
+       }
+
+       ret = hx509_certs_iter(context, sigctx.certs, cert_process, &sigctx);
+       if (ret)
+           goto out;
+    }
+
     ASN1_MALLOC_ENCODE(SignedData,
                       signed_data->data, signed_data->length,
     ASN1_MALLOC_ENCODE(SignedData,
                       signed_data->data, signed_data->length,
-                      &sd, &size, ret);
+                      &sigctx.sd, &size, ret);
     if (ret) {
        hx509_clear_error_string(context);
        goto out;
     if (ret) {
        hx509_clear_error_string(context);
        goto out;
@@ -1362,11 +1541,8 @@ hx509_cms_create_signed_1(hx509_context context,
        _hx509_abort("internal ASN.1 encoder error");
 
 out:
        _hx509_abort("internal ASN.1 encoder error");
 
 out:
-    if (sigdata.data != content.data)
-       der_free_octet_string(&sigdata);
-    free_AlgorithmIdentifier(&digest);
-    _hx509_path_free(&path);
-    free_SignedData(&sd);
+    hx509_certs_free(&sigctx.certs);
+    free_SignedData(&sigctx.sd);
 
     return ret;
 }
 
     return ret;
 }
index b59052bb4e6b330c97e37fe66a2ce235dd26eaeb..ab36fe2dc8f05ddf55413941c3c8372e5e92a5a9 100644 (file)
@@ -32,7 +32,6 @@
  */
 
 #include "hx_locl.h"
  */
 
 #include "hx_locl.h"
-RCSID("$Id$");
 
 struct private_key {
     AlgorithmIdentifier alg;
 
 struct private_key {
     AlgorithmIdentifier alg;
@@ -144,7 +143,7 @@ _hx509_collector_private_key_add(hx509_context context,
     if (private_key) {
        key->private_key = private_key;
     } else {
     if (private_key) {
        key->private_key = private_key;
     } else {
-       ret = _hx509_parse_private_key(context, &alg->algorithm,
+       ret = _hx509_parse_private_key(context, alg,
                                       key_data->data, key_data->length,
                                       &key->private_key);
        if (ret)
                                       key_data->data, key_data->length,
                                       &key->private_key);
        if (ret)
@@ -306,7 +305,7 @@ _hx509_collector_collect_private_keys(hx509_context context,
            c->val.data[i]->private_key = NULL;
        }
     }
            c->val.data[i]->private_key = NULL;
        }
     }
-    (*keys)[nkeys++] = NULL;
+    (*keys)[nkeys] = NULL;
 
     return 0;
 }
 
     return 0;
 }
index 4a8ec8f7565dc121679aa4376d8fb65e4074019b..80631007173dc76463f3cd1347e18cfdffd296ca 100644 (file)
@@ -32,7 +32,6 @@
  */
 
 #include "hx_locl.h"
  */
 
 #include "hx_locl.h"
-RCSID("$Id$");
 
 struct hx509_crypto;
 
 
 struct hx509_crypto;
 
@@ -50,40 +49,21 @@ struct hx509_generate_private_context {
 
 struct hx509_private_key_ops {
     const char *pemtype;
 
 struct hx509_private_key_ops {
     const char *pemtype;
-    const heim_oid *(*key_oid)(void);
+    const heim_oid *key_oid;
+    int (*available)(const hx509_private_key,
+                    const AlgorithmIdentifier *);
     int (*get_spki)(hx509_context,
                    const hx509_private_key,
                    SubjectPublicKeyInfo *);
     int (*export)(hx509_context context,
                  const hx509_private_key,
                  heim_octet_string *);
     int (*get_spki)(hx509_context,
                    const hx509_private_key,
                    SubjectPublicKeyInfo *);
     int (*export)(hx509_context context,
                  const hx509_private_key,
                  heim_octet_string *);
-    int (*import)(hx509_context,
-                 const void *data,
-                 size_t len,
-                 hx509_private_key private_key);
+    int (*import)(hx509_context, const AlgorithmIdentifier *,
+                 const void *, size_t, hx509_private_key);
     int (*generate_private_key)(hx509_context,
                                struct hx509_generate_private_context *,
                                hx509_private_key);
     BIGNUM *(*get_internal)(hx509_context, hx509_private_key, const char *);
     int (*generate_private_key)(hx509_context,
                                struct hx509_generate_private_context *,
                                hx509_private_key);
     BIGNUM *(*get_internal)(hx509_context, hx509_private_key, const char *);
-    int (*handle_alg)(const hx509_private_key,
-                     const AlgorithmIdentifier *,
-                     enum crypto_op_type);
-    int (*sign)(hx509_context context,
-               const hx509_private_key,
-               const AlgorithmIdentifier *,
-               const heim_octet_string *,
-               AlgorithmIdentifier *,
-               heim_octet_string *);
-#if 0
-    const AlgorithmIdentifier *(*preferred_sig_alg)
-       (const hx509_private_key,
-        const hx509_peer_info);
-    int (*unwrap)(hx509_context context,
-                 const hx509_private_key,
-                 const AlgorithmIdentifier *,
-                 const heim_octet_string *,
-                 heim_octet_string *);
-#endif
 };
 
 struct hx509_private_key {
 };
 
 struct hx509_private_key {
@@ -93,8 +73,10 @@ struct hx509_private_key {
     union {
        RSA *rsa;
        void *keydata;
     union {
        RSA *rsa;
        void *keydata;
+#ifdef HAVE_OPENSSL
+       EC_KEY *ecdsa;
+#endif
     } private_key;
     } private_key;
-    /* new crypto layer */
     hx509_private_key_ops *ops;
 };
 
     hx509_private_key_ops *ops;
 };
 
@@ -104,10 +86,10 @@ struct hx509_private_key {
 
 struct signature_alg {
     const char *name;
 
 struct signature_alg {
     const char *name;
-    const heim_oid *(*sig_oid)(void);
-    const AlgorithmIdentifier *(*sig_alg)(void);
-    const heim_oid *(*key_oid)(void);
-    const heim_oid *(*digest_oid)(void);
+    const heim_oid *sig_oid;
+    const AlgorithmIdentifier *sig_alg;
+    const heim_oid *key_oid;
+    const AlgorithmIdentifier *digest_alg;
     int flags;
 #define PROVIDE_CONF 1
 #define REQUIRE_SIGNER 2
     int flags;
 #define PROVIDE_CONF 1
 #define REQUIRE_SIGNER 2
@@ -118,7 +100,7 @@ struct signature_alg {
 
 #define RA_RSA_USES_DIGEST_INFO 0x1000000
 
 
 #define RA_RSA_USES_DIGEST_INFO 0x1000000
 
-
+    time_t best_before; /* refuse signature made after best before date */
     int (*verify_signature)(hx509_context context,
                            const struct signature_alg *,
                            const Certificate *,
     int (*verify_signature)(hx509_context context,
                            const struct signature_alg *,
                            const Certificate *,
@@ -132,6 +114,116 @@ struct signature_alg {
                            const heim_octet_string *,
                            AlgorithmIdentifier *,
                            heim_octet_string *);
                            const heim_octet_string *,
                            AlgorithmIdentifier *,
                            heim_octet_string *);
+    int digest_size;
+};
+
+static const struct signature_alg *
+find_sig_alg(const heim_oid *oid);
+
+/*
+ *
+ */
+
+static const heim_octet_string null_entry_oid = { 2, rk_UNCONST("\x05\x00") };
+
+static const unsigned sha512_oid_tree[] = { 2, 16, 840, 1, 101, 3, 4, 2, 3 };
+const AlgorithmIdentifier _hx509_signature_sha512_data = {
+    { 9, rk_UNCONST(sha512_oid_tree) }, rk_UNCONST(&null_entry_oid)
+};
+
+static const unsigned sha384_oid_tree[] = { 2, 16, 840, 1, 101, 3, 4, 2, 2 };
+const AlgorithmIdentifier _hx509_signature_sha384_data = {
+    { 9, rk_UNCONST(sha384_oid_tree) }, rk_UNCONST(&null_entry_oid)
+};
+
+static const unsigned sha256_oid_tree[] = { 2, 16, 840, 1, 101, 3, 4, 2, 1 };
+const AlgorithmIdentifier _hx509_signature_sha256_data = {
+    { 9, rk_UNCONST(sha256_oid_tree) }, rk_UNCONST(&null_entry_oid)
+};
+
+static const unsigned sha1_oid_tree[] = { 1, 3, 14, 3, 2, 26 };
+const AlgorithmIdentifier _hx509_signature_sha1_data = {
+    { 6, rk_UNCONST(sha1_oid_tree) }, rk_UNCONST(&null_entry_oid)
+};
+
+static const unsigned md5_oid_tree[] = { 1, 2, 840, 113549, 2, 5 };
+const AlgorithmIdentifier _hx509_signature_md5_data = {
+    { 6, rk_UNCONST(md5_oid_tree) }, rk_UNCONST(&null_entry_oid)
+};
+
+static const unsigned md2_oid_tree[] = { 1, 2, 840, 113549, 2, 2 };
+const AlgorithmIdentifier _hx509_signature_md2_data = {
+    { 6, rk_UNCONST(md2_oid_tree) }, rk_UNCONST(&null_entry_oid)
+};
+
+static const unsigned ecPublicKey[] ={ 1, 2, 840, 10045, 2, 1 };
+const AlgorithmIdentifier _hx509_signature_ecPublicKey = {
+    { 6, rk_UNCONST(ecPublicKey) }, NULL
+};
+
+static const unsigned ecdsa_with_sha256_oid[] ={ 1, 2, 840, 10045, 4, 3, 2 };
+const AlgorithmIdentifier _hx509_signature_ecdsa_with_sha256_data = {
+    { 7, rk_UNCONST(ecdsa_with_sha256_oid) }, NULL
+};
+
+static const unsigned ecdsa_with_sha1_oid[] ={ 1, 2, 840, 10045, 4, 1 };
+const AlgorithmIdentifier _hx509_signature_ecdsa_with_sha1_data = {
+    { 6, rk_UNCONST(ecdsa_with_sha1_oid) }, NULL
+};
+
+static const unsigned rsa_with_sha512_oid[] ={ 1, 2, 840, 113549, 1, 1, 13 };
+const AlgorithmIdentifier _hx509_signature_rsa_with_sha512_data = {
+    { 7, rk_UNCONST(rsa_with_sha512_oid) }, NULL
+};
+
+static const unsigned rsa_with_sha384_oid[] ={ 1, 2, 840, 113549, 1, 1, 12 };
+const AlgorithmIdentifier _hx509_signature_rsa_with_sha384_data = {
+    { 7, rk_UNCONST(rsa_with_sha384_oid) }, NULL
+};
+
+static const unsigned rsa_with_sha256_oid[] ={ 1, 2, 840, 113549, 1, 1, 11 };
+const AlgorithmIdentifier _hx509_signature_rsa_with_sha256_data = {
+    { 7, rk_UNCONST(rsa_with_sha256_oid) }, NULL
+};
+
+static const unsigned rsa_with_sha1_oid[] ={ 1, 2, 840, 113549, 1, 1, 5 };
+const AlgorithmIdentifier _hx509_signature_rsa_with_sha1_data = {
+    { 7, rk_UNCONST(rsa_with_sha1_oid) }, NULL
+};
+
+static const unsigned rsa_with_md5_oid[] ={ 1, 2, 840, 113549, 1, 1, 4 };
+const AlgorithmIdentifier _hx509_signature_rsa_with_md5_data = {
+    { 7, rk_UNCONST(rsa_with_md5_oid) }, NULL
+};
+
+static const unsigned rsa_with_md2_oid[] ={ 1, 2, 840, 113549, 1, 1, 2 };
+const AlgorithmIdentifier _hx509_signature_rsa_with_md2_data = {
+    { 7, rk_UNCONST(rsa_with_md2_oid) }, NULL
+};
+
+static const unsigned rsa_oid[] ={ 1, 2, 840, 113549, 1, 1, 1 };
+const AlgorithmIdentifier _hx509_signature_rsa_data = {
+    { 7, rk_UNCONST(rsa_oid) }, NULL
+};
+
+static const unsigned rsa_pkcs1_x509_oid[] ={ 1, 2, 752, 43, 16, 1 };
+const AlgorithmIdentifier _hx509_signature_rsa_pkcs1_x509_data = {
+    { 6, rk_UNCONST(rsa_pkcs1_x509_oid) }, NULL
+};
+
+static const unsigned des_rsdi_ede3_cbc_oid[] ={ 1, 2, 840, 113549, 3, 7 };
+const AlgorithmIdentifier _hx509_des_rsdi_ede3_cbc_oid = {
+    { 6, rk_UNCONST(des_rsdi_ede3_cbc_oid) }, NULL
+};
+
+static const unsigned aes128_cbc_oid[] ={ 2, 16, 840, 1, 101, 3, 4, 1, 2 };
+const AlgorithmIdentifier _hx509_crypto_aes128_cbc_data = {
+    { 9, rk_UNCONST(aes128_cbc_oid) }, NULL
+};
+
+static const unsigned aes256_cbc_oid[] ={ 2, 16, 840, 1, 101, 3, 4, 1, 42 };
+const AlgorithmIdentifier _hx509_crypto_aes256_cbc_data = {
+    { 9, rk_UNCONST(aes256_cbc_oid) }, NULL
 };
 
 /*
 };
 
 /*
@@ -184,6 +276,265 @@ set_digest_alg(DigestAlgorithmIdentifier *id,
     return 0;
 }
 
     return 0;
 }
 
+#ifdef HAVE_OPENSSL
+
+static int
+heim_oid2ecnid(heim_oid *oid)
+{
+    /*
+     * Now map to openssl OID fun
+     */
+
+    if (der_heim_oid_cmp(oid, &asn1_oid_id_ec_group_secp256r1) == 0)
+       return NID_X9_62_prime256v1;
+    else if (der_heim_oid_cmp(oid, &asn1_oid_id_ec_group_secp160r1) == 0)
+       return NID_secp160r1;
+    else if (der_heim_oid_cmp(oid, &asn1_oid_id_ec_group_secp160r2) == 0)
+       return NID_secp160r2;
+
+    return -1;
+}
+
+static int
+parse_ECParameters(hx509_context context, 
+                  heim_octet_string *parameters, int *nid)
+{
+    ECParameters ecparam;
+    size_t size;
+    int ret;
+
+    if (parameters == NULL) {
+       ret = HX509_PARSING_KEY_FAILED;
+       hx509_set_error_string(context, 0, ret,
+                              "EC parameters missing");
+       return ret;
+    }
+
+    ret = decode_ECParameters(parameters->data, parameters->length,
+                             &ecparam, &size);
+    if (ret) {
+       hx509_set_error_string(context, 0, ret,
+                              "Failed to decode EC parameters");
+       return ret;
+    }
+
+    if (ecparam.element != choice_ECParameters_namedCurve) {
+       free_ECParameters(&ecparam);
+       hx509_set_error_string(context, 0, ret,
+                              "EC parameters is not a named curve");
+       return HX509_CRYPTO_SIG_INVALID_FORMAT;
+    }
+
+    *nid = heim_oid2ecnid(&ecparam.u.namedCurve);
+    free_ECParameters(&ecparam);
+    if (*nid == -1) {
+       hx509_set_error_string(context, 0, ret,
+                              "Failed to find matcing NID for EC curve");
+       return HX509_CRYPTO_SIG_INVALID_FORMAT;
+    }
+    return 0;
+}
+
+
+/*
+ *
+ */
+
+static int
+ecdsa_verify_signature(hx509_context context,
+                      const struct signature_alg *sig_alg,
+                      const Certificate *signer,
+                      const AlgorithmIdentifier *alg,
+                      const heim_octet_string *data,
+                      const heim_octet_string *sig)
+{
+    const AlgorithmIdentifier *digest_alg;
+    const SubjectPublicKeyInfo *spi;
+    heim_octet_string digest;
+    int ret;
+    EC_KEY *key = NULL;
+    int groupnid;
+    EC_GROUP *group;
+    const unsigned char *p;
+    long len;
+
+    digest_alg = sig_alg->digest_alg;
+
+    ret = _hx509_create_signature(context,
+                                 NULL,
+                                 digest_alg,
+                                 data,
+                                 NULL,
+                                 &digest);
+    if (ret)
+       return ret;
+
+    /* set up EC KEY */
+    spi = &signer->tbsCertificate.subjectPublicKeyInfo;
+
+    if (der_heim_oid_cmp(&spi->algorithm.algorithm, &asn1_oid_id_ecPublicKey) != 0)
+       return HX509_CRYPTO_SIG_INVALID_FORMAT;
+
+#ifdef HAVE_OPENSSL
+    /*
+     * Find the group id
+     */
+
+    ret = parse_ECParameters(context, spi->algorithm.parameters, &groupnid);
+    if (ret) {
+       der_free_octet_string(&digest);
+       return ret;
+    }
+
+    /*
+     * Create group, key, parse key
+     */
+
+    key = EC_KEY_new();
+    group = EC_GROUP_new_by_curve_name(groupnid);
+    EC_KEY_set_group(key, group);
+    EC_GROUP_free(group);
+
+    p = spi->subjectPublicKey.data;
+    len = spi->subjectPublicKey.length / 8;
+
+    if (o2i_ECPublicKey(&key, &p, len) == NULL) {
+       EC_KEY_free(key);
+       return HX509_CRYPTO_SIG_INVALID_FORMAT;
+    }
+#else
+    key = SubjectPublicKeyInfo2EC_KEY(spi);
+#endif
+
+    ret = ECDSA_verify(-1, digest.data, digest.length,
+                      sig->data, sig->length, key);
+    der_free_octet_string(&digest);
+    EC_KEY_free(key);
+    if (ret != 1) {
+       ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
+       return ret;
+    }
+    
+    return 0;
+}
+
+static int
+ecdsa_create_signature(hx509_context context,
+                      const struct signature_alg *sig_alg,
+                      const hx509_private_key signer,
+                      const AlgorithmIdentifier *alg,
+                      const heim_octet_string *data,
+                      AlgorithmIdentifier *signatureAlgorithm,
+                      heim_octet_string *sig)
+{
+    const AlgorithmIdentifier *digest_alg;
+    heim_octet_string indata;
+    const heim_oid *sig_oid;
+    unsigned int siglen;
+    int ret;
+
+    if (signer->ops && der_heim_oid_cmp(signer->ops->key_oid, &asn1_oid_id_ecPublicKey) != 0)
+       _hx509_abort("internal error passing private key to wrong ops");
+
+    sig_oid = sig_alg->sig_oid;
+    digest_alg = sig_alg->digest_alg;
+
+    if (signatureAlgorithm) {
+       ret = set_digest_alg(signatureAlgorithm, sig_oid, "\x05\x00", 2);
+       if (ret) {
+           hx509_clear_error_string(context);
+           goto error;
+       }
+    }
+
+    ret = _hx509_create_signature(context,
+                                 NULL,
+                                 digest_alg,
+                                 data,
+                                 NULL,
+                                 &indata);
+    if (ret) {
+       if (signatureAlgorithm)
+           free_AlgorithmIdentifier(signatureAlgorithm);
+       goto error;
+    }
+
+    sig->length = ECDSA_size(signer->private_key.ecdsa);
+    sig->data = malloc(sig->length);
+    if (sig->data == NULL) {
+       der_free_octet_string(&indata);
+       ret = ENOMEM;
+       hx509_set_error_string(context, 0, ret, "out of memory");
+       goto error;
+    }
+
+    siglen = sig->length;
+
+    ret = ECDSA_sign(-1, indata.data, indata.length,
+                    sig->data, &siglen, signer->private_key.ecdsa);
+    der_free_octet_string(&indata);
+    if (ret != 1) {
+       ret = HX509_CMS_FAILED_CREATE_SIGATURE;
+       hx509_set_error_string(context, 0, ret,
+                              "ECDSA sign failed: %d", ret);
+       goto error;
+    }
+    if (siglen > sig->length)
+       _hx509_abort("ECDSA signature prelen longer the output len");
+
+    sig->length = siglen;
+
+    return 0;
+ error:
+    if (signatureAlgorithm)
+       free_AlgorithmIdentifier(signatureAlgorithm);
+    return ret;
+}
+
+static int
+ecdsa_available(const hx509_private_key signer,
+               const AlgorithmIdentifier *sig_alg)
+{
+    const struct signature_alg *sig;
+    const EC_GROUP *group;
+    BN_CTX *bnctx = NULL;
+    BIGNUM *order = NULL;
+    int ret = 0;
+
+    if (der_heim_oid_cmp(signer->ops->key_oid, &asn1_oid_id_ecPublicKey) != 0)
+       _hx509_abort("internal error passing private key to wrong ops");
+
+    sig = find_sig_alg(&sig_alg->algorithm);
+
+    if (sig == NULL || sig->digest_size == 0)
+       return 0;
+
+    group = EC_KEY_get0_group(signer->private_key.ecdsa);
+    if (group == NULL)
+       return 0;
+
+    bnctx = BN_CTX_new();
+    order = BN_new();
+    if (order == NULL)
+       goto err;
+
+    if (EC_GROUP_get_order(group, order, bnctx) != 1)
+       goto err;
+
+    if (BN_num_bytes(order) > sig->digest_size)
+       ret = 1;
+ err:
+    if (bnctx)
+       BN_CTX_free(bnctx);
+    if (order)
+       BN_clear_free(order);
+
+    return ret;
+}
+
+
+#endif /* HAVE_OPENSSL */
+
 /*
  *
  */
 /*
  *
  */
@@ -268,9 +619,9 @@ rsa_verify_signature(hx509_context context,
            goto out;
        }
        
            goto out;
        }
        
-       if (sig_alg->digest_oid &&
+       if (sig_alg->digest_alg &&
            der_heim_oid_cmp(&di.digestAlgorithm.algorithm,
            der_heim_oid_cmp(&di.digestAlgorithm.algorithm,
-                            (*sig_alg->digest_oid)()) != 0)
+                            &sig_alg->digest_alg->algorithm) != 0)
        {
            ret = HX509_CRYPTO_OID_MISMATCH;
            hx509_set_error_string(context, 0, ret, "object identifier in RSA sig mismatch");
        {
            ret = HX509_CRYPTO_OID_MISMATCH;
            hx509_set_error_string(context, 0, ret, "object identifier in RSA sig mismatch");
@@ -324,24 +675,27 @@ rsa_create_signature(hx509_context context,
     size_t size;
     int ret;
 
     size_t size;
     int ret;
 
+    if (signer->ops && der_heim_oid_cmp(signer->ops->key_oid, &asn1_oid_id_pkcs1_rsaEncryption) != 0)
+       return HX509_ALG_NOT_SUPP;
+
     if (alg)
        sig_oid = &alg->algorithm;
     else
        sig_oid = signer->signature_alg;
 
     if (alg)
        sig_oid = &alg->algorithm;
     else
        sig_oid = signer->signature_alg;
 
-    if (der_heim_oid_cmp(sig_oid, oid_id_pkcs1_sha256WithRSAEncryption()) == 0) {
+    if (der_heim_oid_cmp(sig_oid, &asn1_oid_id_pkcs1_sha256WithRSAEncryption) == 0) {
        digest_alg = hx509_signature_sha256();
        digest_alg = hx509_signature_sha256();
-    } else if (der_heim_oid_cmp(sig_oid, oid_id_pkcs1_sha1WithRSAEncryption()) == 0) {
+    } else if (der_heim_oid_cmp(sig_oid, &asn1_oid_id_pkcs1_sha1WithRSAEncryption) == 0) {
        digest_alg = hx509_signature_sha1();
        digest_alg = hx509_signature_sha1();
-    } else if (der_heim_oid_cmp(sig_oid, oid_id_pkcs1_md5WithRSAEncryption()) == 0) {
+    } else if (der_heim_oid_cmp(sig_oid, &asn1_oid_id_pkcs1_md5WithRSAEncryption) == 0) {
        digest_alg = hx509_signature_md5();
        digest_alg = hx509_signature_md5();
-    } else if (der_heim_oid_cmp(sig_oid, oid_id_pkcs1_md5WithRSAEncryption()) == 0) {
+    } else if (der_heim_oid_cmp(sig_oid, &asn1_oid_id_pkcs1_md5WithRSAEncryption) == 0) {
        digest_alg = hx509_signature_md5();
        digest_alg = hx509_signature_md5();
-    } else if (der_heim_oid_cmp(sig_oid, oid_id_dsa_with_sha1()) == 0) {
+    } else if (der_heim_oid_cmp(sig_oid, &asn1_oid_id_dsa_with_sha1) == 0) {
        digest_alg = hx509_signature_sha1();
        digest_alg = hx509_signature_sha1();
-    } else if (der_heim_oid_cmp(sig_oid, oid_id_pkcs1_rsaEncryption()) == 0) {
+    } else if (der_heim_oid_cmp(sig_oid, &asn1_oid_id_pkcs1_rsaEncryption) == 0) {
        digest_alg = hx509_signature_sha1();
        digest_alg = hx509_signature_sha1();
-    } else if (der_heim_oid_cmp(sig_oid, oid_id_heim_rsa_pkcs1_x509()) == 0) {
+    } else if (der_heim_oid_cmp(sig_oid, &asn1_oid_id_heim_rsa_pkcs1_x509) == 0) {
        digest_alg = NULL;
     } else
        return HX509_ALG_NOT_SUPP;
        digest_alg = NULL;
     } else
        return HX509_ALG_NOT_SUPP;
@@ -413,6 +767,7 @@ rsa_create_signature(hx509_context context,
 
 static int
 rsa_private_key_import(hx509_context context,
 
 static int
 rsa_private_key_import(hx509_context context,
+                      const AlgorithmIdentifier *keyai,
                       const void *data,
                       size_t len,
                       hx509_private_key private_key)
                       const void *data,
                       size_t len,
                       hx509_private_key private_key)
@@ -426,7 +781,7 @@ rsa_private_key_import(hx509_context context,
                               "Failed to parse RSA key");
        return HX509_PARSING_KEY_FAILED;
     }
                               "Failed to parse RSA key");
        return HX509_PARSING_KEY_FAILED;
     }
-    private_key->signature_alg = oid_id_pkcs1_sha1WithRSAEncryption();
+    private_key->signature_alg = &asn1_oid_id_pkcs1_sha1WithRSAEncryption;
 
     return 0;
 }
 
     return 0;
 }
@@ -449,7 +804,7 @@ rsa_private_key2SPKI(hx509_context context,
     }
     spki->subjectPublicKey.length = len * 8;
 
     }
     spki->subjectPublicKey.length = len * 8;
 
-    ret = set_digest_alg(&spki->algorithm,oid_id_pkcs1_rsaEncryption(),
+    ret = set_digest_alg(&spki->algorithm, &asn1_oid_id_pkcs1_rsaEncryption,
                         "\x05\x00", 2);
     if (ret) {
        hx509_set_error_string(context, 0, ret, "malloc - out of memory");
                         "\x05\x00", 2);
     if (ret) {
        hx509_set_error_string(context, 0, ret, "malloc - out of memory");
@@ -503,7 +858,7 @@ rsa_generate_private_key(hx509_context context,
                               "Failed to generate RSA key");
        return HX509_PARSING_KEY_FAILED;
     }
                               "Failed to generate RSA key");
        return HX509_PARSING_KEY_FAILED;
     }
-    private_key->signature_alg = oid_id_pkcs1_sha1WithRSAEncryption();
+    private_key->signature_alg = &asn1_oid_id_pkcs1_sha1WithRSAEncryption;
 
     return 0;
 }
 
     return 0;
 }
@@ -543,7 +898,9 @@ rsa_private_key_export(hx509_context context,
 }
 
 static BIGNUM *
 }
 
 static BIGNUM *
-rsa_get_internal(hx509_context context, hx509_private_key key, const char *type)
+rsa_get_internal(hx509_context context,
+                hx509_private_key key,
+                const char *type)
 {
     if (strcasecmp(type, "rsa-modulus") == 0) {
        return BN_dup(key->private_key.rsa->n);
 {
     if (strcasecmp(type, "rsa-modulus") == 0) {
        return BN_dup(key->private_key.rsa->n);
@@ -557,7 +914,8 @@ rsa_get_internal(hx509_context context, hx509_private_key key, const char *type)
 
 static hx509_private_key_ops rsa_private_key_ops = {
     "RSA PRIVATE KEY",
 
 static hx509_private_key_ops rsa_private_key_ops = {
     "RSA PRIVATE KEY",
-    oid_id_pkcs1_rsaEncryption,
+    &asn1_oid_id_pkcs1_rsaEncryption,
+    NULL,
     rsa_private_key2SPKI,
     rsa_private_key_export,
     rsa_private_key_import,
     rsa_private_key2SPKI,
     rsa_private_key_export,
     rsa_private_key_import,
@@ -565,6 +923,104 @@ static hx509_private_key_ops rsa_private_key_ops = {
     rsa_get_internal
 };
 
     rsa_get_internal
 };
 
+#ifdef HAVE_OPENSSL
+
+static int
+ecdsa_private_key2SPKI(hx509_context context,
+                      hx509_private_key private_key,
+                      SubjectPublicKeyInfo *spki)
+{
+    memset(spki, 0, sizeof(*spki));
+    return ENOMEM;
+}
+
+static int
+ecdsa_private_key_export(hx509_context context,
+                        const hx509_private_key key,
+                        heim_octet_string *data)
+{
+    return ENOMEM;
+}
+
+static int
+ecdsa_private_key_import(hx509_context context,
+                        const AlgorithmIdentifier *keyai,
+                        const void *data,
+                        size_t len,
+                        hx509_private_key private_key)
+{
+    const unsigned char *p = data;
+    EC_KEY **pkey = NULL;
+
+    if (keyai->parameters) {
+       EC_GROUP *group;
+       int groupnid;
+       EC_KEY *key;
+       int ret;
+
+       ret = parse_ECParameters(context, keyai->parameters, &groupnid);
+       if (ret)
+           return ret;
+       
+       key = EC_KEY_new();
+       if (key == NULL)
+           return ENOMEM;
+       
+       group = EC_GROUP_new_by_curve_name(groupnid);
+       if (group == NULL) {
+           EC_KEY_free(key);
+           return ENOMEM;
+       }
+       EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
+       if (EC_KEY_set_group(key, group) == 0) {
+           EC_KEY_free(key);
+           EC_GROUP_free(group);
+           return ENOMEM;
+       }
+       EC_GROUP_free(group);
+       pkey = &key;
+    }
+
+    private_key->private_key.ecdsa = d2i_ECPrivateKey(pkey, &p, len);
+    if (private_key->private_key.ecdsa == NULL) {
+       hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
+                              "Failed to parse EC private key");
+       return HX509_PARSING_KEY_FAILED;
+    }
+    private_key->signature_alg = &asn1_oid_id_ecdsa_with_SHA256;
+
+    return 0;
+}
+
+static int
+ecdsa_generate_private_key(hx509_context context,
+                          struct hx509_generate_private_context *ctx,
+                          hx509_private_key private_key)
+{
+    return ENOMEM;
+}
+
+static BIGNUM *
+ecdsa_get_internal(hx509_context context, 
+                  hx509_private_key key, 
+                  const char *type)
+{
+    return NULL;
+}
+
+
+static hx509_private_key_ops ecdsa_private_key_ops = {
+    "EC PRIVATE KEY",
+    &asn1_oid_id_ecPublicKey,
+    ecdsa_available,
+    ecdsa_private_key2SPKI,
+    ecdsa_private_key_export,
+    ecdsa_private_key_import,
+    ecdsa_generate_private_key,
+    ecdsa_get_internal
+};
+
+#endif /* HAVE_OPENSSL */
 
 /*
  *
 
 /*
  *
@@ -668,7 +1124,7 @@ dsa_parse_private_key(hx509_context context,
        d2i_DSAPrivateKey(NULL, &p, len);
     if (private_key->private_key.dsa == NULL)
        return EINVAL;
        d2i_DSAPrivateKey(NULL, &p, len);
     if (private_key->private_key.dsa == NULL)
        return EINVAL;
-    private_key->signature_alg = oid_id_dsa_with_sha1();
+    private_key->signature_alg = &asn1_oid_id_dsa_with_sha1;
 
     return 0;
 /* else */
 
     return 0;
 /* else */
@@ -724,7 +1180,7 @@ sha256_create_signature(hx509_context context,
 
     if (signatureAlgorithm) {
        int ret;
 
     if (signatureAlgorithm) {
        int ret;
-       ret = set_digest_alg(signatureAlgorithm, (*sig_alg->sig_oid)(),
+       ret = set_digest_alg(signatureAlgorithm, sig_alg->sig_oid,
                             "\x05\x00", 2);
        if (ret)
            return ret;
                             "\x05\x00", 2);
        if (ret)
            return ret;
@@ -790,7 +1246,7 @@ sha1_create_signature(hx509_context context,
 
     if (signatureAlgorithm) {
        int ret;
 
     if (signatureAlgorithm) {
        int ret;
-       ret = set_digest_alg(signatureAlgorithm, (*sig_alg->sig_oid)(),
+       ret = set_digest_alg(signatureAlgorithm, sig_alg->sig_oid,
                             "\x05\x00", 2);
        if (ret)
            return ret;
                             "\x05\x00", 2);
        if (ret)
            return ret;
@@ -871,131 +1327,176 @@ md2_verify_signature(hx509_context context,
     return 0;
 }
 
     return 0;
 }
 
+#ifdef HAVE_OPENSSL
+
+static const struct signature_alg ecdsa_with_sha256_alg = {
+    "ecdsa-with-sha256",
+    &asn1_oid_id_ecdsa_with_SHA256,
+    &_hx509_signature_ecdsa_with_sha256_data,
+    &asn1_oid_id_ecPublicKey,
+    &_hx509_signature_sha256_data,
+    PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
+    0,
+    ecdsa_verify_signature,
+    ecdsa_create_signature,
+    32
+};
+
+static const struct signature_alg ecdsa_with_sha1_alg = {
+    "ecdsa-with-sha1",
+    &asn1_oid_id_ecdsa_with_SHA1,
+    &_hx509_signature_ecdsa_with_sha1_data,
+    &asn1_oid_id_ecPublicKey,
+    &_hx509_signature_sha1_data,
+    PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
+    0,
+    ecdsa_verify_signature,
+    ecdsa_create_signature,
+    20
+};
+
+#endif
+
 static const struct signature_alg heim_rsa_pkcs1_x509 = {
     "rsa-pkcs1-x509",
 static const struct signature_alg heim_rsa_pkcs1_x509 = {
     "rsa-pkcs1-x509",
-    oid_id_heim_rsa_pkcs1_x509,
-    hx509_signature_rsa_pkcs1_x509,
-    oid_id_pkcs1_rsaEncryption,
+    &asn1_oid_id_heim_rsa_pkcs1_x509,
+    &_hx509_signature_rsa_pkcs1_x509_data,
+    &asn1_oid_id_pkcs1_rsaEncryption,
     NULL,
     PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG,
     NULL,
     PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG,
+    0,
     rsa_verify_signature,
     rsa_create_signature
 };
 
 static const struct signature_alg pkcs1_rsa_sha1_alg = {
     "rsa",
     rsa_verify_signature,
     rsa_create_signature
 };
 
 static const struct signature_alg pkcs1_rsa_sha1_alg = {
     "rsa",
-    oid_id_pkcs1_rsaEncryption,
-    hx509_signature_rsa_with_sha1,
-    oid_id_pkcs1_rsaEncryption,
+    &asn1_oid_id_pkcs1_rsaEncryption,
+    &_hx509_signature_rsa_with_sha1_data,
+    &asn1_oid_id_pkcs1_rsaEncryption,
     NULL,
     PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
     NULL,
     PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
+    0,
     rsa_verify_signature,
     rsa_create_signature
 };
 
 static const struct signature_alg rsa_with_sha256_alg = {
     "rsa-with-sha256",
     rsa_verify_signature,
     rsa_create_signature
 };
 
 static const struct signature_alg rsa_with_sha256_alg = {
     "rsa-with-sha256",
-    oid_id_pkcs1_sha256WithRSAEncryption,
-    hx509_signature_rsa_with_sha256,
-    oid_id_pkcs1_rsaEncryption,
-    oid_id_sha256,
+    &asn1_oid_id_pkcs1_sha256WithRSAEncryption,
+    &_hx509_signature_rsa_with_sha256_data,
+    &asn1_oid_id_pkcs1_rsaEncryption,
+    &_hx509_signature_sha256_data,
     PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
     PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
+    0,
     rsa_verify_signature,
     rsa_create_signature
 };
 
 static const struct signature_alg rsa_with_sha1_alg = {
     "rsa-with-sha1",
     rsa_verify_signature,
     rsa_create_signature
 };
 
 static const struct signature_alg rsa_with_sha1_alg = {
     "rsa-with-sha1",
-    oid_id_pkcs1_sha1WithRSAEncryption,
-    hx509_signature_rsa_with_sha1,
-    oid_id_pkcs1_rsaEncryption,
-    oid_id_secsig_sha_1,
+    &asn1_oid_id_pkcs1_sha1WithRSAEncryption,
+    &_hx509_signature_rsa_with_sha1_data,
+    &asn1_oid_id_pkcs1_rsaEncryption,
+    &_hx509_signature_sha1_data,
     PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
     PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
+    0,
     rsa_verify_signature,
     rsa_create_signature
 };
 
 static const struct signature_alg rsa_with_md5_alg = {
     "rsa-with-md5",
     rsa_verify_signature,
     rsa_create_signature
 };
 
 static const struct signature_alg rsa_with_md5_alg = {
     "rsa-with-md5",
-    oid_id_pkcs1_md5WithRSAEncryption,
-    hx509_signature_rsa_with_md5,
-    oid_id_pkcs1_rsaEncryption,
-    oid_id_rsa_digest_md5,
+    &asn1_oid_id_pkcs1_md5WithRSAEncryption,
+    &_hx509_signature_rsa_with_md5_data,
+    &asn1_oid_id_pkcs1_rsaEncryption,
+    &_hx509_signature_md5_data,
     PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
     PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
+    1230739889,
     rsa_verify_signature,
     rsa_create_signature
 };
 
 static const struct signature_alg rsa_with_md2_alg = {
     "rsa-with-md2",
     rsa_verify_signature,
     rsa_create_signature
 };
 
 static const struct signature_alg rsa_with_md2_alg = {
     "rsa-with-md2",
-    oid_id_pkcs1_md2WithRSAEncryption,
-    hx509_signature_rsa_with_md2,
-    oid_id_pkcs1_rsaEncryption,
-    oid_id_rsa_digest_md2,
+    &asn1_oid_id_pkcs1_md2WithRSAEncryption,
+    &_hx509_signature_rsa_with_md2_data,
+    &asn1_oid_id_pkcs1_rsaEncryption,
+    &_hx509_signature_md2_data,
     PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
     PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
+    1230739889,
     rsa_verify_signature,
     rsa_create_signature
 };
 
 static const struct signature_alg dsa_sha1_alg = {
     "dsa-with-sha1",
     rsa_verify_signature,
     rsa_create_signature
 };
 
 static const struct signature_alg dsa_sha1_alg = {
     "dsa-with-sha1",
-    oid_id_dsa_with_sha1,
+    &asn1_oid_id_dsa_with_sha1,
     NULL,
     NULL,
-    oid_id_dsa,
-    oid_id_secsig_sha_1,
+    &asn1_oid_id_dsa,
+    &_hx509_signature_sha1_data,
     PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG,
     PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG,
+    0,
     dsa_verify_signature,
     /* create_signature */ NULL,
 };
 
 static const struct signature_alg sha256_alg = {
     "sha-256",
     dsa_verify_signature,
     /* create_signature */ NULL,
 };
 
 static const struct signature_alg sha256_alg = {
     "sha-256",
-    oid_id_sha256,
-    hx509_signature_sha256,
+    &asn1_oid_id_sha256,
+    &_hx509_signature_sha256_data,
     NULL,
     NULL,
     SIG_DIGEST,
     NULL,
     NULL,
     SIG_DIGEST,
+    0,
     sha256_verify_signature,
     sha256_create_signature
 };
 
 static const struct signature_alg sha1_alg = {
     "sha1",
     sha256_verify_signature,
     sha256_create_signature
 };
 
 static const struct signature_alg sha1_alg = {
     "sha1",
-    oid_id_secsig_sha_1,
-    hx509_signature_sha1,
+    &asn1_oid_id_secsig_sha_1,
+    &_hx509_signature_sha1_data,
     NULL,
     NULL,
     SIG_DIGEST,
     NULL,
     NULL,
     SIG_DIGEST,
+    0,
     sha1_verify_signature,
     sha1_create_signature
 };
 
 static const struct signature_alg md5_alg = {
     "rsa-md5",
     sha1_verify_signature,
     sha1_create_signature
 };
 
 static const struct signature_alg md5_alg = {
     "rsa-md5",
-    oid_id_rsa_digest_md5,
-    hx509_signature_md5,
+    &asn1_oid_id_rsa_digest_md5,
+    &_hx509_signature_md5_data,
     NULL,
     NULL,
     SIG_DIGEST,
     NULL,
     NULL,
     SIG_DIGEST,
+    0,
     md5_verify_signature
 };
 
 static const struct signature_alg md2_alg = {
     "rsa-md2",
     md5_verify_signature
 };
 
 static const struct signature_alg md2_alg = {
     "rsa-md2",
-    oid_id_rsa_digest_md2,
-    hx509_signature_md2,
+    &asn1_oid_id_rsa_digest_md2,
+    &_hx509_signature_md2_data,
     NULL,
     NULL,
     SIG_DIGEST,
     NULL,
     NULL,
     SIG_DIGEST,
+    0,
     md2_verify_signature
 };
 
 /*
  * Order matter in this structure, "best" first for each "key
     md2_verify_signature
 };
 
 /*
  * Order matter in this structure, "best" first for each "key
- * compatible" type (type is RSA, DSA, none, etc)
+ * compatible" type (type is ECDSA, RSA, DSA, none, etc)
  */
 
 static const struct signature_alg *sig_algs[] = {
  */
 
 static const struct signature_alg *sig_algs[] = {
+#ifdef HAVE_OPENSSL
+    &ecdsa_with_sha256_alg,
+    &ecdsa_with_sha1_alg,
+#endif
     &rsa_with_sha256_alg,
     &rsa_with_sha1_alg,
     &pkcs1_rsa_sha1_alg,
     &rsa_with_sha256_alg,
     &rsa_with_sha1_alg,
     &pkcs1_rsa_sha1_alg,
@@ -1013,19 +1514,51 @@ static const struct signature_alg *sig_algs[] = {
 static const struct signature_alg *
 find_sig_alg(const heim_oid *oid)
 {
 static const struct signature_alg *
 find_sig_alg(const heim_oid *oid)
 {
-    int i;
+    unsigned int i;
     for (i = 0; sig_algs[i]; i++)
     for (i = 0; sig_algs[i]; i++)
-       if (der_heim_oid_cmp((*sig_algs[i]->sig_oid)(), oid) == 0)
+       if (der_heim_oid_cmp(sig_algs[i]->sig_oid, oid) == 0)
            return sig_algs[i];
     return NULL;
 }
 
            return sig_algs[i];
     return NULL;
 }
 
+static const AlgorithmIdentifier *
+alg_for_privatekey(const hx509_private_key pk, int type)
+{
+    const heim_oid *keytype;
+    unsigned int i;
+
+    if (pk->ops == NULL)
+       return NULL;
+
+    keytype = pk->ops->key_oid;
+
+    for (i = 0; sig_algs[i]; i++) {
+       if (sig_algs[i]->key_oid == NULL)
+           continue;
+       if (der_heim_oid_cmp(sig_algs[i]->key_oid, keytype) != 0)
+           continue;
+       if (pk->ops->available && 
+           pk->ops->available(pk, sig_algs[i]->sig_alg) == 0)
+           continue;
+       if (type == HX509_SELECT_PUBLIC_SIG)
+           return sig_algs[i]->sig_alg;
+       if (type == HX509_SELECT_DIGEST)
+           return sig_algs[i]->digest_alg;
+
+       return NULL;
+    }
+    return NULL;
+}
+
 /*
  *
  */
 
 static struct hx509_private_key_ops *private_algs[] = {
     &rsa_private_key_ops,
 /*
  *
  */
 
 static struct hx509_private_key_ops *private_algs[] = {
     &rsa_private_key_ops,
+#ifdef HAVE_OPENSSL
+    &ecdsa_private_key_ops,
+#endif
     NULL
 };
 
     NULL
 };
 
@@ -1036,12 +1569,37 @@ find_private_alg(const heim_oid *oid)
     for (i = 0; private_algs[i]; i++) {
        if (private_algs[i]->key_oid == NULL)
            continue;
     for (i = 0; private_algs[i]; i++) {
        if (private_algs[i]->key_oid == NULL)
            continue;
-       if (der_heim_oid_cmp((*private_algs[i]->key_oid)(), oid) == 0)
+       if (der_heim_oid_cmp(private_algs[i]->key_oid, oid) == 0)
            return private_algs[i];
     }
     return NULL;
 }
 
            return private_algs[i];
     }
     return NULL;
 }
 
+/*
+ * Check if the algorithm `alg' have a best before date, and if it
+ * des, make sure the its before the time `t'.
+ */
+
+int
+_hx509_signature_best_before(hx509_context context,
+                            const AlgorithmIdentifier *alg,
+                            time_t t)
+{
+    const struct signature_alg *md;
+
+    md = find_sig_alg(&alg->algorithm);
+    if (md == NULL) {
+       hx509_clear_error_string(context);
+       return HX509_SIG_ALG_NO_SUPPORTED;
+    }
+    if (md->best_before && md->best_before < t) {
+       hx509_set_error_string(context, 0, HX509_CRYPTO_ALGORITHM_BEST_BEFORE,
+                              "Algorithm %s has passed it best before date",
+                              md->name);
+       return HX509_CRYPTO_ALGORITHM_BEST_BEFORE;
+    }
+    return 0;
+}
 
 int
 _hx509_verify_signature(hx509_context context,
 
 int
 _hx509_verify_signature(hx509_context context,
@@ -1069,7 +1627,7 @@ _hx509_verify_signature(hx509_context context,
        const SubjectPublicKeyInfo *spi;
        spi = &signer->tbsCertificate.subjectPublicKeyInfo;
 
        const SubjectPublicKeyInfo *spi;
        spi = &signer->tbsCertificate.subjectPublicKeyInfo;
 
-       if (der_heim_oid_cmp(&spi->algorithm.algorithm, (*md->key_oid)()) != 0) {
+       if (der_heim_oid_cmp(&spi->algorithm.algorithm, md->key_oid) != 0) {
            hx509_clear_error_string(context);
            return HX509_SIG_ALG_DONT_MATCH_KEY_ALG;
        }
            hx509_clear_error_string(context);
            return HX509_SIG_ALG_DONT_MATCH_KEY_ALG;
        }
@@ -1108,13 +1666,6 @@ _hx509_create_signature(hx509_context context,
 {
     const struct signature_alg *md;
 
 {
     const struct signature_alg *md;
 
-    if (signer && signer->ops && signer->ops->handle_alg &&
-       (*signer->ops->handle_alg)(signer, alg, COT_SIGN))
-    {
-       return (*signer->ops->sign)(context, signer, alg, data,
-                                   signatureAlgorithm, sig);
-    }
-
     md = find_sig_alg(&alg->algorithm);
     if (md == NULL) {
        hx509_set_error_string(context, 0, HX509_SIG_ALG_NO_SUPPORTED,
     md = find_sig_alg(&alg->algorithm);
     if (md == NULL) {
        hx509_set_error_string(context, 0, HX509_SIG_ALG_NO_SUPPORTED,
@@ -1221,7 +1772,7 @@ _hx509_public_encrypt(hx509_context context,
     ciphertext->length = ret;
     ciphertext->data = to;
 
     ciphertext->length = ret;
     ciphertext->data = to;
 
-    ret = der_copy_oid(oid_id_pkcs1_rsaEncryption(), encryption_oid);
+    ret = der_copy_oid(&asn1_oid_id_pkcs1_rsaEncryption, encryption_oid);
     if (ret) {
        der_free_octet_string(ciphertext);
        hx509_set_error_string(context, 0, ENOMEM, "out of memory");
     if (ret) {
        der_free_octet_string(ciphertext);
        hx509_set_error_string(context, 0, ENOMEM, "out of memory");
@@ -1276,7 +1827,7 @@ _hx509_private_key_private_decrypt(hx509_context context,
 
 int
 _hx509_parse_private_key(hx509_context context,
 
 int
 _hx509_parse_private_key(hx509_context context,
-                        const heim_oid *key_oid,
+                        const AlgorithmIdentifier *keyai,
                         const void *data,
                         size_t len,
                         hx509_private_key *private_key)
                         const void *data,
                         size_t len,
                         hx509_private_key *private_key)
@@ -1286,7 +1837,7 @@ _hx509_parse_private_key(hx509_context context,
 
     *private_key = NULL;
 
 
     *private_key = NULL;
 
-    ops = find_private_alg(key_oid);
+    ops = find_private_alg(&keyai->algorithm);
     if (ops == NULL) {
        hx509_clear_error_string(context);
        return HX509_SIG_ALG_NO_SUPPORTED;
     if (ops == NULL) {
        hx509_clear_error_string(context);
        return HX509_SIG_ALG_NO_SUPPORTED;
@@ -1298,7 +1849,7 @@ _hx509_parse_private_key(hx509_context context,
        return ret;
     }
 
        return ret;
     }
 
-    ret = (*ops->import)(context, data, len, *private_key);
+    ret = (*ops->import)(context, keyai, data, len, *private_key);
     if (ret)
        _hx509_private_key_free(private_key);
 
     if (ret)
        _hx509_private_key_free(private_key);
 
@@ -1330,7 +1881,7 @@ _hx509_generate_private_key_init(hx509_context context,
 {
     *ctx = NULL;
 
 {
     *ctx = NULL;
 
-    if (der_heim_oid_cmp(oid, oid_id_pkcs1_rsaEncryption()) != 0) {
+    if (der_heim_oid_cmp(oid, &asn1_oid_id_pkcs1_rsaEncryption) != 0) {
        hx509_set_error_string(context, 0, EINVAL,
                               "private key not an RSA key");
        return EINVAL;
        hx509_set_error_string(context, 0, EINVAL,
                               "private key not an RSA key");
        return EINVAL;
@@ -1400,98 +1951,10 @@ _hx509_generate_private_key(hx509_context context,
     return ret;
 }
 
     return ret;
 }
 
-
 /*
  *
  */
 
 /*
  *
  */
 
-static const heim_octet_string null_entry_oid = { 2, rk_UNCONST("\x05\x00") };
-
-static const unsigned sha512_oid_tree[] = { 2, 16, 840, 1, 101, 3, 4, 2, 3 };
-const AlgorithmIdentifier _hx509_signature_sha512_data = {
-    { 9, rk_UNCONST(sha512_oid_tree) }, rk_UNCONST(&null_entry_oid)
-};
-
-static const unsigned sha384_oid_tree[] = { 2, 16, 840, 1, 101, 3, 4, 2, 2 };
-const AlgorithmIdentifier _hx509_signature_sha384_data = {
-    { 9, rk_UNCONST(sha384_oid_tree) }, rk_UNCONST(&null_entry_oid)
-};
-
-static const unsigned sha256_oid_tree[] = { 2, 16, 840, 1, 101, 3, 4, 2, 1 };
-const AlgorithmIdentifier _hx509_signature_sha256_data = {
-    { 9, rk_UNCONST(sha256_oid_tree) }, rk_UNCONST(&null_entry_oid)
-};
-
-static const unsigned sha1_oid_tree[] = { 1, 3, 14, 3, 2, 26 };
-const AlgorithmIdentifier _hx509_signature_sha1_data = {
-    { 6, rk_UNCONST(sha1_oid_tree) }, rk_UNCONST(&null_entry_oid)
-};
-
-static const unsigned md5_oid_tree[] = { 1, 2, 840, 113549, 2, 5 };
-const AlgorithmIdentifier _hx509_signature_md5_data = {
-    { 6, rk_UNCONST(md5_oid_tree) }, rk_UNCONST(&null_entry_oid)
-};
-
-static const unsigned md2_oid_tree[] = { 1, 2, 840, 113549, 2, 2 };
-const AlgorithmIdentifier _hx509_signature_md2_data = {
-    { 6, rk_UNCONST(md2_oid_tree) }, rk_UNCONST(&null_entry_oid)
-};
-
-static const unsigned rsa_with_sha512_oid[] ={ 1, 2, 840, 113549, 1, 1, 13 };
-const AlgorithmIdentifier _hx509_signature_rsa_with_sha512_data = {
-    { 7, rk_UNCONST(rsa_with_sha512_oid) }, NULL
-};
-
-static const unsigned rsa_with_sha384_oid[] ={ 1, 2, 840, 113549, 1, 1, 12 };
-const AlgorithmIdentifier _hx509_signature_rsa_with_sha384_data = {
-    { 7, rk_UNCONST(rsa_with_sha384_oid) }, NULL
-};
-
-static const unsigned rsa_with_sha256_oid[] ={ 1, 2, 840, 113549, 1, 1, 11 };
-const AlgorithmIdentifier _hx509_signature_rsa_with_sha256_data = {
-    { 7, rk_UNCONST(rsa_with_sha256_oid) }, NULL
-};
-
-static const unsigned rsa_with_sha1_oid[] ={ 1, 2, 840, 113549, 1, 1, 5 };
-const AlgorithmIdentifier _hx509_signature_rsa_with_sha1_data = {
-    { 7, rk_UNCONST(rsa_with_sha1_oid) }, NULL
-};
-
-static const unsigned rsa_with_md5_oid[] ={ 1, 2, 840, 113549, 1, 1, 4 };
-const AlgorithmIdentifier _hx509_signature_rsa_with_md5_data = {
-    { 7, rk_UNCONST(rsa_with_md5_oid) }, NULL
-};
-
-static const unsigned rsa_with_md2_oid[] ={ 1, 2, 840, 113549, 1, 1, 2 };
-const AlgorithmIdentifier _hx509_signature_rsa_with_md2_data = {
-    { 7, rk_UNCONST(rsa_with_md2_oid) }, NULL
-};
-
-static const unsigned rsa_oid[] ={ 1, 2, 840, 113549, 1, 1, 1 };
-const AlgorithmIdentifier _hx509_signature_rsa_data = {
-    { 7, rk_UNCONST(rsa_oid) }, NULL
-};
-
-static const unsigned rsa_pkcs1_x509_oid[] ={ 1, 2, 752, 43, 16, 1 };
-const AlgorithmIdentifier _hx509_signature_rsa_pkcs1_x509_data = {
-    { 6, rk_UNCONST(rsa_pkcs1_x509_oid) }, NULL
-};
-
-static const unsigned des_rsdi_ede3_cbc_oid[] ={ 1, 2, 840, 113549, 3, 7 };
-const AlgorithmIdentifier _hx509_des_rsdi_ede3_cbc_oid = {
-    { 6, rk_UNCONST(des_rsdi_ede3_cbc_oid) }, NULL
-};
-
-static const unsigned aes128_cbc_oid[] ={ 2, 16, 840, 1, 101, 3, 4, 1, 2 };
-const AlgorithmIdentifier _hx509_crypto_aes128_cbc_data = {
-    { 9, rk_UNCONST(aes128_cbc_oid) }, NULL
-};
-
-static const unsigned aes256_cbc_oid[] ={ 2, 16, 840, 1, 101, 3, 4, 1, 42 };
-const AlgorithmIdentifier _hx509_crypto_aes256_cbc_data = {
-    { 9, rk_UNCONST(aes256_cbc_oid) }, NULL
-};
-
 const AlgorithmIdentifier *
 hx509_signature_sha512(void)
 { return &_hx509_signature_sha512_data; }
 const AlgorithmIdentifier *
 hx509_signature_sha512(void)
 { return &_hx509_signature_sha512_data; }
@@ -1516,6 +1979,18 @@ const AlgorithmIdentifier *
 hx509_signature_md2(void)
 { return &_hx509_signature_md2_data; }
 
 hx509_signature_md2(void)
 { return &_hx509_signature_md2_data; }
 
+const AlgorithmIdentifier *
+hx509_signature_ecPublicKey(void)
+{ return &_hx509_signature_ecPublicKey; }
+
+const AlgorithmIdentifier *
+hx509_signature_ecdsa_with_sha256(void)
+{ return &_hx509_signature_ecdsa_with_sha256_data; }
+
+const AlgorithmIdentifier *
+hx509_signature_ecdsa_with_sha1(void)
+{ return &_hx509_signature_ecdsa_with_sha1_data; }
+
 const AlgorithmIdentifier *
 hx509_signature_rsa_with_sha512(void)
 { return &_hx509_signature_rsa_with_sha512_data; }
 const AlgorithmIdentifier *
 hx509_signature_rsa_with_sha512(void)
 { return &_hx509_signature_rsa_with_sha512_data; }
@@ -1565,9 +2040,9 @@ hx509_crypto_aes256_cbc(void)
  */
 
 const AlgorithmIdentifier * _hx509_crypto_default_sig_alg =
  */
 
 const AlgorithmIdentifier * _hx509_crypto_default_sig_alg =
-    &_hx509_signature_rsa_with_sha1_data;
+    &_hx509_signature_rsa_with_sha256_data;
 const AlgorithmIdentifier * _hx509_crypto_default_digest_alg =
 const AlgorithmIdentifier * _hx509_crypto_default_digest_alg =
-    &_hx509_signature_sha1_data;
+    &_hx509_signature_sha256_data;
 const AlgorithmIdentifier * _hx509_crypto_default_secret_alg =
     &_hx509_crypto_aes128_cbc_data;
 
 const AlgorithmIdentifier * _hx509_crypto_default_secret_alg =
     &_hx509_crypto_aes128_cbc_data;
 
@@ -1617,8 +2092,15 @@ _hx509_private_key_free(hx509_private_key *key)
     if (--(*key)->ref > 0)
        return 0;
 
     if (--(*key)->ref > 0)
        return 0;
 
-    if ((*key)->private_key.rsa)
-       RSA_free((*key)->private_key.rsa);
+    if ((*key)->ops && der_heim_oid_cmp((*key)->ops->key_oid, &asn1_oid_id_pkcs1_rsaEncryption) == 0) {
+       if ((*key)->private_key.rsa)
+           RSA_free((*key)->private_key.rsa);
+#ifdef HAVE_OPENSSL
+    } else if ((*key)->ops && der_heim_oid_cmp((*key)->ops->key_oid, &asn1_oid_id_ecPublicKey) == 0) {
+       if ((*key)->private_key.ecdsa)
+           EC_KEY_free((*key)->private_key.ecdsa);
+#endif
+    }
     (*key)->private_key.rsa = NULL;
     free(*key);
     *key = NULL;
     (*key)->private_key.rsa = NULL;
     free(*key);
     *key = NULL;
@@ -1631,7 +2113,7 @@ _hx509_private_key_assign_rsa(hx509_private_key key, void *ptr)
     if (key->private_key.rsa)
        RSA_free(key->private_key.rsa);
     key->private_key.rsa = ptr;
     if (key->private_key.rsa)
        RSA_free(key->private_key.rsa);
     key->private_key.rsa = ptr;
-    key->signature_alg = oid_id_pkcs1_sha1WithRSAEncryption();
+    key->signature_alg = &asn1_oid_id_pkcs1_sha1WithRSAEncryption;
     key->md = &pkcs1_rsa_sha1_alg;
 }
 
     key->md = &pkcs1_rsa_sha1_alg;
 }
 
@@ -1641,7 +2123,7 @@ _hx509_private_key_oid(hx509_context context,
                       heim_oid *data)
 {
     int ret;
                       heim_oid *data)
 {
     int ret;
-    ret = der_copy_oid((*key->ops->key_oid)(), data);
+    ret = der_copy_oid(key->ops->key_oid, data);
     if (ret)
        hx509_set_error_string(context, 0, ret, "malloc out of memory");
     return ret;
     if (ret)
        hx509_set_error_string(context, 0, ret, "malloc out of memory");
     return ret;
@@ -1683,7 +2165,9 @@ _hx509_private_key_export(hx509_context context,
 
 struct hx509cipher {
     const char *name;
 
 struct hx509cipher {
     const char *name;
-    const heim_oid *(*oid_func)(void);
+    int flags;
+#define CIPHER_WEAK 1
+    const heim_oid *oid;
     const AlgorithmIdentifier *(*ai_func)(void);
     const EVP_CIPHER *(*evp_func)(void);
     int (*get_params)(hx509_context, const hx509_crypto,
     const AlgorithmIdentifier *(*ai_func)(void);
     const EVP_CIPHER *(*evp_func)(void);
     int (*get_params)(hx509_context, const hx509_crypto,
@@ -1694,6 +2178,8 @@ struct hx509cipher {
 
 struct hx509_crypto_data {
     char *name;
 
 struct hx509_crypto_data {
     char *name;
+    int flags;
+#define ALLOW_WEAK 1
     const struct hx509cipher *cipher;
     const EVP_CIPHER *c;
     heim_octet_string key;
     const struct hx509cipher *cipher;
     const EVP_CIPHER *c;
     heim_octet_string key;
@@ -1705,15 +2191,10 @@ struct hx509_crypto_data {
  *
  */
 
  *
  */
 
-static const heim_oid *
-oid_private_rc2_40(void)
-{
-    static unsigned oid_data[] = { 127, 1 };
-    static const heim_oid oid = { 2, oid_data };
-
-    return &oid;
-}
+static unsigned private_rc2_40_oid_data[] = { 127, 1 };
 
 
+static heim_oid asn1_oid_private_rc2_40 =
+    { 2, private_rc2_40_oid_data };
 
 /*
  *
 
 /*
  *
@@ -1853,7 +2334,8 @@ CMSRC2CBCParam_set(hx509_context context, const heim_octet_string *param,
 static const struct hx509cipher ciphers[] = {
     {
        "rc2-cbc",
 static const struct hx509cipher ciphers[] = {
     {
        "rc2-cbc",
-       oid_id_pkcs3_rc2_cbc,
+       CIPHER_WEAK,
+       &asn1_oid_id_pkcs3_rc2_cbc,
        NULL,
        EVP_rc2_cbc,
        CMSRC2CBCParam_get,
        NULL,
        EVP_rc2_cbc,
        CMSRC2CBCParam_get,
@@ -1861,7 +2343,8 @@ static const struct hx509cipher ciphers[] = {
     },
     {
        "rc2-cbc",
     },
     {
        "rc2-cbc",
-       oid_id_rsadsi_rc2_cbc,
+       CIPHER_WEAK,
+       &asn1_oid_id_rsadsi_rc2_cbc,
        NULL,
        EVP_rc2_cbc,
        CMSRC2CBCParam_get,
        NULL,
        EVP_rc2_cbc,
        CMSRC2CBCParam_get,
@@ -1869,7 +2352,8 @@ static const struct hx509cipher ciphers[] = {
     },
     {
        "rc2-40-cbc",
     },
     {
        "rc2-40-cbc",
-       oid_private_rc2_40,
+       CIPHER_WEAK,
+       &asn1_oid_private_rc2_40,
        NULL,
        EVP_rc2_40_cbc,
        CMSRC2CBCParam_get,
        NULL,
        EVP_rc2_40_cbc,
        CMSRC2CBCParam_get,
@@ -1877,7 +2361,8 @@ static const struct hx509cipher ciphers[] = {
     },
     {
        "des-ede3-cbc",
     },
     {
        "des-ede3-cbc",
-       oid_id_pkcs3_des_ede3_cbc,
+       0,
+       &asn1_oid_id_pkcs3_des_ede3_cbc,
        NULL,
        EVP_des_ede3_cbc,
        CMSCBCParam_get,
        NULL,
        EVP_des_ede3_cbc,
        CMSCBCParam_get,
@@ -1885,7 +2370,8 @@ static const struct hx509cipher ciphers[] = {
     },
     {
        "des-ede3-cbc",
     },
     {
        "des-ede3-cbc",
-       oid_id_rsadsi_des_ede3_cbc,
+       0,
+       &asn1_oid_id_rsadsi_des_ede3_cbc,
        hx509_crypto_des_rsdi_ede3_cbc,
        EVP_des_ede3_cbc,
        CMSCBCParam_get,
        hx509_crypto_des_rsdi_ede3_cbc,
        EVP_des_ede3_cbc,
        CMSCBCParam_get,
@@ -1893,7 +2379,8 @@ static const struct hx509cipher ciphers[] = {
     },
     {
        "aes-128-cbc",
     },
     {
        "aes-128-cbc",
-       oid_id_aes_128_cbc,
+       0,
+       &asn1_oid_id_aes_128_cbc,
        hx509_crypto_aes128_cbc,
        EVP_aes_128_cbc,
        CMSCBCParam_get,
        hx509_crypto_aes128_cbc,
        EVP_aes_128_cbc,
        CMSCBCParam_get,
@@ -1901,7 +2388,8 @@ static const struct hx509cipher ciphers[] = {
     },
     {
        "aes-192-cbc",
     },
     {
        "aes-192-cbc",
-       oid_id_aes_192_cbc,
+       0,
+       &asn1_oid_id_aes_192_cbc,
        NULL,
        EVP_aes_192_cbc,
        CMSCBCParam_get,
        NULL,
        EVP_aes_192_cbc,
        CMSCBCParam_get,
@@ -1909,7 +2397,8 @@ static const struct hx509cipher ciphers[] = {
     },
     {
        "aes-256-cbc",
     },
     {
        "aes-256-cbc",
-       oid_id_aes_256_cbc,
+       0,
+       &asn1_oid_id_aes_256_cbc,
        hx509_crypto_aes256_cbc,
        EVP_aes_256_cbc,
        CMSCBCParam_get,
        hx509_crypto_aes256_cbc,
        EVP_aes_256_cbc,
        CMSCBCParam_get,
@@ -1923,7 +2412,7 @@ find_cipher_by_oid(const heim_oid *oid)
     int i;
 
     for (i = 0; i < sizeof(ciphers)/sizeof(ciphers[0]); i++)
     int i;
 
     for (i = 0; i < sizeof(ciphers)/sizeof(ciphers[0]); i++)
-       if (der_heim_oid_cmp(oid, (*ciphers[i].oid_func)()) == 0)
+       if (der_heim_oid_cmp(oid, ciphers[i].oid) == 0)
            return &ciphers[i];
 
     return NULL;
            return &ciphers[i];
 
     return NULL;
@@ -1950,7 +2439,7 @@ hx509_crypto_enctype_by_name(const char *name)
     cipher = find_cipher_by_name(name);
     if (cipher == NULL)
        return NULL;
     cipher = find_cipher_by_name(name);
     if (cipher == NULL)
        return NULL;
-    return (*cipher->oid_func)();
+    return cipher->oid;
 }
 
 int
 }
 
 int
@@ -2015,6 +2504,12 @@ hx509_crypto_set_key_name(hx509_crypto crypto, const char *name)
     return 0;
 }
 
     return 0;
 }
 
+void
+hx509_crypto_allow_weak(hx509_crypto crypto)
+{
+    crypto->flags |= ALLOW_WEAK;
+}
+
 int
 hx509_crypto_set_key_data(hx509_crypto crypto, const void *data, size_t length)
 {
 int
 hx509_crypto_set_key_data(hx509_crypto crypto, const void *data, size_t length)
 {
@@ -2111,6 +2606,10 @@ hx509_crypto_encrypt(hx509_crypto crypto,
 
     *ciphertext = NULL;
 
 
     *ciphertext = NULL;
 
+    if ((crypto->cipher->flags & CIPHER_WEAK) &&
+       (crypto->flags & ALLOW_WEAK) == 0)
+       return HX509_CRYPTO_ALGORITHM_BEST_BEFORE;
+
     assert(EVP_CIPHER_iv_length(crypto->c) == ivec->length);
 
     EVP_CIPHER_CTX_init(&evp);
     assert(EVP_CIPHER_iv_length(crypto->c) == ivec->length);
 
     EVP_CIPHER_CTX_init(&evp);
@@ -2189,6 +2688,10 @@ hx509_crypto_decrypt(hx509_crypto crypto,
     clear->data = NULL;
     clear->length = 0;
 
     clear->data = NULL;
     clear->length = 0;
 
+    if ((crypto->cipher->flags & CIPHER_WEAK) &&
+       (crypto->flags & ALLOW_WEAK) == 0)
+       return HX509_CRYPTO_ALGORITHM_BEST_BEFORE;
+
     if (ivec && EVP_CIPHER_iv_length(crypto->c) < ivec->length)
        return HX509_CRYPTO_INTERNAL_ERROR;
 
     if (ivec && EVP_CIPHER_iv_length(crypto->c) < ivec->length)
        return HX509_CRYPTO_INTERNAL_ERROR;
 
@@ -2312,6 +2815,8 @@ PBE_string2key(hx509_context context,
     if (ret)
        goto out;
 
     if (ret)
        goto out;
 
+    hx509_crypto_allow_weak(c);
+
     ret = hx509_crypto_set_key_data(c, key->data, key->length);
     if (ret) {
        hx509_crypto_destroy(c);
     ret = hx509_crypto_set_key_data(c, key->data, key->length);
     if (ret) {
        hx509_crypto_destroy(c);
@@ -2330,33 +2835,33 @@ find_string2key(const heim_oid *oid,
                const EVP_MD **md,
                PBE_string2key_func *s2k)
 {
                const EVP_MD **md,
                PBE_string2key_func *s2k)
 {
-    if (der_heim_oid_cmp(oid, oid_id_pbewithSHAAnd40BitRC2_CBC()) == 0) {
+    if (der_heim_oid_cmp(oid, &asn1_oid_id_pbewithSHAAnd40BitRC2_CBC) == 0) {
        *c = EVP_rc2_40_cbc();
        *md = EVP_sha1();
        *s2k = PBE_string2key;
        *c = EVP_rc2_40_cbc();
        *md = EVP_sha1();
        *s2k = PBE_string2key;
-       return oid_private_rc2_40();
-    } else if (der_heim_oid_cmp(oid, oid_id_pbeWithSHAAnd128BitRC2_CBC()) == 0) {
+       return &asn1_oid_private_rc2_40;
+    } else if (der_heim_oid_cmp(oid, &asn1_oid_id_pbeWithSHAAnd128BitRC2_CBC) == 0) {
        *c = EVP_rc2_cbc();
        *md = EVP_sha1();
        *s2k = PBE_string2key;
        *c = EVP_rc2_cbc();
        *md = EVP_sha1();
        *s2k = PBE_string2key;
-       return oid_id_pkcs3_rc2_cbc();
+       return &asn1_oid_id_pkcs3_rc2_cbc;
 #if 0
 #if 0
-    } else if (der_heim_oid_cmp(oid, oid_id_pbeWithSHAAnd40BitRC4()) == 0) {
+    } else if (der_heim_oid_cmp(oid, &asn1_oid_id_pbeWithSHAAnd40BitRC4) == 0) {
        *c = EVP_rc4_40();
        *md = EVP_sha1();
        *s2k = PBE_string2key;
        return NULL;
        *c = EVP_rc4_40();
        *md = EVP_sha1();
        *s2k = PBE_string2key;
        return NULL;
-    } else if (der_heim_oid_cmp(oid, oid_id_pbeWithSHAAnd128BitRC4()) == 0) {
+    } else if (der_heim_oid_cmp(oid, &asn1_oid_id_pbeWithSHAAnd128BitRC4) == 0) {
        *c = EVP_rc4();
        *md = EVP_sha1();
        *s2k = PBE_string2key;
        *c = EVP_rc4();
        *md = EVP_sha1();
        *s2k = PBE_string2key;
-       return oid_id_pkcs3_rc4();
+       return &asn1_oid_id_pkcs3_rc4;
 #endif
 #endif
-    } else if (der_heim_oid_cmp(oid, oid_id_pbeWithSHAAnd3_KeyTripleDES_CBC()) == 0) {
+    } else if (der_heim_oid_cmp(oid, &asn1_oid_id_pbeWithSHAAnd3_KeyTripleDES_CBC) == 0) {
        *c = EVP_des_ede3_cbc();
        *md = EVP_sha1();
        *s2k = PBE_string2key;
        *c = EVP_des_ede3_cbc();
        *md = EVP_sha1();
        *s2k = PBE_string2key;
-       return oid_id_pkcs3_des_ede3_cbc();
+       return &asn1_oid_id_pkcs3_des_ede3_cbc;
     }
 
     return NULL;
     }
 
     return NULL;
@@ -2467,8 +2972,8 @@ out:
  */
 
 
  */
 
 
-int
-_hx509_match_keys(hx509_cert c, hx509_private_key private_key)
+static int
+match_keys_rsa(hx509_cert c, hx509_private_key private_key)
 {
     const Certificate *cert;
     const SubjectPublicKeyInfo *spi;
 {
     const Certificate *cert;
     const SubjectPublicKeyInfo *spi;
@@ -2523,6 +3028,25 @@ _hx509_match_keys(hx509_cert c, hx509_private_key private_key)
     return ret == 1;
 }
 
     return ret == 1;
 }
 
+static int
+match_keys_ec(hx509_cert c, hx509_private_key private_key)
+{
+    return 1; /* XXX use EC_KEY_check_key */
+}
+
+
+int
+_hx509_match_keys(hx509_cert c, hx509_private_key key)
+{
+    if (der_heim_oid_cmp(key->ops->key_oid, &asn1_oid_id_pkcs1_rsaEncryption) == 0)
+       return match_keys_rsa(c, key);
+    if (der_heim_oid_cmp(key->ops->key_oid, &asn1_oid_id_ecPublicKey) == 0)
+       return match_keys_ec(c, key);
+    return 0;
+
+}
+
+
 static const heim_oid *
 find_keytype(const hx509_private_key key)
 {
 static const heim_oid *
 find_keytype(const hx509_private_key key)
 {
@@ -2534,10 +3058,9 @@ find_keytype(const hx509_private_key key)
     md = find_sig_alg(key->signature_alg);
     if (md == NULL)
        return NULL;
     md = find_sig_alg(key->signature_alg);
     if (md == NULL)
        return NULL;
-    return (*md->key_oid)();
+    return md->key_oid;
 }
 
 }
 
-
 int
 hx509_crypto_select(const hx509_context context,
                    int type,
 int
 hx509_crypto_select(const hx509_context context,
                    int type,
@@ -2545,7 +3068,7 @@ hx509_crypto_select(const hx509_context context,
                    hx509_peer_info peer,
                    AlgorithmIdentifier *selected)
 {
                    hx509_peer_info peer,
                    AlgorithmIdentifier *selected)
 {
-    const AlgorithmIdentifier *def;
+    const AlgorithmIdentifier *def = NULL;
     size_t i, j;
     int ret, bits;
 
     size_t i, j;
     int ret, bits;
 
@@ -2553,11 +3076,17 @@ hx509_crypto_select(const hx509_context context,
 
     if (type == HX509_SELECT_DIGEST) {
        bits = SIG_DIGEST;
 
     if (type == HX509_SELECT_DIGEST) {
        bits = SIG_DIGEST;
-       def = _hx509_crypto_default_digest_alg;
+       if (source)
+           def = alg_for_privatekey(source, type);
+       if (def == NULL)
+           def = _hx509_crypto_default_digest_alg;
     } else if (type == HX509_SELECT_PUBLIC_SIG) {
        bits = SIG_PUBLIC_SIG;
        /* XXX depend on `source´ and `peer´ */
     } else if (type == HX509_SELECT_PUBLIC_SIG) {
        bits = SIG_PUBLIC_SIG;
        /* XXX depend on `source´ and `peer´ */
-       def = _hx509_crypto_default_sig_alg;
+       if (source)
+           def = alg_for_privatekey(source, type);
+       if (def == NULL)
+           def = _hx509_crypto_default_sig_alg;
     } else if (type == HX509_SELECT_SECRET_ENC) {
        bits = SIG_SECRET;
        def = _hx509_crypto_default_secret_alg;
     } else if (type == HX509_SELECT_SECRET_ENC) {
        bits = SIG_SECRET;
        def = _hx509_crypto_default_secret_alg;
@@ -2576,11 +3105,11 @@ hx509_crypto_select(const hx509_context context,
            for (j = 0; sig_algs[j]; j++) {
                if ((sig_algs[j]->flags & bits) != bits)
                    continue;
            for (j = 0; sig_algs[j]; j++) {
                if ((sig_algs[j]->flags & bits) != bits)
                    continue;
-               if (der_heim_oid_cmp((*sig_algs[j]->sig_oid)(),
+               if (der_heim_oid_cmp(sig_algs[j]->sig_oid,
                                     &peer->val[i].algorithm) != 0)
                    continue;
                if (keytype && sig_algs[j]->key_oid &&
                                     &peer->val[i].algorithm) != 0)
                    continue;
                if (keytype && sig_algs[j]->key_oid &&
-                   der_heim_oid_cmp(keytype, (*sig_algs[j]->key_oid)()))
+                   der_heim_oid_cmp(keytype, sig_algs[j]->key_oid))
                    continue;
 
                /* found one, use that */
                    continue;
 
                /* found one, use that */
@@ -2648,7 +3177,7 @@ hx509_crypto_available(hx509_context context,
        if (sig_algs[i]->sig_alg == NULL)
            continue;
        if (keytype && sig_algs[i]->key_oid &&
        if (sig_algs[i]->sig_alg == NULL)
            continue;
        if (keytype && sig_algs[i]->key_oid &&
-           der_heim_oid_cmp((*sig_algs[i]->key_oid)(), keytype))
+           der_heim_oid_cmp(sig_algs[i]->key_oid, keytype))
            continue;
 
        /* found one, add that to the list */
            continue;
 
        /* found one, add that to the list */
@@ -2657,7 +3186,7 @@ hx509_crypto_available(hx509_context context,
            goto out;
        *val = ptr;
 
            goto out;
        *val = ptr;
 
-       ret = copy_AlgorithmIdentifier((*sig_algs[i]->sig_alg)(), &(*val)[len]);
+       ret = copy_AlgorithmIdentifier(sig_algs[i]->sig_alg, &(*val)[len]);
        if (ret)
            goto out;
        len++;
        if (ret)
            goto out;
        len++;
@@ -2667,7 +3196,9 @@ hx509_crypto_available(hx509_context context,
     if (bits & SIG_SECRET) {
 
        for (i = 0; i < sizeof(ciphers)/sizeof(ciphers[0]); i++) {
     if (bits & SIG_SECRET) {
 
        for (i = 0; i < sizeof(ciphers)/sizeof(ciphers[0]); i++) {
-       
+
+           if (ciphers[i].flags & CIPHER_WEAK)
+               continue;
            if (ciphers[i].ai_func == NULL)
                continue;
 
            if (ciphers[i].ai_func == NULL)
                continue;
 
index 0b0a68ceae16614e9ca5999c976e67df0ff200b4..7598aebaae74142152ff97f9aadf5e5b24773e31 100644 (file)
@@ -32,7 +32,6 @@
  */
 
 #include "hx_locl.h"
  */
 
 #include "hx_locl.h"
-RCSID("$Id$");
 
 /**
  * @page page_env Hx509 enviroment functions
 
 /**
  * @page page_env Hx509 enviroment functions
index 6f25404145afcf98d045fb44dee25e2ecd0178de..45813efb38b15e931af287ac340e8569f23ff0ec 100644 (file)
@@ -32,7 +32,6 @@
  */
 
 #include "hx_locl.h"
  */
 
 #include "hx_locl.h"
-RCSID("$Id$");
 
 /**
  * @page page_error Hx509 error reporting functions
 
 /**
  * @page page_error Hx509 error reporting functions
index a364dd2179176eb04c4466386425a3027b945a0e..ba7a23f471238442067f998febf47372e84b1bc3 100644 (file)
@@ -32,7 +32,6 @@
  */
 
 #include "hx_locl.h"
  */
 
 #include "hx_locl.h"
-RCSID("$ID$");
 
 int
 _hx509_map_file_os(const char *fn, heim_octet_string *os)
 
 int
 _hx509_map_file_os(const char *fn, heim_octet_string *os)
index 5e5a2f811bff36bc1c94546dbe477f4adf8d138d..86aad7ec9cdd054c81736601021b1b2cc68c0254 100644 (file)
@@ -36,8 +36,9 @@
 #ifndef HEIMDAL_HX509_H
 #define HEIMDAL_HX509_H 1
 
 #ifndef HEIMDAL_HX509_H
 #define HEIMDAL_HX509_H 1
 
-#include <heim_asn1.h>
 #include <rfc2459_asn1.h>
 #include <rfc2459_asn1.h>
+#include <stdarg.h>
+#include <stdio.h>
 
 typedef struct hx509_cert_attribute_data *hx509_cert_attribute;
 typedef struct hx509_cert_data *hx509_cert;
 
 typedef struct hx509_cert_attribute_data *hx509_cert_attribute;
 typedef struct hx509_cert_data *hx509_cert;
@@ -124,6 +125,17 @@ typedef enum {
 
 /* flags to hx509_cms_unenvelope */
 #define HX509_CMS_UE_DONT_REQUIRE_KU_ENCIPHERMENT      0x01
 
 /* flags to hx509_cms_unenvelope */
 #define HX509_CMS_UE_DONT_REQUIRE_KU_ENCIPHERMENT      0x01
+#define HX509_CMS_UE_ALLOW_WEAK                                0x02
+
+/* flags to hx509_cms_envelope_1 */
+#define HX509_CMS_EV_NO_KU_CHECK                       0x01
+#define HX509_CMS_EV_ALLOW_WEAK                                0x02
+
+/* flags to hx509_cms_verify_signed */
+#define HX509_CMS_VS_ALLOW_DATA_OID_MISMATCH           0x01
+#define HX509_CMS_VS_NO_KU_CHECK                       0x02
+#define HX509_CMS_VS_ALLOW_ZERO_SIGNER                 0x04
+#define HX509_CMS_VS_NO_VALIDATE                       0x08
 
 /* selectors passed to hx509_crypto_select and hx509_crypto_available */
 #define HX509_SELECT_ALL 0
 
 /* selectors passed to hx509_crypto_select and hx509_crypto_available */
 #define HX509_SELECT_ALL 0
@@ -142,8 +154,9 @@ typedef enum {
 #define HX509_CA_TEMPLATE_EKU 64
 
 /* flags hx509_cms_create_signed* */
 #define HX509_CA_TEMPLATE_EKU 64
 
 /* flags hx509_cms_create_signed* */
-#define HX509_CMS_SIGATURE_DETACHED 1
-#define HX509_CMS_SIGATURE_ID_NAME 2
+#define HX509_CMS_SIGNATURE_DETACHED                   0x01
+#define HX509_CMS_SIGNATURE_ID_NAME                    0x02
+#define HX509_CMS_SIGNATURE_NO_SIGNER                  0x04
 
 /* hx509_verify_hostname nametype */
 typedef enum  {
 
 /* hx509_verify_hostname nametype */
 typedef enum  {
index c1dfaf587e69dfe58376cdd6b892ce7c18f0e87e..76bbfaeabaa1a8fdb482f08282d5668a567562b8 100644 (file)
@@ -62,9 +62,10 @@ error_code OID_MISMATCH, "Mismatch bewteen oids"
 error_code NO_PROMPTER, "No prompter function defined"
 error_code SIGNATURE_WITHOUT_SIGNER, "Signature require signer, but non available"
 error_code RSA_PUBLIC_ENCRYPT, "RSA public encyption failed"
 error_code NO_PROMPTER, "No prompter function defined"
 error_code SIGNATURE_WITHOUT_SIGNER, "Signature require signer, but non available"
 error_code RSA_PUBLIC_ENCRYPT, "RSA public encyption failed"
-error_code RSA_PRIVATE_ENCRYPT, "RSA public encyption failed"
-error_code RSA_PUBLIC_DECRYPT, "RSA private decryption failed"
+error_code RSA_PRIVATE_ENCRYPT, "RSA private encyption failed"
+error_code RSA_PUBLIC_DECRYPT, "RSA public decryption failed"
 error_code RSA_PRIVATE_DECRYPT, "RSA private decryption failed"
 error_code RSA_PRIVATE_DECRYPT, "RSA private decryption failed"
+error_code ALGORITHM_BEST_BEFORE, "Algorithm has passed its best before date"
 
 # revoke related errors
 index 96
 
 # revoke related errors
 index 96
index 8de2353f159b867baaee9d1ac9cf809885f43850..2d1c036d53717bae3ca68f54ccaa30c2521d6396 100644 (file)
@@ -33,9 +33,7 @@
 
 /* $Id$ */
 
 
 /* $Id$ */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-#endif
 
 #include <stdio.h>
 #include <stdlib.h>
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -145,7 +143,7 @@ struct hx509_query_data {
     Name *subject_name;
     hx509_path *path;
     char *friendlyname;
     Name *subject_name;
     hx509_path *path;
     char *friendlyname;
-    int (*cmp_func)(void *, hx509_cert);
+    int (*cmp_func)(hx509_context, hx509_cert, void *);
     void *cmp_func_ctx;
     heim_octet_string *keyhash_sha1;
     time_t timenow;
     void *cmp_func_ctx;
     heim_octet_string *keyhash_sha1;
     time_t timenow;
index b68064b512cbaa5549f5086d41febef8982067ba..c4f035ab87ee51ec9b149b0f3185bb63fba3548c 100644 (file)
@@ -32,7 +32,6 @@
  */
 
 #include "hx_locl.h"
  */
 
 #include "hx_locl.h"
-RCSID("$Id$");
 
 /**
  * @page page_keyset Certificate store operations
 
 /**
  * @page page_keyset Certificate store operations
@@ -481,6 +480,10 @@ hx509_certs_find(hx509_context context,
     hx509_certs_end_seq(context, certs, cursor);
     if (ret)
        return ret;
     hx509_certs_end_seq(context, certs, cursor);
     if (ret)
        return ret;
+    /**
+     * Return HX509_CERT_NOT_FOUND if no certificate in certs matched
+     * the query.
+     */
     if (c == NULL) {
        hx509_clear_error_string(context);
        return HX509_CERT_NOT_FOUND;
     if (c == NULL) {
        hx509_clear_error_string(context);
        return HX509_CERT_NOT_FOUND;
@@ -489,6 +492,77 @@ hx509_certs_find(hx509_context context,
     return 0;
 }
 
     return 0;
 }
 
+/**
+ * Filter certificate matching the query.
+ *
+ * @param context a hx509 context.
+ * @param certs certificate store to search.
+ * @param q query allocated with @ref hx509_query functions.
+ * @param result the filtered certificate store, caller must free with
+ *        hx509_certs_free().
+ *
+ * @return Returns an hx509 error code.
+ *
+ * @ingroup hx509_keyset
+ */
+
+int
+hx509_certs_filter(hx509_context context,
+                  hx509_certs certs,
+                  const hx509_query *q,
+                  hx509_certs *result)
+{
+    hx509_cursor cursor;
+    hx509_cert c;
+    int ret, found = 0;
+
+    _hx509_query_statistic(context, 0, q);
+
+    ret = hx509_certs_init(context, "MEMORY:filter-certs", 0,
+                          NULL, result);
+    if (ret)
+       return ret;
+
+    ret = hx509_certs_start_seq(context, certs, &cursor);
+    if (ret) {
+       hx509_certs_free(result);
+       return ret;
+    }
+
+    c = NULL;
+    while (1) {
+       ret = hx509_certs_next_cert(context, certs, cursor, &c);
+       if (ret)
+           break;
+       if (c == NULL)
+           break;
+       if (_hx509_query_match_cert(context, q, c)) {
+           hx509_certs_add(context, *result, c);
+           found = 1;
+       }
+       hx509_cert_free(c);
+    }
+
+    hx509_certs_end_seq(context, certs, cursor);
+    if (ret) {
+       hx509_certs_free(result);
+       return ret;
+    }
+
+    /**
+     * Return HX509_CERT_NOT_FOUND if no certificate in certs matched
+     * the query.
+     */
+    if (!found) {
+       hx509_certs_free(result);
+       hx509_clear_error_string(context);
+       return HX509_CERT_NOT_FOUND;
+    }
+
+    return 0;
+}
+
+
 static int
 certs_merge_func(hx509_context context, void *ctx, hx509_cert c)
 {
 static int
 certs_merge_func(hx509_context context, void *ctx, hx509_cert c)
 {
index 76c0c4263309f9d9036fbe3341c37b5f44f25282..a627fc65a2eab8cb394d2eb6ad628000752a720b 100644 (file)
@@ -32,7 +32,6 @@
  */
 
 #include "hx_locl.h"
  */
 
 #include "hx_locl.h"
-RCSID("$Id$");
 #include <dirent.h>
 
 /*
 #include <dirent.h>
 
 /*
@@ -71,7 +70,7 @@ dir_init(hx509_context context,
            return ENOENT;
        }
 
            return ENOENT;
        }
 
-       if ((sb.st_mode & S_IFDIR) == 0) {
+       if (!S_ISDIR(sb.st_mode)) {
            hx509_set_error_string(context, 0, ENOTDIR,
                                   "%s is not a directory", residue);
            return ENOTDIR;
            hx509_set_error_string(context, 0, ENOTDIR,
                                   "%s is not a directory", residue);
            return ENOTDIR;
index ca0171f8b9970ab362cc30b8166e777140241767..74808f760765a97c2ac098f911785ff7d463dd80 100644 (file)
@@ -32,7 +32,6 @@
  */
 
 #include "hx_locl.h"
  */
 
 #include "hx_locl.h"
-RCSID("$Id$");
 
 typedef enum { USE_PEM, USE_DER } outformat;
 
 
 typedef enum { USE_PEM, USE_DER } outformat;
 
@@ -50,7 +49,8 @@ static int
 parse_certificate(hx509_context context, const char *fn,
                  struct hx509_collector *c,
                  const hx509_pem_header *headers,
 parse_certificate(hx509_context context, const char *fn,
                  struct hx509_collector *c,
                  const hx509_pem_header *headers,
-                 const void *data, size_t len)
+                 const void *data, size_t len,
+                 const AlgorithmIdentifier *ai)
 {
     hx509_cert cert;
     int ret;
 {
     hx509_cert cert;
     int ret;
@@ -130,10 +130,40 @@ out:
 }
 
 static int
 }
 
 static int
-parse_rsa_private_key(hx509_context context, const char *fn,
+parse_pkcs8_private_key(hx509_context context, const char *fn,
+                       struct hx509_collector *c,
+                       const hx509_pem_header *headers,
+                       const void *data, size_t length,
+                       const AlgorithmIdentifier *ai)
+{
+    PKCS8PrivateKeyInfo ki;
+    heim_octet_string keydata;
+   
+    int ret;
+
+    ret = decode_PKCS8PrivateKeyInfo(data, length, &ki, NULL);
+    if (ret)
+       return ret;
+
+    keydata.data = rk_UNCONST(data);
+    keydata.length = length;
+
+    ret = _hx509_collector_private_key_add(context,
+                                          c,
+                                          &ki.privateKeyAlgorithm,
+                                          NULL,
+                                          &ki.privateKey,
+                                          &keydata);
+    free_PKCS8PrivateKeyInfo(&ki);
+    return ret;
+}
+
+static int
+parse_pem_private_key(hx509_context context, const char *fn,
                      struct hx509_collector *c,
                      const hx509_pem_header *headers,
                      struct hx509_collector *c,
                      const hx509_pem_header *headers,
-                     const void *data, size_t len)
+                     const void *data, size_t len,
+                     const AlgorithmIdentifier *ai)
 {
     int ret = 0;
     const char *enc;
 {
     int ret = 0;
     const char *enc;
@@ -159,7 +189,7 @@ parse_rsa_private_key(hx509_context context, const char *fn,
 
        if (strcmp(enc, "4,ENCRYPTED") != 0) {
            hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
 
        if (strcmp(enc, "4,ENCRYPTED") != 0) {
            hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
-                                  "RSA key encrypted in unknown method %s "
+                                  "Private key encrypted in unknown method %s "
                                   "in file",
                                   enc, fn);
            hx509_clear_error_string(context);
                                   "in file",
                                   enc, fn);
            hx509_clear_error_string(context);
@@ -169,7 +199,7 @@ parse_rsa_private_key(hx509_context context, const char *fn,
        dek = hx509_pem_find_header(headers, "DEK-Info");
        if (dek == NULL) {
            hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
        dek = hx509_pem_find_header(headers, "DEK-Info");
        if (dek == NULL) {
            hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
-                                  "Encrypted RSA missing DEK-Info");
+                                  "Encrypted private key missing DEK-Info");
            return HX509_PARSING_KEY_FAILED;
        }
 
            return HX509_PARSING_KEY_FAILED;
        }
 
@@ -201,7 +231,7 @@ parse_rsa_private_key(hx509_context context, const char *fn,
        if (cipher == NULL) {
            free(ivdata);
            hx509_set_error_string(context, 0, HX509_ALG_NOT_SUPP,
        if (cipher == NULL) {
            free(ivdata);
            hx509_set_error_string(context, 0, HX509_ALG_NOT_SUPP,
-                                  "RSA key encrypted with "
+                                  "Private key encrypted with "
                                   "unsupported cipher: %s",
                                   type);
            free(type);
                                   "unsupported cipher: %s",
                                   type);
            free(type);
@@ -218,7 +248,8 @@ parse_rsa_private_key(hx509_context context, const char *fn,
        if (ssize < 0 || ssize < PKCS5_SALT_LEN || ssize < EVP_CIPHER_iv_length(cipher)) {
            free(ivdata);
            hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
        if (ssize < 0 || ssize < PKCS5_SALT_LEN || ssize < EVP_CIPHER_iv_length(cipher)) {
            free(ivdata);
            hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
-                                  "Salt have wrong length in RSA key file");
+                                  "Salt have wrong length in "
+                                  "private key file");
            return HX509_PARSING_KEY_FAILED;
        }
        
            return HX509_PARSING_KEY_FAILED;
        }
        
@@ -231,9 +262,8 @@ parse_rsa_private_key(hx509_context context, const char *fn,
                password = pw->val[i];
                passwordlen = strlen(password);
                
                password = pw->val[i];
                passwordlen = strlen(password);
                
-               ret = try_decrypt(context, c, hx509_signature_rsa(),
-                                 cipher, ivdata, password, passwordlen,
-                                 data, len);
+               ret = try_decrypt(context, c, ai, cipher, ivdata, 
+                                 password, passwordlen, data, len);
                if (ret == 0) {
                    decrypted = 1;
                    break;
                if (ret == 0) {
                    decrypted = 1;
                    break;
@@ -253,9 +283,8 @@ parse_rsa_private_key(hx509_context context, const char *fn,
 
            ret = hx509_lock_prompt(lock, &prompt);
            if (ret == 0)
 
            ret = hx509_lock_prompt(lock, &prompt);
            if (ret == 0)
-               ret = try_decrypt(context, c, hx509_signature_rsa(),
-                                 cipher, ivdata, password, strlen(password),
-                                 data, len);
+               ret = try_decrypt(context, c, ai, cipher, ivdata, password, 
+                                 strlen(password), data, len);
            /* XXX add password to lock password collection ? */
            memset(password, 0, sizeof(password));
        }
            /* XXX add password to lock password collection ? */
            memset(password, 0, sizeof(password));
        }
@@ -267,12 +296,8 @@ parse_rsa_private_key(hx509_context context, const char *fn,
        keydata.data = rk_UNCONST(data);
        keydata.length = len;
 
        keydata.data = rk_UNCONST(data);
        keydata.length = len;
 
-       ret = _hx509_collector_private_key_add(context,
-                                              c,
-                                              hx509_signature_rsa(),
-                                              NULL,
-                                              &keydata,
-                                              NULL);
+       ret = _hx509_collector_private_key_add(context, c, ai, NULL,
+                                              &keydata, NULL);
     }
 
     return ret;
     }
 
     return ret;
@@ -282,10 +307,14 @@ parse_rsa_private_key(hx509_context context, const char *fn,
 struct pem_formats {
     const char *name;
     int (*func)(hx509_context, const char *, struct hx509_collector *,
 struct pem_formats {
     const char *name;
     int (*func)(hx509_context, const char *, struct hx509_collector *,
-               const hx509_pem_header *, const void *, size_t);
+               const hx509_pem_header *, const void *, size_t,
+               const AlgorithmIdentifier *);
+    const AlgorithmIdentifier *(*ai)(void);
 } formats[] = {
 } formats[] = {
-    { "CERTIFICATE", parse_certificate },
-    { "RSA PRIVATE KEY", parse_rsa_private_key }
+    { "CERTIFICATE", parse_certificate, NULL },
+    { "PRIVATE KEY", parse_pkcs8_private_key, NULL },
+    { "RSA PRIVATE KEY", parse_pem_private_key, hx509_signature_rsa },
+    { "EC PRIVATE KEY", parse_pem_private_key, hx509_signature_ecPublicKey }
 };
 
 
 };
 
 
@@ -305,9 +334,18 @@ pem_func(hx509_context context, const char *type,
     for (j = 0; j < sizeof(formats)/sizeof(formats[0]); j++) {
        const char *q = formats[j].name;
        if (strcasecmp(type, q) == 0) {
     for (j = 0; j < sizeof(formats)/sizeof(formats[0]); j++) {
        const char *q = formats[j].name;
        if (strcasecmp(type, q) == 0) {
-           ret = (*formats[j].func)(context, NULL, pem_ctx->c,  header, data, len);
-           if (ret == 0)
-               break;
+           const AlgorithmIdentifier *ai = NULL;
+           if (formats[j].ai != NULL)
+               ai = (*formats[j].ai)();
+
+           ret = (*formats[j].func)(context, NULL, pem_ctx->c, 
+                                    header, data, len, ai);
+           if (ret) {
+               hx509_set_error_string(context, HX509_ERROR_APPEND, ret,
+                                      "Failed parseing PEM format %s", type);
+               return ret;
+           }
+           break;
        }
     }
     if (j == sizeof(formats)/sizeof(formats[0])) {
        }
     }
     if (j == sizeof(formats)/sizeof(formats[0])) {
@@ -409,13 +447,19 @@ file_init_common(hx509_context context,
            }
 
            for (i = 0; i < sizeof(formats)/sizeof(formats[0]); i++) {
            }
 
            for (i = 0; i < sizeof(formats)/sizeof(formats[0]); i++) {
-               ret = (*formats[i].func)(context, p, pem_ctx.c, NULL, ptr, length);
+               const AlgorithmIdentifier *ai = NULL;
+               if (formats[i].ai != NULL)
+                   ai = (*formats[i].ai)();
+
+               ret = (*formats[i].func)(context, p, pem_ctx.c, NULL, ptr, length, ai);
                if (ret == 0)
                    break;
            }
            rk_xfree(ptr);
                if (ret == 0)
                    break;
            }
            rk_xfree(ptr);
-           if (ret)
+           if (ret) {
+               hx509_clear_error_string(context);
                goto out;
                goto out;
+           }
        }
     }
 
        }
     }
 
index 2dc07215636f04a09eb4fa9e758a966f06b2ed8d..01d0c55d1c6da71b513c8bae08f58ffa6bee3935 100644 (file)
@@ -32,7 +32,6 @@
  */
 
 #include "hx_locl.h"
  */
 
 #include "hx_locl.h"
-RCSID("$Id$");
 
 #ifdef HAVE_FRAMEWORK_SECURITY
 
 
 #ifdef HAVE_FRAMEWORK_SECURITY
 
@@ -119,6 +118,8 @@ kc_rsa_private_encrypt(int flen,
     CSSM_DATA sig, in;
     int fret = 0;
 
     CSSM_DATA sig, in;
     int fret = 0;
 
+    if (padding != RSA_PKCS1_PADDING)
+       return -1;
 
     cret = SecKeyGetCSSMKey(privKeyRef, &cssmKey);
     if(cret) abort();
 
     cret = SecKeyGetCSSMKey(privKeyRef, &cssmKey);
     if(cret) abort();
@@ -157,7 +158,62 @@ static int
 kc_rsa_private_decrypt(int flen, const unsigned char *from, unsigned char *to,
                       RSA * rsa, int padding)
 {
 kc_rsa_private_decrypt(int flen, const unsigned char *from, unsigned char *to,
                       RSA * rsa, int padding)
 {
-    return -1;
+    struct kc_rsa *kc = RSA_get_app_data(rsa);
+
+    CSSM_RETURN cret;
+    OSStatus ret;
+    const CSSM_ACCESS_CREDENTIALS *creds;
+    SecKeyRef privKeyRef = (SecKeyRef)kc->item;
+    CSSM_CSP_HANDLE cspHandle;
+    const CSSM_KEY *cssmKey;
+    CSSM_CC_HANDLE handle = 0;
+    CSSM_DATA out, in, rem;
+    int fret = 0;
+    CSSM_SIZE outlen = 0;
+    char remdata[1024];
+
+    if (padding != RSA_PKCS1_PADDING)
+       return -1;
+
+    cret = SecKeyGetCSSMKey(privKeyRef, &cssmKey);
+    if(cret) abort();
+
+    cret = SecKeyGetCSPHandle(privKeyRef, &cspHandle);
+    if(cret) abort();
+
+    ret = SecKeyGetCredentials(privKeyRef, CSSM_ACL_AUTHORIZATION_DECRYPT,
+                              kSecCredentialTypeDefault, &creds);
+    if(ret) abort();
+
+
+    ret = CSSM_CSP_CreateAsymmetricContext (cspHandle,
+                                           CSSM_ALGID_RSA,
+                                           creds,
+                                           cssmKey,
+                                           CSSM_PADDING_PKCS1,
+                                           &handle);
+    if(ret) abort();
+
+    in.Data = (uint8 *)from;
+    in.Length = flen;
+       
+    out.Data = (uint8 *)to;
+    out.Length = kc->keysize;
+       
+    rem.Data = (uint8 *)remdata;
+    rem.Length = sizeof(remdata);
+
+    cret = CSSM_DecryptData(handle, &in, 1, &out, 1, &outlen, &rem);
+    if(cret) {
+       /* cssmErrorString(cret); */
+       fret = -1;
+    } else
+       fret = out.Length;
+
+    if(handle)
+       CSSM_DeleteContext(handle);
+
+    return fret;
 }
 
 static int
 }
 
 static int
@@ -504,8 +560,7 @@ keychain_iter_end(hx509_context context,
     struct iter *iter = cursor;
 
     if (iter->certs) {
     struct iter *iter = cursor;
 
     if (iter->certs) {
-       int ret;
-       ret = hx509_certs_end_seq(context, iter->certs, iter->cursor);
+       hx509_certs_end_seq(context, iter->certs, iter->cursor);
        hx509_certs_free(&iter->certs);
     } else {
        CFRelease(iter->searchRef);
        hx509_certs_free(&iter->certs);
     } else {
        CFRelease(iter->searchRef);
index bf952fbeeea403586156514fbe7c8b7ffa98b9bd..299a3932c9b515b42bf474de12242933719c6450 100644 (file)
@@ -32,7 +32,6 @@
  */
 
 #include "hx_locl.h"
  */
 
 #include "hx_locl.h"
-RCSID("Id$");
 
 /*
  * Should use two hash/tree certificates intead of a array.  Criteria
 
 /*
  * Should use two hash/tree certificates intead of a array.  Criteria
index fae631fb3fdc52801c2714cc75feca2173b4d8ed..136d2d43459fc8453f0dfd6dfb1fb028294acc88 100644 (file)
@@ -32,7 +32,6 @@
  */
 
 #include "hx_locl.h"
  */
 
 #include "hx_locl.h"
-RCSID("$Id$");
 
 
 static int
 
 
 static int
index 652cdc22104cb18bce174b6f8f2d94dd49e371ea..52697f834b25192c207e139fe0c2045928eac396 100644 (file)
@@ -32,7 +32,6 @@
  */
 
 #include "hx_locl.h"
  */
 
 #include "hx_locl.h"
-RCSID("$Id$");
 #ifdef HAVE_DLFCN_H
 #include <dlfcn.h>
 #endif
 #ifdef HAVE_DLFCN_H
 #include <dlfcn.h>
 #endif
@@ -332,7 +331,7 @@ p11_init_slot(hx509_context context,
     }
 
     asprintf(&slot->name, "%.*s",
     }
 
     asprintf(&slot->name, "%.*s",
-            i, slot_info.slotDescription);
+            (int)i, slot_info.slotDescription);
 
     if ((slot_info.flags & CKF_TOKEN_PRESENT) == 0)
        return 0;
 
     if ((slot_info.flags & CKF_TOKEN_PRESENT) == 0)
        return 0;
@@ -711,7 +710,7 @@ collect_cert(hx509_context context,
        
        _hx509_set_cert_attribute(context,
                                  cert,
        
        _hx509_set_cert_attribute(context,
                                  cert,
-                                 oid_id_pkcs_9_at_localKeyId(),
+                                 &asn1_oid_id_pkcs_9_at_localKeyId,
                                  &data);
     }
 
                                  &data);
     }
 
@@ -945,11 +944,7 @@ p11_release_module(struct p11_module *p)
        if (p->slot[i].flags & P11_SESSION_IN_USE)
            _hx509_abort("pkcs11 module release while session in use");
        if (p->slot[i].flags & P11_SESSION) {
        if (p->slot[i].flags & P11_SESSION_IN_USE)
            _hx509_abort("pkcs11 module release while session in use");
        if (p->slot[i].flags & P11_SESSION) {
-           int ret;
-
-           ret = P11FUNC(p, CloseSession, (p->slot[i].session));
-           if (ret != CKR_OK)
-               ;
+           P11FUNC(p, CloseSession, (p->slot[i].session));
        }
 
        if (p->slot[i].name)
        }
 
        if (p->slot[i].name)
index b59bd215f0f50a98c37ac82c3be244fd9b28102e..c17ce3f6ac4fdf70562965186f4624c5b04c500e 100644 (file)
@@ -32,7 +32,6 @@
  */
 
 #include "hx_locl.h"
  */
 
 #include "hx_locl.h"
-RCSID("$Id$");
 
 struct ks_pkcs12 {
     hx509_certs certs;
 
 struct ks_pkcs12 {
     hx509_certs certs;
@@ -45,7 +44,7 @@ typedef int (*collector_func)(hx509_context,
                              const PKCS12_Attributes *);
 
 struct type {
                              const PKCS12_Attributes *);
 
 struct type {
-    const heim_oid * (*oid)(void);
+    const heim_oid *oid;
     collector_func func;
 };
 
     collector_func func;
 };
 
@@ -77,7 +76,7 @@ keyBag_parser(hx509_context context,
     const heim_octet_string *os = NULL;
     int ret;
 
     const heim_octet_string *os = NULL;
     int ret;
 
-    attr = find_attribute(attrs, oid_id_pkcs_9_at_localKeyId());
+    attr = find_attribute(attrs, &asn1_oid_id_pkcs_9_at_localKeyId);
     if (attr)
        os = &attr->attrValues;
 
     if (attr)
        os = &attr->attrValues;
 
@@ -140,7 +139,7 @@ certBag_parser(hx509_context context,
     if (ret)
        return ret;
 
     if (ret)
        return ret;
 
-    if (der_heim_oid_cmp(oid_id_pkcs_9_at_certTypes_x509(), &cb.certType)) {
+    if (der_heim_oid_cmp(&asn1_oid_id_pkcs_9_at_certTypes_x509, &cb.certType)) {
        free_PKCS12_CertBag(&cb);
        return 0;
     }
        free_PKCS12_CertBag(&cb);
        return 0;
     }
@@ -166,13 +165,13 @@ certBag_parser(hx509_context context,
 
     {
        const PKCS12_Attribute *attr;
 
     {
        const PKCS12_Attribute *attr;
-       const heim_oid * (*oids[])(void) = {
-           oid_id_pkcs_9_at_localKeyId, oid_id_pkcs_9_at_friendlyName
+       const heim_oid *oids[] = {
+           &asn1_oid_id_pkcs_9_at_localKeyId, &asn1_oid_id_pkcs_9_at_friendlyName
        };
        int i;
 
        };
        int i;
 
-       for (i = 0; i < sizeof(oids)/sizeof(oids[0]); i++) {
-           const heim_oid *oid = (*(oids[i]))();
+       for  (i = 0; i < sizeof(oids)/sizeof(oids[0]); i++) {
+           const heim_oid *oid = oids[i];
            attr = find_attribute(attrs, oid);
            if (attr)
                _hx509_set_cert_attribute(context, cert, oid,
            attr = find_attribute(attrs, oid);
            if (attr)
                _hx509_set_cert_attribute(context, cert, oid,
@@ -248,7 +247,7 @@ encryptedData_parser(hx509_context context,
     if (ret)
        return ret;
 
     if (ret)
        return ret;
 
-    if (der_heim_oid_cmp(&contentType, oid_id_pkcs7_data()) == 0)
+    if (der_heim_oid_cmp(&contentType, &asn1_oid_id_pkcs7_data) == 0)
        ret = parse_safe_content(context, c, content.data, content.length);
 
     der_free_octet_string(&content);
        ret = parse_safe_content(context, c, content.data, content.length);
 
     der_free_octet_string(&content);
@@ -285,7 +284,7 @@ envelopedData_parser(hx509_context context,
        return ret;
     }
 
        return ret;
     }
 
-    if (der_heim_oid_cmp(&contentType, oid_id_pkcs7_data()) == 0)
+    if (der_heim_oid_cmp(&contentType, &asn1_oid_id_pkcs7_data) == 0)
        ret = parse_safe_content(context, c, content.data, content.length);
 
     der_free_octet_string(&content);
        ret = parse_safe_content(context, c, content.data, content.length);
 
     der_free_octet_string(&content);
@@ -296,12 +295,12 @@ envelopedData_parser(hx509_context context,
 
 
 struct type bagtypes[] = {
 
 
 struct type bagtypes[] = {
-    { oid_id_pkcs12_keyBag, keyBag_parser },
-    { oid_id_pkcs12_pkcs8ShroudedKeyBag, ShroudedKeyBag_parser },
-    { oid_id_pkcs12_certBag, certBag_parser },
-    { oid_id_pkcs7_data, safeContent_parser },
-    { oid_id_pkcs7_encryptedData, encryptedData_parser },
-    { oid_id_pkcs7_envelopedData, envelopedData_parser }
+    { &asn1_oid_id_pkcs12_keyBag, keyBag_parser },
+    { &asn1_oid_id_pkcs12_pkcs8ShroudedKeyBag, ShroudedKeyBag_parser },
+    { &asn1_oid_id_pkcs12_certBag, certBag_parser },
+    { &asn1_oid_id_pkcs7_data, safeContent_parser },
+    { &asn1_oid_id_pkcs7_encryptedData, encryptedData_parser },
+    { &asn1_oid_id_pkcs7_envelopedData, envelopedData_parser }
 };
 
 static void
 };
 
 static void
@@ -314,7 +313,7 @@ parse_pkcs12_type(hx509_context context,
     int i;
 
     for (i = 0; i < sizeof(bagtypes)/sizeof(bagtypes[0]); i++)
     int i;
 
     for (i = 0; i < sizeof(bagtypes)/sizeof(bagtypes[0]); i++)
-       if (der_heim_oid_cmp((*bagtypes[i].oid)(), oid) == 0)
+       if (der_heim_oid_cmp(bagtypes[i].oid, oid) == 0)
            (*bagtypes[i].func)(context, c, data, length, attrs);
 }
 
            (*bagtypes[i].func)(context, c, data, length, attrs);
 }
 
@@ -376,7 +375,7 @@ p12_init(hx509_context context,
        goto out;
     }
 
        goto out;
     }
 
-    if (der_heim_oid_cmp(&pfx.authSafe.contentType, oid_id_pkcs7_data()) != 0) {
+    if (der_heim_oid_cmp(&pfx.authSafe.contentType, &asn1_oid_id_pkcs7_data) != 0) {
        free_PKCS12_PFX(&pfx);
        ret = EINVAL;
        hx509_set_error_string(context, 0, ret,
        free_PKCS12_PFX(&pfx);
        ret = EINVAL;
        hx509_set_error_string(context, 0, ret,
@@ -506,7 +505,7 @@ store_func(hx509_context context, void *ctx, hx509_cert c)
     free(os.data);
     if (ret)
        goto out;
     free(os.data);
     if (ret)
        goto out;
-    ret = der_copy_oid(oid_id_pkcs_9_at_certTypes_x509(), &cb.certType);
+    ret = der_copy_oid(&asn1_oid_id_pkcs_9_at_certTypes_x509, &cb.certType);
     if (ret) {
        free_PKCS12_CertBag(&cb);
        goto out;
     if (ret) {
        free_PKCS12_CertBag(&cb);
        goto out;
@@ -517,7 +516,7 @@ store_func(hx509_context context, void *ctx, hx509_cert c)
     if (ret)
        goto out;
 
     if (ret)
        goto out;
 
-    ret = addBag(context, as, oid_id_pkcs12_certBag(), os.data, os.length);
+    ret = addBag(context, as, &asn1_oid_id_pkcs12_certBag, os.data, os.length);
 
     if (_hx509_cert_private_key_exportable(c)) {
        hx509_private_key key = _hx509_cert_private_key(c);
 
     if (_hx509_cert_private_key_exportable(c)) {
        hx509_private_key key = _hx509_cert_private_key(c);
@@ -541,7 +540,7 @@ store_func(hx509_context context, void *ctx, hx509_cert c)
            free_PKCS8PrivateKeyInfo(&pki);
            return ret;
        }
            free_PKCS8PrivateKeyInfo(&pki);
            return ret;
        }
-       /* set attribute, oid_id_pkcs_9_at_localKeyId() */
+       /* set attribute, asn1_oid_id_pkcs_9_at_localKeyId */
 
        ASN1_MALLOC_ENCODE(PKCS8PrivateKeyInfo, os.data, os.length,
                           &pki, &size, ret);
 
        ASN1_MALLOC_ENCODE(PKCS8PrivateKeyInfo, os.data, os.length,
                           &pki, &size, ret);
@@ -549,7 +548,7 @@ store_func(hx509_context context, void *ctx, hx509_cert c)
        if (ret)
            return ret;
 
        if (ret)
            return ret;
 
-       ret = addBag(context, as, oid_id_pkcs12_keyBag(), os.data, os.length);
+       ret = addBag(context, as, &asn1_oid_id_pkcs12_keyBag, os.data, os.length);
        if (ret)
            return ret;
     }
        if (ret)
            return ret;
     }
@@ -598,7 +597,7 @@ p12_store(hx509_context context,
     if (ret)
        goto out;
 
     if (ret)
        goto out;
 
-    ret = der_copy_oid(oid_id_pkcs7_data(), &pfx.authSafe.contentType);
+    ret = der_copy_oid(&asn1_oid_id_pkcs7_data, &pfx.authSafe.contentType);
     if (ret)
        goto out;
 
     if (ret)
        goto out;
 
index e2ceedecb8ce993a9e7948585e28f25b7f5ea9b5..219a301928c6296a8f276063c53932d30c85e601 100644 (file)
@@ -32,7 +32,6 @@
  */
 
 #include "hx_locl.h"
  */
 
 #include "hx_locl.h"
-RCSID("$Id$");
 
 /**
  * @page page_lock Locking and unlocking certificates and encrypted data.
 
 /**
  * @page page_lock Locking and unlocking certificates and encrypted data.
index 069eed606266f95bd115092412a4383b92fcb014..b8f48d5236b7428fdf3e264480ef5fdb0aede709 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2004 - 2007 Kungliga Tekniska Högskolan
+ * Copyright (c) 2004 - 2009 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden).
  * All rights reserved.
  *
  * (Royal Institute of Technology, Stockholm, Sweden).
  * All rights reserved.
  *
@@ -33,7 +33,6 @@
 
 #include "hx_locl.h"
 #include <wind.h>
 
 #include "hx_locl.h"
 #include <wind.h>
-RCSID("$Id$");
 
 /**
  * @page page_name PKIX/X.509 Names
 
 /**
  * @page page_name PKIX/X.509 Names
@@ -63,20 +62,20 @@ RCSID("$Id$");
 
 static const struct {
     const char *n;
 
 static const struct {
     const char *n;
-    const heim_oid *(*o)(void);
+    const heim_oid *o;
     wind_profile_flags flags;
 } no[] = {
     wind_profile_flags flags;
 } no[] = {
-    { "C", oid_id_at_countryName },
-    { "CN", oid_id_at_commonName },
-    { "DC", oid_id_domainComponent },
-    { "L", oid_id_at_localityName },
-    { "O", oid_id_at_organizationName },
-    { "OU", oid_id_at_organizationalUnitName },
-    { "S", oid_id_at_stateOrProvinceName },
-    { "STREET", oid_id_at_streetAddress },
-    { "UID", oid_id_Userid },
-    { "emailAddress", oid_id_pkcs9_emailAddress },
-    { "serialNumber", oid_id_at_serialNumber }
+    { "C", &asn1_oid_id_at_countryName },
+    { "CN", &asn1_oid_id_at_commonName },
+    { "DC", &asn1_oid_id_domainComponent },
+    { "L", &asn1_oid_id_at_localityName },
+    { "O", &asn1_oid_id_at_organizationName },
+    { "OU", &asn1_oid_id_at_organizationalUnitName },
+    { "S", &asn1_oid_id_at_stateOrProvinceName },
+    { "STREET", &asn1_oid_id_at_streetAddress },
+    { "UID", &asn1_oid_id_Userid },
+    { "emailAddress", &asn1_oid_id_pkcs9_emailAddress },
+    { "serialNumber", &asn1_oid_id_at_serialNumber }
 };
 
 static char *
 };
 
 static char *
@@ -145,7 +144,7 @@ oidtostring(const heim_oid *type)
     size_t i;
 
     for (i = 0; i < sizeof(no)/sizeof(no[0]); i++) {
     size_t i;
 
     for (i = 0; i < sizeof(no)/sizeof(no[0]); i++) {
-       if (der_heim_oid_cmp((*no[i].o)(), type) == 0)
+       if (der_heim_oid_cmp(no[i].o, type) == 0)
            return strdup(no[i].n);
     }
     if (der_print_heim_oid(type, '.', &s) != 0)
            return strdup(no[i].n);
     }
     if (der_print_heim_oid(type, '.', &s) != 0)
@@ -163,7 +162,7 @@ stringtooid(const char *name, size_t len, heim_oid *oid)
 
     for (i = 0; i < sizeof(no)/sizeof(no[0]); i++) {
        if (strncasecmp(no[i].n, name, len) == 0)
 
     for (i = 0; i < sizeof(no)/sizeof(no[0]); i++) {
        if (strncasecmp(no[i].n, name, len) == 0)
-           return der_copy_oid((*no[i].o)(), oid);
+           return der_copy_oid(no[i].o, oid);
     }
     s = malloc(len + 1);
     if (s == NULL)
     }
     s = malloc(len + 1);
     if (s == NULL)
@@ -197,7 +196,7 @@ int
 _hx509_Name_to_string(const Name *n, char **str)
 {
     size_t total_len = 0;
 _hx509_Name_to_string(const Name *n, char **str)
 {
     size_t total_len = 0;
-    int i, j;
+    int i, j, ret;
 
     *str = strdup("");
     if (*str == NULL)
 
     *str = strdup("");
     if (*str == NULL)
@@ -224,15 +223,20 @@ _hx509_Name_to_string(const Name *n, char **str)
                ss = ds->u.utf8String;
                break;
            case choice_DirectoryString_bmpString: {
                ss = ds->u.utf8String;
                break;
            case choice_DirectoryString_bmpString: {
-               uint16_t *bmp = ds->u.bmpString.data;
+               const uint16_t *bmp = ds->u.bmpString.data;
                size_t bmplen = ds->u.bmpString.length;
                size_t k;
 
                size_t bmplen = ds->u.bmpString.length;
                size_t k;
 
-               ss = malloc(bmplen + 1);
+               ret = wind_ucs2utf8_length(bmp, bmplen, &k);
+               if (ret)
+                   return ret;
+               
+               ss = malloc(k + 1);
                if (ss == NULL)
                    _hx509_abort("allocation failure"); /* XXX */
                if (ss == NULL)
                    _hx509_abort("allocation failure"); /* XXX */
-               for (k = 0; k < bmplen; k++)
-                   ss[k] = bmp[k] & 0xff; /* XXX */
+               ret = wind_ucs2utf8(bmp, bmplen, ss, NULL);
+               if (ret)
+                   return ret;
                ss[k] = '\0';
                break;
            }
                ss[k] = '\0';
                break;
            }
@@ -244,15 +248,20 @@ _hx509_Name_to_string(const Name *n, char **str)
                ss[ds->u.teletexString.length] = '\0';
                break;
            case choice_DirectoryString_universalString: {
                ss[ds->u.teletexString.length] = '\0';
                break;
            case choice_DirectoryString_universalString: {
-               uint32_t *uni = ds->u.universalString.data;
+               const uint32_t *uni = ds->u.universalString.data;
                size_t unilen = ds->u.universalString.length;
                size_t k;
 
                size_t unilen = ds->u.universalString.length;
                size_t k;
 
-               ss = malloc(unilen + 1);
+               ret = wind_ucs4utf8_length(uni, unilen, &k);
+               if (ret)
+                   return ret;
+
+               ss = malloc(k + 1);
                if (ss == NULL)
                    _hx509_abort("allocation failure"); /* XXX */
                if (ss == NULL)
                    _hx509_abort("allocation failure"); /* XXX */
-               for (k = 0; k < unilen; k++)
-                   ss[k] = uni[k] & 0xff; /* XXX */
+               ret = wind_ucs4utf8(uni, unilen, ss, NULL);
+               if (ret)
+                   return ret;
                ss[k] = '\0';
                break;
            }
                ss[k] = '\0';
                break;
            }
@@ -344,8 +353,10 @@ dsstringprep(const DirectoryString *ds, uint32_t **rname, size_t *rlen)
        if (name == NULL)
            return ENOMEM;
        ret = wind_utf8ucs4(ds->u.utf8String, name, &len);
        if (name == NULL)
            return ENOMEM;
        ret = wind_utf8ucs4(ds->u.utf8String, name, &len);
-       if (ret)
+       if (ret) {
+           free(name);
            return ret;
            return ret;
+       }
        break;
     default:
        _hx509_abort("unknown directory type: %d", ds->element);
        break;
     default:
        _hx509_abort("unknown directory type: %d", ds->element);
index f5841e497b14b18ba018387f7238e7c5a8b3f160..c796e19173666721200929cf926b806e88b1eb64 100644 (file)
@@ -32,7 +32,6 @@
  */
 
 #include "hx_locl.h"
  */
 
 #include "hx_locl.h"
-RCSID("$Id$");
 
 /**
  * @page page_peer Hx509 crypto selecting functions
 
 /**
  * @page page_peer Hx509 crypto selecting functions
@@ -120,6 +119,39 @@ hx509_peer_info_set_cert(hx509_peer_info peer,
     return 0;
 }
 
     return 0;
 }
 
+/**
+ * Add an additional algorithm that the peer supports.
+ *
+ * @param context A hx509 context.
+ * @param peer the peer to set the new algorithms for
+ * @param val an AlgorithmsIdentier to add
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_peer
+ */
+
+int
+hx509_peer_info_add_cms_alg(hx509_context context,
+                           hx509_peer_info peer,
+                           const AlgorithmIdentifier *val)
+{
+    void *ptr;
+    int ret;
+
+    ptr = realloc(peer->val, sizeof(peer->val[0]) * (peer->len + 1));
+    if (ptr == NULL) {
+       hx509_set_error_string(context, 0, ENOMEM, "out of memory");
+       return ENOMEM;
+    }
+    ret = copy_AlgorithmIdentifier(val, &peer->val[peer->len]);
+    if (ret == 0)
+       peer->len += 1;
+    else
+       hx509_set_error_string(context, 0, ret, "out of memory");
+    return ret;
+}
+
 /**
  * Set the algorithms that the peer supports.
  *
 /**
  * Set the algorithms that the peer supports.
  *
index 38d103905ffd341a848d4ddc327972a1e114ef57..ddafb7f46e603d52c6f6d685ebe43d1315e4bfcc 100644 (file)
@@ -32,7 +32,6 @@
  */
 
 #include "hx_locl.h"
  */
 
 #include "hx_locl.h"
-RCSID("$Id$");
 
 /**
  * @page page_print Hx509 printing functions
 
 /**
  * @page page_print Hx509 printing functions
@@ -547,14 +546,14 @@ check_CRLDistributionPoints(hx509_validate_ctx ctx,
 
 struct {
     const char *name;
 
 struct {
     const char *name;
-    const heim_oid *(*oid)(void);
+    const heim_oid *oid;
     int (*func)(hx509_validate_ctx, heim_any *);
     int (*func)(hx509_validate_ctx, heim_any *);
-} check_altname[] = {
-    { "pk-init", oid_id_pkinit_san, check_pkinit_san },
-    { "jabber", oid_id_pkix_on_xmppAddr, check_utf8_string_san },
-    { "dns-srv", oid_id_pkix_on_dnsSRV, check_altnull },
-    { "card-id", oid_id_uspkicommon_card_id, check_altnull },
-    { "Microsoft NT-PRINCIPAL-NAME", oid_id_pkinit_ms_san, check_utf8_string_san }
+} altname_types[] = {
+    { "pk-init", &asn1_oid_id_pkinit_san, check_pkinit_san },
+    { "jabber", &asn1_oid_id_pkix_on_xmppAddr, check_utf8_string_san },
+    { "dns-srv", &asn1_oid_id_pkix_on_dnsSRV, check_altnull },
+    { "card-id", &asn1_oid_id_uspkicommon_card_id, check_altnull },
+    { "Microsoft NT-PRINCIPAL-NAME", &asn1_oid_id_pkinit_ms_san, check_utf8_string_san }
 };
 
 static int
 };
 
 static int
@@ -597,17 +596,17 @@ check_altName(hx509_validate_ctx ctx,
            validate_print(ctx, HX509_VALIDATE_F_VERBOSE,
                           "%sAltName otherName ", name);
 
            validate_print(ctx, HX509_VALIDATE_F_VERBOSE,
                           "%sAltName otherName ", name);
 
-           for (j = 0; j < sizeof(check_altname)/sizeof(check_altname[0]); j++) {
-               if (der_heim_oid_cmp((*check_altname[j].oid)(),
+           for (j = 0; j < sizeof(altname_types)/sizeof(altname_types[0]); j++) {
+               if (der_heim_oid_cmp(altname_types[j].oid,
                                     &gn.val[i].u.otherName.type_id) != 0)
                    continue;
                
                validate_print(ctx, HX509_VALIDATE_F_VERBOSE, "%s: ",
                                     &gn.val[i].u.otherName.type_id) != 0)
                    continue;
                
                validate_print(ctx, HX509_VALIDATE_F_VERBOSE, "%s: ",
-                              check_altname[j].name);
-               (*check_altname[j].func)(ctx, &gn.val[i].u.otherName.value);
+                              altname_types[j].name);
+               (*altname_types[j].func)(ctx, &gn.val[i].u.otherName.value);
                break;
            }
                break;
            }
-           if (j == sizeof(check_altname)/sizeof(check_altname[0])) {
+           if (j == sizeof(altname_types)/sizeof(altname_types[0])) {
                hx509_oid_print(&gn.val[i].u.otherName.type_id,
                                validate_vprint, ctx);
                validate_print(ctx, HX509_VALIDATE_F_VERBOSE, " unknown");
                hx509_oid_print(&gn.val[i].u.otherName.type_id,
                                validate_vprint, ctx);
                validate_print(ctx, HX509_VALIDATE_F_VERBOSE, " unknown");
@@ -751,14 +750,14 @@ check_authorityInfoAccess(hx509_validate_ctx ctx,
 
 struct {
     const char *name;
 
 struct {
     const char *name;
-    const heim_oid *(*oid)(void);
+    const heim_oid *oid;
     int (*func)(hx509_validate_ctx ctx,
                struct cert_status *status,
                enum critical_flag cf,
                const Extension *);
     enum critical_flag cf;
 } check_extension[] = {
     int (*func)(hx509_validate_ctx ctx,
                struct cert_status *status,
                enum critical_flag cf,
                const Extension *);
     enum critical_flag cf;
 } check_extension[] = {
-#define ext(name, checkname) #name, &oid_id_x509_ce_##name, check_##checkname
+#define ext(name, checkname) #name, &asn1_oid_id_x509_ce_##name, check_##checkname
     { ext(subjectDirectoryAttributes, Null), M_N_C },
     { ext(subjectKeyIdentifier, subjectKeyIdentifier), M_N_C },
     { ext(keyUsage, Null), S_C },
     { ext(subjectDirectoryAttributes, Null), M_N_C },
     { ext(subjectKeyIdentifier, subjectKeyIdentifier), M_N_C },
     { ext(keyUsage, Null), S_C },
@@ -782,13 +781,13 @@ struct {
     { ext(freshestCRL, Null), M_N_C },
     { ext(inhibitAnyPolicy, Null), M_C },
 #undef ext
     { ext(freshestCRL, Null), M_N_C },
     { ext(inhibitAnyPolicy, Null), M_C },
 #undef ext
-#define ext(name, checkname) #name, &oid_id_pkix_pe_##name, check_##checkname
+#define ext(name, checkname) #name, &asn1_oid_id_pkix_pe_##name, check_##checkname
     { ext(proxyCertInfo, proxyCertInfo), M_C },
     { ext(authorityInfoAccess, authorityInfoAccess), M_C },
 #undef ext
     { ext(proxyCertInfo, proxyCertInfo), M_C },
     { ext(authorityInfoAccess, authorityInfoAccess), M_C },
 #undef ext
-    { "US Fed PKI - PIV Interim", oid_id_uspkicommon_piv_interim,
+    { "US Fed PKI - PIV Interim", &asn1_oid_id_uspkicommon_piv_interim,
       check_Null, D_C },
       check_Null, D_C },
-    { "Netscape cert comment", oid_id_netscape_cert_comment,
+    { "Netscape cert comment", &asn1_oid_id_netscape_cert_comment,
       check_Null, D_C },
     { NULL }
 };
       check_Null, D_C },
     { NULL }
 };
@@ -949,7 +948,7 @@ hx509_validate_cert(hx509_context context,
        for (i = 0; i < t->extensions->len; i++) {
 
            for (j = 0; check_extension[j].name; j++)
        for (i = 0; i < t->extensions->len; i++) {
 
            for (j = 0; check_extension[j].name; j++)
-               if (der_heim_oid_cmp((*check_extension[j].oid)(),
+               if (der_heim_oid_cmp(check_extension[j].oid,
                                     &t->extensions->val[i].extnID) == 0)
                    break;
            if (check_extension[j].name == NULL) {
                                     &t->extensions->val[i].extnID) == 0)
                    break;
            if (check_extension[j].name == NULL) {
index 983677714350721eede0bf91ade08b0ab37ceaf0..0d174e0cece8aad1cfa2bf75215759128b47ae67 100644 (file)
@@ -33,7 +33,6 @@
 
 #include "hx_locl.h"
 #include <pkcs10_asn1.h>
 
 #include "hx_locl.h"
 #include <pkcs10_asn1.h>
-RCSID("$Id$");
 
 struct hx509_request_data {
     hx509_name name;
 
 struct hx509_request_data {
     hx509_name name;
index 3f35b0d190083f9ab4b8310ec54943c3dd448de7..adb31164c1c1e89b01e81a2a5c3b01991e4fd2e8 100644 (file)
@@ -50,7 +50,6 @@
  */
 
 #include "hx_locl.h"
  */
 
 #include "hx_locl.h"
-RCSID("$Id$");
 
 struct revoke_crl {
     char *path;
 
 struct revoke_crl {
     char *path;
@@ -235,7 +234,7 @@ verify_ocsp(hx509_context context,
        }
 
        ret = hx509_cert_check_eku(context, signer,
        }
 
        ret = hx509_cert_check_eku(context, signer,
-                                  oid_id_pkix_kp_OCSPSigning(), 0);
+                                  &asn1_oid_id_pkix_kp_OCSPSigning, 0);
        if (ret)
            goto out;
     }
        if (ret)
            goto out;
     }
@@ -295,7 +294,7 @@ parse_ocsp_basic(const void *data, size_t length, OCSPBasicOCSPResponse *basic)
     }
 
     ret = der_heim_oid_cmp(&resp.responseBytes->responseType,
     }
 
     ret = der_heim_oid_cmp(&resp.responseBytes->responseType,
-                          oid_id_pkix_ocsp_basic());
+                          &asn1_oid_id_pkix_ocsp_basic);
     if (ret != 0) {
        free_OCSPResponse(&resp);
        return HX509_REVOKE_WRONG_DATA;
     if (ret != 0) {
        free_OCSPResponse(&resp);
        return HX509_REVOKE_WRONG_DATA;
@@ -1011,8 +1010,7 @@ hx509_ocsp_request(hx509_context context,
            goto out;
        }
        es->len = 1;
            goto out;
        }
        es->len = 1;
-       
-       ret = der_copy_oid(oid_id_pkix_ocsp_nonce(), &es->val[0].extnID);
+       ret = der_copy_oid(&asn1_oid_id_pkix_ocsp_nonce, &es->val[0].extnID);
        if (ret) {
            free_OCSPRequest(&req);
            return ret;
        if (ret) {
            free_OCSPRequest(&req);
            return ret;
index e52947972426d4514b925d4ba85f85aa64620c1a..7f7c9980e03bc6f062eb05b71ec7f316fbba5a40 100644 (file)
@@ -39,7 +39,6 @@
 #include <stdlib.h>
 #include <hx_locl.h>
 
 #include <stdlib.h>
 #include <hx_locl.h>
 
-RCSID("$Id$");
 
 %}
 
 
 %}
 
index da83e527864a3bc15c99462f306409030deb9020..2cdcdf85f63f3d761a390f913a41b602d6d12568 100644 (file)
@@ -32,7 +32,6 @@
  */
 
 #include "hx_locl.h"
  */
 
 #include "hx_locl.h"
-RCSID("$Id$");
 
 static int
 test_name(hx509_context context, const char *name)
 
 static int
 test_name(hx509_context context, const char *name)
index bd0a9846e4c8173c98a2f9e5ea370afade98fc7f..0ecda99348bb35936fb715b816f9872632499601 100644 (file)
 #include <dlfcn.h>
 #endif
 
 #include <dlfcn.h>
 #endif
 
-RCSID("$Id$");
-
-/* XXX should we fetch these for each open ? */
 static HEIMDAL_MUTEX acc_mutex = HEIMDAL_MUTEX_INITIALIZER;
 static cc_initialize_func init_func;
 static HEIMDAL_MUTEX acc_mutex = HEIMDAL_MUTEX_INITIALIZER;
 static cc_initialize_func init_func;
-
 #ifdef HAVE_DLOPEN
 static void *cc_handle;
 #endif
 #ifdef HAVE_DLOPEN
 static void *cc_handle;
 #endif
@@ -135,7 +131,7 @@ init_ccapi(krb5_context context)
 #else
     HEIMDAL_MUTEX_unlock(&acc_mutex);
     krb5_set_error_message(context, KRB5_CC_NOSUPP,
 #else
     HEIMDAL_MUTEX_unlock(&acc_mutex);
     krb5_set_error_message(context, KRB5_CC_NOSUPP,
-                          N_("no support for shared object", "file, error"));
+                          N_("no support for shared object", ""));
     return KRB5_CC_NOSUPP;
 #endif
 }
     return KRB5_CC_NOSUPP;
 #endif
 }
@@ -342,6 +338,7 @@ make_ccred_from_cred(krb5_context context,
        addr->length = incred->addresses.val[i].address.length;
        addr->data = malloc(addr->length);
        if (addr->data == NULL) {
        addr->length = incred->addresses.val[i].address.length;
        addr->data = malloc(addr->length);
        if (addr->data == NULL) {
+           free(addr);
            ret = ENOMEM;
            goto fail;
        }
            ret = ENOMEM;
            goto fail;
        }
@@ -490,16 +487,23 @@ acc_resolve(krb5_context context, krb5_ccache *id, const char *res)
 
     error = (*a->context->func->open_ccache)(a->context, res, &a->ccache);
     if (error == ccNoError) {
 
     error = (*a->context->func->open_ccache)(a->context, res, &a->ccache);
     if (error == ccNoError) {
+       cc_time_t offset;
        error = get_cc_name(a);
        if (error != ccNoError) {
            acc_close(context, *id);
            *id = NULL;
            return translate_cc_error(context, error);
        }
        error = get_cc_name(a);
        if (error != ccNoError) {
            acc_close(context, *id);
            *id = NULL;
            return translate_cc_error(context, error);
        }
+
+       error = (*a->ccache->func->get_kdc_time_offset)(a->ccache,
+                                                       cc_credentials_v5,
+                                                       &offset);
+       if (error == 0) 
+           context->kdc_sec_offset = offset;
+
     } else if (error == ccErrCCacheNotFound) {
        a->ccache = NULL;
        a->cache_name = NULL;
     } else if (error == ccErrCCacheNotFound) {
        a->ccache = NULL;
        a->cache_name = NULL;
-       error = 0;
     } else {
        *id = NULL;
        return translate_cc_error(context, error);
     } else {
        *id = NULL;
        return translate_cc_error(context, error);
@@ -572,6 +576,11 @@ acc_initialize(krb5_context context,
                                                  name);
     }
 
                                                  name);
     }
 
+    if (error == 0 && context->kdc_sec_offset)
+       error = (*a->ccache->func->set_kdc_time_offset)(a->ccache,
+                                                       cc_credentials_v5,
+                                                       context->kdc_sec_offset);
+
     return translate_cc_error(context, error);
 }
 
     return translate_cc_error(context, error);
 }
 
@@ -946,8 +955,10 @@ acc_move(krb5_context context, krb5_ccache from, krb5_ccache to)
            return translate_cc_error(context, error);
     }
 
            return translate_cc_error(context, error);
     }
 
-
     error = (*ato->ccache->func->move)(afrom->ccache, ato->ccache);
     error = (*ato->ccache->func->move)(afrom->ccache, ato->ccache);
+
+    acc_destroy(context, from);
+
     return translate_cc_error(context, error);
 }
 
     return translate_cc_error(context, error);
 }
 
index f08c0fe71845a9370e5f8db1a79b0a88c3e9ce8a..ccffd93b2c9998a409afa771bd3a8ebcdcd22bc1 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "krb5_locl.h"
 
 
 #include "krb5_locl.h"
 
-RCSID("$Id$");
-
 /**
  * Add a specified list of error messages to the et list in context.
  * Call func (probably a comerr-generated function) with a pointer to
 /**
  * Add a specified list of error messages to the et list in context.
  * Call func (probably a comerr-generated function) with a pointer to
index 9e2fb3d63a154b4426c81f4f366417245ba47ee4..f88fb2276adca0f564d0f3503c6dcd18de5b9d18 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "krb5_locl.h"
 
 
 #include "krb5_locl.h"
 
-RCSID("$Id$");
-
 struct addr_operations {
     int af;
     krb5_address_type atype;
 struct addr_operations {
     int af;
     krb5_address_type atype;
@@ -678,6 +676,9 @@ addrport_print_addr (const krb5_address *addr, char *str, size_t len)
     krb5_storage *sp;
 
     sp = krb5_storage_from_data((krb5_data*)rk_UNCONST(&addr->address));
     krb5_storage *sp;
 
     sp = krb5_storage_from_data((krb5_data*)rk_UNCONST(&addr->address));
+    if (sp == NULL)
+        return ENOMEM;
+
     /* for totally obscure reasons, these are not in network byteorder */
     krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_LE);
 
     /* for totally obscure reasons, these are not in network byteorder */
     krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_LE);
 
@@ -1142,10 +1143,12 @@ krb5_parse_address(krb5_context context,
     for (a = ai, i = 0; a != NULL; a = a->ai_next) {
        if (krb5_sockaddr2address (context, ai->ai_addr, &addresses->val[i]))
            continue;
     for (a = ai, i = 0; a != NULL; a = a->ai_next) {
        if (krb5_sockaddr2address (context, ai->ai_addr, &addresses->val[i]))
            continue;
-       if(krb5_address_search(context, &addresses->val[i], addresses))
+       if(krb5_address_search(context, &addresses->val[i], addresses)) {
+           krb5_free_address(context, &addresses->val[i]);
            continue;
            continue;
-       addresses->len = i;
+       }
        i++;
        i++;
+       addresses->len = i;
     }
     freeaddrinfo (ai);
     return 0;
     }
     freeaddrinfo (ai);
     return 0;
@@ -1454,7 +1457,6 @@ krb5_make_addrport (krb5_context context,
     *p++ = (2 >> 24) & 0xFF;
 
     memcpy (p, &port, 2);
     *p++ = (2 >> 24) & 0xFF;
 
     memcpy (p, &port, 2);
-    p += 2;
 
     return 0;
 }
 
     return 0;
 }
index d49fc4997a757af0447c219877547ed74768c2dc..383e82dad4c3f31e85c6f0311350766d9b49bac4 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "krb5_locl.h"
 
 
 #include "krb5_locl.h"
 
-RCSID("$Id$");
-
 void KRB5_LIB_FUNCTION
 krb5_appdefault_boolean(krb5_context context, const char *appname,
                        krb5_const_realm realm, const char *option,
 void KRB5_LIB_FUNCTION
 krb5_appdefault_boolean(krb5_context context, const char *appname,
                        krb5_const_realm realm, const char *option,
index cb86c324fb34a8564653178b39e6e15c5f3a074b..59c0fbd64b66c0a36366276f1068db3af63a2bf1 100644 (file)
@@ -37,8 +37,6 @@
 
 #include "krb5_locl.h"
 
 
 #include "krb5_locl.h"
 
-RCSID("$Id$");
-
 krb5_error_code KRB5_LIB_FUNCTION
 _krb5_principal2principalname (PrincipalName *p,
                               const krb5_principal from)
 krb5_error_code KRB5_LIB_FUNCTION
 _krb5_principal2principalname (PrincipalName *p,
                               const krb5_principal from)
@@ -52,13 +50,23 @@ _krb5_principalname2krb5_principal (krb5_context context,
                                    const PrincipalName from,
                                    const Realm realm)
 {
                                    const PrincipalName from,
                                    const Realm realm)
 {
-    krb5_principal p = malloc(sizeof(*p));
+    krb5_error_code ret;
+    krb5_principal p;
+
+    p = malloc(sizeof(*p));
     if (p == NULL)
        return ENOMEM;
     if (p == NULL)
        return ENOMEM;
-    copy_PrincipalName(&from, &p->name);
+    ret = copy_PrincipalName(&from, &p->name);
+    if (ret) {
+       free(p);
+       return ret;
+    }
     p->realm = strdup(realm);
     p->realm = strdup(realm);
-    if (p->realm == NULL)
+    if (p->realm == NULL) {
+       free_PrincipalName(&p->name);
+        free(p);
        return ENOMEM;
        return ENOMEM;
+    }
     *principal = p;
     return 0;
 }
     *principal = p;
     return 0;
 }
index 66eccbbc0765ded9cbff7c28615ec2747c4d7466..bfc183d168a7dddde2f2c1182a006be7f3464cd0 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "krb5_locl.h"
 
 
 #include "krb5_locl.h"
 
-RCSID("$Id$");
-
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_auth_con_init(krb5_context context,
                   krb5_auth_context *auth_context)
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_auth_con_init(krb5_context context,
                   krb5_auth_context *auth_context)
index 92c03cb782499f090a9d739318a76fefb368eed7..1550239faf2a10e56504665bac4bd945a80f5803 100644 (file)
@@ -33,8 +33,6 @@
 
 #include <krb5_locl.h>
 
 
 #include <krb5_locl.h>
 
-RCSID("$Id$");
-
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_build_ap_req (krb5_context context,
                   krb5_enctype enctype,
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_build_ap_req (krb5_context context,
                   krb5_enctype enctype,
index bbf4f274af1d0c9b4a147271416c1034eff1fa4b..bf77fd4e77ea01e5ab0d5d1274d66f878df8e3bd 100644 (file)
@@ -33,8 +33,6 @@
 
 #include <krb5_locl.h>
 
 
 #include <krb5_locl.h>
 
-RCSID("$Id$");
-
 static krb5_error_code
 make_etypelist(krb5_context context,
               krb5_authdata **auth_data)
 static krb5_error_code
 make_etypelist(krb5_context context,
               krb5_authdata **auth_data)
@@ -81,12 +79,14 @@ make_etypelist(krb5_context context,
 
     ALLOC(*auth_data, 1);
     if (*auth_data == NULL) {
 
     ALLOC(*auth_data, 1);
     if (*auth_data == NULL) {
+        free(buf);
        krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
        return ENOMEM;
     }
 
     ALLOC_SEQ(*auth_data, 1);
     if ((*auth_data)->val == NULL) {
        krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
        return ENOMEM;
     }
 
     ALLOC_SEQ(*auth_data, 1);
     if ((*auth_data)->val == NULL) {
+        free(*auth_data);
        free(buf);
        krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
        return ENOMEM;
        free(buf);
        krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
        return ENOMEM;
index 80b755cd2774eb56a1336bf0ba06b73179c5fd44..12097470d52eae3cd31d8d4ddfa7469131b171db 100644 (file)
 
 #include "krb5_locl.h"
 
 
 #include "krb5_locl.h"
 
-RCSID("$Id$");
+/**
+ * @page krb5_ccache_intro The credential cache functions
+ * @section section_krb5_ccache Kerberos credential caches
+ * 
+ * krb5_ccache structure holds a Kerberos credential cache.
+ *
+ * Heimdal support the follow types of credential caches:
+ *
+ * - SCC
+ *   Store the credential in a database
+ * - FILE
+ *   Store the credential in memory
+ * - MEMORY
+ *   Store the credential in memory
+ * - API
+ *   A credential cache server based solution for Mac OS X
+ * - KCM
+ *   A credential cache server based solution for all platforms
+ *
+ * @subsection Example
+ *
+ * This is a minimalistic version of klist:
+@code
+#include <krb5.h>
+
+int
+main (int argc, char **argv)
+{
+    krb5_context context;
+    krb5_cc_cursor cursor;
+    krb5_error_code ret;
+    krb5_ccache id;
+    krb5_creds creds;
+
+    if (krb5_init_context (&context) != 0)
+       errx(1, "krb5_context");
+
+    ret = krb5_cc_default (context, &id);
+    if (ret)
+       krb5_err(context, 1, ret, "krb5_cc_default");
+
+    ret = krb5_cc_start_seq_get(context, id, &cursor);
+    if (ret)
+       krb5_err(context, 1, ret, "krb5_cc_start_seq_get");
+
+    while((ret = krb5_cc_next_cred(context, id, &cursor, &creds)) == 0){
+        char *principal;
+
+       krb5_unparse_name_short(context, creds.server, &principal);
+       printf("principal: %s\\n", principal);
+       free(principal);
+       krb5_free_cred_contents (context, &creds);
+    }
+    ret = krb5_cc_end_seq_get(context, id, &cursor);
+    if (ret)
+       krb5_err(context, 1, ret, "krb5_cc_end_seq_get");
+
+    krb5_cc_close(context, id);
+
+    krb5_free_context(context);
+    return 0;
+}
+* @endcode
+*/
 
 /**
  * Add a new ccache type with operations `ops', overwriting any
 
 /**
  * Add a new ccache type with operations `ops', overwriting any
@@ -175,23 +238,6 @@ krb5_cc_resolve(krb5_context context,
     }
 }
 
     }
 }
 
-/**
- * Generate a new ccache of type `ops' in `id'.
- *
- * @return Return an error code or 0, see krb5_get_error_message().
- *
- * @ingroup krb5_ccache
- */
-
-
-krb5_error_code KRB5_LIB_FUNCTION
-krb5_cc_gen_new(krb5_context context,
-               const krb5_cc_ops *ops,
-               krb5_ccache *id)
-{
-    return krb5_cc_new_unique(context, ops->prefix, NULL, id);
-}
-
 /**
  * Generates a new unique ccache of `type` in `id'. If `type' is NULL,
  * the library chooses the default credential cache type. The supplied
 /**
  * Generates a new unique ccache of `type` in `id'. If `type' is NULL,
  * the library chooses the default credential cache type. The supplied
@@ -221,7 +267,12 @@ krb5_cc_new_unique(krb5_context context, const char *type,
     ret = _krb5_cc_allocate(context, ops, id);
     if (ret)
        return ret;
     ret = _krb5_cc_allocate(context, ops, id);
     if (ret)
        return ret;
-    return (*id)->ops->gen_new(context, id);
+    ret = (*id)->ops->gen_new(context, id);
+    if (ret) {
+       free(*id);
+       *id = NULL;
+    }
+    return ret;
 }
 
 /**
 }
 
 /**
@@ -676,7 +727,7 @@ krb5_cc_get_principal(krb5_context context,
 
 /**
  * Start iterating over `id', `cursor' is initialized to the
 
 /**
  * Start iterating over `id', `cursor' is initialized to the
- * beginning.
+ * beginning.  Caller must free the cursor with krb5_cc_end_seq_get().
  *
  * @return Return an error code or 0, see krb5_get_error_message().
  *
  *
  * @return Return an error code or 0, see krb5_get_error_message().
  *
@@ -711,32 +762,6 @@ krb5_cc_next_cred (krb5_context context,
     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
- *
- * @ingroup krb5_ccache
- */
-
-
-krb5_error_code KRB5_LIB_FUNCTION
-krb5_cc_next_cred_match(krb5_context context,
-                       const krb5_ccache id,
-                       krb5_cc_cursor * cursor,
-                       krb5_creds * creds,
-                       krb5_flags whichfields,
-                       const krb5_creds * mcreds)
-{
-    krb5_error_code ret;
-    while (1) {
-       ret = krb5_cc_next_cred(context, id, cursor, creds);
-       if (ret)
-           return ret;
-       if (mcreds == NULL || krb5_compare_creds(context, whichfields, mcreds, creds))
-           return 0;
-       krb5_free_cred_contents(context, creds);
-    }
-}
-
 /**
  * Destroy the cursor `cursor'.
  *
 /**
  * Destroy the cursor `cursor'.
  *
@@ -806,25 +831,37 @@ krb5_cc_get_flags(krb5_context context,
 }
 
 /**
 }
 
 /**
- * Copy the contents of `from' to `to'.
+ * Copy the contents of `from' to `to' if the given match function
+ * return true.
+ *
+ * @param context A Kerberos 5 context.
+ * @param from the cache to copy data from.
+ * @param to the cache to copy data to.
+ * @param match a match function that should return TRUE if cred argument should be copied, if NULL, all credentials are copied.
+ * @param matchctx context passed to match function.
+ * @param matched set to true if there was a credential that matched, may be NULL.
+ *
+ * @return Return an error code or 0, see krb5_get_error_message().
  *
  * @ingroup krb5_ccache
  */
 
  *
  * @ingroup krb5_ccache
  */
 
-
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_error_code KRB5_LIB_FUNCTION
-krb5_cc_copy_cache_match(krb5_context context,
-                        const krb5_ccache from,
-                        krb5_ccache to,
-                        krb5_flags whichfields,
-                        const krb5_creds * mcreds,
-                        unsigned int *matched)
+krb5_cc_copy_match_f(krb5_context context,
+                    const krb5_ccache from,
+                    krb5_ccache to,
+                    krb5_boolean (*match)(krb5_context, void *, const krb5_creds *),
+                    void *matchctx,
+                    unsigned int *matched)
 {
     krb5_error_code ret;
     krb5_cc_cursor cursor;
     krb5_creds cred;
     krb5_principal princ;
 
 {
     krb5_error_code ret;
     krb5_cc_cursor cursor;
     krb5_creds cred;
     krb5_principal princ;
 
+    if (matched)
+       *matched = 0;
+
     ret = krb5_cc_get_principal(context, from, &princ);
     if (ret)
        return ret;
     ret = krb5_cc_get_principal(context, from, &princ);
     if (ret)
        return ret;
@@ -838,24 +875,26 @@ krb5_cc_copy_cache_match(krb5_context context,
        krb5_free_principal(context, princ);
        return ret;
     }
        krb5_free_principal(context, princ);
        return ret;
     }
-    if (matched)
-       *matched = 0;
-    while (ret == 0 &&
-          krb5_cc_next_cred_match(context, from, &cursor, &cred,
-                                  whichfields, mcreds) == 0) {
-       if (matched)
-           (*matched)++;
-       ret = krb5_cc_store_cred(context, to, &cred);
-       krb5_free_cred_contents(context, &cred);
+
+    while ((ret = krb5_cc_next_cred(context, from, &cursor, &cred)) == 0) {
+          if (match == NULL || (*match)(context, matchctx, &cred) == 0) {
+              if (matched)
+                  (*matched)++;
+              ret = krb5_cc_store_cred(context, to, &cred);
+              if (ret)
+                  break;
+          }
+          krb5_free_cred_contents(context, &cred);
     }
     krb5_cc_end_seq_get(context, from, &cursor);
     krb5_free_principal(context, princ);
     }
     krb5_cc_end_seq_get(context, from, &cursor);
     krb5_free_principal(context, princ);
+    if (ret == KRB5_CC_END)
+       ret = 0;
     return ret;
 }
 
     return ret;
 }
 
-
 /**
 /**
- * Just like krb5_cc_copy_cache_match, but copy everything.
+ * Just like krb5_cc_copy_match_f(), but copy everything.
  *
  * @ingroup @krb5_ccache
  */
  *
  * @ingroup @krb5_ccache
  */
@@ -865,21 +904,7 @@ krb5_cc_copy_cache(krb5_context context,
                   const krb5_ccache from,
                   krb5_ccache to)
 {
                   const krb5_ccache from,
                   krb5_ccache to)
 {
-    return krb5_cc_copy_cache_match(context, from, to, 0, NULL, NULL);
-}
-
-/**
- * MIT compat glue
- *
- * @ingroup krb5_ccache
- */
-
-krb5_error_code KRB5_LIB_FUNCTION
-krb5_cc_copy_creds(krb5_context context,
-                  const krb5_ccache from,
-                  krb5_ccache to)
-{
-    return krb5_cc_copy_cache(context, from, to);
+    return krb5_cc_copy_match_f(context, from, to, NULL, NULL, NULL);
 }
 
 /**
 }
 
 /**
@@ -1057,10 +1082,14 @@ krb5_cc_cache_end_seq_get (krb5_context context,
 }
 
 /**
 }
 
 /**
- * Search for a matching credential cache of type `type' that have the
+ * Search for a matching credential cache that have the
  * `principal' as the default principal. On success, `id' needs to be
  * freed with krb5_cc_close() or krb5_cc_destroy().
  *
  * `principal' as the default principal. On success, `id' needs to be
  * freed with krb5_cc_close() or krb5_cc_destroy().
  *
+ * @param context A Kerberos 5 context
+ * @param client The principal to search for
+ * @param id the returned credential cache
+ *
  * @return On failure, error code is returned and `id' is set to NULL.
  *
  * @ingroup krb5_ccache
  * @return On failure, error code is returned and `id' is set to NULL.
  *
  * @ingroup krb5_ccache
@@ -1082,7 +1111,7 @@ krb5_cc_cache_match (krb5_context context,
     if (ret)
        return ret;
 
     if (ret)
        return ret;
 
-    while ((ret = krb5_cccol_cursor_next (context, cursor, &cache)) == 0) {
+    while (krb5_cccol_cursor_next (context, cursor, &cache) == 0 && cache != NULL) {
        krb5_principal principal;
 
        ret = krb5_cc_get_principal(context, cache, &principal);
        krb5_principal principal;
 
        ret = krb5_cc_get_principal(context, cache, &principal);
@@ -1107,7 +1136,7 @@ krb5_cc_cache_match (krb5_context context,
        krb5_unparse_name(context, client, &str);
 
        krb5_set_error_message(context, KRB5_CC_NOTFOUND,
        krb5_unparse_name(context, client, &str);
 
        krb5_set_error_message(context, KRB5_CC_NOTFOUND,
-                              N_("Principal %s not found in a "
+                              N_("Principal %s not found in any "
                                  "credential cache", ""),
                               str ? str : "<out of memory>");
        if (str)
                                  "credential cache", ""),
                               str ? str : "<out of memory>");
        if (str)
@@ -1178,7 +1207,7 @@ build_conf_principals(krb5_context context, krb5_ccache id,
     }
 
     ret = krb5_make_principal(context, &cred->server,
     }
 
     ret = krb5_make_principal(context, &cred->server,
-                             krb5_principal_get_realm(context, client),
+                             KRB5_REALM_NAME,
                              KRB5_CONF_NAME, name, pname, NULL);
     free(pname);
     if (ret) {
                              KRB5_CONF_NAME, name, pname, NULL);
     free(pname);
     if (ret) {
@@ -1224,7 +1253,7 @@ krb5_is_config_principal(krb5_context context,
  * @param principal configuration for a specific principal, if
  * NULL, global for the whole cache.
  * @param name name under which the configuraion is stored.
  * @param principal configuration for a specific principal, if
  * NULL, global for the whole cache.
  * @param name name under which the configuraion is stored.
- * @param data data to store
+ * @param data data to store, if NULL, configure is removed.
  *
  * @ingroup krb5_ccache
  */
  *
  * @ingroup krb5_ccache
  */
@@ -1246,15 +1275,17 @@ krb5_cc_set_config(krb5_context context, krb5_ccache id,
     if (ret && ret != KRB5_CC_NOTFOUND)
         goto out;
 
     if (ret && ret != KRB5_CC_NOTFOUND)
         goto out;
 
-    /* not that anyone care when this expire */
-    cred.times.authtime = time(NULL);
-    cred.times.endtime = cred.times.authtime + 3600 * 24 * 30;
-
-    ret = krb5_data_copy(&cred.ticket, data->data, data->length);
-    if (ret)
-       goto out;
-
-    ret = krb5_cc_store_cred(context, id, &cred);
+    if (data) {
+       /* not that anyone care when this expire */
+       cred.times.authtime = time(NULL);
+       cred.times.endtime = cred.times.authtime + 3600 * 24 * 30;
+       
+       ret = krb5_data_copy(&cred.ticket, data->data, data->length);
+       if (ret)
+           goto out;
+       
+       ret = krb5_cc_store_cred(context, id, &cred);
+    }
 
 out:
     krb5_free_cred_contents (context, &cred);
 
 out:
     krb5_free_cred_contents (context, &cred);
@@ -1345,6 +1376,8 @@ krb5_cccol_cursor_new(krb5_context context, krb5_cccol_cursor *cursor)
  * @param cache the returned cursor, pointer is set to NULL on failure
  *        and a cache on success. The returned cache needs to be freed
  *        with krb5_cc_close() or destroyed with krb5_cc_destroy().
  * @param cache the returned cursor, pointer is set to NULL on failure
  *        and a cache on success. The returned cache needs to be freed
  *        with krb5_cc_close() or destroyed with krb5_cc_destroy().
+ *        MIT Kerberos behavies slightly diffrent and sets cache to NULL
+ *        when all caches are iterated over and return 0.
  *
  * @return Return 0 or and error, KRB5_CC_END is returned at the end
  *        of iteration. See krb5_get_error_message().
  *
  * @return Return 0 or and error, KRB5_CC_END is returned at the end
  *        of iteration. See krb5_get_error_message().
@@ -1446,7 +1479,7 @@ krb5_cc_last_change_time(krb5_context context,
  * and mtime is 0, there was no credentials in the caches.
  *
  * @param context A Kerberos 5 context
  * and mtime is 0, there was no credentials in the caches.
  *
  * @param context A Kerberos 5 context
- * @param id The credential cache to probe
+ * @param type The credential cache to probe, if NULL, all type are traversed.
  * @param mtime the last modification time, set to 0 on error.
 
  * @return Return 0 or and error. See krb5_get_error_message().
  * @param mtime the last modification time, set to 0 on error.
 
  * @return Return 0 or and error. See krb5_get_error_message().
@@ -1470,7 +1503,7 @@ krb5_cccol_last_change_time(krb5_context context,
     if (ret)
        return ret;
 
     if (ret)
        return ret;
 
-    while ((ret = krb5_cccol_cursor_next (context, cursor, &id)) == 0) {
+    while (krb5_cccol_cursor_next(context, cursor, &id) == 0 && id != NULL) {
 
        if (type && strcmp(krb5_cc_get_type(context, id), type) != 0)
            continue;
 
        if (type && strcmp(krb5_cc_get_type(context, id), type) != 0)
            continue;
@@ -1487,3 +1520,106 @@ krb5_cccol_last_change_time(krb5_context context,
 
     return 0;
 }
 
     return 0;
 }
+/**
+ * Return a friendly name on credential cache. Free the result with krb5_xfree().
+ *
+ * @return Return an error code or 0, see krb5_get_error_message().
+ *
+ * @ingroup krb5_ccache
+ */
+
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_cc_get_friendly_name(krb5_context context,
+                         krb5_ccache id,
+                         char **name)
+{
+    krb5_error_code ret;
+    krb5_data data;
+
+    ret = krb5_cc_get_config(context, id, NULL, "FriendlyName", &data);
+    if (ret) {
+       krb5_principal principal;
+       ret = krb5_cc_get_principal(context, id, &principal);
+       if (ret)
+           return ret;
+       ret = krb5_unparse_name(context, principal, name);
+       krb5_free_principal(context, principal);
+    } else {
+       ret = asprintf(name, "%.*s", (int)data.length, (char *)data.data);
+       krb5_data_free(&data);
+       if (ret <= 0) {
+           ret = ENOMEM;
+           krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
+       } else
+           ret = 0;
+    }
+
+    return ret;
+}
+
+/**
+ * Set the friendly name on credential cache.
+ *
+ * @return Return an error code or 0, see krb5_get_error_message().
+ *
+ * @ingroup krb5_ccache
+ */
+
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_cc_set_friendly_name(krb5_context context,
+                         krb5_ccache id,
+                         const char *name)
+{
+    krb5_data data;
+
+    data.data = rk_UNCONST(name);
+    data.length = strlen(name);
+
+    return krb5_cc_set_config(context, id, NULL, "FriendlyName", &data);
+}
+
+/**
+ * Get the lifetime of the initial ticket in the cache
+ *
+ * Get the lifetime of the initial ticket in the cache, if the initial
+ * ticket was not found, the error code KRB5_CC_END is returned.
+ *
+ * @param context A Kerberos 5 context.
+ * @param id a credential cache
+ * @param t the relative lifetime of the initial ticket
+ *
+ * @return Return an error code or 0, see krb5_get_error_message().
+ *
+ * @ingroup krb5_ccache
+ */
+
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_cc_get_lifetime(krb5_context context, krb5_ccache id, time_t *t)
+{
+    krb5_cc_cursor cursor;
+    krb5_error_code ret;
+    krb5_creds cred;
+    time_t now;
+
+    *t = 0;
+    now = time(NULL);
+    
+    ret = krb5_cc_start_seq_get(context, id, &cursor);
+    if (ret)
+       return ret;
+
+    while ((ret = krb5_cc_next_cred(context, id, &cursor, &cred)) == 0) {
+       if (cred.flags.b.initial) {
+           if (now < cred.times.endtime)
+               *t = cred.times.endtime - now;
+           krb5_free_cred_contents(context, &cred);
+           goto out;
+       }
+       krb5_free_cred_contents(context, &cred);
+    }
+    
+ out:
+    krb5_cc_end_seq_get(context, id, &cursor);
+
+    return ret;
+}
index 91ed9c5ba07b05cd59fe1b7343cfb6bef8ff24c3..207b86b4887336ec209a4df4e3acde8aea16e4d9 100644 (file)
@@ -31,9 +31,9 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include <krb5_locl.h>
+#define KRB5_DEPRECATED
 
 
-RCSID("$Id$");
+#include <krb5_locl.h>
 
 #undef __attribute__
 #define __attribute__(X)
 
 #undef __attribute__
 #define __attribute__(X)
@@ -82,7 +82,6 @@ chgpw_send_request (krb5_context context,
     krb5_data passwd_data;
     size_t len;
     u_char header[6];
     krb5_data passwd_data;
     size_t len;
     u_char header[6];
-    u_char *p;
     struct iovec iov[3];
     struct msghdr msghdr;
 
     struct iovec iov[3];
     struct msghdr msghdr;
 
@@ -118,13 +117,12 @@ chgpw_send_request (krb5_context context,
        goto out2;
 
     len = 6 + ap_req_data.length + krb_priv_data.length;
        goto out2;
 
     len = 6 + ap_req_data.length + krb_priv_data.length;
-    p = header;
-    *p++ = (len >> 8) & 0xFF;
-    *p++ = (len >> 0) & 0xFF;
-    *p++ = 0;
-    *p++ = 1;
-    *p++ = (ap_req_data.length >> 8) & 0xFF;
-    *p++ = (ap_req_data.length >> 0) & 0xFF;
+    header[0] = (len >> 8) & 0xFF;
+    header[1] = (len >> 0) & 0xFF;
+    header[2] = 0;
+    header[3] = 1;
+    header[4] = (ap_req_data.length >> 8) & 0xFF;
+    header[5] = (ap_req_data.length >> 0) & 0xFF;
 
     memset(&msghdr, 0, sizeof(msghdr));
     msghdr.msg_name       = NULL;
 
     memset(&msghdr, 0, sizeof(msghdr));
     msghdr.msg_name       = NULL;
@@ -231,7 +229,7 @@ setpw_send_request (krb5_context context,
     *p++ = 0xff;
     *p++ = 0x80;
     *p++ = (ap_req_data.length >> 8) & 0xFF;
     *p++ = 0xff;
     *p++ = 0x80;
     *p++ = (ap_req_data.length >> 8) & 0xFF;
-    *p++ = (ap_req_data.length >> 0) & 0xFF;
+    *p   = (ap_req_data.length >> 0) & 0xFF;
 
     memset(&msghdr, 0, sizeof(msghdr));
     msghdr.msg_name       = NULL;
 
     memset(&msghdr, 0, sizeof(msghdr));
     msghdr.msg_name       = NULL;
@@ -693,7 +691,7 @@ krb5_change_password (krb5_context  context,
                      int               *result_code,
                      krb5_data         *result_code_string,
                      krb5_data         *result_string)
                      int               *result_code,
                      krb5_data         *result_code_string,
                      krb5_data         *result_string)
-    __attribute__((deprecated))
+    KRB5_DEPRECATED
 {
     struct kpwd_proc *p = find_chpw_proto("change password");
 
 {
     struct kpwd_proc *p = find_chpw_proto("change password");
 
@@ -711,7 +709,7 @@ krb5_change_password (krb5_context  context,
 #endif /* HEIMDAL_SMALLER */
 
 /**
 #endif /* HEIMDAL_SMALLER */
 
 /**
- * Change passwrod using creds.
+ * Change password using creds.
  *
  * @param context a Keberos context
  * @param creds The initial kadmin/passwd for the principal or an admin principal
  *
  * @param context a Keberos context
  * @param creds The initial kadmin/passwd for the principal or an admin principal
@@ -767,8 +765,6 @@ krb5_set_password(krb5_context context,
     return ret;
 }
 
     return ret;
 }
 
-#ifndef HEIMDAL_SMALLER
-
 /*
  *
  */
 /*
  *
  */
@@ -834,8 +830,6 @@ krb5_set_password_using_ccache(krb5_context context,
     return ret;
 }
 
     return ret;
 }
 
-#endif /* !HEIMDAL_SMALLER */
-
 /*
  *
  */
 /*
  *
  */
index bd0dcc53711a60eee744d08c108e9505ebfc10e3..ebda3e51f75f05703260797ca7d0e7662c0232a2 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "krb5_locl.h"
-
-#undef __attribute__
-#define __attribute__(x)
+#define KRB5_DEPRECATED
 
 
-RCSID("$Id$");
+#include "krb5_locl.h"
 
 #ifndef HEIMDAL_SMALLER
 
 
 #ifndef HEIMDAL_SMALLER
 
@@ -46,7 +43,7 @@ krb5_decode_EncTicketPart (krb5_context context,
                           size_t length,
                           EncTicketPart *t,
                           size_t *len)
                           size_t length,
                           EncTicketPart *t,
                           size_t *len)
-    __attribute__((deprecated))
+    KRB5_DEPRECATED
 {
     return decode_EncTicketPart(data, length, t, len);
 }
 {
     return decode_EncTicketPart(data, length, t, len);
 }
@@ -57,7 +54,7 @@ krb5_encode_EncTicketPart (krb5_context context,
                           size_t length,
                           EncTicketPart *t,
                           size_t *len)
                           size_t length,
                           EncTicketPart *t,
                           size_t *len)
-    __attribute__((deprecated))
+    KRB5_DEPRECATED
 {
     return encode_EncTicketPart(data, length, t, len);
 }
 {
     return encode_EncTicketPart(data, length, t, len);
 }
@@ -68,7 +65,7 @@ krb5_decode_EncASRepPart (krb5_context context,
                          size_t length,
                          EncASRepPart *t,
                          size_t *len)
                          size_t length,
                          EncASRepPart *t,
                          size_t *len)
-    __attribute__((deprecated))
+    KRB5_DEPRECATED
 {
     return decode_EncASRepPart(data, length, t, len);
 }
 {
     return decode_EncASRepPart(data, length, t, len);
 }
@@ -79,7 +76,7 @@ krb5_encode_EncASRepPart (krb5_context context,
                          size_t length,
                          EncASRepPart *t,
                          size_t *len)
                          size_t length,
                          EncASRepPart *t,
                          size_t *len)
-    __attribute__((deprecated))
+    KRB5_DEPRECATED
 {
     return encode_EncASRepPart(data, length, t, len);
 }
 {
     return encode_EncASRepPart(data, length, t, len);
 }
@@ -90,7 +87,7 @@ krb5_decode_EncTGSRepPart (krb5_context context,
                           size_t length,
                           EncTGSRepPart *t,
                           size_t *len)
                           size_t length,
                           EncTGSRepPart *t,
                           size_t *len)
-    __attribute__((deprecated))
+    KRB5_DEPRECATED
 {
     return decode_EncTGSRepPart(data, length, t, len);
 }
 {
     return decode_EncTGSRepPart(data, length, t, len);
 }
@@ -101,7 +98,7 @@ krb5_encode_EncTGSRepPart (krb5_context context,
                           size_t length,
                           EncTGSRepPart *t,
                           size_t *len)
                           size_t length,
                           EncTGSRepPart *t,
                           size_t *len)
-    __attribute__((deprecated))
+    KRB5_DEPRECATED
 {
     return encode_EncTGSRepPart(data, length, t, len);
 }
 {
     return encode_EncTGSRepPart(data, length, t, len);
 }
@@ -112,7 +109,7 @@ krb5_decode_EncAPRepPart (krb5_context context,
                          size_t length,
                          EncAPRepPart *t,
                          size_t *len)
                          size_t length,
                          EncAPRepPart *t,
                          size_t *len)
-    __attribute__((deprecated))
+    KRB5_DEPRECATED
 {
     return decode_EncAPRepPart(data, length, t, len);
 }
 {
     return decode_EncAPRepPart(data, length, t, len);
 }
@@ -123,7 +120,7 @@ krb5_encode_EncAPRepPart (krb5_context context,
                          size_t length,
                          EncAPRepPart *t,
                          size_t *len)
                          size_t length,
                          EncAPRepPart *t,
                          size_t *len)
-    __attribute__((deprecated))
+    KRB5_DEPRECATED
 {
     return encode_EncAPRepPart(data, length, t, len);
 }
 {
     return encode_EncAPRepPart(data, length, t, len);
 }
@@ -134,7 +131,7 @@ krb5_decode_Authenticator (krb5_context context,
                           size_t length,
                           Authenticator *t,
                           size_t *len)
                           size_t length,
                           Authenticator *t,
                           size_t *len)
-    __attribute__((deprecated))
+    KRB5_DEPRECATED
 {
     return decode_Authenticator(data, length, t, len);
 }
 {
     return decode_Authenticator(data, length, t, len);
 }
@@ -145,7 +142,7 @@ krb5_encode_Authenticator (krb5_context context,
                           size_t length,
                           Authenticator *t,
                           size_t *len)
                           size_t length,
                           Authenticator *t,
                           size_t *len)
-    __attribute__((deprecated))
+    KRB5_DEPRECATED
 {
     return encode_Authenticator(data, length, t, len);
 }
 {
     return encode_Authenticator(data, length, t, len);
 }
@@ -156,7 +153,7 @@ krb5_decode_EncKrbCredPart (krb5_context context,
                            size_t length,
                            EncKrbCredPart *t,
                            size_t *len)
                            size_t length,
                            EncKrbCredPart *t,
                            size_t *len)
-    __attribute__((deprecated))
+    KRB5_DEPRECATED
 {
     return decode_EncKrbCredPart(data, length, t, len);
 }
 {
     return decode_EncKrbCredPart(data, length, t, len);
 }
@@ -167,7 +164,7 @@ krb5_encode_EncKrbCredPart (krb5_context context,
                            size_t length,
                            EncKrbCredPart *t,
                            size_t *len)
                            size_t length,
                            EncKrbCredPart *t,
                            size_t *len)
-    __attribute__((deprecated))
+    KRB5_DEPRECATED
 {
     return encode_EncKrbCredPart (data, length, t, len);
 }
 {
     return encode_EncKrbCredPart (data, length, t, len);
 }
@@ -178,7 +175,7 @@ krb5_decode_ETYPE_INFO (krb5_context context,
                        size_t length,
                        ETYPE_INFO *t,
                        size_t *len)
                        size_t length,
                        ETYPE_INFO *t,
                        size_t *len)
-    __attribute__((deprecated))
+    KRB5_DEPRECATED
 {
     return decode_ETYPE_INFO(data, length, t, len);
 }
 {
     return decode_ETYPE_INFO(data, length, t, len);
 }
@@ -189,7 +186,7 @@ krb5_encode_ETYPE_INFO (krb5_context context,
                        size_t length,
                        ETYPE_INFO *t,
                        size_t *len)
                        size_t length,
                        ETYPE_INFO *t,
                        size_t *len)
-    __attribute__((deprecated))
+    KRB5_DEPRECATED
 {
     return encode_ETYPE_INFO (data, length, t, len);
 }
 {
     return encode_ETYPE_INFO (data, length, t, len);
 }
@@ -200,7 +197,7 @@ krb5_decode_ETYPE_INFO2 (krb5_context context,
                        size_t length,
                        ETYPE_INFO2 *t,
                        size_t *len)
                        size_t length,
                        ETYPE_INFO2 *t,
                        size_t *len)
-    __attribute__((deprecated))
+    KRB5_DEPRECATED
 {
     return decode_ETYPE_INFO2(data, length, t, len);
 }
 {
     return decode_ETYPE_INFO2(data, length, t, len);
 }
@@ -211,7 +208,7 @@ krb5_encode_ETYPE_INFO2 (krb5_context context,
                         size_t length,
                         ETYPE_INFO2 *t,
                         size_t *len)
                         size_t length,
                         ETYPE_INFO2 *t,
                         size_t *len)
-    __attribute__((deprecated))
+    KRB5_DEPRECATED
 {
     return encode_ETYPE_INFO2 (data, length, t, len);
 }
 {
     return encode_ETYPE_INFO2 (data, length, t, len);
 }
index 75c48a001ba1e42d2404c16e1048d9b98a10cd48..ee226c78a2e67bc91d85abb0e84090e9aac3ef34 100644 (file)
@@ -32,9 +32,6 @@
  */
 
 #include "krb5_locl.h"
  */
 
 #include "krb5_locl.h"
-RCSID("$Id$");
-
-#ifndef HAVE_NETINFO
 
 /* Gaah! I want a portable funopen */
 struct fileptr {
 
 /* Gaah! I want a portable funopen */
 struct fileptr {
@@ -302,21 +299,65 @@ krb5_config_parse_string_multi(krb5_context context,
     return 0;
 }
 
     return 0;
 }
 
+/**
+ * Parse a configuration file and add the result into res. This
+ * interface can be used to parse several configuration files into one
+ * resulting krb5_config_section by calling it repeatably.
+ *
+ * @param context a Kerberos 5 context.
+ * @param fname a file name to a Kerberos configuration file
+ * @param res the returned result, must be free with krb5_free_config_files().
+ * @return Return an error code or 0, see krb5_get_error_message().
+ *
+ * @ingroup krb5_support
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_config_parse_file_multi (krb5_context context,
                              const char *fname,
                              krb5_config_section **res)
 {
     const char *str;
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_config_parse_file_multi (krb5_context context,
                              const char *fname,
                              krb5_config_section **res)
 {
     const char *str;
+    char *newfname = NULL;
     unsigned lineno = 0;
     krb5_error_code ret;
     struct fileptr f;
     unsigned lineno = 0;
     krb5_error_code ret;
     struct fileptr f;
+
+    /**
+     * If the fname starts with "~/" parse configuration file in the
+     * current users home directory. The behavior can be disabled and
+     * enabled by calling krb5_set_home_dir_access().
+     */
+    if (_krb5_homedir_access(context) && fname[0] == '~' && fname[1] == '/') {
+       const char *home = NULL;
+
+       if(!issuid())
+           home = getenv("HOME");
+
+       if (home == NULL) {
+           struct passwd *pw = getpwuid(getuid());     
+           if(pw != NULL)
+               home = pw->pw_dir;
+       }
+       if (home) {
+           asprintf(&newfname, "%s%s", home, &fname[1]);
+           if (newfname == NULL) {
+               krb5_set_error_message(context, ENOMEM,
+                                      N_("malloc: out of memory", ""));
+               return ENOMEM;
+           }
+           fname = newfname;
+       }
+    }
+
     f.f = fopen(fname, "r");
     f.s = NULL;
     if(f.f == NULL) {
        ret = errno;
        krb5_set_error_message (context, ret, "open %s: %s",
                                fname, strerror(ret));
     f.f = fopen(fname, "r");
     f.s = NULL;
     if(f.f == NULL) {
        ret = errno;
        krb5_set_error_message (context, ret, "open %s: %s",
                                fname, strerror(ret));
+       if (newfname)
+           free(newfname);
        return ret;
     }
 
        return ret;
     }
 
@@ -324,8 +365,12 @@ krb5_config_parse_file_multi (krb5_context context,
     fclose(f.f);
     if (ret) {
        krb5_set_error_message (context, ret, "%s:%u: %s", fname, lineno, str);
     fclose(f.f);
     if (ret) {
        krb5_set_error_message (context, ret, "%s:%u: %s", fname, lineno, str);
+       if (newfname)
+           free(newfname);
        return ret;
     }
        return ret;
     }
+    if (newfname)
+       free(newfname);
     return 0;
 }
 
     return 0;
 }
 
@@ -338,8 +383,6 @@ krb5_config_parse_file (krb5_context context,
     return krb5_config_parse_file_multi(context, fname, res);
 }
 
     return krb5_config_parse_file_multi(context, fname, res);
 }
 
-#endif /* !HAVE_NETINFO */
-
 static void
 free_binding (krb5_context context, krb5_config_binding *b)
 {
 static void
 free_binding (krb5_context context, krb5_config_binding *b)
 {
diff --git a/source4/heimdal/lib/krb5/config_file_netinfo.c b/source4/heimdal/lib/krb5/config_file_netinfo.c
deleted file mode 100644 (file)
index e6993bb..0000000
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (c) 1997 - 2001 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_locl.h"
-RCSID("$Id$");
-
-/*
- * Netinfo implementation from Luke Howard <lukeh@xedoc.com.au>
- */
-
-#ifdef HAVE_NETINFO
-#include <netinfo/ni.h>
-static ni_status
-ni_proplist2binding(ni_proplist *pl, krb5_config_section **ret)
-{
-    int i, j;
-    krb5_config_section **next = NULL;
-
-    for (i = 0; i < pl->ni_proplist_len; i++) {
-       if (!strcmp(pl->nipl_val[i].nip_name, "name"))
-           continue;
-
-       for (j = 0; j < pl->nipl_val[i].nip_val.ni_namelist_len; j++) {
-           krb5_config_binding *b;
-
-           b = malloc(sizeof(*b));
-           if (b == NULL)
-               return NI_FAILED;
-       
-           b->next = NULL;
-           b->type = krb5_config_string;
-           b->name = ni_name_dup(pl->nipl_val[i].nip_name);
-           b->u.string = ni_name_dup(pl->nipl_val[i].nip_val.ninl_val[j]);
-
-           if (next == NULL) {
-               *ret = b;
-           } else {
-               *next = b;
-           }
-           next = &b->next;
-       }
-    }
-    return NI_OK;
-}
-
-static ni_status
-ni_idlist2binding(void *ni, ni_idlist *idlist, krb5_config_section **ret)
-{
-    int i;
-    ni_status nis;
-    krb5_config_section **next;
-
-    for (i = 0; i < idlist->ni_idlist_len; i++) {
-       ni_proplist pl;
-        ni_id nid;
-       ni_idlist children;
-       krb5_config_binding *b;
-       ni_index index;
-
-       nid.nii_instance = 0;
-       nid.nii_object = idlist->ni_idlist_val[i];
-
-       nis = ni_read(ni, &nid, &pl);
-
-       if (nis != NI_OK) {
-            return nis;
-       }
-       index = ni_proplist_match(pl, "name", NULL);
-       b = malloc(sizeof(*b));
-       if (b == NULL) return NI_FAILED;
-
-       if (i == 0) {
-           *ret = b;
-       } else {
-           *next = b;
-       }
-
-       b->type = krb5_config_list;
-       b->name = ni_name_dup(pl.nipl_val[index].nip_val.ninl_val[0]);
-       b->next = NULL;
-       b->u.list = NULL;
-
-       /* get the child directories */
-       nis = ni_children(ni, &nid, &children);
-       if (nis == NI_OK) {
-           nis = ni_idlist2binding(ni, &children, &b->u.list);
-           if (nis != NI_OK) {
-               return nis;
-           }
-       }
-
-       nis = ni_proplist2binding(&pl, b->u.list == NULL ? &b->u.list : &b->u.list->next);
-       ni_proplist_free(&pl);
-       if (nis != NI_OK) {
-           return nis;
-       }
-       next = &b->next;
-    }
-    ni_idlist_free(idlist);
-    return NI_OK;
-}
-
-krb5_error_code KRB5_LIB_FUNCTION
-krb5_config_parse_file (krb5_context context,
-                       const char *fname,
-                       krb5_config_section **res)
-{
-    void *ni = NULL, *lastni = NULL;
-    int i;
-    ni_status nis;
-    ni_id nid;
-    ni_idlist children;
-
-    krb5_config_section *s;
-    int ret;
-
-    s = NULL;
-
-    for (i = 0; i < 256; i++) {
-       if (i == 0) {
-           nis = ni_open(NULL, ".", &ni);
-       } else {
-           if (lastni != NULL) ni_free(lastni);
-           lastni = ni;
-           nis = ni_open(lastni, "..", &ni);
-       }
-       if (nis != NI_OK)
-           break;
-       nis = ni_pathsearch(ni, &nid, "/locations/kerberos");
-       if (nis == NI_OK) {
-           nis = ni_children(ni, &nid, &children);
-           if (nis != NI_OK)
-               break;
-           nis = ni_idlist2binding(ni, &children, &s);
-           break;
-       }
-    }
-
-    if (ni != NULL) ni_free(ni);
-    if (ni != lastni && lastni != NULL) ni_free(lastni);
-
-    ret = (nis == NI_OK) ? 0 : -1;
-    if (ret == 0) {
-       *res = s;
-    } else {
-       *res = NULL;
-    }
-    return ret;
-}
-#endif /* HAVE_NETINFO */
index b41fb3f663790826ea8fbcc50eaf730c7bf40e2d..a3b3d09f41e17a890de607b6a78b6e9e8b5c01bb 100644 (file)
 
 #include "krb5_locl.h"
 
 
 #include "krb5_locl.h"
 
-RCSID("$Id$");
-
 KRB5_LIB_VARIABLE const char *krb5_config_file =
 #ifdef __APPLE__
 KRB5_LIB_VARIABLE const char *krb5_config_file =
 #ifdef __APPLE__
+"~/Library/Preferences/edu.mit.Kerberos:"
 "/Library/Preferences/edu.mit.Kerberos:"
 #endif
 SYSCONFDIR "/krb5.conf:/etc/krb5.conf";
 KRB5_LIB_VARIABLE const char *krb5_defkeyname = KEYTAB_DEFAULT;
 "/Library/Preferences/edu.mit.Kerberos:"
 #endif
 SYSCONFDIR "/krb5.conf:/etc/krb5.conf";
 KRB5_LIB_VARIABLE const char *krb5_defkeyname = KEYTAB_DEFAULT;
+
+KRB5_LIB_VARIABLE const char *krb5_cc_type_api = "API";
+KRB5_LIB_VARIABLE const char *krb5_cc_type_file = "FILE";
+KRB5_LIB_VARIABLE const char *krb5_cc_type_memory = "MEMORY";
+KRB5_LIB_VARIABLE const char *krb5_cc_type_kcm = "KCM";
+KRB5_LIB_VARIABLE const char *krb5_cc_type_scc = "SCC";
index 127dfa117dc83b2dd22d402775826c17db0e9684..fe941350307e1b535940c1f550f15b60386839bf 100644 (file)
@@ -34,8 +34,6 @@
 #include "krb5_locl.h"
 #include <com_err.h>
 
 #include "krb5_locl.h"
 #include <com_err.h>
 
-RCSID("$Id$");
-
 #define INIT_FIELD(C, T, E, D, F)                                      \
     (C)->E = krb5_config_get_ ## T ## _default ((C), NULL, (D),        \
                                                "libdefaults", F, NULL)
 #define INIT_FIELD(C, T, E, D, F)                                      \
     (C)->E = krb5_config_get_ ## T ## _default ((C), NULL, (D),        \
                                                "libdefaults", F, NULL)
@@ -243,9 +241,7 @@ cc_ops_register(krb5_context context)
     krb5_cc_register(context, &krb5_acc_ops, TRUE);
     krb5_cc_register(context, &krb5_fcc_ops, TRUE);
     krb5_cc_register(context, &krb5_mcc_ops, TRUE);
     krb5_cc_register(context, &krb5_acc_ops, TRUE);
     krb5_cc_register(context, &krb5_fcc_ops, TRUE);
     krb5_cc_register(context, &krb5_mcc_ops, TRUE);
-#ifdef HAVE_SQLITE
     krb5_cc_register(context, &krb5_scc_ops, TRUE);
     krb5_cc_register(context, &krb5_scc_ops, TRUE);
-#endif
 #ifdef HAVE_KCM
     krb5_cc_register(context, &krb5_kcm_ops, TRUE);
 #endif
 #ifdef HAVE_KCM
     krb5_cc_register(context, &krb5_kcm_ops, TRUE);
 #endif
@@ -310,6 +306,8 @@ krb5_init_context(krb5_context *context)
     }
     HEIMDAL_MUTEX_init(p->mutex);
 
     }
     HEIMDAL_MUTEX_init(p->mutex);
 
+    p->flags |= KRB5_CTX_F_HOMEDIR_ACCESS;
+
     ret = krb5_get_default_config_files(&files);
     if(ret)
        goto out;
     ret = krb5_get_default_config_files(&files);
     if(ret)
        goto out;
@@ -336,7 +334,7 @@ out:
  * Make a copy for the Kerberos 5 context, allocated krb5_contex shoud
  * be freed with krb5_free_context().
  *
  * Make a copy for the Kerberos 5 context, allocated krb5_contex shoud
  * be freed with krb5_free_context().
  *
- * @param in the Kerberos context to copy
+ * @param context the Kerberos context to copy
  * @param out the copy of the Kerberos, set to NULL error.
  *
  * @return Returns 0 to indicate success.  Otherwise an kerberos et
  * @param out the copy of the Kerberos, set to NULL error.
  *
  * @return Returns 0 to indicate success.  Otherwise an kerberos et
@@ -453,10 +451,10 @@ krb5_free_context(krb5_context context)
     krb5_set_extra_addresses(context, NULL);
     krb5_set_ignore_addresses(context, NULL);
     krb5_set_send_to_kdc_func(context, NULL, NULL);
     krb5_set_extra_addresses(context, NULL);
     krb5_set_ignore_addresses(context, NULL);
     krb5_set_send_to_kdc_func(context, NULL, NULL);
-    if (context->mutex != NULL) {
-       HEIMDAL_MUTEX_destroy(context->mutex);
-       free(context->mutex);
-    }
+
+    HEIMDAL_MUTEX_destroy(context->mutex);
+    free(context->mutex);
+
     memset(context, 0, sizeof(*context));
     free(context);
 }
     memset(context, 0, sizeof(*context));
     free(context);
 }
@@ -552,7 +550,7 @@ krb5_prepend_config_files(const char *filelist, char **pq, char ***ret_pp)
            krb5_free_config_files(pp);
            return ENOMEM;
        }
            krb5_free_config_files(pp);
            return ENOMEM;
        }
-       l = strsep_copy(&p, ":", fn, l + 1);
+       (void)strsep_copy(&p, ":", fn, l + 1);
        ret = add_file(&pp, &len, fn);
        if (ret) {
            krb5_free_config_files(pp);
        ret = add_file(&pp, &len, fn);
        if (ret) {
            krb5_free_config_files(pp);
@@ -641,7 +639,8 @@ krb5_get_default_config_files(char ***pfilenames)
 /**
  * Free a list of configuration files.
  *
 /**
  * Free a list of configuration files.
  *
- * @param filenames list to be freed.
+ * @param filenames list, terminated with a NULL pointer, to be
+ * freed. NULL is an valid argument.
  *
  * @return Returns 0 to indicate success. Otherwise an kerberos et
  * error code is returned, see krb5_get_error_message().
  *
  * @return Returns 0 to indicate success. Otherwise an kerberos et
  * error code is returned, see krb5_get_error_message().
@@ -653,7 +652,7 @@ void KRB5_LIB_FUNCTION
 krb5_free_config_files(char **filenames)
 {
     char **p;
 krb5_free_config_files(char **filenames)
 {
     char **p;
-    for(p = filenames; *p != NULL; p++)
+    for(p = filenames; p && *p != NULL; p++)
        free(*p);
     free(filenames);
 }
        free(*p);
     free(filenames);
 }
@@ -1226,3 +1225,115 @@ krb5_set_max_time_skew (krb5_context context, time_t t)
 {
     context->max_skew = t;
 }
 {
     context->max_skew = t;
 }
+
+/**
+ * Init encryption types in len, val with etypes.
+ *
+ * @param context Kerberos 5 context.
+ * @param len output length of val.
+ * @param val output array of enctypes.
+ * @param etypes etypes to set val and len to, if NULL, use default enctypes.
+
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned, see krb5_get_error_message().
+ *
+ * @ingroup krb5
+ */
+
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_init_etype (krb5_context context,
+                unsigned *len,
+                krb5_enctype **val,
+                const krb5_enctype *etypes)
+{
+    unsigned int i;
+    krb5_error_code ret;
+    krb5_enctype *tmp = NULL;
+
+    ret = 0;
+    if (etypes == NULL) {
+       ret = krb5_get_default_in_tkt_etypes(context, &tmp);
+       if (ret)
+           return ret;
+       etypes = tmp;
+    }
+
+    for (i = 0; etypes[i]; ++i)
+       ;
+    *len = i;
+    *val = malloc(i * sizeof(**val));
+    if (i != 0 && *val == NULL) {
+       ret = ENOMEM;
+       krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
+       goto cleanup;
+    }
+    memmove (*val,
+            etypes,
+            i * sizeof(*tmp));
+cleanup:
+    if (tmp != NULL)
+       free (tmp);
+    return ret;
+}
+
+/*
+ * Allow homedir accces
+ */
+
+static HEIMDAL_MUTEX homedir_mutex = HEIMDAL_MUTEX_INITIALIZER;
+static krb5_boolean allow_homedir = TRUE;
+
+krb5_boolean
+_krb5_homedir_access(krb5_context context)
+{
+    krb5_boolean allow;
+
+    /* is never allowed for root */
+    if (geteuid() == 0)
+       return FALSE;
+
+    if (context && (context->flags & KRB5_CTX_F_HOMEDIR_ACCESS) == 0)
+       return FALSE;
+
+    HEIMDAL_MUTEX_lock(&homedir_mutex);
+    allow = allow_homedir;
+    HEIMDAL_MUTEX_unlock(&homedir_mutex);
+    return allow;
+}
+
+/**
+ * Enable and disable home directory access on either the global state
+ * or the krb5_context state. By calling krb5_set_home_dir_access()
+ * with context set to NULL, the global state is configured otherwise
+ * the state for the krb5_context is modified.
+ *
+ * For home directory access to be allowed, both the global state and
+ * the krb5_context state have to be allowed.
+ *
+ * Administrator (root user), never uses the home directory.
+ *
+ * @param context a Kerberos 5 context or NULL
+ * @param allow allow if TRUE home directory
+ * @return the old value
+ *
+ */
+
+krb5_boolean
+krb5_set_home_dir_access(krb5_context context, krb5_boolean allow)
+{
+    krb5_boolean old;
+    if (context) {
+       old = (context->flags & KRB5_CTX_F_HOMEDIR_ACCESS) ? TRUE : FALSE;
+       if (allow)
+           context->flags |= KRB5_CTX_F_HOMEDIR_ACCESS;
+       else
+           context->flags &= ~KRB5_CTX_F_HOMEDIR_ACCESS;
+    } else {
+       HEIMDAL_MUTEX_lock(&homedir_mutex);
+       old = allow_homedir;
+       allow_homedir = allow;
+       HEIMDAL_MUTEX_unlock(&homedir_mutex);
+    }
+
+    return old;
+}
index fc81d96bec3e2eb39b22ff8932d312c999d35cee..35454bf983cee89d1e08fa1efa134d7dc32ca6f6 100644 (file)
  */
 
 #include "krb5_locl.h"
  */
 
 #include "krb5_locl.h"
-RCSID("$Id$");
-
 #include "krb5-v4compat.h"
 
 #include "krb5-v4compat.h"
 
+#ifndef HEIMDAL_SMALLER
+
 static krb5_error_code
 check_ticket_flags(TicketFlags f)
 {
 static krb5_error_code
 check_ticket_flags(TicketFlags f)
 {
@@ -204,3 +204,5 @@ krb524_convert_creds_kdc_ccache(krb5_context context,
        krb5_free_creds (context, v5_creds);
     return ret;
 }
        krb5_free_creds (context, v5_creds);
     return ret;
 }
+
+#endif
index 37e27110b62f64871e161935a6489cf7bb80d0d2..7f19ddd3dee47ced3012fa5f2128c9e64089a7ba 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "krb5_locl.h"
 
 
 #include "krb5_locl.h"
 
-RCSID("$Id$");
-
 /**
  * Copy the list of realms from `from' to `to'.
  *
 /**
  * Copy the list of realms from `from' to `to'.
  *
index a900cabbba39d4d594c5e4980cfab96f04be5a54..eab946541db7d49bf032c80b698ea9aacb5e487e 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "krb5_locl.h"
 
 
 #include "krb5_locl.h"
 
-RCSID("$Id$");
-
 static u_long table[256];
 
 #define CRC_GEN 0xEDB88320L
 static u_long table[256];
 
 #define CRC_GEN 0xEDB88320L
index 087a4850eba145cc46c137706f2e36dc9abc3931..26c0dfbecbfe9783b1e453d44aae0cc4b7b092d6 100644 (file)
 
 #include "krb5_locl.h"
 
 
 #include "krb5_locl.h"
 
-RCSID("$Id$");
-
-#undef __attribute__
-#define __attribute__(X)
-
-#ifndef HEIMDAL_SMALLER
-
-/* keep this for compatibility with older code */
-krb5_error_code KRB5_LIB_FUNCTION
-krb5_free_creds_contents (krb5_context context, krb5_creds *c)
-    __attribute__((deprecated))
-{
-    return krb5_free_cred_contents (context, c);
-}
-
-#endif /* HEIMDAL_SMALLER */
-
 /**
  * Free content of krb5_creds.
  *
 /**
  * Free content of krb5_creds.
  *
@@ -235,9 +218,7 @@ krb5_compare_creds(krb5_context context, krb5_flags whichfields,
     }
        
     if (match && (whichfields & KRB5_TC_MATCH_KEYTYPE))
     }
        
     if (match && (whichfields & KRB5_TC_MATCH_KEYTYPE))
-       match = krb5_enctypes_compatible_keys(context,
-                                             mcreds->session.keytype,
-                                             creds->session.keytype);
+        match = mcreds->session.keytype == creds->session.keytype;
 
     if (match && (whichfields & KRB5_TC_MATCH_FLAGS_EXACT))
        match = mcreds->flags.i == creds->flags.i;
 
     if (match && (whichfields & KRB5_TC_MATCH_FLAGS_EXACT))
        match = mcreds->flags.i == creds->flags.i;
index bc6512cf1ab850d0b932b9ee20aba4d2243386e5..9fd21173454db2389e284599720f60dab645d2c2 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
+#define KRB5_DEPRECATED
+
 #include "krb5_locl.h"
 #include "krb5_locl.h"
-RCSID("$Id$");
 #include <pkinit_asn1.h>
 
 #include <pkinit_asn1.h>
 
-#undef __attribute__
-#define __attribute__(X)
-
 #define WEAK_ENCTYPES 1
 
 #ifndef HEIMDAL_SMALLER
 #define WEAK_ENCTYPES 1
 
 #ifndef HEIMDAL_SMALLER
@@ -164,6 +162,9 @@ static krb5_error_code hmac(krb5_context context,
 static void free_key_data(krb5_context,
                          struct key_data *,
                          struct encryption_type *);
 static void free_key_data(krb5_context,
                          struct key_data *,
                          struct encryption_type *);
+static void free_key_schedule(krb5_context,
+                             struct key_data *,
+                             struct encryption_type *);
 static krb5_error_code usage2arcfour (krb5_context, unsigned *);
 static void xor (DES_cblock *, const unsigned char *);
 
 static krb5_error_code usage2arcfour (krb5_context, unsigned *);
 static void xor (DES_cblock *, const unsigned char *);
 
@@ -1158,7 +1159,16 @@ _key_schedule(krb5_context context,
 {
     krb5_error_code ret;
     struct encryption_type *et = _find_enctype(key->key->keytype);
 {
     krb5_error_code ret;
     struct encryption_type *et = _find_enctype(key->key->keytype);
-    struct key_type *kt = et->keytype;
+    struct key_type *kt;
+
+    if (et == NULL) {
+       krb5_set_error_message (context, KRB5_PROG_ETYPE_NOSUPP,
+                               N_("encryption type %d not supported", ""),
+                               key->key->keytype);
+       return KRB5_PROG_ETYPE_NOSUPP;
+    }
+
+    kt = et->keytype;
 
     if(kt->schedule == NULL)
        return 0;
 
     if(kt->schedule == NULL)
        return 0;
@@ -1841,14 +1851,25 @@ verify_checksum(krb5_context context,
        return KRB5KRB_AP_ERR_BAD_INTEGRITY; /* XXX */
     }
     keyed_checksum = (ct->flags & F_KEYED) != 0;
        return KRB5KRB_AP_ERR_BAD_INTEGRITY; /* XXX */
     }
     keyed_checksum = (ct->flags & F_KEYED) != 0;
-    if(keyed_checksum && crypto == NULL) {
-       krb5_set_error_message (context, KRB5_PROG_SUMTYPE_NOSUPP,
-                               N_("Checksum type %s is keyed but no "
-                                  "crypto context (key) was passed in", ""),
-                               ct->name);
-       return KRB5_PROG_SUMTYPE_NOSUPP; /* XXX */
-    }
     if(keyed_checksum) {
     if(keyed_checksum) {
+       struct checksum_type *kct;
+       if (crypto == NULL) {
+           krb5_set_error_message (context, KRB5_PROG_SUMTYPE_NOSUPP,
+                                   N_("Checksum type %s is keyed but no "
+                                      "crypto context (key) was passed in", ""),
+                                   ct->name);
+           return KRB5_PROG_SUMTYPE_NOSUPP; /* XXX */
+       }
+       kct = crypto->et->keyed_checksum;
+       if (kct != NULL && kct->type != ct->type) {
+           krb5_set_error_message (context, KRB5_PROG_SUMTYPE_NOSUPP,
+                                   N_("Checksum type %s is keyed, but "
+                                      "the key type %s passed didnt have that checksum "
+                                      "type as the keyed type", ""),
+                                   ct->name, crypto->et->name);
+           return KRB5_PROG_SUMTYPE_NOSUPP; /* XXX */
+       }
+
        ret = get_checksum_key(context, crypto, usage, ct, &dkey);
        if (ret)
            return ret;
        ret = get_checksum_key(context, crypto, usage, ct, &dkey);
        if (ret)
            return ret;
@@ -2348,10 +2369,11 @@ AES_PRF(krb5_context context,
     {
        const EVP_CIPHER *c = (*crypto->et->keytype->evp)();
        EVP_CIPHER_CTX ctx;
     {
        const EVP_CIPHER *c = (*crypto->et->keytype->evp)();
        EVP_CIPHER_CTX ctx;
-       /* XXX blksz 1 for cts, so we can't use that */
+
        EVP_CIPHER_CTX_init(&ctx); /* ivec all zero */
        EVP_CipherInit_ex(&ctx, c, NULL, derived->keyvalue.data, NULL, 1);
        EVP_CIPHER_CTX_init(&ctx); /* ivec all zero */
        EVP_CipherInit_ex(&ctx, c, NULL, derived->keyvalue.data, NULL, 1);
-       EVP_Cipher(&ctx, out->data, result.checksum.data, 16);
+       EVP_Cipher(&ctx, out->data, result.checksum.data,
+                  crypto->et->blocksize);
        EVP_CIPHER_CTX_cleanup(&ctx);
     }
 
        EVP_CIPHER_CTX_cleanup(&ctx);
     }
 
@@ -2737,17 +2759,6 @@ krb5_cksumtype_valid(krb5_context context,
 }
 
 
 }
 
 
-/* if two enctypes have compatible keys */
-krb5_boolean KRB5_LIB_FUNCTION
-krb5_enctypes_compatible_keys(krb5_context context,
-                             krb5_enctype etype1,
-                             krb5_enctype etype2)
-{
-    struct encryption_type *e1 = _find_enctype(etype1);
-    struct encryption_type *e2 = _find_enctype(etype2);
-    return e1 != NULL && e2 != NULL && e1->keytype == e2->keytype;
-}
-
 static krb5_boolean
 derived_crypto(krb5_context context,
               krb5_crypto crypto)
 static krb5_boolean
 derived_crypto(krb5_context context,
               krb5_crypto crypto)
@@ -3147,10 +3158,10 @@ find_iv(krb5_crypto_iov *data, int num_data, int type)
  * Kerberos encrypted data look like this:
  *
  * 1. KRB5_CRYPTO_TYPE_HEADER
  * Kerberos encrypted data look like this:
  *
  * 1. KRB5_CRYPTO_TYPE_HEADER
- * 2. array KRB5_CRYPTO_TYPE_DATA and KRB5_CRYPTO_TYPE_SIGN_ONLY in
- *  any order, however the receiver have to aware of the
- *  order. KRB5_CRYPTO_TYPE_SIGN_ONLY is commonly used headers and
- *  trailers.
+ * 2. array [1,...] KRB5_CRYPTO_TYPE_DATA and array [0,...]
+ *    KRB5_CRYPTO_TYPE_SIGN_ONLY in any order, however the receiver
+ *    have to aware of the order. KRB5_CRYPTO_TYPE_SIGN_ONLY is
+ *    commonly used headers and trailers.
  * 3. KRB5_CRYPTO_TYPE_PADDING, at least on padsize long if padsize > 1
  * 4. KRB5_CRYPTO_TYPE_TRAILER
  */
  * 3. KRB5_CRYPTO_TYPE_PADDING, at least on padsize long if padsize > 1
  * 4. KRB5_CRYPTO_TYPE_TRAILER
  */
@@ -3160,17 +3171,23 @@ krb5_encrypt_iov_ivec(krb5_context context,
                      krb5_crypto crypto,
                      unsigned usage,
                      krb5_crypto_iov *data,
                      krb5_crypto crypto,
                      unsigned usage,
                      krb5_crypto_iov *data,
-                     size_t num_data,
+                     int num_data,
                      void *ivec)
 {
     size_t headersz, trailersz, len;
                      void *ivec)
 {
     size_t headersz, trailersz, len;
-    size_t i, sz, block_sz, pad_sz;
+    int i;
+    size_t sz, block_sz, pad_sz;
     Checksum cksum;
     unsigned char *p, *q;
     krb5_error_code ret;
     struct key_data *dkey;
     const struct encryption_type *et = crypto->et;
     Checksum cksum;
     unsigned char *p, *q;
     krb5_error_code ret;
     struct key_data *dkey;
     const struct encryption_type *et = crypto->et;
-    krb5_crypto_iov *tiv, *piv, *hiv;
+    krb5_crypto_iov *tiv, *piv, *hiv, *div;
+
+    if (num_data < 0) {
+        krb5_clear_error_message(context);
+       return KRB5_CRYPTO_INTERNAL;
+    }
 
     if(!derived_crypto(context, crypto)) {
        krb5_clear_error_message(context);
 
     if(!derived_crypto(context, crypto)) {
        krb5_clear_error_message(context);
@@ -3180,18 +3197,16 @@ krb5_encrypt_iov_ivec(krb5_context context,
     headersz = et->confoundersize;
     trailersz = CHECKSUMSIZE(et->keyed_checksum);
 
     headersz = et->confoundersize;
     trailersz = CHECKSUMSIZE(et->keyed_checksum);
 
-    for (len = 0, i = 0; i < num_data; i++) {
-       if (data[i].flags != KRB5_CRYPTO_TYPE_HEADER &&
-           data[i].flags == KRB5_CRYPTO_TYPE_DATA) {
-           len += data[i].data.length;
-       }
-    }
+    div = find_iv(data, num_data, KRB5_CRYPTO_TYPE_DATA);
+    if (div == NULL)
+       return KRB5_CRYPTO_INTERNAL;
+    
+    len = div->data.length;
 
     sz = headersz + len;
     block_sz = (sz + et->padsize - 1) &~ (et->padsize - 1); /* pad */
 
     pad_sz = block_sz - sz;
 
     sz = headersz + len;
     block_sz = (sz + et->padsize - 1) &~ (et->padsize - 1); /* pad */
 
     pad_sz = block_sz - sz;
-    trailersz += pad_sz;
 
     /* header */
 
 
     /* header */
 
@@ -3278,13 +3293,9 @@ krb5_encrypt_iov_ivec(krb5_context context,
 
     /* XXX replace with EVP_Cipher */
 
 
     /* XXX replace with EVP_Cipher */
 
-    len = hiv->data.length;
-    for (i = 0; i < num_data; i++) {
-       if (data[i].flags != KRB5_CRYPTO_TYPE_DATA &&
-           data[i].flags != KRB5_CRYPTO_TYPE_PADDING)
-           continue;
-       len += data[i].data.length;
-    }
+    len = hiv->data.length + div->data.length;
+    if (piv)
+       len += piv->data.length;
 
     p = q = malloc(len);
     if(p == NULL)
 
     p = q = malloc(len);
     if(p == NULL)
@@ -3292,13 +3303,9 @@ krb5_encrypt_iov_ivec(krb5_context context,
 
     memcpy(q, hiv->data.data, hiv->data.length);
     q += hiv->data.length;
 
     memcpy(q, hiv->data.data, hiv->data.length);
     q += hiv->data.length;
-    for (i = 0; i < num_data; i++) {
-       if (data[i].flags != KRB5_CRYPTO_TYPE_DATA &&
-           data[i].flags != KRB5_CRYPTO_TYPE_PADDING)
-           continue;
-       memcpy(q, data[i].data.data, data[i].data.length);
-       q += data[i].data.length;
-    }
+    memcpy(q, div->data.data, div->data.length);
+    q += div->data.length;
+    memset(q, 0, pad_sz);
 
     ret = _get_derived_key(context, crypto, ENCRYPTION_USAGE(usage), &dkey);
     if(ret) {
 
     ret = _get_derived_key(context, crypto, ENCRYPTION_USAGE(usage), &dkey);
     if(ret) {
@@ -3319,16 +3326,15 @@ krb5_encrypt_iov_ivec(krb5_context context,
 
     /* now copy data back to buffers */
     q = p;
 
     /* now copy data back to buffers */
     q = p;
+
     memcpy(hiv->data.data, q, hiv->data.length);
     q += hiv->data.length;
 
     memcpy(hiv->data.data, q, hiv->data.length);
     q += hiv->data.length;
 
-    for (i = 0; i < num_data; i++) {
-       if (data[i].flags != KRB5_CRYPTO_TYPE_DATA &&
-           data[i].flags != KRB5_CRYPTO_TYPE_PADDING)
-           continue;
-       memcpy(data[i].data.data, q, data[i].data.length);
-       q += data[i].data.length;
-    }
+    memcpy(div->data.data, q, div->data.length);
+    q += div->data.length;
+
+    if (piv)
+       memcpy(piv->data.data, q, pad_sz);
     free(p);
 
     return ret;
     free(p);
 
     return ret;
@@ -3348,7 +3354,7 @@ krb5_encrypt_iov_ivec(krb5_context context,
  * @ingroup krb5_crypto
  *
  * 1. KRB5_CRYPTO_TYPE_HEADER
  * @ingroup krb5_crypto
  *
  * 1. KRB5_CRYPTO_TYPE_HEADER
- * 2. array KRB5_CRYPTO_TYPE_DATA and KRB5_CRYPTO_TYPE_SIGN_ONLY in
+ * 2. one KRB5_CRYPTO_TYPE_DATA and array [0,...] of KRB5_CRYPTO_TYPE_SIGN_ONLY in
  *  any order, however the receiver have to aware of the
  *  order. KRB5_CRYPTO_TYPE_SIGN_ONLY is commonly used unencrypoted
  *  protocol headers and trailers. The output data will be of same
  *  any order, however the receiver have to aware of the
  *  order. KRB5_CRYPTO_TYPE_SIGN_ONLY is commonly used unencrypoted
  *  protocol headers and trailers. The output data will be of same
@@ -3360,17 +3366,23 @@ krb5_decrypt_iov_ivec(krb5_context context,
                      krb5_crypto crypto,
                      unsigned usage,
                      krb5_crypto_iov *data,
                      krb5_crypto crypto,
                      unsigned usage,
                      krb5_crypto_iov *data,
-                     size_t num_data,
+                     unsigned int num_data,
                      void *ivec)
 {
                      void *ivec)
 {
+    unsigned int i;
     size_t headersz, trailersz, len;
     size_t headersz, trailersz, len;
-    size_t i, sz, block_sz, pad_sz;
+    size_t sz, block_sz, pad_sz;
     Checksum cksum;
     unsigned char *p, *q;
     krb5_error_code ret;
     struct key_data *dkey;
     struct encryption_type *et = crypto->et;
     Checksum cksum;
     unsigned char *p, *q;
     krb5_error_code ret;
     struct key_data *dkey;
     struct encryption_type *et = crypto->et;
-    krb5_crypto_iov *tiv, *hiv;
+    krb5_crypto_iov *tiv, *hiv, *div;
+
+    if (num_data < 0) {
+        krb5_clear_error_message(context);
+       return KRB5_CRYPTO_INTERNAL;
+    }
 
     if(!derived_crypto(context, crypto)) {
        krb5_clear_error_message(context);
 
     if(!derived_crypto(context, crypto)) {
        krb5_clear_error_message(context);
@@ -3380,9 +3392,13 @@ krb5_decrypt_iov_ivec(krb5_context context,
     headersz = et->confoundersize;
     trailersz = CHECKSUMSIZE(et->keyed_checksum);
 
     headersz = et->confoundersize;
     trailersz = CHECKSUMSIZE(et->keyed_checksum);
 
-    for (len = 0, i = 0; i < num_data; i++)
-       if (data[i].flags == KRB5_CRYPTO_TYPE_DATA)
+    for (len = 0, i = 0; i < num_data; i++) {
+       if (data[i].flags == KRB5_CRYPTO_TYPE_DATA) {
+           if (len != 0) 
+               return KRB5_CRYPTO_INTERNAL;
            len += data[i].data.length;
            len += data[i].data.length;
+       }
+    }
 
     sz = headersz + len;
     block_sz = (sz + et->padsize - 1) &~ (et->padsize - 1); /* pad */
 
     sz = headersz + len;
     block_sz = (sz + et->padsize - 1) &~ (et->padsize - 1); /* pad */
@@ -3404,7 +3420,9 @@ krb5_decrypt_iov_ivec(krb5_context context,
        return KRB5_BAD_MSIZE;
     tiv->data.length = trailersz;
 
        return KRB5_BAD_MSIZE;
     tiv->data.length = trailersz;
 
-    /* body */
+    div = find_iv(data, num_data, KRB5_CRYPTO_TYPE_DATA);
+    if (div == NULL)
+       return KRB5_CRYPTO_INTERNAL;
 
     /* XXX replace with EVP_Cipher */
 
 
     /* XXX replace with EVP_Cipher */
 
@@ -3421,12 +3439,7 @@ krb5_decrypt_iov_ivec(krb5_context context,
 
     memcpy(q, hiv->data.data, hiv->data.length);
     q += hiv->data.length;
 
     memcpy(q, hiv->data.data, hiv->data.length);
     q += hiv->data.length;
-    for (i = 0; i < num_data; i++) {
-       if (data[i].flags != KRB5_CRYPTO_TYPE_DATA)
-           continue;
-       memcpy(q, data[i].data.data, data[i].data.length);
-       q += data[i].data.length;
-    }
+    memcpy(q, div->data.data, div->data.length);
 
     ret = _get_derived_key(context, crypto, ENCRYPTION_USAGE(usage), &dkey);
     if(ret) {
 
     ret = _get_derived_key(context, crypto, ENCRYPTION_USAGE(usage), &dkey);
     if(ret) {
@@ -3445,24 +3458,12 @@ krb5_decrypt_iov_ivec(krb5_context context,
        return ret;
     }
 
        return ret;
     }
 
-    /* XXX now copy data back to buffers */
-    q = p;
-    memcpy(hiv->data.data, q, hiv->data.length);
-    q += hiv->data.length;
-    len -= hiv->data.length;
-
-    for (i = 0; i < num_data; i++) {
-       if (data[i].flags != KRB5_CRYPTO_TYPE_DATA)
-           continue;
-       if (len < data[i].data.length)
-           data[i].data.length = len;
-       memcpy(data[i].data.data, q, data[i].data.length);
-       q += data[i].data.length;
-       len -= data[i].data.length;
-    }
+    /* copy data back to buffers */
+    memcpy(hiv->data.data, p, hiv->data.length);
+    memcpy(div->data.data, p + hiv->data.length, len - hiv->data.length);
     free(p);
     free(p);
-    if (len)
-       krb5_abortx(context, "data still in the buffer");
+
+    /* check signature */
 
     len = hiv->data.length;
     for (i = 0; i < num_data; i++) {
 
     len = hiv->data.length;
     for (i = 0; i < num_data; i++) {
@@ -3506,7 +3507,7 @@ krb5_decrypt_iov_ivec(krb5_context context,
  * @param usage Key usage for this buffer
  * @param data array of buffers to process
  * @param num_data length of array
  * @param usage Key usage for this buffer
  * @param data array of buffers to process
  * @param num_data length of array
- * @param result output data
+ * @param type output data
  *
  * @return Return an error code or 0.
  * @ingroup krb5_crypto
  *
  * @return Return an error code or 0.
  * @ingroup krb5_crypto
@@ -3517,16 +3518,21 @@ krb5_create_checksum_iov(krb5_context context,
                         krb5_crypto crypto,
                         unsigned usage,
                         krb5_crypto_iov *data,
                         krb5_crypto crypto,
                         unsigned usage,
                         krb5_crypto_iov *data,
-                        size_t num_data,
+                        unsigned int num_data,
                         krb5_cksumtype *type)
 {
     Checksum cksum;
     krb5_crypto_iov *civ;
     krb5_error_code ret;
                         krb5_cksumtype *type)
 {
     Checksum cksum;
     krb5_crypto_iov *civ;
     krb5_error_code ret;
-    unsigned int i;
+    int i;
     size_t len;
     char *p, *q;
 
     size_t len;
     char *p, *q;
 
+    if (num_data < 0) {
+        krb5_clear_error_message(context);
+       return KRB5_CRYPTO_INTERNAL;
+    }
+
     if(!derived_crypto(context, crypto)) {
        krb5_clear_error_message(context);
        return KRB5_CRYPTO_INTERNAL;
     if(!derived_crypto(context, crypto)) {
        krb5_clear_error_message(context);
        return KRB5_CRYPTO_INTERNAL;
@@ -3765,18 +3771,6 @@ krb5_generate_random_block(void *buf, size_t len)
        krb5_abortx(NULL, "Failed to generate random block");
 }
 
        krb5_abortx(NULL, "Failed to generate random block");
 }
 
-static void
-DES3_postproc(krb5_context context,
-             unsigned char *k, size_t len, struct key_data *key)
-{
-    DES3_random_to_key(context, key->key, k, len);
-
-    if (key->schedule) {
-       krb5_free_data(context, key->schedule);
-       key->schedule = NULL;
-    }
-}
-
 static krb5_error_code
 derive_key(krb5_context context,
           struct encryption_type *et,
 static krb5_error_code
 derive_key(krb5_context context,
           struct encryption_type *et,
@@ -3784,7 +3778,7 @@ derive_key(krb5_context context,
           const void *constant,
           size_t len)
 {
           const void *constant,
           size_t len)
 {
-    unsigned char *k;
+    unsigned char *k = NULL;
     unsigned int nblocks = 0, i;
     krb5_error_code ret = 0;
     struct key_type *kt = et->keytype;
     unsigned int nblocks = 0, i;
     krb5_error_code ret = 0;
     struct key_type *kt = et->keytype;
@@ -3796,15 +3790,16 @@ derive_key(krb5_context context,
        nblocks = (kt->bits + et->blocksize * 8 - 1) / (et->blocksize * 8);
        k = malloc(nblocks * et->blocksize);
        if(k == NULL) {
        nblocks = (kt->bits + et->blocksize * 8 - 1) / (et->blocksize * 8);
        k = malloc(nblocks * et->blocksize);
        if(k == NULL) {
-           krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
-           return ENOMEM;
+           ret = ENOMEM;
+           krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
+           goto out;
        }
        ret = _krb5_n_fold(constant, len, k, et->blocksize);
        if (ret) {
        }
        ret = _krb5_n_fold(constant, len, k, et->blocksize);
        if (ret) {
-           free(k);
            krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
            krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
-           return ret;
+           goto out;
        }
        }
+
        for(i = 0; i < nblocks; i++) {
            if(i > 0)
                memcpy(k + i * et->blocksize,
        for(i = 0; i < nblocks; i++) {
            if(i > 0)
                memcpy(k + i * et->blocksize,
@@ -3819,30 +3814,31 @@ derive_key(krb5_context context,
        size_t res_len = (kt->bits + 7) / 8;
 
        if(len != 0 && c == NULL) {
        size_t res_len = (kt->bits + 7) / 8;
 
        if(len != 0 && c == NULL) {
-           krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
-           return ENOMEM;
+           ret = ENOMEM;
+           krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
+           goto out;
        }
        memcpy(c, constant, len);
        (*et->encrypt)(context, key, c, len, 1, 0, NULL);
        k = malloc(res_len);
        if(res_len != 0 && k == NULL) {
            free(c);
        }
        memcpy(c, constant, len);
        (*et->encrypt)(context, key, c, len, 1, 0, NULL);
        k = malloc(res_len);
        if(res_len != 0 && k == NULL) {
            free(c);
-           krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
-           return ENOMEM;
+           ret = ENOMEM;
+           krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
+           goto out;
        }
        ret = _krb5_n_fold(c, len, k, res_len);
        }
        ret = _krb5_n_fold(c, len, k, res_len);
+       free(c);
        if (ret) {
        if (ret) {
-           free(k);
            krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
            krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
-           return ret;
+           goto out;
        }
        }
-       free(c);
     }
 
     /* XXX keytype dependent post-processing */
     switch(kt->type) {
     case KEYTYPE_DES3:
     }
 
     /* XXX keytype dependent post-processing */
     switch(kt->type) {
     case KEYTYPE_DES3:
-       DES3_postproc(context, k, nblocks * et->blocksize, key);
+       DES3_random_to_key(context, key->key, k, nblocks * et->blocksize);
        break;
     case KEYTYPE_AES128:
     case KEYTYPE_AES256:
        break;
     case KEYTYPE_AES128:
     case KEYTYPE_AES256:
@@ -3855,12 +3851,15 @@ derive_key(krb5_context context,
                               kt->type);
        break;
     }
                               kt->type);
        break;
     }
+ out:
     if (key->schedule) {
     if (key->schedule) {
-       krb5_free_data(context, key->schedule);
+       free_key_schedule(context, key, et);
        key->schedule = NULL;
     }
        key->schedule = NULL;
     }
-    memset(k, 0, nblocks * et->blocksize);
-    free(k);
+    if (k) {
+       memset(k, 0, nblocks * et->blocksize);
+       free(k);
+    }
     return ret;
 }
 
     return ret;
 }
 
@@ -3982,16 +3981,25 @@ krb5_crypto_init(krb5_context context,
     return 0;
 }
 
     return 0;
 }
 
+static void
+free_key_schedule(krb5_context context,
+                 struct key_data *key,
+                 struct encryption_type *et)
+{
+    if (et->keytype->cleanup)
+       (*et->keytype->cleanup)(context, key);
+    memset(key->schedule->data, 0, key->schedule->length);
+    krb5_free_data(context, key->schedule);
+}
+
 static void
 free_key_data(krb5_context context, struct key_data *key,
              struct encryption_type *et)
 {
     krb5_free_keyblock(context, key->key);
     if(key->schedule) {
 static void
 free_key_data(krb5_context context, struct key_data *key,
              struct encryption_type *et)
 {
     krb5_free_keyblock(context, key->key);
     if(key->schedule) {
-       if (et->keytype->cleanup)
-           (*et->keytype->cleanup)(context, key);
-       memset(key->schedule->data, 0, key->schedule->length);
-       krb5_free_data(context, key->schedule);
+       free_key_schedule(context, key, et);
+       key->schedule = NULL;
     }
 }
 
     }
 }
 
@@ -4154,7 +4162,7 @@ krb5_string_to_key_derived(krb5_context context,
        return ret;
     }
     kd.schedule = NULL;
        return ret;
     }
     kd.schedule = NULL;
-    DES3_postproc (context, tmp, keylen, &kd); /* XXX */
+    DES3_random_to_key(context, kd.key, tmp, keylen);
     memset(tmp, 0, keylen);
     free(tmp);
     ret = derive_key(context,
     memset(tmp, 0, keylen);
     free(tmp);
     ret = derive_key(context,
@@ -4263,6 +4271,23 @@ krb5_crypto_overhead (krb5_context context, krb5_crypto crypto)
        return crypto_overhead (context, crypto);
 }
 
        return crypto_overhead (context, crypto);
 }
 
+/**
+ * Converts the random bytestring to a protocol key according to
+ * Kerberos crypto frame work. It may be assumed that all the bits of
+ * the input string are equally random, even though the entropy
+ * present in the random source may be limited.
+ *
+ * @param context Kerberos 5 context
+ * @param type the enctype resulting key will be of
+ * @param data input random data to convert to a key
+ * @param data size of input random data, at least krb5_enctype_keysize() long
+ * @param data key, output key, free with krb5_free_keyblock_contents()
+ *
+ * @return Return an error code or 0.
+ *
+ * @ingroup krb5_crypto
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_random_to_key(krb5_context context,
                   krb5_enctype type,
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_random_to_key(krb5_context context,
                   krb5_enctype type,
@@ -4312,7 +4337,7 @@ _krb5_pk_octetstring2key(krb5_context context,
     size_t keylen, offset;
     void *keydata;
     unsigned char counter;
     size_t keylen, offset;
     void *keydata;
     unsigned char counter;
-    unsigned char shaoutput[20];
+    unsigned char shaoutput[SHA_DIGEST_LENGTH];
 
     if(et == NULL) {
        krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP,
 
     if(et == NULL) {
        krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP,
@@ -4463,9 +4488,9 @@ _krb5_pk_kdf(krb5_context context,
     size_t keylen, offset;
     uint32_t counter;
     unsigned char *keydata;
     size_t keylen, offset;
     uint32_t counter;
     unsigned char *keydata;
-    unsigned char shaoutput[20];
+    unsigned char shaoutput[SHA_DIGEST_LENGTH];
 
 
-    if (der_heim_oid_cmp(oid_id_pkinit_kdf_ah_sha1(), &ai->algorithm) != 0) {
+    if (der_heim_oid_cmp(&asn1_oid_id_pkinit_kdf_ah_sha1, &ai->algorithm) != 0) {
        krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP,
                               N_("KDF not supported", ""));
        return KRB5_PROG_ETYPE_NOSUPP;
        krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP,
                               N_("KDF not supported", ""));
        return KRB5_PROG_ETYPE_NOSUPP;
@@ -4572,118 +4597,131 @@ krb5_crypto_prf(krb5_context context,
     return (*et->prf)(context, crypto, input, output);
 }
 
     return (*et->prf)(context, crypto, input, output);
 }
 
-#ifndef HEIMDAL_SMALLER
+static krb5_error_code
+krb5_crypto_prfplus(krb5_context context,
+                   const krb5_crypto crypto,
+                   const krb5_data *input,
+                   size_t length,
+                   krb5_data *output)
+{
+    krb5_error_code ret;
+    krb5_data input2;
+    unsigned char i = 1;
+    unsigned char *p;
 
 
-static struct key_type *keytypes[] = {
-    &keytype_null,
-    &keytype_des,
-    &keytype_des3_derived,
-#ifdef DES3_OLD_ENCTYPE
-    &keytype_des3,
-#endif
-    &keytype_aes128,
-    &keytype_aes256,
-    &keytype_arcfour
-};
+    krb5_data_zero(&input2);
+    krb5_data_zero(output);
 
 
-static int num_keytypes = sizeof(keytypes) / sizeof(keytypes[0]);
+    krb5_clear_error_message(context);
 
 
+    ret = krb5_data_alloc(output, length);
+    if (ret) goto out;
+    ret = krb5_data_alloc(&input2, input->length + 1);
+    if (ret) goto out;
 
 
-static struct key_type *
-_find_keytype(krb5_keytype type)
-{
-    int i;
-    for(i = 0; i < num_keytypes; i++)
-       if(keytypes[i]->type == type)
-           return keytypes[i];
-    return NULL;
-}
+    krb5_clear_error_message(context);
 
 
-/*
- * First take the configured list of etypes for `keytype' if available,
- * else, do `krb5_keytype_to_enctypes'.
- */
+    memcpy(((unsigned char *)input2.data) + 1, input->data, input->length);
 
 
-krb5_error_code KRB5_LIB_FUNCTION
-krb5_keytype_to_enctypes_default (krb5_context context,
-                                 krb5_keytype keytype,
-                                 unsigned *len,
-                                 krb5_enctype **val)
-    __attribute__((deprecated))
-{
-    unsigned int i, n;
-    krb5_enctype *ret;
+    p = output->data;
 
 
-    if (keytype != KEYTYPE_DES || context->etypes_des == NULL)
-       return krb5_keytype_to_enctypes (context, keytype, len, val);
+    while (length) {
+       krb5_data block;
 
 
-    for (n = 0; context->etypes_des[n]; ++n)
-       ;
-    ret = malloc (n * sizeof(*ret));
-    if (ret == NULL && n != 0) {
-       krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
-       return ENOMEM;
-    }
-    for (i = 0; i < n; ++i)
-       ret[i] = context->etypes_des[i];
-    *len = n;
-    *val = ret;
-    return 0;
-}
+       ((unsigned char *)input2.data)[0] = i++;
 
 
-krb5_error_code KRB5_LIB_FUNCTION
-krb5_keytype_to_string(krb5_context context,
-                      krb5_keytype keytype,
-                      char **string)
-    __attribute__((deprecated))
-{
-    struct key_type *kt = _find_keytype(keytype);
-    if(kt == NULL) {
-       krb5_set_error_message(context, KRB5_PROG_KEYTYPE_NOSUPP,
-                              "key type %d not supported", keytype);
-       return KRB5_PROG_KEYTYPE_NOSUPP;
-    }
-    *string = strdup(kt->name);
-    if(*string == NULL) {
-       krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
-       return ENOMEM;
+       ret = krb5_crypto_prf(context, crypto, &input2, &block);
+       if (ret)
+           goto out;
+
+       if (block.length < length) {
+           memcpy(p, block.data, block.length);
+           length -= block.length;
+       } else {
+           memcpy(p, block.data, length);
+           length = 0;
+       }
+       p += block.length;
+       krb5_data_free(&block);
     }
     }
+
+ out:
+    krb5_data_free(&input2);
+    if (ret)
+       krb5_data_free(output);
     return 0;
 }
 
     return 0;
 }
 
+/**
+ * The FX-CF2 key derivation function, used in FAST and preauth framework.
+ *
+ * @param context Kerberos 5 context
+ * @param crypto1 first key to combine
+ * @param crypto2 second key to combine
+ * @param pepper1 factor to combine with first key to garante uniqueness
+ * @param pepper1 factor to combine with second key to garante uniqueness
+ * @param enctype the encryption type of the resulting key
+ * @param res allocated key, free with krb5_free_keyblock_contents()
+ *
+ * @return Return an error code or 0.
+ *
+ * @ingroup krb5_crypto
+ */
 
 krb5_error_code KRB5_LIB_FUNCTION
 
 krb5_error_code KRB5_LIB_FUNCTION
-krb5_string_to_keytype(krb5_context context,
-                      const char *string,
-                      krb5_keytype *keytype)
-    __attribute__((deprecated))
+krb5_crypto_fx_cf2(krb5_context context,
+                  const krb5_crypto crypto1,
+                  const krb5_crypto crypto2,
+                  krb5_data *pepper1,
+                  krb5_data *pepper2,
+                  krb5_enctype enctype,
+                  krb5_keyblock *res)
 {
 {
-    char *end;
-    int i;
+    krb5_error_code ret;
+    krb5_data os1, os2;
+    size_t i, keysize;
 
 
-    for(i = 0; i < num_keytypes; i++)
-       if(strcasecmp(keytypes[i]->name, string) == 0){
-           *keytype = keytypes[i]->type;
-           return 0;
-       }
+    memset(res, 0, sizeof(*res));
 
 
-    /* check if the enctype is a number */
-    *keytype = strtol(string, &end, 0);
-    if(*end == '\0' && *keytype != 0) {
-       if (krb5_enctype_valid(context, *keytype) == 0)
-           return 0;
+    ret = krb5_enctype_keysize(context, enctype, &keysize);
+    if (ret)
+       return ret;
+
+    ret = krb5_data_alloc(&res->keyvalue, keysize);
+    if (ret)
+       goto out;
+    ret = krb5_crypto_prfplus(context, crypto1, pepper1, keysize, &os1);
+    if (ret)
+       goto out;
+    ret = krb5_crypto_prfplus(context, crypto2, pepper2, keysize, &os2);
+    if (ret)
+       goto out;
+
+    res->keytype = enctype;
+    {
+       unsigned char *p1 = os1.data, *p2 = os2.data, *p3 = res->keyvalue.data;
+       for (i = 0; i < keysize; i++)
+           p3[i] = p1[i] ^ p2[i];
     }
     }
+ out:
+    if (ret)
+       krb5_data_free(&res->keyvalue);
+    krb5_data_free(&os1);
+    krb5_data_free(&os2);
 
 
-    krb5_set_error_message(context, KRB5_PROG_KEYTYPE_NOSUPP,
-                          "key type %s not supported", string);
-    return KRB5_PROG_KEYTYPE_NOSUPP;
+    return ret;
 }
 
 }
 
+
+
+#ifndef HEIMDAL_SMALLER
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_keytype_to_enctypes (krb5_context context,
                          krb5_keytype keytype,
                          unsigned *len,
                          krb5_enctype **val)
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_keytype_to_enctypes (krb5_context context,
                          krb5_keytype keytype,
                          unsigned *len,
                          krb5_enctype **val)
+    KRB5_DEPRECATED
 {
     int i;
     unsigned n = 0;
 {
     int i;
     unsigned n = 0;
@@ -4691,18 +4729,26 @@ krb5_keytype_to_enctypes (krb5_context context,
 
     for (i = num_etypes - 1; i >= 0; --i) {
        if (etypes[i]->keytype->type == keytype
 
     for (i = num_etypes - 1; i >= 0; --i) {
        if (etypes[i]->keytype->type == keytype
-           && !(etypes[i]->flags & F_PSEUDO))
+           && !(etypes[i]->flags & F_PSEUDO)
+           && krb5_enctype_valid(context, etypes[i]->type) == 0)
            ++n;
     }
            ++n;
     }
+    if (n == 0) {
+       krb5_set_error_message(context, KRB5_PROG_KEYTYPE_NOSUPP,
+                              "Keytype have no mapping");
+       return KRB5_PROG_KEYTYPE_NOSUPP;
+    }
+
     ret = malloc(n * sizeof(*ret));
     if (ret == NULL && n != 0) {
     ret = malloc(n * sizeof(*ret));
     if (ret == NULL && n != 0) {
-       krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     n = 0;
     for (i = num_etypes - 1; i >= 0; --i) {
        if (etypes[i]->keytype->type == keytype
        return ENOMEM;
     }
     n = 0;
     for (i = num_etypes - 1; i >= 0; --i) {
        if (etypes[i]->keytype->type == keytype
-           && !(etypes[i]->flags & F_PSEUDO))
+           && !(etypes[i]->flags & F_PSEUDO)
+           && krb5_enctype_valid(context, etypes[i]->type) == 0)
            ret[n++] = etypes[i]->type;
     }
     *len = n;
            ret[n++] = etypes[i]->type;
     }
     *len = n;
@@ -4710,4 +4756,16 @@ krb5_keytype_to_enctypes (krb5_context context,
     return 0;
 }
 
     return 0;
 }
 
+/* if two enctypes have compatible keys */
+krb5_boolean KRB5_LIB_FUNCTION
+krb5_enctypes_compatible_keys(krb5_context context,
+                             krb5_enctype etype1,
+                             krb5_enctype etype2)
+    KRB5_DEPRECATED
+{
+    struct encryption_type *e1 = _find_enctype(etype1);
+    struct encryption_type *e2 = _find_enctype(etype2);
+    return e1 != NULL && e2 != NULL && e1->keytype == e2->keytype;
+}
+
 #endif /* HEIMDAL_SMALLER */
 #endif /* HEIMDAL_SMALLER */
index d6099c3c6c36fe2282379e092197371da0e79a68..993d6058bfba5c7b227eeaa8a9da7f6dd3d97911 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "krb5_locl.h"
 
 
 #include "krb5_locl.h"
 
-RCSID("$Id$");
-
 /**
  * Reset the (potentially uninitalized) krb5_data structure.
  *
 /**
  * Reset the (potentially uninitalized) krb5_data structure.
  *
@@ -52,7 +50,9 @@ krb5_data_zero(krb5_data *p)
 
 /**
  * Free the content of krb5_data structure, its ok to free a zeroed
 
 /**
  * Free the content of krb5_data structure, its ok to free a zeroed
- * structure. When done, the structure will be zeroed.
+ * structure (with memset() or krb5_data_zero()). When done, the
+ * structure will be zeroed. The same function is called
+ * krb5_free_data_contents() in MIT Kerberos.
  *
  * @param p krb5_data to free.
  *
  *
  * @param p krb5_data to free.
  *
@@ -67,21 +67,6 @@ krb5_data_free(krb5_data *p)
     krb5_data_zero(p);
 }
 
     krb5_data_zero(p);
 }
 
-/**
- * Same as krb5_data_free().
- *
- * @param context Kerberos 5 context.
- * @param data krb5_data to free.
- *
- * @ingroup krb5
- */
-
-void KRB5_LIB_FUNCTION
-krb5_free_data_contents(krb5_context context, krb5_data *data)
-{
-    krb5_data_free(data);
-}
-
 /**
  * Free krb5_data (and its content).
  *
 /**
  * Free krb5_data (and its content).
  *
index 594f998e26d31d3dd33645b516edf9db5d19e1c0..499150f4691f839c55c6887cbaa0fc546ac31a4d 100644 (file)
@@ -33,8 +33,6 @@
 
 #include <krb5_locl.h>
 
 
 #include <krb5_locl.h>
 
-RCSID("$Id$");
-
 /**
  * Convert the getaddrinfo() error code to a Kerberos et error code.
  *
 /**
  * Convert the getaddrinfo() error code to a Kerberos et error code.
  *
index 6374fa17aef669c2c91c9aac90d5aae9271e1d2d..829c080a555478cc49bb342691dac9abf33dbb95 100644 (file)
 
 #include "krb5_locl.h"
 
 
 #include "krb5_locl.h"
 
-RCSID("$Id$");
-
 #undef __attribute__
 #undef __attribute__
-#define __attribute__(X)
+#define __attribute__(x)
 
 /**
  * Clears the error message from the Kerberos 5 context.
 
 /**
  * Clears the error message from the Kerberos 5 context.
@@ -172,6 +170,9 @@ krb5_get_error_message(krb5_context context, krb5_error_code code)
     }
     HEIMDAL_MUTEX_unlock(context->mutex);
 
     }
     HEIMDAL_MUTEX_unlock(context->mutex);
 
+    if (code == 0)
+       return strdup("Success");
+
     cstr = krb5_get_err_text(context, code);
     if (cstr)
        return strdup(cstr);
     cstr = krb5_get_err_text(context, code);
     if (cstr)
        return strdup(cstr);
@@ -198,80 +199,3 @@ krb5_free_error_message(krb5_context context, const char *msg)
 {
     free(rk_UNCONST(msg));
 }
 {
     free(rk_UNCONST(msg));
 }
-
-#ifndef HEIMDAL_SMALLER
-
-/**
- * Free the error message returned by krb5_get_error_string(),
- * deprecated, use krb5_free_error_message().
- *
- * @param context Kerberos context
- * @param msg error message to free
- *
- * @ingroup krb5_deprecated
- */
-
-void KRB5_LIB_FUNCTION
-krb5_free_error_string(krb5_context context, char *str)
-    __attribute__((deprecated))
-{
-    krb5_free_error_message(context, str);
-}
-
-/**
- * Set the error message returned by krb5_get_error_string(),
- * deprecated, use krb5_set_error_message().
- *
- * @param context Kerberos context
- * @param msg error message to free
- *
- * @ingroup krb5_deprecated
- */
-
-krb5_error_code KRB5_LIB_FUNCTION
-krb5_set_error_string(krb5_context context, const char *fmt, ...)
-    __attribute__((format (printf, 2, 3))) __attribute__((deprecated))
-{
-    va_list ap;
-
-    va_start(ap, fmt);
-    krb5_vset_error_message (context, 0, fmt, ap);
-    va_end(ap);
-    return 0;
-}
-
-/**
- * Set the error message returned by krb5_get_error_string(),
- * deprecated, use krb5_set_error_message().
- *
- * @param context Kerberos context
- * @param msg error message to free
- *
- * @ingroup krb5_deprecated
- */
-
-krb5_error_code KRB5_LIB_FUNCTION
-krb5_vset_error_string(krb5_context context, const char *fmt, va_list args)
-    __attribute__ ((format (printf, 2, 0))) __attribute__((deprecated))
-{
-    krb5_vset_error_message(context, 0, fmt, args);
-    return 0;
-}
-
-/**
- * Clar the error message returned by krb5_get_error_string(),
- * deprecated, use krb5_clear_error_message().
- *
- * @param context Kerberos context
- *
- * @ingroup krb5_deprecated
- */
-
-void KRB5_LIB_FUNCTION
-krb5_clear_error_string(krb5_context context)
-     __attribute__((deprecated))
-{
-    krb5_clear_error_message(context);
-}
-
-#endif /* !HEIMDAL_SMALLER */
index a712d9c83a17c13355c11f6ac7ee99e26008e0aa..67988d0d7b99739622d3c42b56a005fdec8e7f44 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "krb5_locl.h"
 
 
 #include "krb5_locl.h"
 
-RCSID("$Id$");
-
 static krb5_error_code
 copy_hostname(krb5_context context,
              const char *orig_hostname,
 static krb5_error_code
 copy_hostname(krb5_context context,
              const char *orig_hostname,
@@ -50,9 +48,19 @@ copy_hostname(krb5_context context,
     return 0;
 }
 
     return 0;
 }
 
-/*
- * Try to make `orig_hostname' into a more canonical one in the newly
- * allocated space returned in `new_hostname'.
+/**
+ * krb5_expand_hostname() tries to make orig_hostname into a more
+ * canonical one in the newly allocated space returned in
+ * new_hostname.
+
+ * @param context a Keberos context
+ * @param orig_hostname hostname to canonicalise.
+ * @param new_hostname output hostname, caller must free hostname with
+ *        krb5_xfree().
+ *
+ * @return Return an error code or 0, see krb5_get_error_message().
+ *
+ * @ingroup krb5_support
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
@@ -114,9 +122,22 @@ vanilla_hostname (krb5_context context,
     return 0;
 }
 
     return 0;
 }
 
-/*
- * expand `hostname' to a name we believe to be a hostname in newly
- * allocated space in `host' and return realms in `realms'.
+/**
+ * krb5_expand_hostname_realms() expands orig_hostname to a name we
+ * believe to be a hostname in newly allocated space in new_hostname
+ * and return the realms new_hostname is believed to belong to in
+ * realms.
+ *
+ * @param context a Keberos context
+ * @param orig_hostname hostname to canonicalise.
+ * @param new_hostname output hostname, caller must free hostname with
+ *        krb5_xfree().
+ * @param realms output possible realms, is an array that is terminated
+ *        with NULL. Caller must free with krb5_free_host_realm().
+ *
+ * @return Return an error code or 0, see krb5_get_error_message().
+ *
+ * @ingroup krb5_support
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
index b745c67e11daca70a0308beef5ef45122ad25cf7..f8e74f1ddc1c1964a1290fe717b388f1098dab76 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "krb5_locl.h"
 
 
 #include "krb5_locl.h"
 
-RCSID("$Id$");
-
 typedef struct krb5_fcache{
     char *filename;
     int version;
 typedef struct krb5_fcache{
     char *filename;
     int version;
@@ -233,8 +231,8 @@ scrub_file (int fd)
  * hardlink)
  */
 
  * hardlink)
  */
 
-static krb5_error_code
-erase_file(krb5_context context, const char *filename)
+krb5_error_code
+_krb5_erase_file(krb5_context context, const char *filename)
 {
     int fd;
     struct stat sb1, sb2;
 {
     int fd;
     struct stat sb1, sb2;
@@ -453,7 +451,7 @@ static krb5_error_code
 fcc_destroy(krb5_context context,
            krb5_ccache id)
 {
 fcc_destroy(krb5_context context,
            krb5_ccache id)
 {
-    erase_file(context, FILENAME(id));
+    _krb5_erase_file(context, FILENAME(id));
     return 0;
 }
 
     return 0;
 }
 
@@ -740,8 +738,10 @@ fcc_remove_cred(krb5_context context,
 {
     krb5_error_code ret;
     krb5_ccache copy, newfile;
 {
     krb5_error_code ret;
     krb5_ccache copy, newfile;
+    char *newname;
+    int fd;
 
 
-    ret = krb5_cc_gen_new(context, &krb5_mcc_ops, &copy);
+    ret = krb5_cc_new_unique(context, krb5_cc_type_memory, NULL, &copy);
     if (ret)
        return ret;
 
     if (ret)
        return ret;
 
@@ -757,8 +757,24 @@ fcc_remove_cred(krb5_context context,
        return ret;
     }
 
        return ret;
     }
 
-    ret = krb5_cc_gen_new(context, &krb5_fcc_ops, &newfile);
+    asprintf(&newname, "FILE:%s.XXXXXX", FILENAME(id));
+    if (newname == NULL) {
+       krb5_cc_destroy(context, copy);
+       return ret;
+    }
+
+    fd = mkstemp(&newname[5]);
+    if (fd < 0) {
+       ret = errno;
+       krb5_cc_destroy(context, copy);
+       return ret;
+    }
+    close(fd);
+
+    ret = krb5_cc_resolve(context, newname, &newfile);
     if (ret) {
     if (ret) {
+       unlink(&newname[5]);
+       free(newname);
        krb5_cc_destroy(context, copy);
        return ret;
     }
        krb5_cc_destroy(context, copy);
        return ret;
     }
@@ -766,11 +782,18 @@ fcc_remove_cred(krb5_context context,
     ret = krb5_cc_copy_cache(context, copy, newfile);
     krb5_cc_destroy(context, copy);
     if (ret) {
     ret = krb5_cc_copy_cache(context, copy, newfile);
     krb5_cc_destroy(context, copy);
     if (ret) {
+       free(newname);
        krb5_cc_destroy(context, newfile);
        return ret;
     }
 
        krb5_cc_destroy(context, newfile);
        return ret;
     }
 
-    return krb5_cc_move(context, newfile, id);
+    ret = rename(&newname[5], FILENAME(id));
+    if (ret)
+       ret = errno;
+    free(newname);
+    krb5_cc_close(context, newfile);
+
+    return ret;
 }
 
 static krb5_error_code
 }
 
 static krb5_error_code
@@ -822,12 +845,13 @@ fcc_get_cache_next(krb5_context context, krb5_cc_cursor cursor, krb5_ccache *id)
     iter->first = 0;
 
     fn = krb5_cc_default_name(context);
     iter->first = 0;
 
     fn = krb5_cc_default_name(context);
-    if (strncasecmp(fn, "FILE:", 5) != 0) {
+    if (fn == NULL || strncasecmp(fn, "FILE:", 5) != 0) {
        ret = _krb5_expand_default_cc_name(context,
                                           KRB5_DEFAULT_CCNAME_FILE,
                                           &expandedfn);
        if (ret)
            return ret;
        ret = _krb5_expand_default_cc_name(context,
                                           KRB5_DEFAULT_CCNAME_FILE,
                                           &expandedfn);
        if (ret)
            return ret;
+       fn = expandedfn;
     }
     ret = krb5_cc_resolve(context, fn, id);
     if (expandedfn)
     }
     ret = krb5_cc_resolve(context, fn, id);
     if (expandedfn)
@@ -900,10 +924,10 @@ fcc_move(krb5_context context, krb5_ccache from, krb5_ccache to)
        fcc_unlock(context, fd1);
        close(fd1);
 
        fcc_unlock(context, fd1);
        close(fd1);
 
-       erase_file(context, FILENAME(from));
+       _krb5_erase_file(context, FILENAME(from));
 
        if (ret) {
 
        if (ret) {
-           erase_file(context, FILENAME(to));
+           _krb5_erase_file(context, FILENAME(to));
            return ret;
        }
     }
            return ret;
        }
     }
@@ -913,10 +937,14 @@ fcc_move(krb5_context context, krb5_ccache from, krb5_ccache to)
        krb5_storage *sp;
        int fd;
        ret = init_fcc (context, to, &sp, &fd);
        krb5_storage *sp;
        int fd;
        ret = init_fcc (context, to, &sp, &fd);
-       krb5_storage_free(sp);
+       if (sp)
+           krb5_storage_free(sp);
        fcc_unlock(context, fd);
        close(fd);
     }
        fcc_unlock(context, fd);
        close(fd);
     }
+
+    fcc_destroy(context, from);
+
     return ret;
 }
 
     return ret;
 }
 
index da1eb1de1c5f8bd33ae5f5f9495e56353dffb82f..7f4374374be6d89b07235b36406bd1450cd0ebc6 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "krb5_locl.h"
 
 
 #include "krb5_locl.h"
 
-RCSID("$Id$");
-
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_free_kdc_rep(krb5_context context, krb5_kdc_rep *rep)
 {
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_free_kdc_rep(krb5_context context, krb5_kdc_rep *rep)
 {
index 581b61a15b3b28f3c044255ef5f51c682794f383..f6e9f6e2472663257f1d63f04a9b5c7a62c061fe 100644 (file)
 
 #include "krb5_locl.h"
 
 
 #include "krb5_locl.h"
 
-RCSID("$Id$");
-
-/*
+/**
  * Free all memory allocated by `realmlist'
  * Free all memory allocated by `realmlist'
+ *
+ * @param context A Kerberos 5 context.
+ * @param realmlist realmlist to free, NULL is ok
+ *
+ * @return a Kerberos error code, always 0.
+ *
+ * @ingroup krb5_support
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
index 99745b830539de0c63905c46745573b5a1b5c5b3..2764f1a9144fa29c1f1104bf23dcda90610c1300 100644 (file)
@@ -33,8 +33,6 @@
 
 #include <krb5_locl.h>
 
 
 #include <krb5_locl.h>
 
-RCSID("$Id$");
-
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_generate_seq_number(krb5_context context,
                         const krb5_keyblock *key,
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_generate_seq_number(krb5_context context,
                         const krb5_keyblock *key,
index 4ab4b9bf6c89221ed81170bc51c92647561255d5..efb6cce28848ae8f4bffd8d8d2c47bf7e949ce7f 100644 (file)
@@ -33,8 +33,6 @@
 
 #include <krb5_locl.h>
 
 
 #include <krb5_locl.h>
 
-RCSID("$Id$");
-
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_generate_subkey(krb5_context context,
                     const krb5_keyblock *key,
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_generate_subkey(krb5_context context,
                     const krb5_keyblock *key,
index ce167853192ac0c43eda16f1b736c320a9d44ed5..8f366fa1487dc7d9ea3eebb5be5936c88c54cdff 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "krb5_locl.h"
 
 
 #include "krb5_locl.h"
 
-RCSID("$Id: get_addrs.c 23815 2008-09-13 09:21:03Z lha $");
-
 #ifdef __osf__
 /* hate */
 struct rtentry;
 #ifdef __osf__
 /* hate */
 struct rtentry;
@@ -43,9 +41,7 @@ struct mbuf;
 #ifdef HAVE_NET_IF_H
 #include <net/if.h>
 #endif
 #ifdef HAVE_NET_IF_H
 #include <net/if.h>
 #endif
-#ifdef HAVE_IFADDR_H
 #include <ifaddrs.h>
 #include <ifaddrs.h>
-#endif
 
 static krb5_error_code
 gethostname_fallback (krb5_context context, krb5_addresses *res)
 
 static krb5_error_code
 gethostname_fallback (krb5_context context, krb5_addresses *res)
@@ -106,8 +102,6 @@ find_all_addresses (krb5_context context, krb5_addresses *res, int flags)
     unsigned int num, idx;
     krb5_addresses ignore_addresses;
 
     unsigned int num, idx;
     krb5_addresses ignore_addresses;
 
-    res->val = NULL;
-
     if (getifaddrs(&ifa0) == -1) {
        ret = errno;
        krb5_set_error_message(context, ret, "getifaddrs: %s", strerror(ret));
     if (getifaddrs(&ifa0) == -1) {
        ret = errno;
        krb5_set_error_message(context, ret, "getifaddrs: %s", strerror(ret));
@@ -232,13 +226,14 @@ get_addrs_int (krb5_context context, krb5_addresses *res, int flags)
 {
     krb5_error_code ret = -1;
 
 {
     krb5_error_code ret = -1;
 
+    res->len = 0;
+    res->val = NULL;
+
     if (flags & SCAN_INTERFACES) {
        ret = find_all_addresses (context, res, flags);
        if(ret || res->len == 0)
            ret = gethostname_fallback (context, res);
     } else {
     if (flags & SCAN_INTERFACES) {
        ret = find_all_addresses (context, res, flags);
        if(ret || res->len == 0)
            ret = gethostname_fallback (context, res);
     } else {
-       res->len = 0;
-       res->val = NULL;
        ret = 0;
     }
 
        ret = 0;
     }
 
index 97e0022ee12f5a3cd3da8194c45d152b8b12b0ff..e609bcadcca560e7a9ac0f5920f811f0b45ba29c 100644 (file)
@@ -33,8 +33,6 @@
 
 #include <krb5_locl.h>
 
 
 #include <krb5_locl.h>
 
-RCSID("$Id$");
-
 /*
  * Take the `body' and encode it into `padata' using the credentials
  * in `creds'.
 /*
  * Take the `body' and encode it into `padata' using the credentials
  * in `creds'.
@@ -375,17 +373,18 @@ decrypt_tkt_with_subkey (krb5_context context,
     if (ret)
        return ret;
 
     if (ret)
        return ret;
 
-    ret = krb5_decode_EncASRepPart(context,
-                                  data.data,
+    ret = decode_EncASRepPart(data.data,
+                             data.length,
+                             &dec_rep->enc_part,
+                             &size);
+    if (ret)
+       ret = decode_EncTGSRepPart(data.data,
                                   data.length,
                                   &dec_rep->enc_part,
                                   &size);
     if (ret)
                                   data.length,
                                   &dec_rep->enc_part,
                                   &size);
     if (ret)
-       ret = krb5_decode_EncTGSRepPart(context,
-                                       data.data,
-                                       data.length,
-                                       &dec_rep->enc_part,
-                                       &size);
+      krb5_set_error_message(context, ret, 
+                            N_("Failed to decode encpart in ticket", ""));
     krb5_data_free (&data);
     return ret;
 }
     krb5_data_free (&data);
     return ret;
 }
@@ -477,7 +476,7 @@ get_cred_kdc(krb5_context context,
        if (len != size)
            krb5_abortx(context, "internal asn1 error");
        
        if (len != size)
            krb5_abortx(context, "internal asn1 error");
        
-       ret = krb5_padata_add(context, &padata, KRB5_PADATA_S4U2SELF, buf, len);
+       ret = krb5_padata_add(context, &padata, KRB5_PADATA_FOR_USER, buf, len);
        if (ret)
            goto out;
     }
        if (ret)
            goto out;
     }
@@ -561,7 +560,7 @@ get_cred_kdc(krb5_context context,
     } else if(krb5_rd_error(context, &resp, &error) == 0) {
        ret = krb5_error_from_rd_error(context, &error, in_creds);
        krb5_free_error_contents(context, &error);
     } else if(krb5_rd_error(context, &resp, &error) == 0) {
        ret = krb5_error_from_rd_error(context, &error, in_creds);
        krb5_free_error_contents(context, &error);
-    } else if(resp.data && ((char*)resp.data)[0] == 4) {
+    } else if(resp.length > 0 && ((char*)resp.data)[0] == 4) {
        ret = KRB5KRB_AP_ERR_V4_REPLY;
        krb5_clear_error_message(context);
     } else {
        ret = KRB5KRB_AP_ERR_V4_REPLY;
        krb5_clear_error_message(context);
     } else {
@@ -1217,6 +1216,10 @@ krb5_get_creds_opt_free(krb5_context context, krb5_get_creds_opt opt)
 {
     if (opt->self)
        krb5_free_principal(context, opt->self);
 {
     if (opt->self)
        krb5_free_principal(context, opt->self);
+    if (opt->ticket) {
+       free_Ticket(opt->ticket);
+       free(opt->ticket);
+    }
     memset(opt, 0, sizeof(*opt));
     free(opt);
 }
     memset(opt, 0, sizeof(*opt));
     free(opt);
 }
index c804ab9e56128b7bd92f08247c8d381bfb0c927c..82d0642934f909c2b0476093b5e19c3398a80474 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "krb5_locl.h"
 
 
 #include "krb5_locl.h"
 
-RCSID("$Id$");
-
 /*
  * Try to find out what's a reasonable default principal.
  */
 /*
  * Try to find out what's a reasonable default principal.
  */
index a2518bbab731984010adfc61612fd0460a84efdf..f09df264c176b0865de9d13b93075bccba162884 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "krb5_locl.h"
 
 
 #include "krb5_locl.h"
 
-RCSID("$Id$");
-
 /*
  * Return a NULL-terminated list of default realms in `realms'.
  * Free this memory with krb5_free_host_realm.
 /*
  * Return a NULL-terminated list of default realms in `realms'.
  * Free this memory with krb5_free_host_realm.
index a7072a013605306cb15d4c6421cb6b0ef0b099ba..19e48173df92b0d17873c406286257033504c76e 100644 (file)
@@ -33,8 +33,6 @@
 
 #include <krb5_locl.h>
 
 
 #include <krb5_locl.h>
 
-RCSID("$Id$");
-
 static krb5_error_code
 add_addrs(krb5_context context,
          krb5_addresses *addr,
 static krb5_error_code
 add_addrs(krb5_context context,
          krb5_addresses *addr,
index 2ea075f6c5d5a77abb0cd08fc46c399c28ee0a40..7d7fef6e1caf9592b7e1a4b697545ef04a3d54f7 100644 (file)
@@ -34,8 +34,6 @@
 #include "krb5_locl.h"
 #include <resolve.h>
 
 #include "krb5_locl.h"
 #include <resolve.h>
 
-RCSID("$Id$");
-
 /* To automagically find the correct realm of a host (without
  * [domain_realm] in krb5.conf) add a text record for your domain with
  * the name of your realm, like this:
 /* To automagically find the correct realm of a host (without
  * [domain_realm] in krb5.conf) add a text record for your domain with
  * the name of your realm, like this:
@@ -51,14 +49,14 @@ RCSID("$Id$");
  */
 
 static int
  */
 
 static int
-copy_txt_to_realms (struct resource_record *head,
+copy_txt_to_realms (struct rk_resource_record *head,
                    krb5_realm **realms)
 {
                    krb5_realm **realms)
 {
-    struct resource_record *rr;
+    struct rk_resource_record *rr;
     unsigned int n, i;
 
     for(n = 0, rr = head; rr; rr = rr->next)
     unsigned int n, i;
 
     for(n = 0, rr = head; rr; rr = rr->next)
-       if (rr->type == T_TXT)
+       if (rr->type == rk_ns_t_txt)
            ++n;
 
     if (n == 0)
            ++n;
 
     if (n == 0)
@@ -72,7 +70,7 @@ copy_txt_to_realms (struct resource_record *head,
        (*realms)[i] = NULL;
 
     for (i = 0, rr = head; rr; rr = rr->next) {
        (*realms)[i] = NULL;
 
     for (i = 0, rr = head; rr; rr = rr->next) {
-       if (rr->type == T_TXT) {
+       if (rr->type == rk_ns_t_txt) {
            char *tmp;
 
            tmp = strdup(rr->u.txt);
            char *tmp;
 
            tmp = strdup(rr->u.txt);
@@ -96,7 +94,7 @@ dns_find_realm(krb5_context context,
 {
     static const char *default_labels[] = { "_kerberos", NULL };
     char dom[MAXHOSTNAMELEN];
 {
     static const char *default_labels[] = { "_kerberos", NULL };
     char dom[MAXHOSTNAMELEN];
-    struct dns_reply *r;
+    struct rk_dns_reply *r;
     const char **labels;
     char **config_labels;
     int i, ret;
     const char **labels;
     char **config_labels;
     int i, ret;
@@ -116,10 +114,10 @@ dns_find_realm(krb5_context context,
                krb5_config_free_strings(config_labels);
            return -1;
        }
                krb5_config_free_strings(config_labels);
            return -1;
        }
-       r = dns_lookup(dom, "TXT");
+       r = rk_dns_lookup(dom, "TXT");
        if(r != NULL) {
            ret = copy_txt_to_realms (r->head, realms);
        if(r != NULL) {
            ret = copy_txt_to_realms (r->head, realms);
-           dns_free_data(r);
+           rk_dns_free_data(r);
            if(ret == 0) {
                if (config_labels)
                    krb5_config_free_strings(config_labels);
            if(ret == 0) {
                if (config_labels)
                    krb5_config_free_strings(config_labels);
index cc49e16030cbb4f78d50770dcba47dceb615ff3e..84b1ffb71f581d0f5d70f90c667ae31920c66553 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "krb5_locl.h"
-
-RCSID("$Id$");
-
-krb5_error_code KRB5_LIB_FUNCTION
-krb5_init_etype (krb5_context context,
-                unsigned *len,
-                krb5_enctype **val,
-                const krb5_enctype *etypes)
-{
-    unsigned int i;
-    krb5_error_code ret;
-    krb5_enctype *tmp = NULL;
-
-    ret = 0;
-    if (etypes == NULL) {
-       ret = krb5_get_default_in_tkt_etypes(context,
-                                            &tmp);
-       if (ret)
-           return ret;
-       etypes = tmp;
-    }
-
-    for (i = 0; etypes[i]; ++i)
-       ;
-    *len = i;
-    *val = malloc(i * sizeof(**val));
-    if (i != 0 && *val == NULL) {
-       ret = ENOMEM;
-       krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
-       goto cleanup;
-    }
-    memmove (*val,
-            etypes,
-            i * sizeof(*tmp));
-cleanup:
-    if (tmp != NULL)
-       free (tmp);
-    return ret;
-}
-
-static krb5_error_code
-check_server_referral(krb5_context context,
-                     krb5_kdc_rep *rep,
-                     unsigned flags,
-                     krb5_const_principal requested,
-                     krb5_const_principal returned,
-                     const krb5_keyblock const * key)
-{
-    krb5_error_code ret;
-    PA_ServerReferralData ref;
-    krb5_crypto session;
-    EncryptedData ed;
-    size_t len;
-    krb5_data data;
-    PA_DATA *pa;
-    int i = 0, cmp;
-
-    if (rep->kdc_rep.padata == NULL)
-       goto noreferral;
-
-    pa = krb5_find_padata(rep->kdc_rep.padata->val,
-                         rep->kdc_rep.padata->len,
-                         KRB5_PADATA_SERVER_REFERRAL, &i);
-    if (pa == NULL)
-       goto noreferral;
-
-    memset(&ed, 0, sizeof(ed));
-    memset(&ref, 0, sizeof(ref));
-
-    ret = decode_EncryptedData(pa->padata_value.data,
-                              pa->padata_value.length,
-                              &ed, &len);
-    if (ret)
-       return ret;
-    if (len != pa->padata_value.length) {
-       free_EncryptedData(&ed);
-       krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED,
-                              N_("Referral EncryptedData wrong for realm %s",
-                                 "realm"), requested->realm);
-       return KRB5KRB_AP_ERR_MODIFIED;
-    }
-
-    ret = krb5_crypto_init(context, key, 0, &session);
-    if (ret) {
-       free_EncryptedData(&ed);
-       return ret;
-    }
-
-    ret = krb5_decrypt_EncryptedData(context, session,
-                                    KRB5_KU_PA_SERVER_REFERRAL,
-                                    &ed, &data);
-    free_EncryptedData(&ed);
-    krb5_crypto_destroy(context, session);
-    if (ret)
-       return ret;
-
-    ret = decode_PA_ServerReferralData(data.data, data.length, &ref, &len);
-    if (ret) {
-       krb5_data_free(&data);
-       return ret;
-    }
-    krb5_data_free(&data);
-
-    if (strcmp(requested->realm, returned->realm) != 0) {
-       free_PA_ServerReferralData(&ref);
-       krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED,
-                              N_("server ref realm mismatch, "
-                                 "requested realm %s got back %s", ""),
-                              requested->realm, returned->realm);
-       return KRB5KRB_AP_ERR_MODIFIED;
-    }
-
-    if (returned->name.name_string.len == 2 &&
-       strcmp(returned->name.name_string.val[0], KRB5_TGS_NAME) == 0)
-    {
-       const char *realm = returned->name.name_string.val[1];
-
-       if (ref.referred_realm == NULL
-           || strcmp(*ref.referred_realm, realm) != 0)
-       {
-           free_PA_ServerReferralData(&ref);
-           krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED,
-                                  N_("tgt returned with wrong ref", ""));
-           return KRB5KRB_AP_ERR_MODIFIED;
-       }
-    } else if (krb5_principal_compare(context, returned, requested) == 0) {
-       free_PA_ServerReferralData(&ref);
-       krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED,
-                              N_("req princ no same as returned", ""));
-       return KRB5KRB_AP_ERR_MODIFIED;
-    }
-
-    if (ref.requested_principal_name) {
-       cmp = _krb5_principal_compare_PrincipalName(context,
-                                                   requested,
-                                                   ref.requested_principal_name);
-       if (!cmp) {
-           free_PA_ServerReferralData(&ref);
-           krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED,
-                                  N_("referred principal not same "
-                                     "as requested", ""));
-           return KRB5KRB_AP_ERR_MODIFIED;
-       }
-    } else if (flags & EXTRACT_TICKET_AS_REQ) {
-       free_PA_ServerReferralData(&ref);
-       krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED,
-                              N_("Requested principal missing on AS-REQ", ""));
-       return KRB5KRB_AP_ERR_MODIFIED;
-    }
-
-    free_PA_ServerReferralData(&ref);
-
-    return ret;
-noreferral:
-    if (krb5_principal_compare(context, requested, returned) == FALSE) {
-       krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED,
-                              N_("Not same server principal returned "
-                                 "as requested", ""));
-       return KRB5KRB_AP_ERR_MODIFIED;
-    }
-    return 0;
-}
-
-
-/*
- * Verify referral data
- */
-
-
-static krb5_error_code
-check_client_referral(krb5_context context,
-                     krb5_kdc_rep *rep,
-                     krb5_const_principal requested,
-                     krb5_const_principal mapped,
-                     krb5_keyblock const * key)
-{
-    krb5_error_code ret;
-    PA_ClientCanonicalized canon;
-    krb5_crypto crypto;
-    krb5_data data;
-    PA_DATA *pa;
-    size_t len;
-    int i = 0;
-
-    if (rep->kdc_rep.padata == NULL)
-       goto noreferral;
-
-    pa = krb5_find_padata(rep->kdc_rep.padata->val,
-                         rep->kdc_rep.padata->len,
-                         KRB5_PADATA_CLIENT_CANONICALIZED, &i);
-    if (pa == NULL)
-       goto noreferral;
-
-    ret = decode_PA_ClientCanonicalized(pa->padata_value.data,
-                                       pa->padata_value.length,
-                                       &canon, &len);
-    if (ret) {
-       krb5_set_error_message(context, ret,
-                              N_("Failed to decode ClientCanonicalized "
-                                 "from realm %s", ""), requested->realm);
-       return ret;
-    }
-
-    ASN1_MALLOC_ENCODE(PA_ClientCanonicalizedNames, data.data, data.length,
-                      &canon.names, &len, ret);
-    if (ret) {
-       free_PA_ClientCanonicalized(&canon);
-       return ret;
-    }
-    if (data.length != len)
-       krb5_abortx(context, "internal asn.1 error");
-
-    ret = krb5_crypto_init(context, key, 0, &crypto);
-    if (ret) {
-       free(data.data);
-       free_PA_ClientCanonicalized(&canon);
-       return ret;
-    }
-
-    ret = krb5_verify_checksum(context, crypto, KRB5_KU_CANONICALIZED_NAMES,
-                              data.data, data.length,
-                              &canon.canon_checksum);
-    krb5_crypto_destroy(context, crypto);
-    free(data.data);
-    if (ret) {
-       krb5_set_error_message(context, ret,
-                              N_("Failed to verify client canonicalized "
-                                 "data from realm %s", ""),
-                              requested->realm);
-       free_PA_ClientCanonicalized(&canon);
-       return ret;
-    }
-
-    if (!_krb5_principal_compare_PrincipalName(context,
-                                              requested,
-                                              &canon.names.requested_name))
-    {
-       free_PA_ClientCanonicalized(&canon);
-       krb5_set_error_message(context, KRB5_PRINC_NOMATCH,
-                              N_("Requested name doesn't match"
-                                 " in client referral", ""));
-       return KRB5_PRINC_NOMATCH;
-    }
-    if (!_krb5_principal_compare_PrincipalName(context,
-                                              mapped,
-                                              &canon.names.mapped_name))
-    {
-       free_PA_ClientCanonicalized(&canon);
-       krb5_set_error_message(context, KRB5_PRINC_NOMATCH,
-                              N_("Mapped name doesn't match"
-                                 " in client referral", ""));
-       return KRB5_PRINC_NOMATCH;
-    }
-
-    return 0;
-
-noreferral:
-    if (krb5_principal_compare(context, requested, mapped) == FALSE) {
-       krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED,
-                              N_("Not same client principal returned "
-                                 "as requested", ""));
-       return KRB5KRB_AP_ERR_MODIFIED;
-    }
-    return 0;
-}
-
-
+#define KRB5_DEPRECATED
 
 
-static krb5_error_code
-decrypt_tkt (krb5_context context,
-            krb5_keyblock *key,
-            krb5_key_usage usage,
-            krb5_const_pointer decrypt_arg,
-            krb5_kdc_rep *dec_rep)
-{
-    krb5_error_code ret;
-    krb5_data data;
-    size_t size;
-    krb5_crypto crypto;
-
-    ret = krb5_crypto_init(context, key, 0, &crypto);
-    if (ret)
-       return ret;
-
-    ret = krb5_decrypt_EncryptedData (context,
-                                     crypto,
-                                     usage,
-                                     &dec_rep->kdc_rep.enc_part,
-                                     &data);
-    krb5_crypto_destroy(context, crypto);
-
-    if (ret)
-       return ret;
-
-    ret = krb5_decode_EncASRepPart(context,
-                                  data.data,
-                                  data.length,
-                                  &dec_rep->enc_part,
-                                  &size);
-    if (ret)
-       ret = krb5_decode_EncTGSRepPart(context,
-                                       data.data,
-                                       data.length,
-                                       &dec_rep->enc_part,
-                                       &size);
-    krb5_data_free (&data);
-    if (ret)
-       return ret;
-    return 0;
-}
-
-int
-_krb5_extract_ticket(krb5_context context,
-                    krb5_kdc_rep *rep,
-                    krb5_creds *creds,
-                    krb5_keyblock *key,
-                    krb5_const_pointer keyseed,
-                    krb5_key_usage key_usage,
-                    krb5_addresses *addrs,
-                    unsigned nonce,
-                    unsigned flags,
-                    krb5_decrypt_proc decrypt_proc,
-                    krb5_const_pointer decryptarg)
-{
-    krb5_error_code ret;
-    krb5_principal tmp_principal;
-    size_t len;
-    time_t tmp_time;
-    krb5_timestamp sec_now;
-
-    /* decrypt */
-
-    if (decrypt_proc == NULL)
-       decrypt_proc = decrypt_tkt;
-
-    ret = (*decrypt_proc)(context, key, key_usage, decryptarg, rep);
-    if (ret)
-       goto out;
-
-    /* save session key */
-
-    creds->session.keyvalue.length = 0;
-    creds->session.keyvalue.data   = NULL;
-    creds->session.keytype = rep->enc_part.key.keytype;
-    ret = krb5_data_copy (&creds->session.keyvalue,
-                         rep->enc_part.key.keyvalue.data,
-                         rep->enc_part.key.keyvalue.length);
-    if (ret) {
-       krb5_clear_error_message(context);
-       goto out;
-    }
-
-    /*
-     * HACK:
-     * this is really a ugly hack, to support using the Netbios Domain Name
-     * as realm against windows KDC's, they always return the full realm
-     * based on the DNS Name.
-     */
-    flags |= EXTRACT_TICKET_ALLOW_SERVER_MISMATCH;
-    flags |= EXTRACT_TICKET_ALLOW_CNAME_MISMATCH;
-
-   /* compare client and save */
-    ret = _krb5_principalname2krb5_principal (context,
-                                             &tmp_principal,
-                                             rep->kdc_rep.cname,
-                                             rep->kdc_rep.crealm);
-    if (ret)
-       goto out;
-
-    /* check client referral and save principal */
-    /* anonymous here ? */
-    if((flags & EXTRACT_TICKET_ALLOW_CNAME_MISMATCH) == 0) {
-       ret = check_client_referral(context, rep,
-                                   creds->client,
-                                   tmp_principal,
-                                   &creds->session);
-       if (ret) {
-           krb5_free_principal (context, tmp_principal);
-           goto out;
-       }
-    }
-    krb5_free_principal (context, creds->client);
-    creds->client = tmp_principal;
-
-    /* check server referral and save principal */
-    ret = _krb5_principalname2krb5_principal (context,
-                                             &tmp_principal,
-                                             rep->kdc_rep.ticket.sname,
-                                             rep->kdc_rep.ticket.realm);
-    if (ret)
-       goto out;
-    if((flags & EXTRACT_TICKET_ALLOW_SERVER_MISMATCH) == 0){
-       ret = check_server_referral(context,
-                                   rep,
-                                   flags,
-                                   creds->server,
-                                   tmp_principal,
-                                   &creds->session);
-       if (ret) {
-           krb5_free_principal (context, tmp_principal);
-           goto out;
-       }
-    }
-    krb5_free_principal(context, creds->server);
-    creds->server = tmp_principal;
-
-    /* verify names */
-    if(flags & EXTRACT_TICKET_MATCH_REALM){
-       const char *srealm = krb5_principal_get_realm(context, creds->server);
-       const char *crealm = krb5_principal_get_realm(context, creds->client);
-
-       if (strcmp(rep->enc_part.srealm, srealm) != 0 ||
-           strcmp(rep->enc_part.srealm, crealm) != 0)
-       {
-           ret = KRB5KRB_AP_ERR_MODIFIED;
-           krb5_clear_error_message(context);
-           goto out;
-       }
-    }
-
-    /* compare nonces */
-
-    if (nonce != rep->enc_part.nonce) {
-       ret = KRB5KRB_AP_ERR_MODIFIED;
-       krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
-       goto out;
-    }
-
-    /* set kdc-offset */
-
-    krb5_timeofday (context, &sec_now);
-    if (rep->enc_part.flags.initial
-       && context->kdc_sec_offset == 0
-       && krb5_config_get_bool (context, NULL,
-                                "libdefaults",
-                                "kdc_timesync",
-                                NULL)) {
-       context->kdc_sec_offset = rep->enc_part.authtime - sec_now;
-       krb5_timeofday (context, &sec_now);
-    }
-
-    /* check all times */
-
-    if (rep->enc_part.starttime) {
-       tmp_time = *rep->enc_part.starttime;
-    } else
-       tmp_time = rep->enc_part.authtime;
-
-    if (creds->times.starttime == 0
-       && abs(tmp_time - sec_now) > context->max_skew) {
-       ret = KRB5KRB_AP_ERR_SKEW;
-       krb5_set_error_message (context, ret,
-                               N_("time skew (%d) larger than max (%d)", ""),
-                              abs(tmp_time - sec_now),
-                              (int)context->max_skew);
-       goto out;
-    }
-
-    if (creds->times.starttime != 0
-       && tmp_time != creds->times.starttime) {
-       krb5_clear_error_message (context);
-       ret = KRB5KRB_AP_ERR_MODIFIED;
-       goto out;
-    }
-
-    creds->times.starttime = tmp_time;
-
-    if (rep->enc_part.renew_till) {
-       tmp_time = *rep->enc_part.renew_till;
-    } else
-       tmp_time = 0;
-
-    if (creds->times.renew_till != 0
-       && tmp_time > creds->times.renew_till) {
-       krb5_clear_error_message (context);
-       ret = KRB5KRB_AP_ERR_MODIFIED;
-       goto out;
-    }
-
-    creds->times.renew_till = tmp_time;
-
-    creds->times.authtime = rep->enc_part.authtime;
-
-    if (creds->times.endtime != 0
-       && rep->enc_part.endtime > creds->times.endtime) {
-       krb5_clear_error_message (context);
-       ret = KRB5KRB_AP_ERR_MODIFIED;
-       goto out;
-    }
-
-    creds->times.endtime  = rep->enc_part.endtime;
-
-    if(rep->enc_part.caddr)
-       krb5_copy_addresses (context, rep->enc_part.caddr, &creds->addresses);
-    else if(addrs)
-       krb5_copy_addresses (context, addrs, &creds->addresses);
-    else {
-       creds->addresses.len = 0;
-       creds->addresses.val = NULL;
-    }
-    creds->flags.b = rep->enc_part.flags;
-       
-    creds->authdata.len = 0;
-    creds->authdata.val = NULL;
-
-    /* extract ticket */
-    ASN1_MALLOC_ENCODE(Ticket, creds->ticket.data, creds->ticket.length,
-                      &rep->kdc_rep.ticket, &len, ret);
-    if(ret)
-       goto out;
-    if (creds->ticket.length != len)
-       krb5_abortx(context, "internal error in ASN.1 encoder");
-    creds->second_ticket.length = 0;
-    creds->second_ticket.data   = NULL;
-
-
-out:
-    memset (rep->enc_part.key.keyvalue.data, 0,
-           rep->enc_part.key.keyvalue.length);
-    return ret;
-}
+#include "krb5_locl.h"
 
 
+#ifndef HEIMDAL_SMALLER
 
 static krb5_error_code
 make_pa_enc_timestamp(krb5_context context, PA_DATA *pa,
 
 static krb5_error_code
 make_pa_enc_timestamp(krb5_context context, PA_DATA *pa,
@@ -626,6 +108,8 @@ add_padata(krb5_context context,
     if(salt == NULL) {
        /* default to standard salt */
        ret = krb5_get_pw_salt (context, client, &salt2);
     if(salt == NULL) {
        /* default to standard salt */
        ret = krb5_get_pw_salt (context, client, &salt2);
+       if (ret)
+           return ret;
        salt = &salt2;
     }
     if (!enctypes) {
        salt = &salt2;
     }
     if (!enctypes) {
@@ -861,11 +345,10 @@ set_ptypes(krb5_context context,
                *preauth = &preauth2;
                ALLOC_SEQ(*preauth, 1);
                (*preauth)->val[0].type = KRB5_PADATA_ENC_TIMESTAMP;
                *preauth = &preauth2;
                ALLOC_SEQ(*preauth, 1);
                (*preauth)->val[0].type = KRB5_PADATA_ENC_TIMESTAMP;
-               krb5_decode_ETYPE_INFO(context,
-                                      md.val[i].padata_value.data,
-                                      md.val[i].padata_value.length,
-                                      &(*preauth)->val[0].info,
-                                      NULL);
+               decode_ETYPE_INFO(md.val[i].padata_value.data,
+                                 md.val[i].padata_value.length,
+                                 &(*preauth)->val[0].info,
+                                 NULL);
                break;
            default:
                break;
                break;
            default:
                break;
@@ -891,6 +374,7 @@ krb5_get_in_cred(krb5_context context,
                 krb5_const_pointer decryptarg,
                 krb5_creds *creds,
                 krb5_kdc_rep *ret_as_reply)
                 krb5_const_pointer decryptarg,
                 krb5_creds *creds,
                 krb5_kdc_rep *ret_as_reply)
+    KRB5_DEPRECATED
 {
     krb5_error_code ret;
     AS_REQ a;
 {
     krb5_error_code ret;
     AS_REQ a;
@@ -1055,6 +539,7 @@ krb5_get_in_tkt(krb5_context context,
                krb5_creds *creds,
                krb5_ccache ccache,
                krb5_kdc_rep *ret_as_reply)
                krb5_creds *creds,
                krb5_ccache ccache,
                krb5_kdc_rep *ret_as_reply)
+    KRB5_DEPRECATED
 {
     krb5_error_code ret;
 
 {
     krb5_error_code ret;
 
@@ -1076,3 +561,5 @@ krb5_get_in_tkt(krb5_context context,
        ret = krb5_cc_store_cred (context, ccache, creds);
     return ret;
 }
        ret = krb5_cc_store_cred (context, ccache, creds);
     return ret;
 }
+
+#endif /* HEIMDAL_SMALLER */
index c9869eb45075889edcc51a69b97bfc306815a707..5d0361b8161a6f01b5b983acc7ce64fa0ae2dc6d 100644 (file)
@@ -33,8 +33,6 @@
 
 #include <krb5_locl.h>
 
 
 #include <krb5_locl.h>
 
-RCSID("$Id$");
-
 int KRB5_LIB_FUNCTION
 krb5_getportbyname (krb5_context context,
                    const char *service,
 int KRB5_LIB_FUNCTION
 krb5_getportbyname (krb5_context context,
                    const char *service,
index 547a14e04cebd2ce4854a62fd950b0bbffd59cbf..2e8a0d18d85f37ada44eb3653eef6f8f0b2f5789 100644 (file)
@@ -17,6 +17,8 @@ error_code OPNOTSUPP,         "Operation not supported"
 error_code EOF,                        "End of file"
 error_code BAD_MKEY,           "Failed to get the master key"
 error_code SERVICE_NOMATCH,    "Unacceptable service used"
 error_code EOF,                        "End of file"
 error_code BAD_MKEY,           "Failed to get the master key"
 error_code SERVICE_NOMATCH,    "Unacceptable service used"
+error_code NOT_SEEKABLE,       "File descriptor not seekable"
+error_code TOO_BIG,            "Offset too large"
 
 index 64
 prefix HEIM_PKINIT
 
 index 64
 prefix HEIM_PKINIT
index 89ea3004ed06f67486854599ea9ed4085f86d085..b1bd94d3b9cd113433dcb72d8e8908e59ab917b3 100644 (file)
 #undef __attribute__
 #define __attribute__(x)
 
 #undef __attribute__
 #define __attribute__(x)
 
-RCSID("$Id$");
+/**
+ * @page krb5_init_creds_intro The initial credential handing functions
+ * @section section_krb5_init_creds Initial credential
+ *
+ * Functions to get initial credentials: @ref krb5_credential .
+ */
 
 
-void KRB5_LIB_FUNCTION
-krb5_get_init_creds_opt_init(krb5_get_init_creds_opt *opt)
-    __attribute__((deprecated))
-{
-    memset (opt, 0, sizeof(*opt));
-}
+/**
+ * Allocate a new krb5_get_init_creds_opt structure, free with
+ * krb5_get_init_creds_opt_free().
+ *
+ * @ingroup krb5_credential
+ */
 
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_get_init_creds_opt_alloc(krb5_context context,
 
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_get_init_creds_opt_alloc(krb5_context context,
@@ -71,67 +76,11 @@ krb5_get_init_creds_opt_alloc(krb5_context context,
     return 0;
 }
 
     return 0;
 }
 
-krb5_error_code
-_krb5_get_init_creds_opt_copy(krb5_context context,
-                             const krb5_get_init_creds_opt *in,
-                             krb5_get_init_creds_opt **out)
-{
-    krb5_get_init_creds_opt *opt;
-
-    *out = NULL;
-    opt = calloc(1, sizeof(*opt));
-    if (opt == NULL) {
-       krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
-       return ENOMEM;
-    }
-    if (in)
-       *opt = *in;
-    if(opt->opt_private == NULL) {
-       opt->opt_private = calloc(1, sizeof(*opt->opt_private));
-       if (opt->opt_private == NULL) {
-           krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
-           free(opt);
-           return ENOMEM;
-       }
-       opt->opt_private->refcount = 1;
-    } else
-       opt->opt_private->refcount++;
-    *out = opt;
-    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;
-    }  
-}
-
+/**
+ * Free krb5_get_init_creds_opt structure.
+ *
+ * @ingroup krb5_credential
+ */
 
 void KRB5_LIB_FUNCTION
 krb5_get_init_creds_opt_free(krb5_context context,
 
 void KRB5_LIB_FUNCTION
 krb5_get_init_creds_opt_free(krb5_context context,
@@ -142,7 +91,6 @@ krb5_get_init_creds_opt_free(krb5_context context,
     if (opt->opt_private->refcount < 1) /* abort ? */
        return;
     if (--opt->opt_private->refcount == 0) {
     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);
     }
        _krb5_get_init_creds_opt_free_pkinit(opt);
        free(opt->opt_private);
     }
@@ -368,35 +316,6 @@ krb5_get_init_creds_opt_set_pac_request(krb5_context context,
     return 0;
 }
 
     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_message(context, ENOMEM, N_("malloc: out of memory", ""));
-       return ENOMEM;
-    }
-
-    ret = copy_KRB_ERROR(opt->opt_private->error, *error);
-    if (ret)
-       krb5_clear_error_message(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_error_code KRB5_LIB_FUNCTION
 krb5_get_init_creds_opt_set_addressless(krb5_context context,
                                        krb5_get_init_creds_opt *opt,
@@ -445,3 +364,54 @@ krb5_get_init_creds_opt_set_win2k(krb5_context context,
     return 0;
 }
 
     return 0;
 }
 
+
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_get_init_creds_opt_set_process_last_req(krb5_context context,
+                                            krb5_get_init_creds_opt *opt,
+                                            krb5_gic_process_last_req func,
+                                            void *ctx)
+{
+    krb5_error_code ret;
+    ret = require_ext_opt(context, opt, "init_creds_opt_set_win2k");
+    if (ret)
+       return ret;
+
+    opt->opt_private->lr.func = func;
+    opt->opt_private->lr.ctx = ctx;
+
+    return 0;
+}
+
+
+#ifndef HEIMDAL_SMALLER
+
+void KRB5_LIB_FUNCTION
+krb5_get_init_creds_opt_init(krb5_get_init_creds_opt *opt)
+    KRB5_DEPRECATED
+{
+    memset (opt, 0, sizeof(*opt));
+}
+
+/**
+ * Deprecated: use the new krb5_init_creds_init() and
+ * krb5_init_creds_get_error().
+ *
+ * @ingroup krb5_deprecated
+ */
+
+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_DEPRECATED
+{
+    *error = calloc(1, sizeof(**error));
+    if (*error == NULL) {
+       krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
+       return ENOMEM;
+    }
+
+    return 0;
+}
+
+#endif /* HEIMDAL_SMALLER */
index 0b75522e9df5bfccf127862d1f69bc9eb2836dcc..0435ab5d3b825210f2421bf6bf40f309409218d0 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden).
  * All rights reserved.
  *
  * (Royal Institute of Technology, Stockholm, Sweden).
  * All rights reserved.
  *
 
 #include "krb5_locl.h"
 
 
 #include "krb5_locl.h"
 
-RCSID("$Id$");
-
 typedef struct krb5_get_init_creds_ctx {
     KDCOptions flags;
     krb5_creds cred;
     krb5_addresses *addrs;
     krb5_enctype *etypes;
     krb5_preauthtype *pre_auth_types;
 typedef struct krb5_get_init_creds_ctx {
     KDCOptions flags;
     krb5_creds cred;
     krb5_addresses *addrs;
     krb5_enctype *etypes;
     krb5_preauthtype *pre_auth_types;
-    const char *in_tkt_service;
+    char *in_tkt_service;
     unsigned nonce;
     unsigned pk_nonce;
 
     unsigned nonce;
     unsigned pk_nonce;
 
@@ -49,13 +47,26 @@ typedef struct krb5_get_init_creds_ctx {
     AS_REQ as_req;
     int pa_counter;
 
     AS_REQ as_req;
     int pa_counter;
 
-    const char *password;
-    krb5_s2k_proc key_proc;
+    /* password and keytab_data is freed on completion */
+    char *password;
+    krb5_keytab_key_proc_args *keytab_data;
+
+    krb5_pointer *keyseed;
+    krb5_s2k_proc keyproc;
 
     krb5_get_init_creds_tristate req_pac;
 
     krb5_pk_init_ctx pk_init_ctx;
     int ic_flags;
 
     krb5_get_init_creds_tristate req_pac;
 
     krb5_pk_init_ctx pk_init_ctx;
     int ic_flags;
+
+    METHOD_DATA md;
+    KRB_ERROR error;
+    AS_REP as_rep;
+    EncKDCRepPart enc_part;
+    
+    krb5_prompter_fct prompter;
+    void *prompter_data;
+
 } krb5_get_init_creds_ctx;
 
 static krb5_error_code
 } krb5_get_init_creds_ctx;
 
 static krb5_error_code
@@ -74,7 +85,7 @@ default_s2k_func(krb5_context context, krb5_enctype type,
        opaque = *s2kparms;
     else
        krb5_data_zero(&opaque);
        opaque = *s2kparms;
     else
        krb5_data_zero(&opaque);
-       
+
     *key = malloc(sizeof(**key));
     if (*key == NULL)
        return ENOMEM;
     *key = malloc(sizeof(**key));
     if (*key == NULL)
        return ENOMEM;
@@ -88,14 +99,24 @@ default_s2k_func(krb5_context context, krb5_enctype type,
 }
 
 static void
 }
 
 static void
-free_init_creds_ctx(krb5_context context, krb5_get_init_creds_ctx *ctx)
+free_init_creds_ctx(krb5_context context, krb5_init_creds_context ctx)
 {
     if (ctx->etypes)
        free(ctx->etypes);
     if (ctx->pre_auth_types)
        free (ctx->pre_auth_types);
 {
     if (ctx->etypes)
        free(ctx->etypes);
     if (ctx->pre_auth_types)
        free (ctx->pre_auth_types);
+    if (ctx->in_tkt_service)
+       free(ctx->in_tkt_service);
+    if (ctx->keytab_data)
+       free(ctx->keytab_data);
+    krb5_data_free(&ctx->req_buffer);
+    krb5_free_cred_contents(context, &ctx->cred);
+    free_METHOD_DATA(&ctx->md);
+    free_AS_REP(&ctx->as_rep);
+    free_EncKDCRepPart(&ctx->enc_part);
+    free_KRB_ERROR(&ctx->error);
     free_AS_REQ(&ctx->as_req);
     free_AS_REQ(&ctx->as_req);
-    memset(&ctx->as_req, 0, sizeof(ctx->as_req));
+    memset(ctx, 0, sizeof(*ctx));
 }
 
 static int
 }
 
 static int
@@ -127,11 +148,9 @@ init_cred (krb5_context context,
           krb5_creds *cred,
           krb5_principal client,
           krb5_deltat start_time,
           krb5_creds *cred,
           krb5_principal client,
           krb5_deltat start_time,
-          const char *in_tkt_service,
           krb5_get_init_creds_opt *options)
 {
     krb5_error_code ret;
           krb5_get_init_creds_opt *options)
 {
     krb5_error_code ret;
-    krb5_const_realm client_realm;
     int tmp;
     krb5_timestamp now;
 
     int tmp;
     krb5_timestamp now;
 
@@ -148,8 +167,6 @@ init_cred (krb5_context context,
            goto out;
     }
 
            goto out;
     }
 
-    client_realm = krb5_principal_get_realm (context, cred->client);
-
     if (start_time)
        cred->times.starttime  = now + start_time;
 
     if (start_time)
        cred->times.starttime  = now + start_time;
 
@@ -164,18 +181,6 @@ init_cred (krb5_context context,
        cred->times.renew_till = now + options->renew_life;
     }
 
        cred->times.renew_till = now + options->renew_life;
     }
 
-    if (in_tkt_service) {
-       ret = krb5_parse_name (context, in_tkt_service, &cred->server);
-       if (ret)
-           goto out;
-       krb5_principal_set_realm (context, cred->server, client_realm);
-    } else {
-       ret = krb5_make_principal(context, &cred->server,
-                                 client_realm, KRB5_TGS_NAME, client_realm,
-                                 NULL);
-       if (ret)
-           goto out;
-    }
     return 0;
 
 out:
     return 0;
 
 out:
@@ -195,28 +200,71 @@ report_expiration (krb5_context context,
                   time_t now)
 {
     char *p;
                   time_t now)
 {
     char *p;
-       
+
     asprintf (&p, "%s%s", str, ctime(&now));
     (*prompter) (context, data, NULL, p, 0, NULL);
     free (p);
 }
 
 /*
     asprintf (&p, "%s%s", str, ctime(&now));
     (*prompter) (context, data, NULL, p, 0, NULL);
     free (p);
 }
 
 /*
- * Parse the last_req data and show it to the user if it's interesting
+ * Check the context, and in the case there is a expiration warning,
+ * use the prompter to print the warning.
+ *
+ * @param context A Kerberos 5 context.
+ * @param options An GIC options structure
+ * @param ctx The krb5_init_creds_context check for expiration.
  */
 
  */
 
-static void
-print_expire (krb5_context context,
-             krb5_const_realm realm,
-             krb5_kdc_rep *rep,
-             krb5_prompter_fct prompter,
-             krb5_data *data)
+static krb5_error_code
+process_last_request(krb5_context context,
+                    krb5_get_init_creds_opt *options,
+                    krb5_init_creds_context ctx)
 {
 {
-    int i;
-    LastReq *lr = &rep->enc_part.last_req;
+    krb5_const_realm realm;
+    LastReq *lr;
+    krb5_boolean reported = FALSE;
     krb5_timestamp sec;
     time_t t;
     krb5_timestamp sec;
     time_t t;
-    krb5_boolean reported = FALSE;
+    size_t i;
+
+    /*
+     * First check if there is a API consumer.
+     */
+
+    realm = krb5_principal_get_realm (context, ctx->cred.client);
+    lr = &ctx->enc_part.last_req;
+
+    if (options && options->opt_private && options->opt_private->lr.func) {
+       krb5_last_req_entry **lre;
+
+       lre = calloc(lr->len + 1, sizeof(**lre));
+       if (lre == NULL) {
+           krb5_set_error_message(context, ENOMEM,
+                                  N_("malloc: out of memory", ""));
+           return ENOMEM;
+       }
+       for (i = 0; i < lr->len; i++) {
+           lre[i] = calloc(1, sizeof(*lre[i]));
+           if (lre[i] == NULL)
+               break;
+           lre[i]->lr_type = lr->val[i].lr_type;
+           lre[i]->value = lr->val[i].lr_value;
+       }
+
+       (*options->opt_private->lr.func)(context, lre,
+                                        options->opt_private->lr.ctx);
+
+       for (i = 0; i < lr->len; i++)
+           free(lre[i]);
+       free(lre);
+    }
+
+    /*
+     * Now check if we should prompt the user
+     */
+
+    if (ctx->prompter == NULL)
+        return 0;
 
     krb5_timeofday (context, &sec);
 
 
     krb5_timeofday (context, &sec);
 
@@ -229,13 +277,15 @@ print_expire (krb5_context context,
        if (lr->val[i].lr_value <= t) {
            switch (abs(lr->val[i].lr_type)) {
            case LR_PW_EXPTIME :
        if (lr->val[i].lr_value <= t) {
            switch (abs(lr->val[i].lr_type)) {
            case LR_PW_EXPTIME :
-               report_expiration(context, prompter, data,
+               report_expiration(context, ctx->prompter, 
+                                 ctx->prompter_data,
                                  "Your password will expire at ",
                                  lr->val[i].lr_value);
                reported = TRUE;
                break;
            case LR_ACCT_EXPTIME :
                                  "Your password will expire at ",
                                  lr->val[i].lr_value);
                reported = TRUE;
                break;
            case LR_ACCT_EXPTIME :
-               report_expiration(context, prompter, data,
+               report_expiration(context, ctx->prompter, 
+                                 ctx->prompter_data,
                                  "Your account will expire at ",
                                  lr->val[i].lr_value);
                reported = TRUE;
                                  "Your account will expire at ",
                                  lr->val[i].lr_value);
                reported = TRUE;
@@ -245,12 +295,14 @@ print_expire (krb5_context context,
     }
 
     if (!reported
     }
 
     if (!reported
-       && rep->enc_part.key_expiration
-       && *rep->enc_part.key_expiration <= t) {
-       report_expiration(context, prompter, data,
+       && ctx->enc_part.key_expiration
+       && *ctx->enc_part.key_expiration <= t) {
+        report_expiration(context, ctx->prompter, 
+                         ctx->prompter_data,
                          "Your password/account will expire at ",
                          "Your password/account will expire at ",
-                         *rep->enc_part.key_expiration);
+                         *ctx->enc_part.key_expiration);
     }
     }
+    return 0;
 }
 
 static krb5_addresses no_addrs = { 0, NULL };
 }
 
 static krb5_addresses no_addrs = { 0, NULL };
@@ -259,11 +311,10 @@ static krb5_error_code
 get_init_creds_common(krb5_context context,
                      krb5_principal client,
                      krb5_deltat start_time,
 get_init_creds_common(krb5_context context,
                      krb5_principal client,
                      krb5_deltat start_time,
-                     const char *in_tkt_service,
                      krb5_get_init_creds_opt *options,
                      krb5_get_init_creds_opt *options,
-                     krb5_get_init_creds_ctx *ctx)
+                     krb5_init_creds_context ctx)
 {
 {
-    krb5_get_init_creds_opt default_opt;
+    krb5_get_init_creds_opt *default_opt = NULL;
     krb5_error_code ret;
     krb5_enctype *etypes;
     krb5_preauthtype *pre_auth_types;
     krb5_error_code ret;
     krb5_enctype *etypes;
     krb5_preauthtype *pre_auth_types;
@@ -271,37 +322,51 @@ get_init_creds_common(krb5_context context,
     memset(ctx, 0, sizeof(*ctx));
 
     if (options == NULL) {
     memset(ctx, 0, sizeof(*ctx));
 
     if (options == NULL) {
-       krb5_get_init_creds_opt_init (&default_opt);
-       options = &default_opt;
-    } else {
-       _krb5_get_init_creds_opt_free_krb5_error(options);
+       const char *realm = krb5_principal_get_realm(context, client);
+
+        krb5_get_init_creds_opt_alloc (context, &default_opt);
+       options = default_opt;
+       krb5_get_init_creds_opt_set_default_flags(context, NULL, realm, options);
     }
 
     if (options->opt_private) {
     }
 
     if (options->opt_private) {
-       ctx->password = options->opt_private->password;
-       ctx->key_proc = options->opt_private->key_proc;
+       if (options->opt_private->password) {
+           ret = krb5_init_creds_set_password(context, ctx, 
+                                              options->opt_private->password);
+           if (ret)
+               goto out;
+       }
+
+       ctx->keyproc = options->opt_private->key_proc;
        ctx->req_pac = options->opt_private->req_pac;
        ctx->pk_init_ctx = options->opt_private->pk_init_ctx;
        ctx->ic_flags = options->opt_private->flags;
     } else
        ctx->req_pac = KRB5_INIT_CREDS_TRISTATE_UNSET;
 
        ctx->req_pac = options->opt_private->req_pac;
        ctx->pk_init_ctx = options->opt_private->pk_init_ctx;
        ctx->ic_flags = options->opt_private->flags;
     } else
        ctx->req_pac = KRB5_INIT_CREDS_TRISTATE_UNSET;
 
-    if (ctx->key_proc == NULL)
-       ctx->key_proc = default_s2k_func;
+    if (ctx->keyproc == NULL)
+       ctx->keyproc = default_s2k_func;
 
 
-    if (ctx->ic_flags & KRB5_INIT_CREDS_CANONICALIZE)
+    /* Enterprise name implicitly turns on canonicalize */
+    if ((ctx->ic_flags & KRB5_INIT_CREDS_CANONICALIZE) || 
+       krb5_principal_get_type(context, client) == KRB5_NT_ENTERPRISE_PRINCIPAL)
        ctx->flags.canonicalize = 1;
 
     ctx->pre_auth_types = NULL;
     ctx->addrs = NULL;
     ctx->etypes = NULL;
     ctx->pre_auth_types = NULL;
        ctx->flags.canonicalize = 1;
 
     ctx->pre_auth_types = NULL;
     ctx->addrs = NULL;
     ctx->etypes = NULL;
     ctx->pre_auth_types = NULL;
-    ctx->in_tkt_service = in_tkt_service;
 
 
-    ret = init_cred (context, &ctx->cred, client, start_time,
-                    in_tkt_service, options);
-    if (ret)
+    ret = init_cred(context, &ctx->cred, client, start_time, options);
+    if (ret) {
+       if (default_opt)
+           krb5_get_init_creds_opt_free(context, default_opt);
        return ret;
        return ret;
+    }
+
+    ret = krb5_init_creds_set_service(context, ctx, NULL);
+    if (ret)
+       goto out;
 
     if (options->flags & KRB5_GET_INIT_CREDS_OPT_FORWARDABLE)
        ctx->flags.forwardable = options->forwardable;
 
     if (options->flags & KRB5_GET_INIT_CREDS_OPT_FORWARDABLE)
        ctx->flags.forwardable = options->forwardable;
@@ -336,8 +401,9 @@ get_init_creds_common(krb5_context context,
        etypes = malloc((options->etype_list_length + 1)
                        * sizeof(krb5_enctype));
        if (etypes == NULL) {
        etypes = malloc((options->etype_list_length + 1)
                        * sizeof(krb5_enctype));
        if (etypes == NULL) {
-           krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
-           return ENOMEM;
+           ret = ENOMEM;
+           krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
+           goto out;
        }
        memcpy (etypes, options->etype_list,
                options->etype_list_length * sizeof(krb5_enctype));
        }
        memcpy (etypes, options->etype_list,
                options->etype_list_length * sizeof(krb5_enctype));
@@ -348,19 +414,24 @@ get_init_creds_common(krb5_context context,
        pre_auth_types = malloc((options->preauth_list_length + 1)
                                * sizeof(krb5_preauthtype));
        if (pre_auth_types == NULL) {
        pre_auth_types = malloc((options->preauth_list_length + 1)
                                * sizeof(krb5_preauthtype));
        if (pre_auth_types == NULL) {
-           krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
-           return ENOMEM;
+           ret = ENOMEM;
+           krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
+           goto out;
        }
        memcpy (pre_auth_types, options->preauth_list,
                options->preauth_list_length * sizeof(krb5_preauthtype));
        pre_auth_types[options->preauth_list_length] = KRB5_PADATA_NONE;
        ctx->pre_auth_types = pre_auth_types;
     }
        }
        memcpy (pre_auth_types, options->preauth_list,
                options->preauth_list_length * sizeof(krb5_preauthtype));
        pre_auth_types[options->preauth_list_length] = KRB5_PADATA_NONE;
        ctx->pre_auth_types = pre_auth_types;
     }
-    if (options->flags & KRB5_GET_INIT_CREDS_OPT_SALT)
-       ;                       /* XXX */
     if (options->flags & KRB5_GET_INIT_CREDS_OPT_ANONYMOUS)
        ctx->flags.request_anonymous = options->anonymous;
     if (options->flags & KRB5_GET_INIT_CREDS_OPT_ANONYMOUS)
        ctx->flags.request_anonymous = options->anonymous;
+    if (default_opt)
+        krb5_get_init_creds_opt_free(context, default_opt);
     return 0;
     return 0;
+ out:
+    if (default_opt)
+       krb5_get_init_creds_opt_free(context, default_opt);
+    return ret;
 }
 
 static krb5_error_code
 }
 
 static krb5_error_code
@@ -382,18 +453,20 @@ change_password (krb5_context context,
     krb5_data result_code_string;
     krb5_data result_string;
     char *p;
     krb5_data result_code_string;
     krb5_data result_string;
     char *p;
-    krb5_get_init_creds_opt options;
+    krb5_get_init_creds_opt *options;
 
     memset (&cpw_cred, 0, sizeof(cpw_cred));
 
 
     memset (&cpw_cred, 0, sizeof(cpw_cred));
 
-    krb5_get_init_creds_opt_init (&options);
-    krb5_get_init_creds_opt_set_tkt_life (&options, 60);
-    krb5_get_init_creds_opt_set_forwardable (&options, FALSE);
-    krb5_get_init_creds_opt_set_proxiable (&options, FALSE);
+    ret = krb5_get_init_creds_opt_alloc(context, &options);
+    if (ret)
+        return ret;
+    krb5_get_init_creds_opt_set_tkt_life (options, 60);
+    krb5_get_init_creds_opt_set_forwardable (options, FALSE);
+    krb5_get_init_creds_opt_set_proxiable (options, FALSE);
     if (old_options && old_options->flags & KRB5_GET_INIT_CREDS_OPT_PREAUTH_LIST)
     if (old_options && old_options->flags & KRB5_GET_INIT_CREDS_OPT_PREAUTH_LIST)
-       krb5_get_init_creds_opt_set_preauth_list (&options,
+       krb5_get_init_creds_opt_set_preauth_list (options,
                                                  old_options->preauth_list,
                                                  old_options->preauth_list,
-                                                 old_options->preauth_list_length);                                    
+                                                 old_options->preauth_list_length);
 
     krb5_data_zero (&result_code_string);
     krb5_data_zero (&result_string);
 
     krb5_data_zero (&result_code_string);
     krb5_data_zero (&result_string);
@@ -406,7 +479,8 @@ change_password (krb5_context context,
                                        data,
                                        0,
                                        "kadmin/changepw",
                                        data,
                                        0,
                                        "kadmin/changepw",
-                                       &options);
+                                       options);
+    krb5_get_init_creds_opt_free(context, options);
     if (ret)
        goto out;
 
     if (ret)
        goto out;
 
@@ -455,7 +529,9 @@ change_password (krb5_context context,
              (int)result_string.length,
              result_string.length > 0 ? (char*)result_string.data : "");
 
              (int)result_string.length,
              result_string.length > 0 ? (char*)result_string.data : "");
 
-    ret = (*prompter) (context, data, NULL, p, 0, NULL);
+    /* return the result */
+    (*prompter) (context, data, NULL, p, 0, NULL);
+
     free (p);
     if (result_code == 0) {
        strlcpy (newpw, buf1, newpw_sz);
     free (p);
     if (result_code == 0) {
        strlcpy (newpw, buf1, newpw_sz);
@@ -475,6 +551,7 @@ out:
     return ret;
 }
 
     return ret;
 }
 
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_keyblock_key_proc (krb5_context context,
                        krb5_keytype type,
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_keyblock_key_proc (krb5_context context,
                        krb5_keytype type,
@@ -485,68 +562,17 @@ krb5_keyblock_key_proc (krb5_context context,
     return krb5_copy_keyblock (context, keyseed, key);
 }
 
     return krb5_copy_keyblock (context, keyseed, key);
 }
 
-krb5_error_code KRB5_LIB_FUNCTION
-krb5_get_init_creds_keytab(krb5_context context,
-                          krb5_creds *creds,
-                          krb5_principal client,
-                          krb5_keytab keytab,
-                          krb5_deltat start_time,
-                          const char *in_tkt_service,
-                          krb5_get_init_creds_opt *options)
-{
-    krb5_get_init_creds_ctx ctx;
-    krb5_error_code ret;
-    krb5_keytab_key_proc_args *a;
-
-    ret = get_init_creds_common(context, client, start_time,
-                               in_tkt_service, options, &ctx);
-    if (ret)
-       goto out;
-
-    a = malloc (sizeof(*a));
-    if (a == NULL) {
-       ret = ENOMEM;
-       krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
-       goto out;
-    }
-    a->principal = ctx.cred.client;
-    a->keytab    = keytab;
-
-    ret = krb5_get_in_cred (context,
-                           KDCOptions2int(ctx.flags),
-                           ctx.addrs,
-                           ctx.etypes,
-                           ctx.pre_auth_types,
-                           NULL,
-                           krb5_keytab_key_proc,
-                           a,
-                           NULL,
-                           NULL,
-                           &ctx.cred,
-                           NULL);
-    free (a);
-
-    if (ret == 0 && creds)
-       *creds = ctx.cred;
-    else
-       krb5_free_cred_contents (context, &ctx.cred);
-
- out:
-    free_init_creds_ctx(context, &ctx);
-    return ret;
-}
-
 /*
  *
  */
 
 static krb5_error_code
 /*
  *
  */
 
 static krb5_error_code
-init_creds_init_as_req (krb5_context context,
-                       KDCOptions opts,
-                       const krb5_creds *creds,
-                       const krb5_addresses *addrs,
-                       const krb5_enctype *etypes,
-                       AS_REQ *a)
+init_as_req (krb5_context context,
+            KDCOptions opts,
+            const krb5_creds *creds,
+            const krb5_addresses *addrs,
+            const krb5_enctype *etypes,
+            AS_REQ *a)
 {
     krb5_error_code ret;
 
 {
     krb5_error_code ret;
 
@@ -906,7 +932,7 @@ make_pa_enc_timestamp(krb5_context context, METHOD_DATA *md,
     krb5_crypto_destroy(context, crypto);
     if (ret)
        return ret;
     krb5_crypto_destroy(context, crypto);
     if (ret)
        return ret;
-               
+
     ASN1_MALLOC_ENCODE(EncryptedData, buf, buf_size, &encdata, &len, ret);
     free_EncryptedData(&encdata);
     if (ret)
     ASN1_MALLOC_ENCODE(EncryptedData, buf, buf_size, &encdata, &len, ret);
     free_EncryptedData(&encdata);
     if (ret)
@@ -924,7 +950,7 @@ static krb5_error_code
 add_enc_ts_padata(krb5_context context,
                  METHOD_DATA *md,
                  krb5_principal client,
 add_enc_ts_padata(krb5_context context,
                  METHOD_DATA *md,
                  krb5_principal client,
-                 krb5_s2k_proc key_proc,
+                 krb5_s2k_proc keyproc,
                  krb5_const_pointer keyseed,
                  krb5_enctype *enctypes,
                  unsigned netypes,
                  krb5_const_pointer keyseed,
                  krb5_enctype *enctypes,
                  unsigned netypes,
@@ -939,6 +965,8 @@ add_enc_ts_padata(krb5_context context,
     if(salt == NULL) {
        /* default to standard salt */
        ret = krb5_get_pw_salt (context, client, &salt2);
     if(salt == NULL) {
        /* default to standard salt */
        ret = krb5_get_pw_salt (context, client, &salt2);
+       if (ret)
+           return ret;
        salt = &salt2;
     }
     if (!enctypes) {
        salt = &salt2;
     }
     if (!enctypes) {
@@ -951,8 +979,8 @@ add_enc_ts_padata(krb5_context context,
     for (i = 0; i < netypes; ++i) {
        krb5_keyblock *key;
 
     for (i = 0; i < netypes; ++i) {
        krb5_keyblock *key;
 
-       ret = (*key_proc)(context, enctypes[i], keyseed,
-                         *salt, s2kparams, &key);
+       ret = (*keyproc)(context, enctypes[i], keyseed,
+                        *salt, s2kparams, &key);
        if (ret)
            continue;
        ret = make_pa_enc_timestamp (context, md, enctypes[i], key);
        if (ret)
            continue;
        ret = make_pa_enc_timestamp (context, md, enctypes[i], key);
@@ -973,28 +1001,28 @@ pa_data_to_md_ts_enc(krb5_context context,
                     struct pa_info_data *ppaid,
                     METHOD_DATA *md)
 {
                     struct pa_info_data *ppaid,
                     METHOD_DATA *md)
 {
-    if (ctx->key_proc == NULL || ctx->password == NULL)
+    if (ctx->keyproc == NULL || ctx->keyseed == NULL)
        return 0;
 
     if (ppaid) {
        add_enc_ts_padata(context, md, client,
        return 0;
 
     if (ppaid) {
        add_enc_ts_padata(context, md, client,
-                         ctx->key_proc, ctx->password,
+                         ctx->keyproc, ctx->keyseed,
                          &ppaid->etype, 1,
                          &ppaid->salt, ppaid->s2kparams);
     } else {
        krb5_salt salt;
                          &ppaid->etype, 1,
                          &ppaid->salt, ppaid->s2kparams);
     } else {
        krb5_salt salt;
-       
+
        /* make a v5 salted pa-data */
        add_enc_ts_padata(context, md, client,
        /* make a v5 salted pa-data */
        add_enc_ts_padata(context, md, client,
-                         ctx->key_proc, ctx->password,
+                         ctx->keyproc, ctx->keyseed,
                          a->req_body.etype.val, a->req_body.etype.len,
                          NULL, NULL);
                          a->req_body.etype.val, a->req_body.etype.len,
                          NULL, NULL);
-       
+
        /* make a v4 salted pa-data */
        salt.salttype = KRB5_PW_SALT;
        krb5_data_zero(&salt.saltvalue);
        add_enc_ts_padata(context, md, client,
        /* make a v4 salted pa-data */
        salt.salttype = KRB5_PW_SALT;
        krb5_data_zero(&salt.saltvalue);
        add_enc_ts_padata(context, md, client,
-                         ctx->key_proc, ctx->password,
+                         ctx->keyproc, ctx->keyseed,
                          a->req_body.etype.val, a->req_body.etype.len,
                          &salt, NULL);
     }
                          a->req_body.etype.val, a->req_body.etype.len,
                          &salt, NULL);
     }
@@ -1012,7 +1040,7 @@ pa_data_to_key_plain(krb5_context context,
 {
     krb5_error_code ret;
 
 {
     krb5_error_code ret;
 
-    ret = (*ctx->key_proc)(context, etype, ctx->password,
+    ret = (*ctx->keyproc)(context, etype, ctx->keyseed,
                           salt, s2kparams, key);
     return ret;
 }
                           salt, s2kparams, key);
     return ret;
 }
@@ -1058,7 +1086,7 @@ pa_data_add_pac_request(krb5_context context,
        break;
     case KRB5_INIT_CREDS_TRISTATE_FALSE:
        req.include_pac = 0;
        break;
     case KRB5_INIT_CREDS_TRISTATE_FALSE:
        req.include_pac = 0;
-    }  
+    }
 
     ASN1_MALLOC_ENCODE(PA_PAC_REQUEST, buf, length,
                       &req, &len, ret);
 
     ASN1_MALLOC_ENCODE(PA_PAC_REQUEST, buf, length,
                       &req, &len, ret);
@@ -1111,12 +1139,12 @@ process_pa_data_to_md(krb5_context context,
 
     } else if (in_md->len != 0) {
        struct pa_info_data paid, *ppaid;
 
     } else if (in_md->len != 0) {
        struct pa_info_data paid, *ppaid;
-       
+
        memset(&paid, 0, sizeof(paid));
        memset(&paid, 0, sizeof(paid));
-       
+
        paid.etype = ENCTYPE_NULL;
        ppaid = process_pa_info(context, creds->client, a, &paid, in_md);
        paid.etype = ENCTYPE_NULL;
        ppaid = process_pa_info(context, creds->client, a, &paid, in_md);
-       
+
        pa_data_to_md_ts_enc(context, a, creds->client, ctx, ppaid, *out_md);
        if (ppaid)
            free_paid(context, ppaid);
        pa_data_to_md_ts_enc(context, a, creds->client, ctx, ppaid, *out_md);
        if (ppaid)
            free_paid(context, ppaid);
@@ -1137,7 +1165,7 @@ process_pa_data_to_key(krb5_context context,
                       krb5_get_init_creds_ctx *ctx,
                       krb5_creds *creds,
                       AS_REQ *a,
                       krb5_get_init_creds_ctx *ctx,
                       krb5_creds *creds,
                       AS_REQ *a,
-                      krb5_kdc_rep *rep,
+                      AS_REP *rep,
                       const krb5_krbhst_info *hi,
                       krb5_keyblock **key)
 {
                       const krb5_krbhst_info *hi,
                       krb5_keyblock **key)
 {
@@ -1148,12 +1176,12 @@ process_pa_data_to_key(krb5_context context,
 
     memset(&paid, 0, sizeof(paid));
 
 
     memset(&paid, 0, sizeof(paid));
 
-    etype = rep->kdc_rep.enc_part.etype;
+    etype = rep->enc_part.etype;
 
 
-    if (rep->kdc_rep.padata) {
+    if (rep->padata) {
        paid.etype = etype;
        ppaid = process_pa_info(context, creds->client, a, &paid,
        paid.etype = etype;
        ppaid = process_pa_info(context, creds->client, a, &paid,
-                               rep->kdc_rep.padata);
+                               rep->padata);
     }
     if (ppaid == NULL) {
        ret = krb5_get_pw_salt (context, creds->client, &paid.salt);
     }
     if (ppaid == NULL) {
        ret = krb5_get_pw_salt (context, creds->client, &paid.salt);
@@ -1164,16 +1192,16 @@ process_pa_data_to_key(krb5_context context,
     }
 
     pa = NULL;
     }
 
     pa = NULL;
-    if (rep->kdc_rep.padata) {
+    if (rep->padata) {
        int idx = 0;
        int idx = 0;
-       pa = krb5_find_padata(rep->kdc_rep.padata->val,
-                             rep->kdc_rep.padata->len,
+       pa = krb5_find_padata(rep->padata->val,
+                             rep->padata->len,
                              KRB5_PADATA_PK_AS_REP,
                              &idx);
        if (pa == NULL) {
            idx = 0;
                              KRB5_PADATA_PK_AS_REP,
                              &idx);
        if (pa == NULL) {
            idx = 0;
-           pa = krb5_find_padata(rep->kdc_rep.padata->val,
-                                 rep->kdc_rep.padata->len,
+           pa = krb5_find_padata(rep->padata->val,
+                                 rep->padata->len,
                                  KRB5_PADATA_PK_AS_REP_19,
                                  &idx);
        }
                                  KRB5_PADATA_PK_AS_REP_19,
                                  &idx);
        }
@@ -1193,7 +1221,7 @@ process_pa_data_to_key(krb5_context context,
        ret = EINVAL;
        krb5_set_error_message(context, ret, N_("no support for PKINIT compiled in", ""));
 #endif
        ret = EINVAL;
        krb5_set_error_message(context, ret, N_("no support for PKINIT compiled in", ""));
 #endif
-    } else if (ctx->password)
+    } else if (ctx->keyseed)
        ret = pa_data_to_key_plain(context, creds->client, ctx,
                                   paid.salt, paid.s2kparams, etype, key);
     else {
        ret = pa_data_to_key_plain(context, creds->client, ctx,
                                   paid.salt, paid.s2kparams, etype, key);
     else {
@@ -1205,109 +1233,340 @@ process_pa_data_to_key(krb5_context context,
     return ret;
 }
 
     return ret;
 }
 
-static krb5_error_code
-init_cred_loop(krb5_context context,
-              krb5_get_init_creds_opt *init_cred_opts,
-              const krb5_prompter_fct prompter,
-              void *prompter_data,
-              krb5_get_init_creds_ctx *ctx,
-              krb5_creds *creds,
-              krb5_kdc_rep *ret_as_reply)
+/**
+ * Start a new context to get a new initial credential.
+ *
+ * @param context A Kerberos 5 context.
+ * @param client The Kerberos principal to get the credential for, if
+ *     NULL is given, the default principal is used as determined by
+ *     krb5_get_default_principal().
+ * @param prompter
+ * @param prompter_data
+ * @param start_time the time the ticket should start to be valid or 0 for now.
+ * @param options a options structure, can be NULL for default options.
+ * @param rctx A new allocated free with krb5_init_creds_free().
+ *
+ * @return 0 for success or an Kerberos 5 error code, see krb5_get_error_message().
+ *
+ * @ingroup krb5_credential
+ */
+
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_init_creds_init(krb5_context context,
+                    krb5_principal client,
+                    krb5_prompter_fct prompter,
+                    void *prompter_data,
+                    krb5_deltat start_time,
+                    krb5_get_init_creds_opt *options,
+                    krb5_init_creds_context *rctx)
 {
 {
+    krb5_init_creds_context ctx;
     krb5_error_code ret;
     krb5_error_code ret;
-    krb5_kdc_rep rep;
-    METHOD_DATA md;
-    krb5_data resp;
-    size_t len;
-    size_t size;
-    krb5_krbhst_info *hi = NULL;
-    krb5_sendto_ctx stctx = NULL;
-
 
 
-    memset(&md, 0, sizeof(md));
-    memset(&rep, 0, sizeof(rep));
+    *rctx = NULL;
 
 
-    _krb5_get_init_creds_opt_free_krb5_error(init_cred_opts);
-
-    if (ret_as_reply)
-       memset(ret_as_reply, 0, sizeof(*ret_as_reply));
+    ctx = calloc(1, sizeof(*ctx));
+    if (ctx == NULL) {
+       krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
+       return ENOMEM;
+    }
 
 
-    ret = init_creds_init_as_req(context, ctx->flags, creds,
-                                ctx->addrs, ctx->etypes, &ctx->as_req);
-    if (ret)
+    ret = get_init_creds_common(context, client, start_time, options, ctx);
+    if (ret) {
+       free(ctx);
        return ret;
        return ret;
-
-    ret = krb5_sendto_ctx_alloc(context, &stctx);
-    if (ret)
-       goto out;
-    krb5_sendto_ctx_set_func(stctx, _krb5_kdc_retry, NULL);
+    }
 
     /* Set a new nonce. */
     krb5_generate_random_block (&ctx->nonce, sizeof(ctx->nonce));
 
     /* Set a new nonce. */
     krb5_generate_random_block (&ctx->nonce, sizeof(ctx->nonce));
-    ctx->nonce &= 0xffffffff;
+    ctx->nonce &= 0x7fffffff;
     /* XXX these just needs to be the same when using Windows PK-INIT */
     ctx->pk_nonce = ctx->nonce;
 
     /* XXX these just needs to be the same when using Windows PK-INIT */
     ctx->pk_nonce = ctx->nonce;
 
-    /*
-     * Increase counter when we want other pre-auth types then
-     * KRB5_PA_ENC_TIMESTAMP.
-     */
-#define MAX_PA_COUNTER 3
+    ctx->prompter = prompter;
+    ctx->prompter_data = prompter_data;
 
 
-    ctx->pa_counter = 0;
-    while (ctx->pa_counter < MAX_PA_COUNTER) {
+    *rctx = ctx;
 
 
-       ctx->pa_counter++;
+    return ret;
+}
 
 
-       if (ctx->as_req.padata) {
-           free_METHOD_DATA(ctx->as_req.padata);
-           free(ctx->as_req.padata);
-           ctx->as_req.padata = NULL;
-       }
+/**
+ * Sets the service that the is requested. This call is only neede for
+ * special initial tickets, by default the a krbtgt is fetched in the default realm.
+ *
+ * @param context a Kerberos 5 context.
+ * @param ctx a krb5_init_creds_context context.
+ * @param service the service given as a string, for example
+ *        "kadmind/admin". If NULL, the default krbtgt in the clients
+ *        realm is set.
+ *
+ * @return 0 for success, or an Kerberos 5 error code, see krb5_get_error_message().
+ * @ingroup krb5_credential
+ */
 
 
-       /* Set a new nonce. */
-       ctx->as_req.req_body.nonce = ctx->nonce;
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_init_creds_set_service(krb5_context context,
+                           krb5_init_creds_context ctx,
+                           const char *service)
+{
+    krb5_const_realm client_realm;
+    krb5_principal principal;
+    krb5_error_code ret;
+
+    client_realm = krb5_principal_get_realm (context, ctx->cred.client);
 
 
-       /* fill_in_md_data */
-       ret = process_pa_data_to_md(context, creds, &ctx->as_req, ctx,
-                                   &md, &ctx->as_req.padata,
-                                   prompter, prompter_data);
+    if (service) {
+       ret = krb5_parse_name (context, service, &principal);
        if (ret)
        if (ret)
-           goto out;
+           return ret;
+       krb5_principal_set_realm (context, principal, client_realm);
+    } else {
+       ret = krb5_make_principal(context, &principal,
+                                 client_realm, KRB5_TGS_NAME, client_realm,
+                                 NULL);
+       if (ret)
+           return ret;
+    }
+    krb5_free_principal(context, ctx->cred.server);
+    ctx->cred.server = principal;
 
 
-       krb5_data_free(&ctx->req_buffer);
+    return 0;
+}
 
 
-       ASN1_MALLOC_ENCODE(AS_REQ,
-                          ctx->req_buffer.data, ctx->req_buffer.length,
-                          &ctx->as_req, &len, ret);
-       if (ret)
-           goto out;
-       if(len != ctx->req_buffer.length)
-           krb5_abortx(context, "internal error in ASN.1 encoder");
+/**
+ * Sets the password that will use for the request.
+ *
+ * @param context a Kerberos 5 context.
+ * @param ctx ctx krb5_init_creds_context context.
+ * @param password the password to use.
+ *
+ * @return 0 for success, or an Kerberos 5 error code, see krb5_get_error_message().
+ * @ingroup krb5_credential
+ */
 
 
-       ret = krb5_sendto_context (context, stctx, &ctx->req_buffer,
-                                  creds->client->realm, &resp);
-       if (ret)
-           goto out;
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_init_creds_set_password(krb5_context context,
+                            krb5_init_creds_context ctx,
+                            const char *password)
+{
+    if (ctx->password)
+       memset(ctx->password, 0, strlen(ctx->password));
+    if (password) {
+       ctx->password = strdup(password);
+       if (ctx->password == NULL) {
+           krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
+           return ENOMEM;
+       }
+       ctx->keyseed = (void *) ctx->password;
+    } else {
+       ctx->keyseed = NULL;
+       ctx->password = NULL;
+    }
+
+    return 0;
+}
+
+static krb5_error_code
+keytab_key_proc(krb5_context context, krb5_enctype enctype,
+               krb5_const_pointer keyseed,
+               krb5_salt salt, krb5_data *s2kparms,
+               krb5_keyblock **key)
+{
+    krb5_keytab_key_proc_args *args  = rk_UNCONST(keyseed);
+    krb5_keytab keytab = args->keytab;
+    krb5_principal principal = args->principal;
+    krb5_error_code ret;
+    krb5_keytab real_keytab;
+    krb5_keytab_entry entry;
+
+    if(keytab == NULL)
+       krb5_kt_default(context, &real_keytab);
+    else
+       real_keytab = keytab;
+
+    ret = krb5_kt_get_entry (context, real_keytab, principal,
+                            0, enctype, &entry);
+
+    if (keytab == NULL)
+       krb5_kt_close (context, real_keytab);
+
+    if (ret)
+       return ret;
+
+    ret = krb5_copy_keyblock (context, &entry.keyblock, key);
+    krb5_kt_free_entry(context, &entry);
+    return ret;
+}
+
+
+/**
+ * Set the keytab to use for authentication.
+ *
+ * @param context a Kerberos 5 context.
+ * @param ctx ctx krb5_init_creds_context context.
+ * @param keytab the keytab to read the key from.
+ *
+ * @return 0 for success, or an Kerberos 5 error code, see krb5_get_error_message().
+ * @ingroup krb5_credential
+ */
+
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_init_creds_set_keytab(krb5_context context,
+                          krb5_init_creds_context ctx,
+                          krb5_keytab keytab)
+{
+    krb5_keytab_key_proc_args *a;
+    
+    a = malloc(sizeof(*a));
+    if (a == NULL) {
+       krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
+       return ENOMEM;
+    }
+       
+    a->principal = ctx->cred.client;
+    a->keytab    = keytab;
+
+    ctx->keytab_data = a;
+    ctx->keyseed = (void *)a;
+    ctx->keyproc = keytab_key_proc;
+
+    return 0;
+}
+
+static krb5_error_code
+keyblock_key_proc(krb5_context context, krb5_enctype enctype,
+                 krb5_const_pointer keyseed,
+                 krb5_salt salt, krb5_data *s2kparms,
+                 krb5_keyblock **key)
+{
+    return krb5_copy_keyblock (context, keyseed, key);
+}
+
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_init_creds_set_keyblock(krb5_context context,
+                            krb5_init_creds_context ctx,
+                            krb5_keyblock *keyblock)
+{
+    ctx->keyseed = (void *)keyblock;
+    ctx->keyproc = keyblock_key_proc;
+
+    return 0;
+}
+
+/**
+ * The core loop if krb5_get_init_creds() function family. Create the
+ * packets and have the caller send them off to the KDC. 
+ *
+ * If the caller want all work been done for them, use
+ * krb5_init_creds_get() instead.
+ *
+ * @param context a Kerberos 5 context.
+ * @param ctx ctx krb5_init_creds_context context.
+ * @param in input data from KDC, first round it should be reset by krb5_data_zer().
+ * @param out reply to KDC.
+ * @param hostinfo KDC address info, first round it can be NULL.
+ * @param flags status of the round, if 1 is set, continue one more round.
+ *
+ * @return 0 for success, or an Kerberos 5 error code, see
+ *     krb5_get_error_message().
+ *
+ * @ingroup krb5_credential
+ */
+
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_init_creds_step(krb5_context context,
+                    krb5_init_creds_context ctx,
+                    krb5_data *in,
+                    krb5_data *out,
+                    krb5_krbhst_info *hostinfo,
+                    unsigned int *flags)
+{
+    krb5_error_code ret;
+    size_t len;
+    size_t size;
 
 
-       memset (&rep, 0, sizeof(rep));
-       ret = decode_AS_REP(resp.data, resp.length, &rep.kdc_rep, &size);
+    krb5_data_zero(out);
+
+    if (ctx->as_req.req_body.cname == NULL) {
+       ret = init_as_req(context, ctx->flags, &ctx->cred,
+                         ctx->addrs, ctx->etypes, &ctx->as_req);
+       if (ret) {
+           free_init_creds_ctx(context, ctx);
+           return ret;
+       }
+    }
+
+#define MAX_PA_COUNTER 10
+    if (ctx->pa_counter > MAX_PA_COUNTER) {
+       krb5_set_error_message(context, KRB5_GET_IN_TKT_LOOP,
+                              N_("Looping %d times while getting "
+                                 "initial credentials", ""),
+                              ctx->pa_counter);
+       return KRB5_GET_IN_TKT_LOOP;
+    }
+    ctx->pa_counter++;
+
+    /* Lets process the input packet */
+    if (in && in->length) {
+       krb5_kdc_rep rep;
+
+       memset(&rep, 0, sizeof(rep));
+
+       ret = decode_AS_REP(in->data, in->length, &rep.kdc_rep, &size);
        if (ret == 0) {
        if (ret == 0) {
-           krb5_data_free(&resp);
-           krb5_clear_error_message(context);
-           break;
+           krb5_keyblock *key = NULL;
+           unsigned eflags = EXTRACT_TICKET_AS_REQ;
+
+           if (ctx->flags.canonicalize) {
+               eflags |= EXTRACT_TICKET_ALLOW_SERVER_MISMATCH;
+               eflags |= EXTRACT_TICKET_MATCH_REALM;
+           }
+           if (ctx->ic_flags & KRB5_INIT_CREDS_NO_C_CANON_CHECK)
+               eflags |= EXTRACT_TICKET_ALLOW_CNAME_MISMATCH;
+
+           ret = process_pa_data_to_key(context, ctx, &ctx->cred,
+                                        &ctx->as_req, &rep.kdc_rep, hostinfo, &key);
+           if (ret) {
+               free_AS_REP(&rep.kdc_rep);
+               goto out;
+           }
+
+           ret = _krb5_extract_ticket(context,
+                                      &rep,
+                                      &ctx->cred,
+                                      key,
+                                      NULL,
+                                      KRB5_KU_AS_REP_ENC_PART,
+                                      NULL,
+                                      ctx->nonce,
+                                      eflags,
+                                      NULL,
+                                      NULL);
+           krb5_free_keyblock(context, key);
+
+           *flags = 0;
+
+           if (ret == 0)
+               ret = copy_EncKDCRepPart(&rep.enc_part, &ctx->enc_part);
+
+           free_AS_REP(&rep.kdc_rep);
+           free_EncASRepPart(&rep.enc_part);
+
+           return ret;
+
        } else {
            /* let's try to parse it as a KRB-ERROR */
        } else {
            /* let's try to parse it as a KRB-ERROR */
-           KRB_ERROR error;
 
 
-           ret = krb5_rd_error(context, &resp, &error);
-           if(ret && resp.data && ((char*)resp.data)[0] == 4)
+           free_KRB_ERROR(&ctx->error);
+
+           ret = krb5_rd_error(context, in, &ctx->error);
+           if(ret && in->length && ((char*)in->data)[0] == 4)
                ret = KRB5KRB_AP_ERR_V4_REPLY;
                ret = KRB5KRB_AP_ERR_V4_REPLY;
-           krb5_data_free(&resp);
            if (ret)
                goto out;
 
            if (ret)
                goto out;
 
-           ret = krb5_error_from_rd_error(context, &error, creds);
+           ret = krb5_error_from_rd_error(context, &ctx->error, &ctx->cred);
 
            /*
             * If no preauth was set and KDC requires it, give it one
 
            /*
             * If no preauth was set and KDC requires it, give it one
@@ -1315,169 +1574,198 @@ init_cred_loop(krb5_context context,
             */
 
            if (ret == KRB5KDC_ERR_PREAUTH_REQUIRED) {
             */
 
            if (ret == KRB5KDC_ERR_PREAUTH_REQUIRED) {
-               free_METHOD_DATA(&md);
-               memset(&md, 0, sizeof(md));
 
 
-               if (error.e_data) {
-                   ret = decode_METHOD_DATA(error.e_data->data,
-                                            error.e_data->length,
-                                            &md,
+               free_METHOD_DATA(&ctx->md);
+               memset(&ctx->md, 0, sizeof(ctx->md));
+
+               if (ctx->error.e_data) {
+                   ret = decode_METHOD_DATA(ctx->error.e_data->data,
+                                            ctx->error.e_data->length,
+                                            &ctx->md,
                                             NULL);
                    if (ret)
                        krb5_set_error_message(context, ret,
                                             NULL);
                    if (ret)
                        krb5_set_error_message(context, ret,
-                                              N_("failed to decode METHOD DATA", ""));
+                                              N_("Failed to decode METHOD-DATA", ""));
                } else {
                } else {
-                   /* XXX guess what the server want here add add md */
+                   krb5_set_error_message(context, ret,
+                                          N_("Preauth required but no preauth "
+                                             "options send by KDC", ""));
                }
                }
-               krb5_free_error_contents(context, &error);
-               if (ret)
+           } else if (ret == KRB5KRB_AP_ERR_SKEW && context->kdc_sec_offset == 0) {
+               /* 
+                * Try adapt to timeskrew when we are using pre-auth, and
+                * if there was a time skew, try again.
+                */
+               krb5_set_real_time(context, ctx->error.stime, -1);
+               if (context->kdc_sec_offset)
+                   ret = 0; 
+           } else if (ret == KRB5_KDC_ERR_WRONG_REALM && ctx->flags.canonicalize) {
+               /* client referal to a new realm */
+               if (ctx->error.crealm) {
+                   krb5_set_error_message(context, ret,
+                                          N_("Got a client referral, not but no realm", ""));
                    goto out;
                    goto out;
-           } else {
-               _krb5_get_init_creds_opt_set_krb5_error(context,
-                                                       init_cred_opts,
-                                                       &error);
-               if (ret_as_reply)
-                   rep.error = error;
-               else
-                   krb5_free_error_contents(context, &error);
-               goto out;
+               }
+               ret = krb5_principal_set_realm(context, 
+                                              ctx->cred.client,
+                                              *ctx->error.crealm);
            }
            }
+           if (ret)
+               goto out;
        }
     }
 
        }
     }
 
-    {
-       krb5_keyblock *key = NULL;
-       unsigned flags = EXTRACT_TICKET_AS_REQ;
+    if (ctx->as_req.padata) {
+       free_METHOD_DATA(ctx->as_req.padata);
+       free(ctx->as_req.padata);
+       ctx->as_req.padata = NULL;
+    }
 
 
-       if (ctx->flags.request_anonymous)
-           flags |= EXTRACT_TICKET_ALLOW_SERVER_MISMATCH;
-       if (ctx->flags.canonicalize) {
-           flags |= EXTRACT_TICKET_ALLOW_SERVER_MISMATCH;
-           flags |= EXTRACT_TICKET_MATCH_REALM;
-       }
-       if (ctx->ic_flags & KRB5_INIT_CREDS_NO_C_CANON_CHECK)
-           flags |= EXTRACT_TICKET_ALLOW_CNAME_MISMATCH;
+    /* Set a new nonce. */
+    ctx->as_req.req_body.nonce = ctx->nonce;
+
+    /* fill_in_md_data */
+    ret = process_pa_data_to_md(context, &ctx->cred, &ctx->as_req, ctx,
+                               &ctx->md, &ctx->as_req.padata,
+                               ctx->prompter, ctx->prompter_data);
+    if (ret)
+       goto out;
 
 
-       ret = process_pa_data_to_key(context, ctx, creds,
-                                    &ctx->as_req, &rep, hi, &key);
-       if (ret)
-           goto out;
-       
-       ret = _krb5_extract_ticket(context,
-                                  &rep,
-                                  creds,
-                                  key,
-                                  NULL,
-                                  KRB5_KU_AS_REP_ENC_PART,
-                                  NULL,
-                                  ctx->nonce,
-                                  flags,
-                                  NULL,
-                                  NULL);
-       krb5_free_keyblock(context, key);
-    }
-out:
-    if (stctx)
-       krb5_sendto_ctx_free(context, stctx);
     krb5_data_free(&ctx->req_buffer);
     krb5_data_free(&ctx->req_buffer);
-    free_METHOD_DATA(&md);
-    memset(&md, 0, sizeof(md));
 
 
-    if (ret == 0 && ret_as_reply)
-       *ret_as_reply = rep;
-    else
-       krb5_free_kdc_rep (context, &rep);
+    ASN1_MALLOC_ENCODE(AS_REQ,
+                      ctx->req_buffer.data, ctx->req_buffer.length,
+                      &ctx->as_req, &len, ret);
+    if (ret)
+       goto out;
+    if(len != ctx->req_buffer.length)
+       krb5_abortx(context, "internal error in ASN.1 encoder");
+
+    out->data = ctx->req_buffer.data;
+    out->length = ctx->req_buffer.length;
+
+    *flags = 1;
+
+    return 0;
+ out:
     return ret;
 }
 
     return ret;
 }
 
+/**
+ * Extract the newly acquired credentials from krb5_init_creds_context
+ * context.
+ *
+ * @param context A Kerberos 5 context.
+ * @param ctx
+ * @param cred credentials, free with krb5_free_cred_contents().
+ *
+ * @return 0 for sucess or An Kerberos error code, see krb5_get_error_message().
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_error_code KRB5_LIB_FUNCTION
-krb5_get_init_creds(krb5_context context,
-                   krb5_creds *creds,
-                   krb5_principal client,
-                   krb5_prompter_fct prompter,
-                   void *data,
-                   krb5_deltat start_time,
-                   const char *in_tkt_service,
-                   krb5_get_init_creds_opt *options)
+krb5_init_creds_get_creds(krb5_context context,
+                         krb5_init_creds_context ctx,
+                         krb5_creds *cred)
 {
 {
-    krb5_get_init_creds_ctx ctx;
-    krb5_kdc_rep kdc_reply;
-    krb5_error_code ret;
-    char buf[BUFSIZ];
-    int done;
+    return krb5_copy_creds_contents(context, &ctx->cred, cred);
+}
+
+/**
+ * Get the last error from the transaction.
+ *
+ * @return Returns 0 or an error code
+ *
+ * @ingroup krb5_credential
+ */
 
 
-    memset(&kdc_reply, 0, sizeof(kdc_reply));
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_init_creds_get_error(krb5_context context,
+                         krb5_init_creds_context ctx,
+                         KRB_ERROR *error)
+{
+    krb5_error_code ret;
 
 
-    ret = get_init_creds_common(context, client, start_time,
-                               in_tkt_service, options, &ctx);
+    ret = copy_KRB_ERROR(&ctx->error, error);
     if (ret)
     if (ret)
-       goto out;
+       krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
 
 
-    done = 0;
-    while(!done) {
-       memset(&kdc_reply, 0, sizeof(kdc_reply));
-
-       ret = init_cred_loop(context,
-                            options,
-                            prompter,
-                            data,
-                            &ctx,
-                            &ctx.cred,
-                            &kdc_reply);
-       
-       switch (ret) {
-       case 0 :
-           done = 1;
-           break;
-       case KRB5KDC_ERR_KEY_EXPIRED :
-           /* try to avoid recursion */
+    return ret;
+}
 
 
-           /* don't try to change password where then where none */
-           if (prompter == NULL || ctx.password == NULL)
-               goto out;
+/**
+ * Free the krb5_init_creds_context allocated by krb5_init_creds_init().
+ *
+ * @param context A Kerberos 5 context.
+ * @param ctx The krb5_init_creds_context to free.
+ *
+ * @ingroup krb5_credential
+ */
 
 
-           krb5_clear_error_message (context);
+void KRB5_LIB_FUNCTION
+krb5_init_creds_free(krb5_context context,
+                    krb5_init_creds_context ctx)
+{
+    free_init_creds_ctx(context, ctx);
+    free(ctx);
+}
 
 
-           if (ctx.in_tkt_service != NULL
-               && strcmp (ctx.in_tkt_service, "kadmin/changepw") == 0)
-               goto out;
+/**
+ * Get new credentials as setup by the krb5_init_creds_context.
+ *
+ * @param context A Kerberos 5 context.
+ * @param ctx The krb5_init_creds_context to process.
+ *
+ * @ingroup krb5_credential
+ */
 
 
-           ret = change_password (context,
-                                  client,
-                                  ctx.password,
-                                  buf,
-                                  sizeof(buf),
-                                  prompter,
-                                  data,
-                                  options);
-           if (ret)
-               goto out;
-           ctx.password = buf;
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_init_creds_get(krb5_context context, krb5_init_creds_context ctx)
+{
+    krb5_sendto_ctx stctx = NULL;
+    krb5_krbhst_info *hostinfo = NULL;
+    krb5_error_code ret;
+    krb5_data in, out;
+    unsigned int flags = 0;
+
+    krb5_data_zero(&in);
+    krb5_data_zero(&out);
+
+    ret = krb5_sendto_ctx_alloc(context, &stctx);
+    if (ret)
+       goto out;
+    krb5_sendto_ctx_set_func(stctx, _krb5_kdc_retry, NULL);
+
+    while (1) {
+       flags = 0;
+       ret = krb5_init_creds_step(context, ctx, &in, &out, hostinfo, &flags);
+       krb5_data_free(&in);
+       if (ret)
+           goto out;
+
+       if ((flags & 1) == 0)
            break;
            break;
-       default:
+
+       ret = krb5_sendto_context (context, stctx, &out, 
+                                  ctx->cred.client->realm, &in);
+       if (ret)
            goto out;
            goto out;
-       }
-    }
 
 
-    if (prompter)
-       print_expire (context,
-                     krb5_principal_get_realm (context, ctx.cred.client),
-                     &kdc_reply,
-                     prompter,
-                     data);
+    }
 
  out:
 
  out:
-    memset (buf, 0, sizeof(buf));
-    free_init_creds_ctx(context, &ctx);
-    krb5_free_kdc_rep (context, &kdc_reply);
-    if (ret == 0)
-       *creds = ctx.cred;
-    else
-       krb5_free_cred_contents (context, &ctx.cred);
+    if (stctx)
+       krb5_sendto_ctx_free(context, stctx);
 
     return ret;
 }
 
 
     return ret;
 }
 
+/**
+ * Get new credentials using password.
+ *
+ * @ingroup krb5_credential
+ */
+
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_get_init_creds_password(krb5_context context,
                             krb5_creds *creds,
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_get_init_creds_password(krb5_context context,
                             krb5_creds *creds,
@@ -1487,29 +1775,23 @@ krb5_get_init_creds_password(krb5_context context,
                             void *data,
                             krb5_deltat start_time,
                             const char *in_tkt_service,
                             void *data,
                             krb5_deltat start_time,
                             const char *in_tkt_service,
-                            krb5_get_init_creds_opt *in_options)
+                            krb5_get_init_creds_opt *options)
 {
 {
-    krb5_get_init_creds_opt *options;
+    krb5_init_creds_context ctx;
     char buf[BUFSIZ];
     krb5_error_code ret;
     char buf[BUFSIZ];
     krb5_error_code ret;
+    int chpw = 0;
 
 
-    if (in_options == NULL) {
-       const char *realm = krb5_principal_get_realm(context, client);
-       ret = krb5_get_init_creds_opt_alloc(context, &options);
-       if (ret == 0)
-           krb5_get_init_creds_opt_set_default_flags(context,
-                                                     NULL,
-                                                     realm,
-                                                     options);
-    } else
-       ret = _krb5_get_init_creds_opt_copy(context, in_options, &options);
+ again:
+    ret = krb5_init_creds_init(context, client, prompter, data, start_time, options, &ctx);
     if (ret)
     if (ret)
-       return ret;
+       goto out;
 
 
-    if (password == NULL &&
-       options->opt_private->password == NULL &&
-       options->opt_private->pk_init_ctx == NULL)
-    {
+    ret = krb5_init_creds_set_service(context, ctx, in_tkt_service);
+    if (ret)
+       goto out;
+
+    if (prompter != NULL && ctx->password == NULL && password == NULL) {
        krb5_prompt prompt;
        krb5_data password_data;
        char *p, *q;
        krb5_prompt prompt;
        krb5_data password_data;
        char *p, *q;
@@ -1528,40 +1810,67 @@ krb5_get_init_creds_password(krb5_context context,
        free (q);
        if (ret) {
            memset (buf, 0, sizeof(buf));
        free (q);
        if (ret) {
            memset (buf, 0, sizeof(buf));
-           krb5_get_init_creds_opt_free(context, options);
            ret = KRB5_LIBOS_PWDINTR;
            krb5_clear_error_message (context);
            ret = KRB5_LIBOS_PWDINTR;
            krb5_clear_error_message (context);
-           return ret;
+           goto out;
        }
        password = password_data.data;
     }
 
        }
        password = password_data.data;
     }
 
-    if (options->opt_private->password == NULL) {
-       ret = krb5_get_init_creds_opt_set_pa_password(context, options,
-                                                     password, NULL);
-       if (ret) {
-           krb5_get_init_creds_opt_free(context, options);
-           memset(buf, 0, sizeof(buf));
-           return ret;
-       }
+    if (password) {
+       ret = krb5_init_creds_set_password(context, ctx, password);
+       if (ret)
+           goto out;
     }
 
     }
 
-    ret = krb5_get_init_creds(context, creds, client, prompter,
-                             data, start_time, in_tkt_service, options);
-    krb5_get_init_creds_opt_free(context, options);
+    ret = krb5_init_creds_get(context, ctx);
+    
+    if (ret == 0)
+       process_last_request(context, options, ctx);
+
+
+    if (ret == KRB5KDC_ERR_KEY_EXPIRED && chpw == 0) {
+       char buf[1024];
+
+       /* try to avoid recursion */
+       if (in_tkt_service != NULL && strcmp(in_tkt_service, "kadmin/changepw") == 0)
+          goto out;
+
+       /* don't try to change password where then where none */
+       if (prompter == NULL)
+           goto out;
+
+       ret = change_password (context,
+                              client,
+                              ctx->password,
+                              buf,
+                              sizeof(buf),
+                              prompter,
+                              data,
+                              options);
+       if (ret)
+           goto out;
+       chpw = 1;
+       krb5_init_creds_free(context, ctx);
+       goto again;
+    }
+
+ out:
+    if (ret == 0)
+       krb5_init_creds_get_creds(context, ctx, creds);
+
+    if (ctx)
+       krb5_init_creds_free(context, ctx);
+
     memset(buf, 0, sizeof(buf));
     return ret;
 }
 
     memset(buf, 0, sizeof(buf));
     return ret;
 }
 
-static krb5_error_code
-init_creds_keyblock_key_proc (krb5_context context,
-                             krb5_enctype type,
-                             krb5_salt salt,
-                             krb5_const_pointer keyseed,
-                             krb5_keyblock **key)
-{
-    return krb5_copy_keyblock (context, keyseed, key);
-}
+/**
+ * Get new credentials using keyblock.
+ *
+ * @ingroup krb5_credential
+ */
 
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_get_init_creds_keyblock(krb5_context context,
 
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_get_init_creds_keyblock(krb5_context context,
@@ -1572,33 +1881,80 @@ krb5_get_init_creds_keyblock(krb5_context context,
                             const char *in_tkt_service,
                             krb5_get_init_creds_opt *options)
 {
                             const char *in_tkt_service,
                             krb5_get_init_creds_opt *options)
 {
-    struct krb5_get_init_creds_ctx ctx;
+    krb5_init_creds_context ctx;
     krb5_error_code ret;
 
     krb5_error_code ret;
 
-    ret = get_init_creds_common(context, client, start_time,
-                               in_tkt_service, options, &ctx);
+    memset(creds, 0, sizeof(*creds));
+
+    ret = krb5_init_creds_init(context, client, NULL, NULL, start_time, options, &ctx);
     if (ret)
        goto out;
 
     if (ret)
        goto out;
 
-    ret = krb5_get_in_cred (context,
-                           KDCOptions2int(ctx.flags),
-                           ctx.addrs,
-                           ctx.etypes,
-                           ctx.pre_auth_types,
-                           NULL,
-                           init_creds_keyblock_key_proc,
-                           keyblock,
-                           NULL,
-                           NULL,
-                           &ctx.cred,
-                           NULL);
-
-    if (ret == 0 && creds)
-       *creds = ctx.cred;
-    else
-       krb5_free_cred_contents (context, &ctx.cred);
+    ret = krb5_init_creds_set_service(context, ctx, in_tkt_service);
+    if (ret)
+       goto out;
+
+    ret = krb5_init_creds_set_keyblock(context, ctx, keyblock);
+    if (ret)
+       goto out;
+
+    ret = krb5_init_creds_get(context, ctx);
+
+    if (ret == 0)
+        process_last_request(context, options, ctx);
+
+ out:
+    if (ret == 0)
+       krb5_init_creds_get_creds(context, ctx, creds);
+
+    if (ctx)
+       krb5_init_creds_free(context, ctx);
+
+    return ret;
+}
+
+/**
+ * Get new credentials using keytab.
+ *
+ * @ingroup krb5_credential
+ */
+
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_get_init_creds_keytab(krb5_context context,
+                          krb5_creds *creds,
+                          krb5_principal client,
+                          krb5_keytab keytab,
+                          krb5_deltat start_time,
+                          const char *in_tkt_service,
+                          krb5_get_init_creds_opt *options)
+{
+    krb5_init_creds_context ctx;
+    krb5_error_code ret;
+
+    memset(creds, 0, sizeof(*creds));
+
+    ret = krb5_init_creds_init(context, client, NULL, NULL, start_time, options, &ctx);
+    if (ret)
+       goto out;
+
+    ret = krb5_init_creds_set_service(context, ctx, in_tkt_service);
+    if (ret)
+       goto out;
+
+    ret = krb5_init_creds_set_keytab(context, ctx, keytab);
+    if (ret)
+       goto out;
+
+    ret = krb5_init_creds_get(context, ctx);
+    if (ret == 0)
+        process_last_request(context, options, ctx);
 
  out:
 
  out:
-    free_init_creds_ctx(context, &ctx);
+    if (ret == 0)
+       krb5_init_creds_get_creds(context, ctx, creds);
+
+    if (ctx)
+       krb5_init_creds_free(context, ctx);
+
     return ret;
 }
     return ret;
 }
index 8a8f1efc11a09334db2498adf12d8bb240675b73..f0343419725f5aa0a8569f328ba478128f6a2537 100644 (file)
 
 #include "kcm.h"
 
 
 #include "kcm.h"
 
-RCSID("$Id$");
-
 typedef struct krb5_kcmcache {
     char *name;
     struct sockaddr_un path;
     char *door_path;
 } krb5_kcmcache;
 
 typedef struct krb5_kcmcache {
     char *name;
     struct sockaddr_un path;
     char *door_path;
 } krb5_kcmcache;
 
+typedef struct krb5_kcm_cursor {
+    unsigned long offset;
+    unsigned long length;
+    kcmuuid_t *uuids;
+} *krb5_kcm_cursor;
+
+
 #define KCMCACHE(X)    ((krb5_kcmcache *)(X)->data.data)
 #define CACHENAME(X)   (KCMCACHE(X)->name)
 #define KCMCACHE(X)    ((krb5_kcmcache *)(X)->data.data)
 #define CACHENAME(X)   (KCMCACHE(X)->name)
-#define KCMCURSOR(C)   (*(uint32_t *)(C))
+#define KCMCURSOR(C)   ((krb5_kcm_cursor)(C))
+
+#ifdef HAVE_DOOR_CREATE
 
 static krb5_error_code
 try_door(krb5_context context,
 
 static krb5_error_code
 try_door(krb5_context context,
@@ -61,7 +68,6 @@ try_door(krb5_context context,
         krb5_data *request_data,
         krb5_data *response_data)
 {
         krb5_data *request_data,
         krb5_data *response_data)
 {
-#ifdef HAVE_DOOR_CREATE
     door_arg_t arg;
     int fd;
     int ret;
     door_arg_t arg;
     int fd;
     int ret;
@@ -91,10 +97,8 @@ try_door(krb5_context context,
        return ret;
 
     return 0;
        return ret;
 
     return 0;
-#else
-    return KRB5_CC_IO;
-#endif
 }
 }
+#endif /* HAVE_DOOR_CREATE */
 
 static krb5_error_code
 try_unix_socket(krb5_context context,
 
 static krb5_error_code
 try_unix_socket(krb5_context context,
@@ -143,9 +147,11 @@ kcm_send_request(krb5_context context,
     ret = KRB5_CC_NOSUPP;
 
     for (i = 0; i < context->max_retries; i++) {
     ret = KRB5_CC_NOSUPP;
 
     for (i = 0; i < context->max_retries; i++) {
+#ifdef HAVE_DOOR_CREATE
        ret = try_door(context, k, &request_data, response_data);
        if (ret == 0 && response_data->length != 0)
            break;
        ret = try_door(context, k, &request_data, response_data);
        if (ret == 0 && response_data->length != 0)
            break;
+#endif
        ret = try_unix_socket(context, k, &request_data, response_data);
        if (ret == 0 && response_data->length != 0)
            break;
        ret = try_unix_socket(context, k, &request_data, response_data);
        if (ret == 0 && response_data->length != 0)
            break;
@@ -207,7 +213,8 @@ kcm_alloc(krb5_context context, const char *name, krb5_ccache *id)
 
     k = malloc(sizeof(*k));
     if (k == NULL) {
 
     k = malloc(sizeof(*k));
     if (k == NULL) {
-       krb5_set_error_message(context, KRB5_CC_NOMEM, N_("malloc: out of memory", ""));
+       krb5_set_error_message(context, KRB5_CC_NOMEM,
+                              N_("malloc: out of memory", ""));
        return KRB5_CC_NOMEM;
     }
 
        return KRB5_CC_NOMEM;
     }
 
@@ -309,8 +316,6 @@ kcm_free(krb5_context context, krb5_ccache *id)
        memset(k, 0, sizeof(*k));
        krb5_data_free(&(*id)->data);
     }
        memset(k, 0, sizeof(*k));
        krb5_data_free(&(*id)->data);
     }
-
-    *id = NULL;
 }
 
 static const char *
 }
 
 static const char *
@@ -609,10 +614,10 @@ kcm_get_first (krb5_context context,
               krb5_cc_cursor *cursor)
 {
     krb5_error_code ret;
               krb5_cc_cursor *cursor)
 {
     krb5_error_code ret;
+    krb5_kcm_cursor c;
     krb5_kcmcache *k = KCMCACHE(id);
     krb5_storage *request, *response;
     krb5_data response_data;
     krb5_kcmcache *k = KCMCACHE(id);
     krb5_storage *request, *response;
     krb5_data response_data;
-    int32_t tmp;
 
     ret = kcm_storage_request(context, KCM_OP_GET_FIRST, &request);
     if (ret)
 
     ret = kcm_storage_request(context, KCM_OP_GET_FIRST, &request);
     if (ret)
@@ -625,27 +630,56 @@ kcm_get_first (krb5_context context,
     }
 
     ret = kcm_call(context, k, request, &response, &response_data);
     }
 
     ret = kcm_call(context, k, request, &response, &response_data);
-    if (ret) {
-       krb5_storage_free(request);
+    krb5_storage_free(request);
+    if (ret)
+       return ret;
+
+    c = calloc(1, sizeof(*c));
+    if (c == NULL) {
+       ret = ENOMEM;
+       krb5_set_error_message(context, ret, 
+                              N_("malloc: out of memory", ""));
        return ret;
     }
 
        return ret;
     }
 
-    ret = krb5_ret_int32(response, &tmp);
-    if (ret || tmp < 0)
-       ret = KRB5_CC_IO;
+    while (1) {
+       ssize_t sret;
+       kcmuuid_t uuid;
+       void *ptr;
+
+       sret = krb5_storage_read(response, &uuid, sizeof(uuid));
+       if (sret == 0) {
+           ret = 0;
+           break;
+       } else if (sret != sizeof(uuid)) {
+           ret = EINVAL;
+           break;
+       }
+
+       ptr = realloc(c->uuids, sizeof(c->uuids[0]) * (c->length + 1));
+       if (ptr == NULL) {
+           free(c->uuids);
+           free(c);
+           krb5_set_error_message(context, ENOMEM, 
+                                  N_("malloc: out of memory", ""));
+           return ENOMEM;
+       }
+       c->uuids = ptr;
+
+       memcpy(&c->uuids[c->length], &uuid, sizeof(uuid));
+       c->length += 1;
+    }
 
 
-    krb5_storage_free(request);
     krb5_storage_free(response);
     krb5_data_free(&response_data);
 
     krb5_storage_free(response);
     krb5_data_free(&response_data);
 
-    if (ret)
+    if (ret) {
+        free(c->uuids);
+        free(c);
        return ret;
        return ret;
+    }
 
 
-    *cursor = malloc(sizeof(tmp));
-    if (*cursor == NULL)
-       return KRB5_CC_NOMEM;
-
-    KCMCURSOR(*cursor) = tmp;
+    *cursor = c;
 
     return 0;
 }
 
     return 0;
 }
@@ -666,8 +700,15 @@ kcm_get_next (krb5_context context,
 {
     krb5_error_code ret;
     krb5_kcmcache *k = KCMCACHE(id);
 {
     krb5_error_code ret;
     krb5_kcmcache *k = KCMCACHE(id);
+    krb5_kcm_cursor c = KCMCURSOR(*cursor);
     krb5_storage *request, *response;
     krb5_data response_data;
     krb5_storage *request, *response;
     krb5_data response_data;
+    ssize_t sret;
+
+ again:
+
+    if (c->offset >= c->length)
+       return KRB5_CC_END;
 
     ret = kcm_storage_request(context, KCM_OP_GET_NEXT, &request);
     if (ret)
 
     ret = kcm_storage_request(context, KCM_OP_GET_NEXT, &request);
     if (ret)
@@ -679,23 +720,26 @@ kcm_get_next (krb5_context context,
        return ret;
     }
 
        return ret;
     }
 
-    ret = krb5_store_int32(request, KCMCURSOR(*cursor));
-    if (ret) {
+    sret = krb5_storage_write(request, 
+                             &c->uuids[c->offset],
+                             sizeof(c->uuids[c->offset]));
+    c->offset++;
+    if (sret != sizeof(c->uuids[c->offset])) {
        krb5_storage_free(request);
        krb5_storage_free(request);
-       return ret;
+       krb5_clear_error_message(context);
+       return ENOMEM;
     }
 
     ret = kcm_call(context, k, request, &response, &response_data);
     }
 
     ret = kcm_call(context, k, request, &response, &response_data);
-    if (ret) {
-       krb5_storage_free(request);
-       return ret;
+    krb5_storage_free(request);
+    if (ret == KRB5_CC_END) {
+       goto again;
     }
 
     ret = krb5_ret_creds(response, creds);
     if (ret)
        ret = KRB5_CC_IO;
 
     }
 
     ret = krb5_ret_creds(response, creds);
     if (ret)
        ret = KRB5_CC_IO;
 
-    krb5_storage_free(request);
     krb5_storage_free(response);
     krb5_data_free(&response_data);
 
     krb5_storage_free(response);
     krb5_data_free(&response_data);
 
@@ -717,6 +761,7 @@ kcm_end_get (krb5_context context,
 {
     krb5_error_code ret;
     krb5_kcmcache *k = KCMCACHE(id);
 {
     krb5_error_code ret;
     krb5_kcmcache *k = KCMCACHE(id);
+    krb5_kcm_cursor c = KCMCURSOR(*cursor);
     krb5_storage *request;
 
     ret = kcm_storage_request(context, KCM_OP_END_GET, &request);
     krb5_storage *request;
 
     ret = kcm_storage_request(context, KCM_OP_END_GET, &request);
@@ -729,22 +774,14 @@ kcm_end_get (krb5_context context,
        return ret;
     }
 
        return ret;
     }
 
-    ret = krb5_store_int32(request, KCMCURSOR(*cursor));
-    if (ret) {
-       krb5_storage_free(request);
-       return ret;
-    }
-
     ret = kcm_call(context, k, request, NULL, NULL);
     ret = kcm_call(context, k, request, NULL, NULL);
-    if (ret) {
-       krb5_storage_free(request);
+    krb5_storage_free(request);
+    if (ret)
        return ret;
        return ret;
-    }
 
 
-    krb5_storage_free(request);
+    free(c->uuids);
+    free(c);
 
 
-    KCMCURSOR(*cursor) = 0;
-    free(*cursor);
     *cursor = NULL;
 
     return ret;
     *cursor = NULL;
 
     return ret;
index aa6353d7c82c109e616bf0b59f87d8b8cd57e729..57ed7875fc46b0c4e2db183ed261a27b7df287f8 100644 (file)
 
 #include "krb5_locl.h"
 
 
 #include "krb5_locl.h"
 
-RCSID("$Id$");
+/**
+ * Zero out a keyblock
+ *
+ * @param keyblock keyblock to zero out
+ *
+ * @ingroup krb5_crypto
+ */
 
 void KRB5_LIB_FUNCTION
 krb5_keyblock_zero(krb5_keyblock *keyblock)
 
 void KRB5_LIB_FUNCTION
 krb5_keyblock_zero(krb5_keyblock *keyblock)
@@ -42,6 +48,15 @@ krb5_keyblock_zero(krb5_keyblock *keyblock)
     krb5_data_zero(&keyblock->keyvalue);
 }
 
     krb5_data_zero(&keyblock->keyvalue);
 }
 
+/**
+ * Free a keyblock's content, also zero out the content of the keyblock.
+ *
+ * @param context a Kerberos 5 context
+ * @param keyblock keyblock content to free, NULL is valid argument
+ *
+ * @ingroup krb5_crypto
+ */
+
 void KRB5_LIB_FUNCTION
 krb5_free_keyblock_contents(krb5_context context,
                            krb5_keyblock *keyblock)
 void KRB5_LIB_FUNCTION
 krb5_free_keyblock_contents(krb5_context context,
                            krb5_keyblock *keyblock)
@@ -54,6 +69,16 @@ krb5_free_keyblock_contents(krb5_context context,
     }
 }
 
     }
 }
 
+/**
+ * Free a keyblock, also zero out the content of the keyblock, uses
+ * krb5_free_keyblock_contents() to free the content.
+ *
+ * @param context a Kerberos 5 context
+ * @param keyblock keyblock to free, NULL is valid argument
+ *
+ * @ingroup krb5_crypto
+ */
+
 void KRB5_LIB_FUNCTION
 krb5_free_keyblock(krb5_context context,
                   krb5_keyblock *keyblock)
 void KRB5_LIB_FUNCTION
 krb5_free_keyblock(krb5_context context,
                   krb5_keyblock *keyblock)
@@ -64,6 +89,19 @@ krb5_free_keyblock(krb5_context context,
     }
 }
 
     }
 }
 
+/**
+ * Copy a keyblock, free the output keyblock with
+ * krb5_free_keyblock_contents().
+ *
+ * @param context a Kerberos 5 context
+ * @param inblock the key to copy
+ * @param to the output key.
+ *
+ * @param 0 on success or a Kerberos 5 error code
+ *
+ * @ingroup krb5_crypto
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_copy_keyblock_contents (krb5_context context,
                             const krb5_keyblock *inblock,
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_copy_keyblock_contents (krb5_context context,
                             const krb5_keyblock *inblock,
@@ -72,31 +110,62 @@ krb5_copy_keyblock_contents (krb5_context context,
     return copy_EncryptionKey(inblock, to);
 }
 
     return copy_EncryptionKey(inblock, to);
 }
 
+/**
+ * Copy a keyblock, free the output keyblock with
+ * krb5_free_keyblock().
+ *
+ * @param context a Kerberos 5 context
+ * @param inblock the key to copy
+ * @param to the output key.
+ *
+ * @param 0 on success or a Kerberos 5 error code
+ *
+ * @ingroup krb5_crypto
+ */
+
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_copy_keyblock (krb5_context context,
                    const krb5_keyblock *inblock,
                    krb5_keyblock **to)
 {
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_copy_keyblock (krb5_context context,
                    const krb5_keyblock *inblock,
                    krb5_keyblock **to)
 {
+    krb5_error_code ret;
     krb5_keyblock *k;
     krb5_keyblock *k;
+    
+    *to = NULL;
 
 
-    k = malloc (sizeof(*k));
+    k = calloc (1, sizeof(*k));
     if (k == NULL) {
        krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     if (k == NULL) {
        krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
+
+    ret = krb5_copy_keyblock_contents (context, inblock, k);
+    if (ret) {
+      free(k);
+      return ret;
+    }
     *to = k;
     *to = k;
-    return krb5_copy_keyblock_contents (context, inblock, k);
+    return 0;
 }
 
 }
 
+/**
+ * Get encryption type of a keyblock.
+ *
+ * @ingroup krb5_crypto
+ */
+
 krb5_enctype
 krb5_keyblock_get_enctype(const krb5_keyblock *block)
 {
     return block->keytype;
 }
 
 krb5_enctype
 krb5_keyblock_get_enctype(const krb5_keyblock *block)
 {
     return block->keytype;
 }
 
-/*
+/**
  * Fill in `key' with key data of type `enctype' from `data' of length
  * Fill in `key' with key data of type `enctype' from `data' of length
- * `size'. Key should be freed using krb5_free_keyblock_contents.
+ * `size'. Key should be freed using krb5_free_keyblock_contents().
+ *
+ * @ingroup krb5_crypto
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
index aa7c77ce46c2f79f8feacd2c5e531bf12dbb7201..fcc74e847ea976e78572cd8cfae8b2da63aa18a9 100644 (file)
 
 #include "krb5_locl.h"
 
 
 #include "krb5_locl.h"
 
-RCSID("$Id$");
+/**
+ * @page krb5_keytab_intro The keytab handing functions
+ * @section section_krb5_keytab Kerberos Keytabs
+ *
+ * See the library functions here: @ref krb5_keytab
+ *
+ * Keytabs are long term key storage for servers, their equvalment of
+ * password files.
+ *
+ * Normally the only function that useful for server are to specify
+ * what keytab to use to other core functions like krb5_rd_req()
+ * krb5_kt_resolve(), and krb5_kt_close().
+ *
+ * @subsection krb5_keytab_names Keytab names
+ *
+ * A keytab name is on the form type:residual. The residual part is
+ * specific to each keytab-type.
+ * 
+ * When a keytab-name is resolved, the type is matched with an internal
+ * list of keytab types. If there is no matching keytab type,
+ * the default keytab is used. The current default type is FILE.
+ *
+ * The default value can be changed in the configuration file
+ * /etc/krb5.conf by setting the variable
+ * [defaults]default_keytab_name.
+ *
+ * The keytab types that are implemented in Heimdal are:
+ * - file 
+ *   store the keytab in a file, the type's name is FILE .  The
+ *   residual part is a filename. For compatibility with other
+ *   Kerberos implemtation WRFILE and JAVA14 is also accepted.  WRFILE
+ *   has the same format as FILE. JAVA14 have a format that is
+ *   compatible with older versions of MIT kerberos and SUN's Java
+ *   based installation.  They store a truncted kvno, so when the knvo
+ *   excess 255, they are truncted in this format.
+ *
+ * - keytab
+ *   store the keytab in a AFS keyfile (usually /usr/afs/etc/KeyFile ),
+ *   the type's name is AFSKEYFILE. The residual part is a filename.
+ *
+ * - krb4
+ *   the keytab is a Kerberos 4 srvtab that is on-the-fly converted to
+ *   a keytab. The type's name is krb4 The residual part is a
+ *   filename.
+ *
+ * - memory
+ *   The keytab is stored in a memory segment. This allows sensitive
+ *   and/or temporary data not to be stored on disk. The type's name
+ *   is MEMORY. Each MEMORY keytab is referenced counted by and
+ *   opened by the residual name, so two handles can point to the
+ *   same memory area.  When the last user closes the entry, it
+ *   disappears.
+ *
+ *
+ * @subsection krb5_keytab_example Keytab example
+ *
+ *  This is a minimalistic version of ktutil.
+ *
+ * @code
+int
+main (int argc, char **argv)
+{
+    krb5_context context;
+    krb5_keytab keytab;
+    krb5_kt_cursor cursor;
+    krb5_keytab_entry entry;
+    krb5_error_code ret;
+    char *principal;
 
 
-/*
- * Register a new keytab in `ops'
- * Return 0 or an error.
+    if (krb5_init_context (&context) != 0)
+       errx(1, "krb5_context");
+
+    ret = krb5_kt_default (context, &keytab);
+    if (ret)
+       krb5_err(context, 1, ret, "krb5_kt_default");
+
+    ret = krb5_kt_start_seq_get(context, keytab, &cursor);
+    if (ret)
+       krb5_err(context, 1, ret, "krb5_kt_start_seq_get");
+    while((ret = krb5_kt_next_entry(context, keytab, &entry, &cursor)) == 0){
+       krb5_unparse_name_short(context, entry.principal, &principal);
+       printf("principal: %s\n", principal);
+       free(principal);
+       krb5_kt_free_entry(context, &entry);
+    }
+    ret = krb5_kt_end_seq_get(context, keytab, &cursor);
+    if (ret)
+       krb5_err(context, 1, ret, "krb5_kt_end_seq_get");
+    ret = krb5_kt_close(context, keytab);
+    if (ret)
+       krb5_err(context, 1, ret, "krb5_kt_close");
+    krb5_free_context(context);
+    return 0;
+}
+ * @endcode
+ *
+ */
+
+
+/**
+ * Register a new keytab backend.
+ *
+ * @param context a Keberos context.
+ * @param ops a backend to register.
+ *
+ * @return Return an error code or 0, see krb5_get_error_message().
+ *
+ * @ingroup krb5_keytab
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
@@ -55,7 +158,8 @@ krb5_kt_register(krb5_context context,
     tmp = realloc(context->kt_types,
                  (context->num_kt_types + 1) * sizeof(*context->kt_types));
     if(tmp == NULL) {
     tmp = realloc(context->kt_types,
                  (context->num_kt_types + 1) * sizeof(*context->kt_types));
     if(tmp == NULL) {
-       krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
+       krb5_set_error_message(context, ENOMEM,
+                              N_("malloc: out of memory", ""));
        return ENOMEM;
     }
     memcpy(&tmp[context->num_kt_types], ops,
        return ENOMEM;
     }
     memcpy(&tmp[context->num_kt_types], ops,
@@ -65,12 +169,20 @@ krb5_kt_register(krb5_context context,
     return 0;
 }
 
     return 0;
 }
 
-/*
+/**
  * Resolve the keytab name (of the form `type:residual') in `name'
  * into a keytab in `id'.
  * Resolve the keytab name (of the form `type:residual') in `name'
  * into a keytab in `id'.
- * Return 0 or an error
+ *
+ * @param context a Keberos context.
+ * @param name name to resolve
+ * @param id resulting keytab, free with krb5_kt_close().
+ *
+ * @return Return an error code or 0, see krb5_get_error_message().
+ *
+ * @ingroup krb5_keytab
  */
 
  */
 
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_kt_resolve(krb5_context context,
                const char *name,
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_kt_resolve(krb5_context context,
                const char *name,
@@ -120,9 +232,16 @@ krb5_kt_resolve(krb5_context context,
     return ret;
 }
 
     return ret;
 }
 
-/*
+/**
  * copy the name of the default keytab into `name'.
  * copy the name of the default keytab into `name'.
- * Return 0 or KRB5_CONFIG_NOTENUFSPACE if `namesize' is too short.
+ *
+ * @param context a Keberos context.
+ * @param name buffer where the name will be written
+ * @param namesize length of name
+ *
+ * @return Return an error code or 0, see krb5_get_error_message().
+ *
+ * @ingroup krb5_keytab
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
@@ -135,9 +254,16 @@ krb5_kt_default_name(krb5_context context, char *name, size_t namesize)
     return 0;
 }
 
     return 0;
 }
 
-/*
- * copy the name of the default modify keytab into `name'.
- * Return 0 or KRB5_CONFIG_NOTENUFSPACE if `namesize' is too short.
+/**
+ * Copy the name of the default modify keytab into `name'.
+ *
+ * @param context a Keberos context.
+ * @param name buffer where the name will be written
+ * @param namesize length of name
+ *
+ * @return Return an error code or 0, see krb5_get_error_message().
+ *
+ * @ingroup krb5_keytab
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
@@ -166,9 +292,15 @@ krb5_kt_default_modify_name(krb5_context context, char *name, size_t namesize)
     return 0;
 }
 
     return 0;
 }
 
-/*
+/**
  * Set `id' to the default keytab.
  * Set `id' to the default keytab.
- * Return 0 or an error.
+ *
+ * @param context a Keberos context.
+ * @param id the new default keytab.
+ *
+ * @return Return an error code or 0, see krb5_get_error_message().
+ *
+ * @ingroup krb5_keytab
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
@@ -177,10 +309,20 @@ krb5_kt_default(krb5_context context, krb5_keytab *id)
     return krb5_kt_resolve (context, context->default_keytab, id);
 }
 
     return krb5_kt_resolve (context, context->default_keytab, id);
 }
 
-/*
+/**
  * Read the key identified by `(principal, vno, enctype)' from the
  * keytab in `keyprocarg' (the default if == NULL) into `*key'.
  * Read the key identified by `(principal, vno, enctype)' from the
  * keytab in `keyprocarg' (the default if == NULL) into `*key'.
- * Return 0 or an error.
+ *
+ * @param context a Keberos context.
+ * @param keyprocarg
+ * @param principal
+ * @param vno
+ * @param enctype
+ * @param key
+ *
+ * @return Return an error code or 0, see krb5_get_error_message().
+ *
+ * @ingroup krb5_keytab
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
@@ -212,9 +354,18 @@ krb5_kt_read_service_key(krb5_context context,
     return ret;
 }
 
     return ret;
 }
 
-/*
+/**
  * Return the type of the `keytab' in the string `prefix of length
  * `prefixsize'.
  * Return the type of the `keytab' in the string `prefix of length
  * `prefixsize'.
+ *
+ * @param context a Keberos context.
+ * @param keytab the keytab to get the prefix for
+ * @param prefix prefix buffer
+ * @param prefixsize length of prefix buffer
+ *
+ * @return Return an error code or 0, see krb5_get_error_message().
+ *
+ * @ingroup krb5_keytab
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
@@ -227,9 +378,17 @@ krb5_kt_get_type(krb5_context context,
     return 0;
 }
 
     return 0;
 }
 
-/*
+/**
  * Retrieve the name of the keytab `keytab' into `name', `namesize'
  * Retrieve the name of the keytab `keytab' into `name', `namesize'
- * Return 0 or an error.
+ *
+ * @param context a Keberos context.
+ * @param keytab the keytab to get the name for.
+ * @param name name buffer.
+ * @param namesize size of name buffer.
+ *
+ * @return Return an error code or 0, see krb5_get_error_message().
+ *
+ * @ingroup krb5_keytab
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
@@ -241,10 +400,18 @@ krb5_kt_get_name(krb5_context context,
     return (*keytab->get_name)(context, keytab, name, namesize);
 }
 
     return (*keytab->get_name)(context, keytab, name, namesize);
 }
 
-/*
+/**
  * Retrieve the full name of the keytab `keytab' and store the name in
  * Retrieve the full name of the keytab `keytab' and store the name in
- * `str'. `str' needs to be freed by the caller using free(3).
- * Returns 0 or an error. On error, *str is set to NULL.
+ * `str'.
+ *
+ * @param context a Keberos context.
+ * @param keytab keytab to get name for.
+ * @param str the name of the keytab name, usee krb5_xfree() to free
+ *        the string.  On error, *str is set to NULL.
+ *
+ * @return Return an error code or 0, see krb5_get_error_message().
+ *
+ * @ingroup krb5_keytab
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
@@ -275,9 +442,16 @@ krb5_kt_get_full_name(krb5_context context,
     return 0;
 }
 
     return 0;
 }
 
-/*
+/**
  * Finish using the keytab in `id'.  All resources will be released,
  * Finish using the keytab in `id'.  All resources will be released,
- * even on errors.  Return 0 or an error.
+ * even on errors.
+ *
+ * @param context a Keberos context.
+ * @param id keytab to close.
+ *
+ * @return Return an error code or 0, see krb5_get_error_message().
+ *
+ * @ingroup krb5_keytab
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
@@ -292,10 +466,61 @@ krb5_kt_close(krb5_context context,
     return ret;
 }
 
     return ret;
 }
 
+/**
+ * Destroy (remove) the keytab in `id'.  All resources will be released,
+ * even on errors, does the equvalment of krb5_kt_close() on the resources.
+ *
+ * @param context a Keberos context.
+ * @param id keytab to destroy.
+ *
+ * @return Return an error code or 0, see krb5_get_error_message().
+ *
+ * @ingroup krb5_keytab
+ */
+
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_kt_destroy(krb5_context context,
+               krb5_keytab id)
+{
+    krb5_error_code ret;
+
+    ret = (*id->destroy)(context, id);
+    krb5_kt_close(context, id);
+    return ret;
+}
+
 /*
 /*
+ * Match any aliases in keytab `entry' with `principal'.
+ */
+
+static krb5_boolean
+compare_aliseses(krb5_context context,
+                krb5_keytab_entry *entry,
+                krb5_const_principal principal)
+{
+    unsigned int i;
+    if (entry->aliases == NULL)
+       return FALSE;
+    for (i = 0; i < entry->aliases->len; i++)
+       if (krb5_principal_compare(context, &entry->aliases->val[i], principal))
+           return TRUE;
+    return FALSE;
+}
+
+/**
  * Compare `entry' against `principal, vno, enctype'.
  * Any of `principal, vno, enctype' might be 0 which acts as a wildcard.
  * Return TRUE if they compare the same, FALSE otherwise.
  * Compare `entry' against `principal, vno, enctype'.
  * Any of `principal, vno, enctype' might be 0 which acts as a wildcard.
  * Return TRUE if they compare the same, FALSE otherwise.
+ *
+ * @param context a Keberos context.
+ * @param entry an entry to match with.
+ * @param principal principal to match, NULL matches all principals.
+ * @param vno key version to match, 0 matches all key version numbers.
+ * @param enctype encryption type to match, 0 matches all encryption types.
+ *
+ * @return Return TRUE or match, FALSE if not matched.
+ *
+ * @ingroup krb5_keytab
  */
 
 krb5_boolean KRB5_LIB_FUNCTION
  */
 
 krb5_boolean KRB5_LIB_FUNCTION
@@ -306,7 +531,8 @@ krb5_kt_compare(krb5_context context,
                krb5_enctype enctype)
 {
     if(principal != NULL &&
                krb5_enctype enctype)
 {
     if(principal != NULL &&
-       !krb5_principal_compare(context, entry->principal, principal))
+       !(krb5_principal_compare(context, entry->principal, principal) ||
+        compare_aliseses(context, entry, principal)))
        return FALSE;
     if(vno && vno != entry->vno)
        return FALSE;
        return FALSE;
     if(vno && vno != entry->vno)
        return FALSE;
@@ -315,11 +541,53 @@ krb5_kt_compare(krb5_context context,
     return TRUE;
 }
 
     return TRUE;
 }
 
-/*
+krb5_error_code
+_krb5_kt_principal_not_found(krb5_context context,
+                            krb5_error_code ret,
+                            krb5_keytab id,
+                            krb5_const_principal principal,
+                            krb5_enctype enctype,
+                            int kvno)
+{
+    char princ[256], kvno_str[25], *kt_name;
+    char *enctype_str = NULL;
+    
+    krb5_unparse_name_fixed (context, principal, princ, sizeof(princ));
+    krb5_kt_get_full_name (context, id, &kt_name);
+    krb5_enctype_to_string(context, enctype, &enctype_str);
+    
+    if (kvno)
+       snprintf(kvno_str, sizeof(kvno_str), "(kvno %d)", kvno);
+    else
+       kvno_str[0] = '\0';
+    
+    krb5_set_error_message (context, ret,
+                           N_("Failed to find %s%s in keytab %s (%s)",
+                              "principal, kvno, keytab file, enctype"),
+                           princ,
+                           kvno_str,
+                           kt_name ? kt_name : "unknown keytab",
+                           enctype_str ? enctype_str : "unknown enctype");
+    free(kt_name);
+    free(enctype_str);
+    return ret;
+}
+
+
+/**
  * Retrieve the keytab entry for `principal, kvno, enctype' into `entry'
  * Retrieve the keytab entry for `principal, kvno, enctype' into `entry'
- * from the keytab `id'.
- * kvno == 0 is a wildcard and gives the keytab with the highest vno.
- * Return 0 or an error.
+ * from the keytab `id'. Matching is done like krb5_kt_compare().
+ *
+ * @param context a Keberos context.
+ * @param id a keytab.
+ * @param principal principal to match, NULL matches all principals.
+ * @param kvno key version to match, 0 matches all key version numbers.
+ * @param enctype encryption type to match, 0 matches all encryption types.
+ * @param entry the returned entry, free with krb5_kt_free_entry().
+ *
+ * @return Return an error code or 0, see krb5_get_error_message().
+ *
+ * @ingroup krb5_keytab
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
@@ -365,37 +633,23 @@ krb5_kt_get_entry(krb5_context context,
        krb5_kt_free_entry(context, &tmp);
     }
     krb5_kt_end_seq_get (context, id, &cursor);
        krb5_kt_free_entry(context, &tmp);
     }
     krb5_kt_end_seq_get (context, id, &cursor);
-    if (entry->vno) {
-       return 0;
-    } else {
-       char princ[256], kvno_str[25], *kt_name;
-       char *enctype_str = NULL;
-
-       krb5_unparse_name_fixed (context, principal, princ, sizeof(princ));
-       krb5_kt_get_full_name (context, id, &kt_name);
-       krb5_enctype_to_string(context, enctype, &enctype_str);
-
-       if (kvno)
-           snprintf(kvno_str, sizeof(kvno_str), "(kvno %d)", kvno);
-       else
-           kvno_str[0] = '\0';
-
-       krb5_set_error_message (context, KRB5_KT_NOTFOUND,
-                               N_("Failed to find %s%s in keytab %s (%s)",
-                                  "principal, kvno, keytab file, enctype"),
-                               princ,
-                               kvno_str,
-                               kt_name ? kt_name : "unknown keytab",
-                               enctype_str ? enctype_str : "unknown enctype");
-       free(kt_name);
-       free(enctype_str);
-       return KRB5_KT_NOTFOUND;
-    }
+    if (entry->vno == 0)
+       return _krb5_kt_principal_not_found(context, KRB5_KT_NOTFOUND,
+                                           id, principal, enctype, kvno);
+    return 0;
 }
 
 }
 
-/*
+/**
  * Copy the contents of `in' into `out'.
  * Copy the contents of `in' into `out'.
- * Return 0 or an error.  */
+ *
+ * @param context a Keberos context.
+ * @param in the keytab entry to copy.
+ * @param out the copy of the keytab entry, free with krb5_kt_free_entry().
+ *
+ * @return Return an error code or 0, see krb5_get_error_message().
+ *
+ * @ingroup krb5_keytab
+ */
 
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_kt_copy_entry_contents(krb5_context context,
 
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_kt_copy_entry_contents(krb5_context context,
@@ -422,8 +676,15 @@ fail:
     return ret;
 }
 
     return ret;
 }
 
-/*
+/**
  * Free the contents of `entry'.
  * Free the contents of `entry'.
+ *
+ * @param context a Keberos context.
+ * @param entry the entry to free
+ *
+ * @return Return an error code or 0, see krb5_get_error_message().
+ *
+ * @ingroup krb5_keytab
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
@@ -436,9 +697,16 @@ krb5_kt_free_entry(krb5_context context,
     return 0;
 }
 
     return 0;
 }
 
-/*
+/**
  * Set `cursor' to point at the beginning of `id'.
  * Set `cursor' to point at the beginning of `id'.
- * Return 0 or an error.
+ *
+ * @param context a Keberos context.
+ * @param id a keytab.
+ * @param cursor a newly allocated cursor, free with krb5_kt_end_seq_get().
+ *
+ * @return Return an error code or 0, see krb5_get_error_message().
+ *
+ * @ingroup krb5_keytab
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
@@ -456,10 +724,18 @@ krb5_kt_start_seq_get(krb5_context context,
     return (*id->start_seq_get)(context, id, cursor);
 }
 
     return (*id->start_seq_get)(context, id, cursor);
 }
 
-/*
- * Get the next entry from `id' pointed to by `cursor' and advance the
- * `cursor'.
- * Return 0 or an error.
+/**
+ * Get the next entry from keytab, advance the cursor.  On last entry
+ * the function will return KRB5_KT_END.
+ *
+ * @param context a Keberos context.
+ * @param id a keytab.
+ * @param entry the returned entry, free with krb5_kt_free_entry().
+ * @param cursor the cursor of the iteration.
+ *
+ * @return Return an error code or 0, see krb5_get_error_message().
+ *
+ * @ingroup krb5_keytab
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
@@ -478,8 +754,16 @@ krb5_kt_next_entry(krb5_context context,
     return (*id->next_entry)(context, id, entry, cursor);
 }
 
     return (*id->next_entry)(context, id, entry, cursor);
 }
 
-/*
+/**
  * Release all resources associated with `cursor'.
  * Release all resources associated with `cursor'.
+ *
+ * @param context a Keberos context.
+ * @param id a keytab.
+ * @param cursor the cursor to free.
+ *
+ * @return Return an error code or 0, see krb5_get_error_message().
+ *
+ * @ingroup krb5_keytab
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
@@ -496,9 +780,16 @@ krb5_kt_end_seq_get(krb5_context context,
     return (*id->end_seq_get)(context, id, cursor);
 }
 
     return (*id->end_seq_get)(context, id, cursor);
 }
 
-/*
+/**
  * Add the entry in `entry' to the keytab `id'.
  * Add the entry in `entry' to the keytab `id'.
- * Return 0 or an error.
+ *
+ * @param context a Keberos context.
+ * @param id a keytab.
+ * @param entry the entry to add
+ *
+ * @return Return an error code or 0, see krb5_get_error_message().
+ *
+ * @ingroup krb5_keytab
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
@@ -516,9 +807,17 @@ krb5_kt_add_entry(krb5_context context,
     return (*id->add)(context, id,entry);
 }
 
     return (*id->add)(context, id,entry);
 }
 
-/*
- * Remove the entry `entry' from the keytab `id'.
- * Return 0 or an error.
+/**
+ * Remove an entry from the keytab, matching is done using
+ * krb5_kt_compare().
+
+ * @param context a Keberos context.
+ * @param id a keytab.
+ * @param entry the entry to remove
+ *
+ * @return Return an error code or 0, see krb5_get_error_message().
+ *
+ * @ingroup krb5_keytab
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
index 7a2d9b9f706145426c5079b99d21c925d9c99e0a..02de8c8028cd40b3f62ac4942bc8f87f72615807 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "krb5_locl.h"
 
 
 #include "krb5_locl.h"
 
-RCSID("$Id$");
-
 struct any_data {
     krb5_keytab kt;
     char *name;
 struct any_data {
     krb5_keytab kt;
     char *name;
@@ -253,6 +251,7 @@ const krb5_kt_ops krb5_any_ops = {
     any_resolve,
     any_get_name,
     any_close,
     any_resolve,
     any_get_name,
     any_close,
+    NULL, /* destroy */
     NULL, /* get */
     any_start_seq_get,
     any_next_entry,
     NULL, /* get */
     any_start_seq_get,
     any_next_entry,
index f494cac253c4886190dfe3b1fa9058188a4f5683..819366443ff4ceb6fa5d92293d0da4bcc9cefea7 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "krb5_locl.h"
 
 
 #include "krb5_locl.h"
 
-RCSID("$Id$");
-
 #define KRB5_KT_VNO_1 1
 #define KRB5_KT_VNO_2 2
 #define KRB5_KT_VNO   KRB5_KT_VNO_2
 #define KRB5_KT_VNO_1 1
 #define KRB5_KT_VNO_2 2
 #define KRB5_KT_VNO   KRB5_KT_VNO_2
@@ -331,6 +329,14 @@ fkt_close(krb5_context context, krb5_keytab id)
     return 0;
 }
 
     return 0;
 }
 
+static krb5_error_code
+fkt_destroy(krb5_context context, krb5_keytab id)
+{
+    struct fkt_data *d = id->data;
+    _krb5_erase_file(context, d->filename);
+    return 0;
+}
+
 static krb5_error_code
 fkt_get_name(krb5_context context,
             krb5_keytab id,
 static krb5_error_code
 fkt_get_name(krb5_context context,
             krb5_keytab id,
@@ -445,6 +451,7 @@ fkt_next_entry_int(krb5_context context,
     int ret;
     int8_t tmp8;
     int32_t tmp32;
     int ret;
     int8_t tmp8;
     int32_t tmp32;
+    uint32_t utmp32;
     off_t pos, curpos;
 
     pos = krb5_storage_seek(cursor->sp, 0, SEEK_CUR);
     off_t pos, curpos;
 
     pos = krb5_storage_seek(cursor->sp, 0, SEEK_CUR);
@@ -459,8 +466,8 @@ loop:
     ret = krb5_kt_ret_principal (context, d, cursor->sp, &entry->principal);
     if (ret)
        goto out;
     ret = krb5_kt_ret_principal (context, d, cursor->sp, &entry->principal);
     if (ret)
        goto out;
-    ret = krb5_ret_int32(cursor->sp, &tmp32);
-    entry->timestamp = tmp32;
+    ret = krb5_ret_uint32(cursor->sp, &utmp32);
+    entry->timestamp = utmp32;
     if (ret)
        goto out;
     ret = krb5_ret_int8(cursor->sp, &tmp8);
     if (ret)
        goto out;
     ret = krb5_ret_int8(cursor->sp, &tmp8);
@@ -476,10 +483,19 @@ loop:
     curpos = krb5_storage_seek(cursor->sp, 0, SEEK_CUR);
     if(len + 4 + pos - curpos >= 4) {
        ret = krb5_ret_int32(cursor->sp, &tmp32);
     curpos = krb5_storage_seek(cursor->sp, 0, SEEK_CUR);
     if(len + 4 + pos - curpos >= 4) {
        ret = krb5_ret_int32(cursor->sp, &tmp32);
-       if (ret == 0 && tmp32 != 0) {
+       if (ret == 0 && tmp32 != 0)
            entry->vno = tmp32;
            entry->vno = tmp32;
-       }
     }
     }
+    /* there might be a flags field here */
+    if(len + 4 + pos - curpos >= 8) {
+       ret = krb5_ret_uint32(cursor->sp, &utmp32);
+       if (ret == 0)
+           entry->flags = tmp32;
+    } else
+       entry->flags = 0;
+
+    entry->aliases = NULL;
+
     if(start) *start = pos;
     if(end) *end = pos + 4 + len;
  out:
     if(start) *start = pos;
     if(end) *end = pos + 4 + len;
  out:
@@ -653,6 +669,15 @@ fkt_add_entry(krb5_context context,
                krb5_storage_free(emem);
                goto out;
            }
                krb5_storage_free(emem);
                goto out;
            }
+           ret = krb5_store_uint32 (emem, entry->flags);
+           if (ret) {
+               krb5_set_error_message(context, ret,
+                                      N_("Failed storing extended kvno "
+                                         "in keytab %s", ""),
+                                      d->filename);
+               krb5_storage_free(emem);
+               goto out;
+           }
        }
 
        ret = krb5_storage_to_data(emem, &keytab);
        }
 
        ret = krb5_storage_to_data(emem, &keytab);
@@ -744,6 +769,7 @@ const krb5_kt_ops krb5_fkt_ops = {
     fkt_resolve,
     fkt_get_name,
     fkt_close,
     fkt_resolve,
     fkt_get_name,
     fkt_close,
+    fkt_destroy,
     NULL, /* get */
     fkt_start_seq_get,
     fkt_next_entry,
     NULL, /* get */
     fkt_start_seq_get,
     fkt_next_entry,
@@ -757,6 +783,7 @@ const krb5_kt_ops krb5_wrfkt_ops = {
     fkt_resolve,
     fkt_get_name,
     fkt_close,
     fkt_resolve,
     fkt_get_name,
     fkt_close,
+    fkt_destroy,
     NULL, /* get */
     fkt_start_seq_get,
     fkt_next_entry,
     NULL, /* get */
     fkt_start_seq_get,
     fkt_next_entry,
@@ -770,6 +797,7 @@ const krb5_kt_ops krb5_javakt_ops = {
     fkt_resolve_java14,
     fkt_get_name,
     fkt_close,
     fkt_resolve_java14,
     fkt_get_name,
     fkt_close,
+    fkt_destroy,
     NULL, /* get */
     fkt_start_seq_get,
     fkt_next_entry,
     NULL, /* get */
     fkt_start_seq_get,
     fkt_next_entry,
index 71d3d89d583abcf15f498f2b3862f5ddd6b68a9e..54666c7d447dbe0e9e4802654bf534435340297f 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "krb5_locl.h"
 
 
 #include "krb5_locl.h"
 
-RCSID("$Id$");
-
 #ifndef HEIMDAL_SMALLER
 
 /* afs keyfile operations --------------------------------------- */
 #ifndef HEIMDAL_SMALLER
 
 /* afs keyfile operations --------------------------------------- */
@@ -275,6 +273,8 @@ akf_next_entry(krb5_context context,
        ret = 0;
 
     entry->timestamp = time(NULL);
        ret = 0;
 
     entry->timestamp = time(NULL);
+    entry->flags = 0;
+    entry->aliases = NULL;
 
  out:
     krb5_storage_seek(cursor->sp, pos + 4 + 8, SEEK_SET);
 
  out:
     krb5_storage_seek(cursor->sp, pos + 4 + 8, SEEK_SET);
@@ -440,6 +440,7 @@ const krb5_kt_ops krb5_akf_ops = {
     akf_resolve,
     akf_get_name,
     akf_close,
     akf_resolve,
     akf_get_name,
     akf_close,
+    NULL, /* destroy */
     NULL, /* get */
     akf_start_seq_get,
     akf_next_entry,
     NULL, /* get */
     akf_start_seq_get,
     akf_next_entry,
index defd10d67cc74be16ae2f9187e827e53608bd74e..73ffa1c67d7fa3353db83d578397319fe5b4892f 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "krb5_locl.h"
 
 
 #include "krb5_locl.h"
 
-RCSID("$Id$");
-
 /* memory operations -------------------------------------------- */
 
 struct mkt_data {
 /* memory operations -------------------------------------------- */
 
 struct mkt_data {
@@ -228,6 +226,7 @@ const krb5_kt_ops krb5_mkt_ops = {
     mkt_resolve,
     mkt_get_name,
     mkt_close,
     mkt_resolve,
     mkt_get_name,
     mkt_close,
+    NULL, /* destroy */
     NULL, /* get */
     mkt_start_seq_get,
     mkt_next_entry,
     NULL, /* get */
     mkt_start_seq_get,
     mkt_next_entry,
index 0ba4e7b54ac6d1af10465fa6c035c4fb57d4d448..13dafacf21bd2227d8a20a118b7d36fbfb255a1b 100644 (file)
 #define KRB5KDC_ERR_KEY_EXP KRB5KDC_ERR_KEY_EXPIRED
 #endif
 
 #define KRB5KDC_ERR_KEY_EXP KRB5KDC_ERR_KEY_EXPIRED
 #endif
 
+#ifndef KRB5_DEPRECATED
+#define KRB5_DEPRECATED __attribute__((deprecated))
+#endif
+
 /* simple constants */
 
 #ifndef TRUE
 /* simple constants */
 
 #ifndef TRUE
@@ -92,6 +96,8 @@ typedef Checksum krb5_checksum;
 
 typedef ENCTYPE krb5_enctype;
 
 
 typedef ENCTYPE krb5_enctype;
 
+typedef struct krb5_get_init_creds_ctx *krb5_init_creds_context;
+
 typedef heim_octet_string krb5_data;
 
 /* PKINIT related forward declarations */
 typedef heim_octet_string krb5_data;
 
 /* PKINIT related forward declarations */
@@ -219,6 +225,8 @@ typedef enum krb5_key_usage {
     /* Keyusage for the server referral in a TGS req */
     KRB5_KU_SAM_ENC_NONCE_SAD = 27,
     /* Encryption of the SAM-NONCE-OR-SAD field */
     /* Keyusage for the server referral in a TGS req */
     KRB5_KU_SAM_ENC_NONCE_SAD = 27,
     /* Encryption of the SAM-NONCE-OR-SAD field */
+    KRB5_KU_PA_PKINIT_KX = 44,
+    /* Encryption type of the kdc session contribution in pk-init */
     KRB5_KU_DIGEST_ENCRYPT = -18,
     /* Encryption key usage used in the digest encryption field */
     KRB5_KU_DIGEST_OPAQUE = -19,
     KRB5_KU_DIGEST_ENCRYPT = -18,
     /* Encryption key usage used in the digest encryption field */
     KRB5_KU_DIGEST_OPAQUE = -19,
@@ -272,13 +280,13 @@ typedef HostAddress krb5_address;
 typedef HostAddresses krb5_addresses;
 
 typedef enum krb5_keytype {
 typedef HostAddresses krb5_addresses;
 
 typedef enum krb5_keytype {
-    KEYTYPE_NULL       = 0,
-    KEYTYPE_DES                = 1,
-    KEYTYPE_DES3       = 7,
-    KEYTYPE_AES128     = 17,
-    KEYTYPE_AES256     = 18,
-    KEYTYPE_ARCFOUR    = 23,
-    KEYTYPE_ARCFOUR_56 = 24
+    KEYTYPE_NULL       = ETYPE_NULL,
+    KEYTYPE_DES                = ETYPE_DES_CBC_CRC,
+    KEYTYPE_DES3       = ETYPE_OLD_DES3_CBC_SHA1,
+    KEYTYPE_AES128     = ETYPE_AES128_CTS_HMAC_SHA1_96,
+    KEYTYPE_AES256     = ETYPE_AES256_CTS_HMAC_SHA1_96,
+    KEYTYPE_ARCFOUR    = ETYPE_ARCFOUR_HMAC_MD5,
+    KEYTYPE_ARCFOUR_56 = ETYPE_ARCFOUR_HMAC_MD5_56
 } krb5_keytype;
 
 typedef EncryptionKey krb5_keyblock;
 } krb5_keytype;
 
 typedef EncryptionKey krb5_keyblock;
@@ -317,6 +325,7 @@ typedef const char *krb5_const_realm; /* stupid language */
 typedef Principal krb5_principal_data;
 typedef struct Principal *krb5_principal;
 typedef const struct Principal *krb5_const_principal;
 typedef Principal krb5_principal_data;
 typedef struct Principal *krb5_principal;
 typedef const struct Principal *krb5_const_principal;
+typedef struct Principals *krb5_principals;
 
 typedef time_t krb5_deltat;
 typedef time_t krb5_timestamp;
 
 typedef time_t krb5_deltat;
 typedef time_t krb5_timestamp;
@@ -478,6 +487,8 @@ typedef struct krb5_keytab_entry {
     krb5_kvno vno;
     krb5_keyblock keyblock;
     uint32_t timestamp;
     krb5_kvno vno;
     krb5_keyblock keyblock;
     uint32_t timestamp;
+    uint32_t flags;
+    krb5_principals aliases;
 } krb5_keytab_entry;
 
 typedef struct krb5_kt_cursor {
 } krb5_keytab_entry;
 
 typedef struct krb5_kt_cursor {
@@ -497,6 +508,7 @@ struct krb5_keytab_data {
     krb5_error_code (*resolve)(krb5_context, const char*, krb5_keytab);
     krb5_error_code (*get_name)(krb5_context, krb5_keytab, char*, size_t);
     krb5_error_code (*close)(krb5_context, krb5_keytab);
     krb5_error_code (*resolve)(krb5_context, const char*, krb5_keytab);
     krb5_error_code (*get_name)(krb5_context, krb5_keytab, char*, size_t);
     krb5_error_code (*close)(krb5_context, krb5_keytab);
+    krb5_error_code (*destroy)(krb5_context, krb5_keytab);
     krb5_error_code (*get)(krb5_context, krb5_keytab, krb5_const_principal,
                           krb5_kvno, krb5_enctype, krb5_keytab_entry*);
     krb5_error_code (*start_seq_get)(krb5_context, krb5_keytab, krb5_kt_cursor*);
     krb5_error_code (*get)(krb5_context, krb5_keytab, krb5_const_principal,
                           krb5_kvno, krb5_enctype, krb5_keytab_entry*);
     krb5_error_code (*start_seq_get)(krb5_context, krb5_keytab, krb5_kt_cursor*);
@@ -593,7 +605,8 @@ typedef EncAPRepPart krb5_ap_rep_enc_part;
 
 #define KRB5_TGS_NAME_SIZE (6)
 #define KRB5_TGS_NAME ("krbtgt")
 
 #define KRB5_TGS_NAME_SIZE (6)
 #define KRB5_TGS_NAME ("krbtgt")
-
+#define KRB5_WELLKNOWN_NAME ("WELLKNOWN")
+#define KRB5_ANON_NAME ("ANONYMOUS")
 #define KRB5_DIGEST_NAME ("digest")
 
 typedef enum {
 #define KRB5_DIGEST_NAME ("digest")
 
 typedef enum {
@@ -636,7 +649,7 @@ typedef krb5_error_code (*krb5_s2k_proc)(krb5_context /*context*/,
 
 struct _krb5_get_init_creds_opt_private;
 
 
 struct _krb5_get_init_creds_opt_private;
 
-typedef struct _krb5_get_init_creds_opt {
+struct _krb5_get_init_creds_opt {
     krb5_flags flags;
     krb5_deltat tkt_life;
     krb5_deltat renew_life;
     krb5_flags flags;
     krb5_deltat tkt_life;
     krb5_deltat renew_life;
@@ -652,7 +665,9 @@ typedef struct _krb5_get_init_creds_opt {
     int preauth_list_length;
     krb5_data *salt;
     struct _krb5_get_init_creds_opt_private *opt_private;
     int preauth_list_length;
     krb5_data *salt;
     struct _krb5_get_init_creds_opt_private *opt_private;
-} krb5_get_init_creds_opt;
+};
+
+typedef struct _krb5_get_init_creds_opt krb5_get_init_creds_opt;
 
 #define KRB5_GET_INIT_CREDS_OPT_TKT_LIFE       0x0001
 #define KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE     0x0002
 
 #define KRB5_GET_INIT_CREDS_OPT_TKT_LIFE       0x0001
 #define KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE     0x0002
@@ -661,7 +676,7 @@ typedef struct _krb5_get_init_creds_opt {
 #define KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST     0x0010
 #define KRB5_GET_INIT_CREDS_OPT_ADDRESS_LIST   0x0020
 #define KRB5_GET_INIT_CREDS_OPT_PREAUTH_LIST   0x0040
 #define KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST     0x0010
 #define KRB5_GET_INIT_CREDS_OPT_ADDRESS_LIST   0x0020
 #define KRB5_GET_INIT_CREDS_OPT_PREAUTH_LIST   0x0040
-#define KRB5_GET_INIT_CREDS_OPT_SALT           0x0080
+#define KRB5_GET_INIT_CREDS_OPT_SALT           0x0080 /* no supported */
 #define KRB5_GET_INIT_CREDS_OPT_ANONYMOUS      0x0100
 #define KRB5_GET_INIT_CREDS_OPT_DISABLE_TRANSITED_CHECK        0x0200
 
 #define KRB5_GET_INIT_CREDS_OPT_ANONYMOUS      0x0100
 #define KRB5_GET_INIT_CREDS_OPT_DISABLE_TRANSITED_CHECK        0x0200
 
@@ -727,22 +742,22 @@ enum {
 typedef krb5_error_code (*krb5_send_to_kdc_func)(krb5_context,
                                                 void *,
                                                 krb5_krbhst_info *,
 typedef krb5_error_code (*krb5_send_to_kdc_func)(krb5_context,
                                                 void *,
                                                 krb5_krbhst_info *,
-                                                time_t timeout,
+                                                time_t,
                                                 const krb5_data *,
                                                 krb5_data *);
 
                                                 const krb5_data *,
                                                 krb5_data *);
 
-/* flags for krb5_parse_name_flags */
+/** flags for krb5_parse_name_flags */
 enum {
 enum {
-    KRB5_PRINCIPAL_PARSE_NO_REALM = 1,
-    KRB5_PRINCIPAL_PARSE_MUST_REALM = 2,
-    KRB5_PRINCIPAL_PARSE_ENTERPRISE = 4
+    KRB5_PRINCIPAL_PARSE_NO_REALM = 1, /**< Require that there are no realm */
+    KRB5_PRINCIPAL_PARSE_REQUIRE_REALM = 2, /**< Require a realm present */
+    KRB5_PRINCIPAL_PARSE_ENTERPRISE = 4 /**< Parse as a NT-ENTERPRISE name */
 };
 
 };
 
-/* flags for krb5_unparse_name_flags */
+/** flags for krb5_unparse_name_flags */
 enum {
 enum {
-    KRB5_PRINCIPAL_UNPARSE_SHORT = 1,
-    KRB5_PRINCIPAL_UNPARSE_NO_REALM = 2,
-    KRB5_PRINCIPAL_UNPARSE_DISPLAY = 4
+    KRB5_PRINCIPAL_UNPARSE_SHORT = 1, /**< No realm if it is the default realm */
+    KRB5_PRINCIPAL_UNPARSE_NO_REALM = 2, /**< No realm */
+    KRB5_PRINCIPAL_UNPARSE_DISPLAY = 4 /**< No quoting */
 };
 
 typedef struct krb5_sendto_ctx_data *krb5_sendto_ctx;
 };
 
 typedef struct krb5_sendto_ctx_data *krb5_sendto_ctx;
@@ -787,6 +802,20 @@ typedef struct krb5_crypto_iov {
 } krb5_crypto_iov;
 
 
 } krb5_crypto_iov;
 
 
+/* Glue for MIT */
+
+typedef struct {
+    int32_t lr_type;
+    krb5_timestamp value;
+} krb5_last_req_entry;
+
+typedef krb5_error_code
+(*krb5_gic_process_last_req)(krb5_context, krb5_last_req_entry **, void *);
+
+/*
+ *
+ */
+
 #include <krb5-protos.h>
 
 /* variables */
 #include <krb5-protos.h>
 
 /* variables */
@@ -810,5 +839,11 @@ extern KRB5_LIB_VARIABLE const krb5_kt_ops krb4_fkt_ops;
 extern KRB5_LIB_VARIABLE const krb5_kt_ops krb5_srvtab_fkt_ops;
 extern KRB5_LIB_VARIABLE const krb5_kt_ops krb5_any_ops;
 
 extern KRB5_LIB_VARIABLE const krb5_kt_ops krb5_srvtab_fkt_ops;
 extern KRB5_LIB_VARIABLE const krb5_kt_ops krb5_any_ops;
 
+extern KRB5_LIB_VARIABLE const char *krb5_cc_type_api;
+extern KRB5_LIB_VARIABLE const char *krb5_cc_type_file;
+extern KRB5_LIB_VARIABLE const char *krb5_cc_type_memory;
+extern KRB5_LIB_VARIABLE const char *krb5_cc_type_kcm;
+extern KRB5_LIB_VARIABLE const char *krb5_cc_type_scc;
+
 #endif /* __KRB5_H__ */
 
 #endif /* __KRB5_H__ */
 
index ec0cb3bc0b23745fe58941c41d3fccd7c408b5c1..5a7fe6a41334db5766ed065bf0c794611cc366ff 100644 (file)
 
 #include <krb5-types.h>
 
 
 #include <krb5-types.h>
 
+ #ifdef __APPLE__
+#pragma pack(push,2)
+#endif
+
 enum {
     cc_credentials_v5 = 2
 };
 enum {
     cc_credentials_v5 = 2
 };
@@ -92,7 +96,7 @@ typedef struct cc_credentials_v5_t cc_credentials_v5_t;
 typedef struct cc_credentials_t *cc_credentials_t;
 typedef struct cc_credentials_iterator_t *cc_credentials_iterator_t;
 typedef struct cc_string_t *cc_string_t;
 typedef struct cc_credentials_t *cc_credentials_t;
 typedef struct cc_credentials_iterator_t *cc_credentials_iterator_t;
 typedef struct cc_string_t *cc_string_t;
-typedef time_t cc_time_t;
+typedef cc_uint32 cc_time_t;
 
 typedef struct cc_data {
     cc_uint32 type;
 
 typedef struct cc_data {
     cc_uint32 type;
@@ -227,4 +231,9 @@ struct cc_context_t {
 typedef cc_int32
 (*cc_initialize_func)(cc_context_t*, cc_int32, cc_int32 *, char const **);
 
 typedef cc_int32
 (*cc_initialize_func)(cc_context_t*, cc_int32, cc_int32 *, char const **);
 
+#ifdef __APPLE__
+#pragma pack(pop)
+#endif
+
+
 #endif /* KRB5_CCAPI_H */
 #endif /* KRB5_CCAPI_H */
index c076992d0bafc836f7c2200afb325f9d183590d0..098e04b95928f94d4995ff0084595c24c7a0b6a4 100644 (file)
@@ -106,7 +106,13 @@ error_code PUBLIC_KEY_ENCRYPTION_NOT_SUPPORTED, "Public key encryption not suppo
 #error_code ERR_KDC_NOT_FOUND, "IAKERB proxy could not find a KDC"
 #error_code ERR_KDC_NO_RESPONSE,       "IAKERB proxy never reeived a response from a KDC"
 
 #error_code ERR_KDC_NOT_FOUND, "IAKERB proxy could not find a KDC"
 #error_code ERR_KDC_NO_RESPONSE,       "IAKERB proxy never reeived a response from a KDC"
 
-# 82-127 are reserved
+# 82-93 are reserved
+
+index 94
+error_code INVALID_HASH_ALG, "Invalid OTP digest algorithm"
+error_code INVALID_ITERATION_COUNT, "Invalid OTP iteration count"
+
+# 97-127 are reserved
 
 index 128
 prefix
 
 index 128
 prefix
index ced722f2d9c05f4a58dabe5ba8cf7d1a06b1ba8a..2d8bc07de39204fdc57f195006a0b0d54c471595 100644 (file)
@@ -36,9 +36,7 @@
 #ifndef __KRB5_LOCL_H__
 #define __KRB5_LOCL_H__
 
 #ifndef __KRB5_LOCL_H__
 #define __KRB5_LOCL_H__
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-#endif
 
 #include <errno.h>
 #include <ctype.h>
 
 #include <errno.h>
 #include <ctype.h>
@@ -214,11 +212,14 @@ struct _krb5_get_init_creds_opt_private {
     krb5_get_init_creds_tristate req_pac;
     /* PKINIT */
     krb5_pk_init_ctx pk_init_ctx;
     krb5_get_init_creds_tristate req_pac;
     /* PKINIT */
     krb5_pk_init_ctx pk_init_ctx;
-    KRB_ERROR *error;
     krb5_get_init_creds_tristate addressless;
     int flags;
 #define KRB5_INIT_CREDS_CANONICALIZE           1
 #define KRB5_INIT_CREDS_NO_C_CANON_CHECK       2
     krb5_get_init_creds_tristate addressless;
     int flags;
 #define KRB5_INIT_CREDS_CANONICALIZE           1
 #define KRB5_INIT_CREDS_NO_C_CANON_CHECK       2
+    struct {
+        krb5_gic_process_last_req func;
+        void *ctx;
+    } lr;
 };
 
 typedef struct krb5_context_data {
 };
 
 typedef struct krb5_context_data {
@@ -261,6 +262,7 @@ typedef struct krb5_context_data {
     int flags;
 #define KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME   1
 #define KRB5_CTX_F_CHECK_PAC                   2
     int flags;
 #define KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME   1
 #define KRB5_CTX_F_CHECK_PAC                   2
+#define KRB5_CTX_F_HOMEDIR_ACCESS              4
     struct send_to_kdc *send_to_kdc;
 } krb5_context_data;
 
     struct send_to_kdc *send_to_kdc;
 } krb5_context_data;
 
@@ -295,6 +297,7 @@ struct krb5_pk_identity {
     hx509_context hx509ctx;
     hx509_verify_ctx verify_ctx;
     hx509_certs certs;
     hx509_context hx509ctx;
     hx509_verify_ctx verify_ctx;
     hx509_certs certs;
+    hx509_cert cert;
     hx509_certs anchors;
     hx509_certs certpool;
     hx509_revoke_ctx revokectx;
     hx509_certs anchors;
     hx509_certs certpool;
     hx509_revoke_ctx revokectx;
index 7348ac3f00a2f3947865cd9f9085e8578f6bd696..e9111abec992cfb0215631e8dc5afd4a1b2a51d7 100644 (file)
@@ -35,8 +35,6 @@
 #include <resolve.h>
 #include "locate_plugin.h"
 
 #include <resolve.h>
 #include "locate_plugin.h"
 
-RCSID("$Id$");
-
 static int
 string_to_proto(const char *string)
 {
 static int
 string_to_proto(const char *string)
 {
@@ -61,8 +59,8 @@ srv_find_realm(krb5_context context, krb5_krbhst_info ***res, int *count,
               const char *proto, const char *service, int port)
 {
     char domain[1024];
               const char *proto, const char *service, int port)
 {
     char domain[1024];
-    struct dns_reply *r;
-    struct resource_record *rr;
+    struct rk_dns_reply *r;
+    struct rk_resource_record *rr;
     int num_srv;
     int proto_num;
     int def_port;
     int num_srv;
     int proto_num;
     int def_port;
@@ -87,32 +85,32 @@ srv_find_realm(krb5_context context, krb5_krbhst_info ***res, int *count,
 
     snprintf(domain, sizeof(domain), "_%s._%s.%s.", service, proto, realm);
 
 
     snprintf(domain, sizeof(domain), "_%s._%s.%s.", service, proto, realm);
 
-    r = dns_lookup(domain, dns_type);
+    r = rk_dns_lookup(domain, dns_type);
     if(r == NULL)
        return KRB5_KDC_UNREACH;
 
     for(num_srv = 0, rr = r->head; rr; rr = rr->next)
     if(r == NULL)
        return KRB5_KDC_UNREACH;
 
     for(num_srv = 0, rr = r->head; rr; rr = rr->next)
-       if(rr->type == T_SRV)
+       if(rr->type == rk_ns_t_srv)
            num_srv++;
 
     *res = malloc(num_srv * sizeof(**res));
     if(*res == NULL) {
            num_srv++;
 
     *res = malloc(num_srv * sizeof(**res));
     if(*res == NULL) {
-       dns_free_data(r);
+       rk_dns_free_data(r);
        krb5_set_error_message(context, ENOMEM,
                               N_("malloc: out of memory", ""));
        return ENOMEM;
     }
 
        krb5_set_error_message(context, ENOMEM,
                               N_("malloc: out of memory", ""));
        return ENOMEM;
     }
 
-    dns_srv_order(r);
+    rk_dns_srv_order(r);
 
     for(num_srv = 0, rr = r->head; rr; rr = rr->next)
 
     for(num_srv = 0, rr = r->head; rr; rr = rr->next)
-       if(rr->type == T_SRV) {
+       if(rr->type == rk_ns_t_srv) {
            krb5_krbhst_info *hi;
            size_t len = strlen(rr->u.srv->target);
 
            hi = calloc(1, sizeof(*hi) + len);
            if(hi == NULL) {
            krb5_krbhst_info *hi;
            size_t len = strlen(rr->u.srv->target);
 
            hi = calloc(1, sizeof(*hi) + len);
            if(hi == NULL) {
-               dns_free_data(r);
+               rk_dns_free_data(r);
                while(--num_srv >= 0)
                    free((*res)[num_srv]);
                free(*res);
                while(--num_srv >= 0)
                    free((*res)[num_srv]);
                free(*res);
@@ -134,7 +132,7 @@ srv_find_realm(krb5_context context, krb5_krbhst_info ***res, int *count,
 
     *count = num_srv;
        
 
     *count = num_srv;
        
-    dns_free_data(r);
+    rk_dns_free_data(r);
     return 0;
 }
 
     return 0;
 }
 
@@ -948,7 +946,7 @@ gethostlist(krb5_context context, const char *realm,
            return ENOMEM;
        }
     }
            return ENOMEM;
        }
     }
-    (*hostlist)[nhost++] = NULL;
+    (*hostlist)[nhost] = NULL;
     krb5_krbhst_free(context, handle);
     return 0;
 }
     krb5_krbhst_free(context, handle);
     return 0;
 }
index 529488ddfd131b7d8f9f704e3ee91b08399cfcc9..b1b1f0ef230efcf796cd6f01cccc2b05b624c501 100644 (file)
@@ -36,9 +36,7 @@
 #ifndef HEIMDAL_KRB5_LOCATE_PLUGIN_H
 #define HEIMDAL_KRB5_LOCATE_PLUGIN_H 1
 
 #ifndef HEIMDAL_KRB5_LOCATE_PLUGIN_H
 #define HEIMDAL_KRB5_LOCATE_PLUGIN_H 1
 
-#include <krb5.h>
-
-#define KRB5_PLUGIN_LOCATE "resolve"
+#define KRB5_PLUGIN_LOCATE "service_locator"
 
 enum locate_service_type {
     locate_service_kdc = 1,
 
 enum locate_service_type {
     locate_service_kdc = 1,
index 587cf7ed9701533028555b7c465e7f42f74ac3be..31d267320f112aed770de496f08f419acec4f191 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "krb5_locl.h"
 
 
 #include "krb5_locl.h"
 
-RCSID("$Id$");
-
 struct facility {
     int min;
     int max;
 struct facility {
     int min;
     int max;
index 752608069d054d5dd13916d3c27a2efbbbe2e59d..78ef68db3d1cf2af97fbaad2311420e97d270e3b 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "krb5_locl.h"
 
 
 #include "krb5_locl.h"
 
-RCSID("$Id$");
-
 typedef struct krb5_mcache {
     char *name;
     unsigned int refcnt;
 typedef struct krb5_mcache {
     char *name;
     unsigned int refcnt;
index 4cee5e22e19c1237283b60c5a1d7bd4108d81df5..e47383880c4dd009eaad7cb73f7f3bae6b1ff9e7 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "krb5_locl.h"
 
 
 #include "krb5_locl.h"
 
-RCSID("$Id$");
-
 krb5_error_code KRB5_LIB_FUNCTION
 _krb5_s4u2self_to_checksumdata(krb5_context context,
                               const PA_S4U2Self *self,
 krb5_error_code KRB5_LIB_FUNCTION
 _krb5_s4u2self_to_checksumdata(krb5_context context,
                               const PA_S4U2Self *self,
index f8f13922f590d750e1237e0964f3e83265ec472e..dab5c6046a26ae6676e5368d31a27e2fca1b6b65 100644 (file)
@@ -31,8 +31,9 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
+#define KRB5_DEPRECATED
+
 #include "krb5_locl.h"
 #include "krb5_locl.h"
-RCSID("$Id$");
 
 #ifndef HEIMDAL_SMALLER
 
 
 #ifndef HEIMDAL_SMALLER
 
@@ -315,8 +316,9 @@ krb5_c_enctype_compare(krb5_context context,
                       krb5_enctype e1,
                       krb5_enctype e2,
                       krb5_boolean *similar)
                       krb5_enctype e1,
                       krb5_enctype e2,
                       krb5_boolean *similar)
+    KRB5_DEPRECATED
 {
 {
-    *similar = krb5_enctypes_compatible_keys(context, e1, e2);
+    *similar = (e1 == e2);
     return 0;
 }
 
     return 0;
 }
 
@@ -370,4 +372,18 @@ krb5_c_prf(krb5_context context,
     return ret;
 }
 
     return ret;
 }
 
+/**
+ * MIT compat glue
+ *
+ * @ingroup krb5_ccache
+ */
+
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_cc_copy_creds(krb5_context context,
+                  const krb5_ccache from,
+                  krb5_ccache to)
+{
+    return krb5_cc_copy_cache(context, from, to);
+}
+
 #endif /* HEIMDAL_SMALLER */
 #endif /* HEIMDAL_SMALLER */
index 989aa23d754fbfac39bc53bfe8663ae08f37c8d5..f623fc495b1d8e2c2f75438324c049646369f62d 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "krb5_locl.h"
 
 
 #include "krb5_locl.h"
 
-RCSID("$Id$");
-
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_mk_error(krb5_context context,
              krb5_error_code error_code,
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_mk_error(krb5_context context,
              krb5_error_code error_code,
index 86a6b669b1f41c25e19010320d1139ea07ee380c..40f09ae33f11f9010deb25e4e89976303469264b 100644 (file)
@@ -33,9 +33,6 @@
 
 #include <krb5_locl.h>
 
 
 #include <krb5_locl.h>
 
-RCSID("$Id$");
-
-
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_mk_priv(krb5_context context,
             krb5_auth_context auth_context,
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_mk_priv(krb5_context context,
             krb5_auth_context auth_context,
index bba276183abf2f46bb64f530fa4dab6dcc3066c0..8eef0ea652b1108d6857bf20fd618507c53c5196 100644 (file)
@@ -33,8 +33,6 @@
 
 #include <krb5_locl.h>
 
 
 #include <krb5_locl.h>
 
-RCSID("$Id$");
-
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_mk_rep(krb5_context context,
            krb5_auth_context auth_context,
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_mk_rep(krb5_context context,
            krb5_auth_context auth_context,
index 15706377388b386ab06ef9c5cb0ef7fb4f2fa487..c87fa61293371ed6c352cfb640a74e810a9f0882 100644 (file)
@@ -33,8 +33,6 @@
 
 #include <krb5_locl.h>
 
 
 #include <krb5_locl.h>
 
-RCSID("$Id$");
-
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_mk_req_exact(krb5_context context,
                  krb5_auth_context *auth_context,
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_mk_req_exact(krb5_context context,
                  krb5_auth_context *auth_context,
index aba804716c5143d4244a575e07ee82a6ebd4b63a..d130272aa1641bb2fff8bb96f878b0549489efde 100644 (file)
@@ -33,8 +33,6 @@
 
 #include <krb5_locl.h>
 
 
 #include <krb5_locl.h>
 
-RCSID("$Id$");
-
 krb5_error_code
 _krb5_mk_req_internal(krb5_context context,
                      krb5_auth_context *auth_context,
 krb5_error_code
 _krb5_mk_req_internal(krb5_context context,
                      krb5_auth_context *auth_context,
index fa45b09f18ed8a9a30c3c52d275a13f816812039..0623f6aae1ba4a1c65f2c2f1d76703ca869618a6 100644 (file)
@@ -32,8 +32,6 @@
 
 #include "krb5_locl.h"
 
 
 #include "krb5_locl.h"
 
-RCSID("$Id$");
-
 static krb5_error_code
 rr13(unsigned char *buf, size_t len)
 {
 static krb5_error_code
 rr13(unsigned char *buf, size_t len)
 {
@@ -109,8 +107,10 @@ _krb5_n_fold(const void *str, size_t len, void *key, size_t size)
     unsigned char *tmp = malloc(maxlen);
     unsigned char *buf = malloc(len);
 
     unsigned char *tmp = malloc(maxlen);
     unsigned char *buf = malloc(len);
 
-    if (tmp == NULL || buf == NULL)
-       return ENOMEM;
+    if (tmp == NULL || buf == NULL) {
+        ret = ENOMEM;
+       goto out;
+    }
 
     memcpy(buf, str, len);
     memset(key, 0, size);
 
     memcpy(buf, str, len);
     memset(key, 0, size);
@@ -129,9 +129,13 @@ _krb5_n_fold(const void *str, size_t len, void *key, size_t size)
        }
     } while(l != 0);
 out:
        }
     } while(l != 0);
 out:
-    memset(buf, 0, len);
-    free(buf);
-    memset(tmp, 0, maxlen);
-    free(tmp);
+    if (buf) {
+        memset(buf, 0, len);
+       free(buf);
+    }
+    if (tmp) {
+        memset(tmp, 0, maxlen);
+       free(tmp);
+    }
     return ret;
 }
     return ret;
 }
index 3c55eb3dc3aa5b6180e2aa8de1116faeee311e50..b66e79960d007fb9da4a12f4a38f2a320ce24e20 100644 (file)
@@ -34,8 +34,6 @@
 #include "krb5_locl.h"
 #include <wind.h>
 
 #include "krb5_locl.h"
 #include <wind.h>
 
-RCSID("$Id$");
-
 struct PAC_INFO_BUFFER {
     uint32_t type;
     uint32_t buffersize;
 struct PAC_INFO_BUFFER {
     uint32_t type;
     uint32_t buffersize;
@@ -613,6 +611,7 @@ verify_logonname(krb5_context context,
        ret = wind_ucs2utf8(ucs2, ucs2len, s, &u8len);
        free(ucs2);
        if (ret) {
        ret = wind_ucs2utf8(ucs2, ucs2len, s, &u8len);
        free(ucs2);
        if (ret) {
+           free(s);
            krb5_set_error_message(context, ret, "Failed to convert to UTF-8");
            return ret;
        }
            krb5_set_error_message(context, ret, "Failed to convert to UTF-8");
            return ret;
        }
index 022260e7094607d52374b3ac756347854fb0db2a..aa08248ed19007dc3d775a666b8c686a24cbac8d 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "krb5_locl.h"
 
 
 #include "krb5_locl.h"
 
-RCSID("$Id$");
-
 PA_DATA *
 krb5_find_padata(PA_DATA *val, unsigned len, int type, int *idx)
 {
 PA_DATA *
 krb5_find_padata(PA_DATA *val, unsigned len, int type, int *idx)
 {
index de5e90a68e13615c855c9e48572fc154031f9f22..18b5b5e0171e659167a2e6e7e966bf3345eb8b83 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "krb5_locl.h"
 
 
 #include "krb5_locl.h"
 
-RCSID("$Id$");
-
 struct krb5_dh_moduli {
     char *name;
     unsigned long bits;
 struct krb5_dh_moduli {
     char *name;
     unsigned long bits;
@@ -60,7 +58,13 @@ struct krb5_pk_cert {
 
 struct krb5_pk_init_ctx_data {
     struct krb5_pk_identity *id;
 
 struct krb5_pk_init_ctx_data {
     struct krb5_pk_identity *id;
-    DH *dh;
+    enum { USE_RSA, USE_DH, USE_ECDH } keyex;
+    union {
+       DH *dh;
+#ifdef HAVE_OPENSSL
+       EC_KEY *eckey;
+#endif
+    } u;
     krb5_data *clientDHNonce;
     struct krb5_dh_moduli **m;
     hx509_peer_info peer;
     krb5_data *clientDHNonce;
     struct krb5_dh_moduli **m;
     hx509_peer_info peer;
@@ -122,6 +126,45 @@ integer_to_BN(krb5_context context, const char *field, const heim_integer *f)
     return bn;
 }
 
     return bn;
 }
 
+static krb5_error_code
+select_dh_group(krb5_context context, DH *dh, unsigned long bits,
+               struct krb5_dh_moduli **moduli)
+{
+    const struct krb5_dh_moduli *m;
+
+    if (bits == 0) {
+       m = moduli[1]; /* XXX */
+       if (m == NULL)
+           m = moduli[0]; /* XXX */
+    } else {
+       int i;
+       for (i = 0; moduli[i] != NULL; i++) {
+           if (bits < moduli[i]->bits)
+               break;
+       }
+       if (moduli[i] == NULL) {
+           krb5_set_error_message(context, EINVAL,
+                                  N_("Did not find a DH group parameter "
+                                     "matching requirement of %lu bits", ""),
+                                  bits);
+           return EINVAL;
+       }
+       m = moduli[i];
+    }
+
+    dh->p = integer_to_BN(context, "p", &m->p);
+    if (dh->p == NULL)
+       return ENOMEM;
+    dh->g = integer_to_BN(context, "g", &m->g);
+    if (dh->g == NULL)
+       return ENOMEM;
+    dh->q = integer_to_BN(context, "q", &m->q);
+    if (dh->q == NULL)
+       return ENOMEM;
+
+    return 0;
+}
+
 struct certfind {
     const char *type;
     const heim_oid *oid;
 struct certfind {
     const char *type;
     const heim_oid *oid;
@@ -139,12 +182,12 @@ find_cert(krb5_context context, struct krb5_pk_identity *id,
     struct certfind cf[3] = {
        { "PKINIT EKU" },
        { "MS EKU" },
     struct certfind cf[3] = {
        { "PKINIT EKU" },
        { "MS EKU" },
-       { "no" }
+       { "any (or no)" }
     };
     int i, ret;
 
     };
     int i, ret;
 
-    cf[0].oid = oid_id_pkekuoid();
-    cf[1].oid = oid_id_pkinit_ms_eku();
+    cf[0].oid = &asn1_oid_id_pkekuoid;
+    cf[1].oid = &asn1_oid_id_pkinit_ms_eku;
     cf[2].oid = NULL;
 
     for (i = 0; i < sizeof(cf)/sizeof(cf[0]); i++) {
     cf[2].oid = NULL;
 
     for (i = 0; i < sizeof(cf)/sizeof(cf[0]); i++) {
@@ -159,7 +202,7 @@ find_cert(krb5_context context, struct krb5_pk_identity *id,
        if (ret == 0)
            break;
        pk_copy_error(context, id->hx509ctx, ret,
        if (ret == 0)
            break;
        pk_copy_error(context, id->hx509ctx, ret,
-                     "Failed cert for finding %s OID", cf[i].type);
+                     "Failed finding certificate with %s OID", cf[i].type);
     }
     return ret;
 }
     }
     return ret;
 }
@@ -173,37 +216,22 @@ create_signature(krb5_context context,
                 hx509_peer_info peer,
                 krb5_data *sd_data)
 {
                 hx509_peer_info peer,
                 krb5_data *sd_data)
 {
-    hx509_cert cert = NULL;
-    hx509_query *q = NULL;
-    int ret;
-
-    ret = hx509_query_alloc(id->hx509ctx, &q);
-    if (ret) {
-       pk_copy_error(context, id->hx509ctx, ret,
-                     "Allocate query to find signing certificate");
-       return ret;
-    }
+    int ret, flags = 0;
 
 
-    hx509_query_match_option(q, HX509_QUERY_OPTION_PRIVATE_KEY);
-    hx509_query_match_option(q, HX509_QUERY_OPTION_KU_DIGITALSIGNATURE);
-
-    ret = find_cert(context, id, q, &cert);
-    hx509_query_free(id->hx509ctx, q);
-    if (ret)
-       return ret;
+    if (id->cert == NULL)
+       flags |= HX509_CMS_SIGNATURE_NO_SIGNER;
 
     ret = hx509_cms_create_signed_1(id->hx509ctx,
 
     ret = hx509_cms_create_signed_1(id->hx509ctx,
-                                   0,
+                                   flags,
                                    eContentType,
                                    eContent->data,
                                    eContent->length,
                                    NULL,
                                    eContentType,
                                    eContent->data,
                                    eContent->length,
                                    NULL,
-                                   cert,
+                                   id->cert,
                                    peer,
                                    NULL,
                                    id->certs,
                                    sd_data);
                                    peer,
                                    NULL,
                                    id->certs,
                                    sd_data);
-    hx509_cert_free(cert);
     if (ret) {
        pk_copy_error(context, id->hx509ctx, ret,
                      "Create CMS signedData");
     if (ret) {
        pk_copy_error(context, id->hx509ctx, ret,
                      "Create CMS signedData");
@@ -222,6 +250,9 @@ cert2epi(hx509_context context, void *ctx, hx509_cert c)
     void *p;
     int ret;
 
     void *p;
     int ret;
 
+    if (ids->len > 10)
+       return 0;
+
     memset(&id, 0, sizeof(id));
 
     ret = hx509_cert_get_subject(c, &subject);
     memset(&id, 0, sizeof(id));
 
     ret = hx509_cert_get_subject(c, &subject);
@@ -319,7 +350,6 @@ static krb5_error_code
 build_auth_pack(krb5_context context,
                unsigned nonce,
                krb5_pk_init_ctx ctx,
 build_auth_pack(krb5_context context,
                unsigned nonce,
                krb5_pk_init_ctx ctx,
-               DH *dh,
                const KDC_REQ_BODY *body,
                AuthPack *a)
 {
                const KDC_REQ_BODY *body,
                AuthPack *a)
 {
@@ -368,12 +398,49 @@ build_auth_pack(krb5_context context,
     if (ret)
        return ret;
 
     if (ret)
        return ret;
 
-    if (dh) {
-       DomainParameters dp;
-       heim_integer dh_pub_key;
+    if (ctx->keyex == USE_DH || ctx->keyex == USE_ECDH) {
+       const char *moduli_file;
+       unsigned long dh_min_bits;
        krb5_data dhbuf;
        size_t size;
 
        krb5_data dhbuf;
        size_t size;
 
+       krb5_data_zero(&dhbuf);
+
+
+
+       moduli_file = krb5_config_get_string(context, NULL,
+                                            "libdefaults",
+                                            "moduli",
+                                            NULL);
+
+       dh_min_bits =
+           krb5_config_get_int_default(context, NULL, 0,
+                                       "libdefaults",
+                                       "pkinit_dh_min_bits",
+                                       NULL);
+
+       ret = _krb5_parse_moduli(context, moduli_file, &ctx->m);
+       if (ret)
+           return ret;
+       
+       ctx->u.dh = DH_new();
+       if (ctx->u.dh == NULL) {
+           krb5_set_error_message(context, ENOMEM,
+                                  N_("malloc: out of memory", ""));
+           return ENOMEM;
+       }
+
+       ret = select_dh_group(context, ctx->u.dh, dh_min_bits, ctx->m);
+       if (ret)
+           return ret;
+
+       if (DH_generate_key(ctx->u.dh) != 1) {
+           krb5_set_error_message(context, ENOMEM,
+                                  N_("pkinit: failed to generate DH key", ""));
+           return ENOMEM;
+       }
+
+
        if (1 /* support_cached_dh */) {
            ALLOC(a->clientDHNonce, 1);
            if (a->clientDHNonce == NULL) {
        if (1 /* support_cached_dh */) {
            ALLOC(a->clientDHNonce, 1);
            if (a->clientDHNonce == NULL) {
@@ -385,7 +452,7 @@ build_auth_pack(krb5_context context,
                krb5_clear_error_message(context);
                return ret;
            }
                krb5_clear_error_message(context);
                return ret;
            }
-           memset(a->clientDHNonce->data, 0, a->clientDHNonce->length);
+           RAND_bytes(a->clientDHNonce->data, a->clientDHNonce->length);
            ret = krb5_copy_data(context, a->clientDHNonce,
                                 &ctx->clientDHNonce);
            if (ret)
            ret = krb5_copy_data(context, a->clientDHNonce,
                                 &ctx->clientDHNonce);
            if (ret)
@@ -395,64 +462,135 @@ build_auth_pack(krb5_context context,
        ALLOC(a->clientPublicValue, 1);
        if (a->clientPublicValue == NULL)
            return ENOMEM;
        ALLOC(a->clientPublicValue, 1);
        if (a->clientPublicValue == NULL)
            return ENOMEM;
-       ret = der_copy_oid(oid_id_dhpublicnumber(),
-                          &a->clientPublicValue->algorithm.algorithm);
-       if (ret)
-           return ret;
-       
-       memset(&dp, 0, sizeof(dp));
 
 
-       ret = BN_to_integer(context, dh->p, &dp.p);
-       if (ret) {
-           free_DomainParameters(&dp);
-           return ret;
-       }
-       ret = BN_to_integer(context, dh->g, &dp.g);
-       if (ret) {
-           free_DomainParameters(&dp);
-           return ret;
-       }
-       ret = BN_to_integer(context, dh->q, &dp.q);
-       if (ret) {
-           free_DomainParameters(&dp);
-           return ret;
-       }
-       dp.j = NULL;
-       dp.validationParms = NULL;
+       if (ctx->keyex == USE_DH) {
+           DH *dh = ctx->u.dh;
+           DomainParameters dp;
+           heim_integer dh_pub_key;
 
 
-       a->clientPublicValue->algorithm.parameters =
-           malloc(sizeof(*a->clientPublicValue->algorithm.parameters));
-       if (a->clientPublicValue->algorithm.parameters == NULL) {
+           ret = der_copy_oid(&asn1_oid_id_dhpublicnumber,
+                              &a->clientPublicValue->algorithm.algorithm);
+           if (ret)
+               return ret;
+           
+           memset(&dp, 0, sizeof(dp));
+           
+           ret = BN_to_integer(context, dh->p, &dp.p);
+           if (ret) {
+               free_DomainParameters(&dp);
+               return ret;
+           }
+           ret = BN_to_integer(context, dh->g, &dp.g);
+           if (ret) {
+               free_DomainParameters(&dp);
+               return ret;
+           }
+           ret = BN_to_integer(context, dh->q, &dp.q);
+           if (ret) {
+               free_DomainParameters(&dp);
+               return ret;
+           }
+           dp.j = NULL;
+           dp.validationParms = NULL;
+           
+           a->clientPublicValue->algorithm.parameters =
+               malloc(sizeof(*a->clientPublicValue->algorithm.parameters));
+           if (a->clientPublicValue->algorithm.parameters == NULL) {
+               free_DomainParameters(&dp);
+               return ret;
+           }
+           
+           ASN1_MALLOC_ENCODE(DomainParameters,
+                              a->clientPublicValue->algorithm.parameters->data,
+                              a->clientPublicValue->algorithm.parameters->length,
+                              &dp, &size, ret);
            free_DomainParameters(&dp);
            free_DomainParameters(&dp);
-           return ret;
-       }
+           if (ret)
+               return ret;
+           if (size != a->clientPublicValue->algorithm.parameters->length)
+               krb5_abortx(context, "Internal ASN1 encoder error");
+           
+           ret = BN_to_integer(context, dh->pub_key, &dh_pub_key);
+           if (ret)
+               return ret;
+           
+           ASN1_MALLOC_ENCODE(DHPublicKey, dhbuf.data, dhbuf.length,
+                              &dh_pub_key, &size, ret);
+           der_free_heim_integer(&dh_pub_key);
+           if (ret)
+               return ret;
+           if (size != dhbuf.length)
+               krb5_abortx(context, "asn1 internal error");
+       } else if (ctx->keyex == USE_ECDH) {
+#ifdef HAVE_OPENSSL
+           ECParameters ecp;
+           unsigned char *p;
+           int len;
+
+           /* copy in public key, XXX find the best curve that the server support or use the clients curve if possible */
+
+           ecp.element = choice_ECParameters_namedCurve;
+           ret = der_copy_oid(&asn1_oid_id_ec_group_secp256r1,
+                              &ecp.u.namedCurve);
+           if (ret)
+               return ret;
 
 
-       ASN1_MALLOC_ENCODE(DomainParameters,
-                          a->clientPublicValue->algorithm.parameters->data,
-                          a->clientPublicValue->algorithm.parameters->length,
-                          &dp, &size, ret);
-       free_DomainParameters(&dp);
-       if (ret)
-           return ret;
-       if (size != a->clientPublicValue->algorithm.parameters->length)
-           krb5_abortx(context, "Internal ASN1 encoder error");
+           ALLOC(a->clientPublicValue->algorithm.parameters, 1);
+           if (a->clientPublicValue->algorithm.parameters == NULL) {
+               free_ECParameters(&ecp);
+               return ENOMEM;
+           }
+           ASN1_MALLOC_ENCODE(ECParameters, p, len, &ecp, &size, ret);
+           free_ECParameters(&ecp);
+           if (ret)
+               return ret;
+           if (size != len)
+               krb5_abortx(context, "asn1 internal error");
+           
+           a->clientPublicValue->algorithm.parameters->data = p;
+           a->clientPublicValue->algorithm.parameters->length = size;
 
 
-       ret = BN_to_integer(context, dh->pub_key, &dh_pub_key);
-       if (ret)
-           return ret;
+           /* copy in public key */
 
 
-       ASN1_MALLOC_ENCODE(DHPublicKey, dhbuf.data, dhbuf.length,
-                          &dh_pub_key, &size, ret);
-       der_free_heim_integer(&dh_pub_key);
-       if (ret)
-           return ret;
-       if (size != dhbuf.length)
-           krb5_abortx(context, "asn1 internal error");
+           ret = der_copy_oid(&asn1_oid_id_ecPublicKey,
+                              &a->clientPublicValue->algorithm.algorithm);
+           if (ret)
+               return ret;
+
+           ctx->u.eckey = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
+           if (ctx->u.eckey == NULL)
+               return ENOMEM;
+
+           ret = EC_KEY_generate_key(ctx->u.eckey);
+           if (ret != 1)
+               return EINVAL;
 
 
+           /* encode onto dhkey */
+
+           len = i2o_ECPublicKey(ctx->u.eckey, NULL);
+           if (len <= 0)
+               abort();
+
+           dhbuf.data = malloc(len);
+           if (dhbuf.data == NULL)
+               abort();
+           dhbuf.length = len;
+           p = dhbuf.data;
+
+           len = i2o_ECPublicKey(ctx->u.eckey, &p);
+           if (len <= 0)
+               abort();
+
+           /* XXX verify that this is right with RFC3279 */
+#else
+           return EINVAL;
+#endif
+       } else
+           krb5_abortx(context, "internal error");
        a->clientPublicValue->subjectPublicKey.length = dhbuf.length * 8;
        a->clientPublicValue->subjectPublicKey.data = dhbuf.data;
     }
        a->clientPublicValue->subjectPublicKey.length = dhbuf.length * 8;
        a->clientPublicValue->subjectPublicKey.data = dhbuf.data;
     }
-
+    
     {
        a->supportedCMSTypes = calloc(1, sizeof(*a->supportedCMSTypes));
        if (a->supportedCMSTypes == NULL)
     {
        a->supportedCMSTypes = calloc(1, sizeof(*a->supportedCMSTypes));
        if (a->supportedCMSTypes == NULL)
@@ -546,13 +684,13 @@ pk_mk_padata(krb5_context context,
        if (buf.length != size)
            krb5_abortx(context, "internal ASN1 encoder error");
 
        if (buf.length != size)
            krb5_abortx(context, "internal ASN1 encoder error");
 
-       oid = oid_id_pkcs7_data();
+       oid = &asn1_oid_id_pkcs7_data;
     } else if (ctx->type == PKINIT_27) {
        AuthPack ap;
        
        memset(&ap, 0, sizeof(ap));
 
     } else if (ctx->type == PKINIT_27) {
        AuthPack ap;
        
        memset(&ap, 0, sizeof(ap));
 
-       ret = build_auth_pack(context, nonce, ctx, ctx->dh, req_body, &ap);
+       ret = build_auth_pack(context, nonce, ctx, req_body, &ap);
        if (ret) {
            free_AuthPack(&ap);
            goto out;
        if (ret) {
            free_AuthPack(&ap);
            goto out;
@@ -569,7 +707,7 @@ pk_mk_padata(krb5_context context,
        if (buf.length != size)
            krb5_abortx(context, "internal ASN1 encoder error");
 
        if (buf.length != size)
            krb5_abortx(context, "internal ASN1 encoder error");
 
-       oid = oid_id_pkauthdata();
+       oid = &asn1_oid_id_pkauthdata;
     } else
        krb5_abortx(context, "internal pkinit error");
 
     } else
        krb5_abortx(context, "internal pkinit error");
 
@@ -579,7 +717,7 @@ pk_mk_padata(krb5_context context,
     if (ret)
        goto out;
 
     if (ret)
        goto out;
 
-    ret = hx509_cms_wrap_ContentInfo(oid_id_pkcs7_signedData(), &sd_buf, &buf);
+    ret = hx509_cms_wrap_ContentInfo(&asn1_oid_id_pkcs7_signedData, &sd_buf, &buf);
     krb5_data_free(&sd_buf);
     if (ret) {
        krb5_set_error_message(context, ret,
     krb5_data_free(&sd_buf);
     if (ret) {
        krb5_set_error_message(context, ret,
@@ -648,8 +786,8 @@ pk_mk_padata(krb5_context context,
     if (ret)
        free(buf.data);
 
     if (ret)
        free(buf.data);
 
-    if (ret == 0 && ctx->type == PKINIT_WIN2K)
-       krb5_padata_add(context, md, KRB5_PADATA_PK_AS_09_BINDING, NULL, 0);
+    if (ret == 0)
+       krb5_padata_add(context, md, KRB5_PADATA_PK_AS_09_BINDING, NULL, 0);
 
  out:
     free_ContentInfo(&content_info);
 
  out:
     free_ContentInfo(&content_info);
@@ -721,14 +859,14 @@ _krb5_pk_mk_padata(krb5_context context,
     return pk_mk_padata(context, ctx, req_body, nonce, md);
 }
 
     return pk_mk_padata(context, ctx, req_body, nonce, md);
 }
 
-krb5_error_code KRB5_LIB_FUNCTION
-_krb5_pk_verify_sign(krb5_context context,
-                    const void *data,
-                    size_t length,
-                    struct krb5_pk_identity *id,
-                    heim_oid *contentType,
-                    krb5_data *content,
-                    struct krb5_pk_cert **signer)
+static krb5_error_code
+pk_verify_sign(krb5_context context,
+              const void *data,
+              size_t length,
+              struct krb5_pk_identity *id,
+              heim_oid *contentType,
+              krb5_data *content,
+              struct krb5_pk_cert **signer)
 {
     hx509_certs signer_certs;
     int ret;
 {
     hx509_certs signer_certs;
     int ret;
@@ -737,6 +875,7 @@ _krb5_pk_verify_sign(krb5_context context,
 
     ret = hx509_cms_verify_signed(id->hx509ctx,
                                  id->verify_ctx,
 
     ret = hx509_cms_verify_signed(id->hx509ctx,
                                  id->verify_ctx,
+                                 HX509_CMS_VS_ALLOW_DATA_OID_MISMATCH|HX509_CMS_VS_NO_KU_CHECK,
                                  data,
                                  length,
                                  NULL,
                                  data,
                                  length,
                                  NULL,
@@ -902,7 +1041,7 @@ pk_verify_host(krb5_context context,
 
     if (ctx->require_eku) {
        ret = hx509_cert_check_eku(ctx->id->hx509ctx, host->cert,
 
     if (ctx->require_eku) {
        ret = hx509_cert_check_eku(ctx->id->hx509ctx, host->cert,
-                                  oid_id_pkkdcekuoid(), 0);
+                                  &asn1_oid_id_pkkdcekuoid, 0);
        if (ret) {
            krb5_set_error_message(context, ret,
                                   N_("No PK-INIT KDC EKU in kdc certificate", ""));
        if (ret) {
            krb5_set_error_message(context, ret,
                                   N_("No PK-INIT KDC EKU in kdc certificate", ""));
@@ -915,7 +1054,7 @@ pk_verify_host(krb5_context context,
 
        ret = hx509_cert_find_subjectAltName_otherName(ctx->id->hx509ctx,
                                                       host->cert,
 
        ret = hx509_cert_find_subjectAltName_otherName(ctx->id->hx509ctx,
                                                       host->cert,
-                                                      oid_id_pkinit_san(),
+                                                      &asn1_oid_id_pkinit_san,
                                                       &list);
        if (ret) {
            krb5_set_error_message(context, ret,
                                                       &list);
        if (ret) {
            krb5_set_error_message(context, ret,
@@ -995,16 +1134,20 @@ pk_rd_pa_reply_enckey(krb5_context context,
     struct krb5_pk_cert *host = NULL;
     krb5_data content;
     heim_oid contentType = { 0, NULL };
     struct krb5_pk_cert *host = NULL;
     krb5_data content;
     heim_oid contentType = { 0, NULL };
+    int flags = HX509_CMS_UE_DONT_REQUIRE_KU_ENCIPHERMENT;
 
 
-    if (der_heim_oid_cmp(oid_id_pkcs7_envelopedData(), dataType)) {
+    if (der_heim_oid_cmp(&asn1_oid_id_pkcs7_envelopedData, dataType)) {
        krb5_set_error_message(context, EINVAL,
                               N_("PKINIT: Invalid content type", ""));
        return EINVAL;
     }
 
        krb5_set_error_message(context, EINVAL,
                               N_("PKINIT: Invalid content type", ""));
        return EINVAL;
     }
 
+    if (ctx->type == PKINIT_WIN2K)
+       flags |= HX509_CMS_UE_ALLOW_WEAK;
+
     ret = hx509_cms_unenvelope(ctx->id->hx509ctx,
                               ctx->id->certs,
     ret = hx509_cms_unenvelope(ctx->id->hx509ctx,
                               ctx->id->certs,
-                              HX509_CMS_UE_DONT_REQUIRE_KU_ENCIPHERMENT,
+                              flags,
                               indata->data,
                               indata->length,
                               NULL,
                               indata->data,
                               indata->length,
                               NULL,
@@ -1042,7 +1185,9 @@ pk_rd_pa_reply_enckey(krb5_context context,
        heim_octet_string out;
 
        ret = hx509_cms_unwrap_ContentInfo(&content, &type, &out, NULL);
        heim_octet_string out;
 
        ret = hx509_cms_unwrap_ContentInfo(&content, &type, &out, NULL);
-       if (der_heim_oid_cmp(&type, oid_id_pkcs7_signedData())) {
+       if (ret)
+           goto out;
+       if (der_heim_oid_cmp(&type, &asn1_oid_id_pkcs7_signedData)) {
            ret = EINVAL; /* XXX */
            krb5_set_error_message(context, ret,
                                   N_("PKINIT: Invalid content type", ""));
            ret = EINVAL; /* XXX */
            krb5_set_error_message(context, ret,
                                   N_("PKINIT: Invalid content type", ""));
@@ -1061,13 +1206,13 @@ pk_rd_pa_reply_enckey(krb5_context context,
        }
     }
 
        }
     }
 
-    ret = _krb5_pk_verify_sign(context,
-                              content.data,
-                              content.length,
-                              ctx->id,
-                              &contentType,
-                              &content,
-                              &host);
+    ret = pk_verify_sign(context,
+                        content.data,
+                        content.length,
+                        ctx->id,
+                        &contentType,
+                        &content,
+                        &host);
     if (ret)
        goto out;
 
     if (ret)
        goto out;
 
@@ -1079,13 +1224,13 @@ pk_rd_pa_reply_enckey(krb5_context context,
 
 #if 0
     if (type == PKINIT_WIN2K) {
 
 #if 0
     if (type == PKINIT_WIN2K) {
-       if (der_heim_oid_cmp(&contentType, oid_id_pkcs7_data()) != 0) {
+       if (der_heim_oid_cmp(&contentType, &asn1_oid_id_pkcs7_data) != 0) {
            ret = KRB5KRB_AP_ERR_MSG_TYPE;
            krb5_set_error_message(context, ret, "PKINIT: reply key, wrong oid");
            goto out;
        }
     } else {
            ret = KRB5KRB_AP_ERR_MSG_TYPE;
            krb5_set_error_message(context, ret, "PKINIT: reply key, wrong oid");
            goto out;
        }
     } else {
-       if (der_heim_oid_cmp(&contentType, oid_id_pkrkeydata()) != 0) {
+       if (der_heim_oid_cmp(&contentType, &asn1_oid_id_pkrkeydata) != 0) {
            ret = KRB5KRB_AP_ERR_MSG_TYPE;
            krb5_set_error_message(context, ret, "PKINIT: reply key, wrong oid");
            goto out;
            ret = KRB5KRB_AP_ERR_MSG_TYPE;
            krb5_set_error_message(context, ret, "PKINIT: reply key, wrong oid");
            goto out;
@@ -1131,32 +1276,33 @@ pk_rd_pa_reply_dh(krb5_context context,
                   PA_DATA *pa,
                   krb5_keyblock **key)
 {
                   PA_DATA *pa,
                   krb5_keyblock **key)
 {
-    unsigned char *p, *dh_gen_key = NULL;
+    const unsigned char *p;
+    unsigned char *dh_gen_key = NULL;
     struct krb5_pk_cert *host = NULL;
     BIGNUM *kdc_dh_pubkey = NULL;
     KDCDHKeyInfo kdc_dh_info;
     heim_oid contentType = { 0, NULL };
     krb5_data content;
     krb5_error_code ret;
     struct krb5_pk_cert *host = NULL;
     BIGNUM *kdc_dh_pubkey = NULL;
     KDCDHKeyInfo kdc_dh_info;
     heim_oid contentType = { 0, NULL };
     krb5_data content;
     krb5_error_code ret;
-    int dh_gen_keylen;
+    int dh_gen_keylen = 0;
     size_t size;
 
     krb5_data_zero(&content);
     memset(&kdc_dh_info, 0, sizeof(kdc_dh_info));
 
     size_t size;
 
     krb5_data_zero(&content);
     memset(&kdc_dh_info, 0, sizeof(kdc_dh_info));
 
-    if (der_heim_oid_cmp(oid_id_pkcs7_signedData(), dataType)) {
+    if (der_heim_oid_cmp(&asn1_oid_id_pkcs7_signedData, dataType)) {
        krb5_set_error_message(context, EINVAL,
                               N_("PKINIT: Invalid content type", ""));
        return EINVAL;
     }
 
        krb5_set_error_message(context, EINVAL,
                               N_("PKINIT: Invalid content type", ""));
        return EINVAL;
     }
 
-    ret = _krb5_pk_verify_sign(context,
-                              indata->data,
-                              indata->length,
-                              ctx->id,
-                              &contentType,
-                              &content,
-                              &host);
+    ret = pk_verify_sign(context,
+                        indata->data,
+                        indata->length,
+                        ctx->id,
+                        &contentType,
+                        &content,
+                        &host);
     if (ret)
        goto out;
 
     if (ret)
        goto out;
 
@@ -1165,7 +1311,7 @@ pk_rd_pa_reply_dh(krb5_context context,
     if (ret)
        goto out;
 
     if (ret)
        goto out;
 
-    if (der_heim_oid_cmp(&contentType, oid_id_pkdhkeydata())) {
+    if (der_heim_oid_cmp(&contentType, &asn1_oid_id_pkdhkeydata)) {
        ret = KRB5KRB_AP_ERR_MSG_TYPE;
        krb5_set_error_message(context, ret,
                               N_("pkinit - dh reply contains wrong oid", ""));
        ret = KRB5KRB_AP_ERR_MSG_TYPE;
        krb5_set_error_message(context, ret,
                               N_("pkinit - dh reply contains wrong oid", ""));
@@ -1221,7 +1367,7 @@ pk_rd_pa_reply_dh(krb5_context context,
     p = kdc_dh_info.subjectPublicKey.data;
     size = (kdc_dh_info.subjectPublicKey.length + 7) / 8;
 
     p = kdc_dh_info.subjectPublicKey.data;
     size = (kdc_dh_info.subjectPublicKey.length + 7) / 8;
 
-    {
+    if (ctx->keyex == USE_DH) {
        DHPublicKey k;
        ret = decode_DHPublicKey(p, size, &k, NULL);
        if (ret) {
        DHPublicKey k;
        ret = decode_DHPublicKey(p, size, &k, NULL);
        if (ret) {
@@ -1237,30 +1383,78 @@ pk_rd_pa_reply_dh(krb5_context context,
            ret = ENOMEM;
            goto out;
        }
            ret = ENOMEM;
            goto out;
        }
-    }
 
 
-    dh_gen_keylen = DH_size(ctx->dh);
-    size = BN_num_bytes(ctx->dh->p);
-    if (size < dh_gen_keylen)
-       size = dh_gen_keylen;
 
 
-    dh_gen_key = malloc(size);
-    if (dh_gen_key == NULL) {
-       ret = ENOMEM;
-       krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
-       goto out;
-    }
-    memset(dh_gen_key, 0, size - dh_gen_keylen);
+       dh_gen_keylen = DH_size(ctx->u.dh);
+       size = BN_num_bytes(ctx->u.dh->p);
+       if (size < dh_gen_keylen)
+           size = dh_gen_keylen;
 
 
-    dh_gen_keylen = DH_compute_key(dh_gen_key + (size - dh_gen_keylen),
-                                  kdc_dh_pubkey, ctx->dh);
-    if (dh_gen_keylen == -1) {
-       ret = KRB5KRB_ERR_GENERIC;
-       krb5_set_error_message(context, ret,
-                              N_("PKINIT: Can't compute Diffie-Hellman key", ""));
-       goto out;
-    }
+       dh_gen_key = malloc(size);
+       if (dh_gen_key == NULL) {
+           ret = ENOMEM;
+           krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
+           goto out;
+       }
+       memset(dh_gen_key, 0, size - dh_gen_keylen);
+       
+       dh_gen_keylen = DH_compute_key(dh_gen_key + (size - dh_gen_keylen),
+                                      kdc_dh_pubkey, ctx->u.dh);
+       if (dh_gen_keylen == -1) {
+           ret = KRB5KRB_ERR_GENERIC;
+           krb5_set_error_message(context, ret,
+                                  N_("PKINIT: Can't compute Diffie-Hellman key", ""));
+           goto out;
+       }
+    } else {
+#ifdef HAVE_OPENSSL
+       const EC_GROUP *group;
+       EC_KEY *public = NULL;
+
+       group = EC_KEY_get0_group(ctx->u.eckey);
+
+       public = EC_KEY_new();
+       if (public == NULL) {
+           ret = ENOMEM;
+           goto out;
+       }
+       if (EC_KEY_set_group(public, group) != 1) {
+           EC_KEY_free(public);
+           ret = ENOMEM;
+           goto out;
+       }
 
 
+       if (o2i_ECPublicKey(&public, &p, size) == NULL) {
+           EC_KEY_free(public);
+           ret = KRB5KRB_ERR_GENERIC;
+           krb5_set_error_message(context, ret,
+                                  N_("PKINIT: Can't parse ECDH public key", ""));
+           goto out;
+       }
+
+       size = (EC_GROUP_get_degree(group) + 7) / 8;
+       dh_gen_key = malloc(size);
+       if (dh_gen_key == NULL) {
+           EC_KEY_free(public);
+           ret = ENOMEM;
+           krb5_set_error_message(context, ret,
+                                  N_("malloc: out of memory", ""));
+           goto out;
+       }
+       dh_gen_keylen = ECDH_compute_key(dh_gen_key, size,
+                                        EC_KEY_get0_public_key(public), ctx->u.eckey, NULL);
+       EC_KEY_free(public);
+       if (dh_gen_keylen == -1) {
+           ret = KRB5KRB_ERR_GENERIC;
+           krb5_set_error_message(context, ret,
+                                  N_("PKINIT: Can't compute ECDH public key", ""));
+           goto out;
+       }
+#else
+       ret = EINVAL;
+#endif
+    }
+       
     *key = malloc (sizeof (**key));
     if (*key == NULL) {
        ret = ENOMEM;
     *key = malloc (sizeof (**key));
     if (*key == NULL) {
        ret = ENOMEM;
@@ -1286,7 +1480,7 @@ pk_rd_pa_reply_dh(krb5_context context,
     if (kdc_dh_pubkey)
        BN_free(kdc_dh_pubkey);
     if (dh_gen_key) {
     if (kdc_dh_pubkey)
        BN_free(kdc_dh_pubkey);
     if (dh_gen_key) {
-       memset(dh_gen_key, 0, DH_size(ctx->dh));
+       memset(dh_gen_key, 0, dh_gen_keylen);
        free(dh_gen_key);
     }
     if (host)
        free(dh_gen_key);
     }
     if (host)
@@ -1343,12 +1537,42 @@ _krb5_pk_rd_pa_reply(krb5_context context,
        case choice_PA_PK_AS_REP_encKeyPack:
            os = rep.u.encKeyPack;
            break;
        case choice_PA_PK_AS_REP_encKeyPack:
            os = rep.u.encKeyPack;
            break;
-       default:
+       default: {
+           PA_PK_AS_REP_BTMM btmm;
            free_PA_PK_AS_REP(&rep);
            free_PA_PK_AS_REP(&rep);
-           krb5_set_error_message(context, EINVAL,
-                                  N_("PKINIT: -27 reply "
-                                     "invalid content type", ""));
-           return EINVAL;
+           memset(&rep, 0, sizeof(rep));
+           
+           ret = decode_PA_PK_AS_REP_BTMM(pa->padata_value.data,
+                                          pa->padata_value.length,
+                                          &btmm,
+                                          &size);
+           if (ret) {
+               krb5_set_error_message(context, EINVAL,
+                                      N_("PKINIT: -27 reply "
+                                         "invalid content type", ""));
+               return EINVAL;
+           }
+
+           if (btmm.dhSignedData || btmm.encKeyPack == NULL) {
+               free_PA_PK_AS_REP_BTMM(&btmm);
+               ret = EINVAL;
+               krb5_set_error_message(context, ret,
+                                      N_("DH mode not supported for BTMM mode", ""));
+               return ret;
+           }
+
+           /*
+            * Transform to IETF style PK-INIT reply so that free works below
+            */
+
+           rep.element = choice_PA_PK_AS_REP_encKeyPack;
+           rep.u.encKeyPack.data = btmm.encKeyPack->data;
+           rep.u.encKeyPack.length = btmm.encKeyPack->length;
+           btmm.encKeyPack->data = NULL;
+           btmm.encKeyPack->length = 0;
+           free_PA_PK_AS_REP_BTMM(&btmm);
+           os = rep.u.encKeyPack;
+       }
        }
 
        ret = hx509_cms_unwrap_ContentInfo(&os, &oid, &data, NULL);
        }
 
        ret = hx509_cms_unwrap_ContentInfo(&os, &oid, &data, NULL);
@@ -1484,18 +1708,10 @@ hx_pass_prompter(void *data, const hx509_prompt *prompter)
     return 0;
 }
 
     return 0;
 }
 
-
-void KRB5_LIB_FUNCTION
-_krb5_pk_allow_proxy_certificate(struct krb5_pk_identity *id,
-                                int boolean)
-{
-    hx509_verify_set_proxy_certificate(id->verify_ctx, boolean);
-}
-
-
 krb5_error_code KRB5_LIB_FUNCTION
 _krb5_pk_load_id(krb5_context context,
                 struct krb5_pk_identity **ret_id,
 krb5_error_code KRB5_LIB_FUNCTION
 _krb5_pk_load_id(krb5_context context,
                 struct krb5_pk_identity **ret_id,
+                int flags,
                 const char *user_id,
                 const char *anchor_id,
                 char * const *chain_list,
                 const char *user_id,
                 const char *anchor_id,
                 char * const *chain_list,
@@ -1517,7 +1733,7 @@ _krb5_pk_load_id(krb5_context context,
        return HEIM_PKINIT_NO_VALID_CA;
     }
 
        return HEIM_PKINIT_NO_VALID_CA;
     }
 
-    if (user_id == NULL) {
+    if (user_id == NULL && (flags & 4) == 0) {
        krb5_set_error_message(context, HEIM_PKINIT_NO_PRIVATE_KEY,
                               N_("PKINIT: No user certificate given", ""));
        return HEIM_PKINIT_NO_PRIVATE_KEY;
        krb5_set_error_message(context, HEIM_PKINIT_NO_PRIVATE_KEY,
                               N_("PKINIT: No user certificate given", ""));
        return HEIM_PKINIT_NO_PRIVATE_KEY;
@@ -1537,6 +1753,11 @@ _krb5_pk_load_id(krb5_context context,
        goto out;
 
     ret = hx509_lock_init(id->hx509ctx, &lock);
        goto out;
 
     ret = hx509_lock_init(id->hx509ctx, &lock);
+    if (ret) {
+       pk_copy_error(context, id->hx509ctx, ret, "Failed init lock");
+       goto out;
+    }
+
     if (password && password[0])
        hx509_lock_add_password(lock, password);
 
     if (password && password[0])
        hx509_lock_add_password(lock, password);
 
@@ -1550,11 +1771,15 @@ _krb5_pk_load_id(krb5_context context,
            goto out;
     }
 
            goto out;
     }
 
-    ret = hx509_certs_init(id->hx509ctx, user_id, 0, lock, &id->certs);
-    if (ret) {
-       pk_copy_error(context, id->hx509ctx, ret,
-                     "Failed to init cert certs");
-       goto out;
+    if (user_id) {
+       ret = hx509_certs_init(id->hx509ctx, user_id, 0, lock, &id->certs);
+       if (ret) {
+           pk_copy_error(context, id->hx509ctx, ret,
+                         "Failed to init cert certs");
+           goto out;
+       }
+    } else {
+       id->certs = NULL;
     }
 
     ret = hx509_certs_init(id->hx509ctx, anchor_id, 0, NULL, &id->anchors);
     }
 
     ret = hx509_certs_init(id->hx509ctx, anchor_id, 0, NULL, &id->anchors);
@@ -1628,50 +1853,12 @@ _krb5_pk_load_id(krb5_context context,
     } else
        *ret_id = id;
 
     } else
        *ret_id = id;
 
-    hx509_lock_free(lock);
+    if (lock)
+        hx509_lock_free(lock);
 
     return ret;
 }
 
 
     return ret;
 }
 
-static krb5_error_code
-select_dh_group(krb5_context context, DH *dh, unsigned long bits,
-               struct krb5_dh_moduli **moduli)
-{
-    const struct krb5_dh_moduli *m;
-
-    if (bits == 0) {
-       m = moduli[1]; /* XXX */
-       if (m == NULL)
-           m = moduli[0]; /* XXX */
-    } else {
-       int i;
-       for (i = 0; moduli[i] != NULL; i++) {
-           if (bits < moduli[i]->bits)
-               break;
-       }
-       if (moduli[i] == NULL) {
-           krb5_set_error_message(context, EINVAL,
-                                  N_("Did not find a DH group parameter "
-                                     "matching requirement of %lu bits", ""),
-                                  bits);
-           return EINVAL;
-       }
-       m = moduli[i];
-    }
-
-    dh->p = integer_to_BN(context, "p", &m->p);
-    if (dh->p == NULL)
-       return ENOMEM;
-    dh->g = integer_to_BN(context, "g", &m->g);
-    if (dh->g == NULL)
-       return ENOMEM;
-    dh->q = integer_to_BN(context, "q", &m->q);
-    if (dh->q == NULL)
-       return ENOMEM;
-
-    return 0;
-}
-
 /*
  *
  */
 /*
  *
  */
@@ -1752,8 +1939,10 @@ _krb5_parse_moduli_line(krb5_context context,
 
     while (isspace((unsigned char)*p))
        p++;
 
     while (isspace((unsigned char)*p))
        p++;
-    if (*p  == '#')
+    if (*p  == '#') {
+        free(m1);
        return 0;
        return 0;
+    }
     ret = EINVAL;
 
     p1 = strsep(&p, " \t");
     ret = EINVAL;
 
     p1 = strsep(&p, " \t");
@@ -1764,7 +1953,7 @@ _krb5_parse_moduli_line(krb5_context context,
        goto out;
     }
     m1->name = strdup(p1);
        goto out;
     }
     m1->name = strdup(p1);
-    if (p1 == NULL) {
+    if (m1->name == NULL) {
        ret = ENOMEM;
        krb5_set_error_message(context, ret, N_("malloc: out of memeory", ""));
        goto out;
        ret = ENOMEM;
        krb5_set_error_message(context, ret, N_("malloc: out of memeory", ""));
        goto out;
@@ -2002,12 +2191,22 @@ _krb5_get_init_creds_opt_free_pkinit(krb5_get_init_creds_opt *opt)
     if (opt->opt_private == NULL || opt->opt_private->pk_init_ctx == NULL)
        return;
     ctx = opt->opt_private->pk_init_ctx;
     if (opt->opt_private == NULL || opt->opt_private->pk_init_ctx == NULL)
        return;
     ctx = opt->opt_private->pk_init_ctx;
-    if (ctx->dh)
-       DH_free(ctx->dh);
-    ctx->dh = NULL;
+    switch (ctx->keyex) {
+    case USE_DH:
+       DH_free(ctx->u.dh);
+       break;
+    case USE_RSA:
+       break;
+    case USE_ECDH: 
+#ifdef HAVE_OPENSSL
+       EC_KEY_free(ctx->u.eckey);
+#endif
+       break;
+    }
     if (ctx->id) {
        hx509_verify_destroy_ctx(ctx->id->verify_ctx);
        hx509_certs_free(&ctx->id->certs);
     if (ctx->id) {
        hx509_verify_destroy_ctx(ctx->id->verify_ctx);
        hx509_certs_free(&ctx->id->certs);
+       hx509_cert_free(ctx->id->cert);
        hx509_certs_free(&ctx->id->anchors);
        hx509_certs_free(&ctx->id->certpool);
        hx509_context_free(&ctx->id->hx509ctx);
        hx509_certs_free(&ctx->id->anchors);
        hx509_certs_free(&ctx->id->certpool);
        hx509_context_free(&ctx->id->hx509ctx);
@@ -2056,9 +2255,6 @@ krb5_get_init_creds_opt_set_pkinit(krb5_context context,
                               N_("malloc: out of memory", ""));
        return ENOMEM;
     }
                               N_("malloc: out of memory", ""));
        return ENOMEM;
     }
-    opt->opt_private->pk_init_ctx->dh = NULL;
-    opt->opt_private->pk_init_ctx->id = NULL;
-    opt->opt_private->pk_init_ctx->clientDHNonce = NULL;
     opt->opt_private->pk_init_ctx->require_binding = 0;
     opt->opt_private->pk_init_ctx->require_eku = 1;
     opt->opt_private->pk_init_ctx->require_krbtgt_otherName = 1;
     opt->opt_private->pk_init_ctx->require_binding = 0;
     opt->opt_private->pk_init_ctx->require_eku = 1;
     opt->opt_private->pk_init_ctx->require_krbtgt_otherName = 1;
@@ -2086,6 +2282,7 @@ krb5_get_init_creds_opt_set_pkinit(krb5_context context,
 
     ret = _krb5_pk_load_id(context,
                           &opt->opt_private->pk_init_ctx->id,
 
     ret = _krb5_pk_load_id(context,
                           &opt->opt_private->pk_init_ctx->id,
+                          flags,
                           user_id,
                           x509_anchors,
                           pool,
                           user_id,
                           x509_anchors,
                           pool,
@@ -2099,50 +2296,58 @@ krb5_get_init_creds_opt_set_pkinit(krb5_context context,
        return ret;
     }
 
        return ret;
     }
 
-    if ((flags & 2) == 0) {
-       const char *moduli_file;
-       unsigned long dh_min_bits;
-
-       moduli_file = krb5_config_get_string(context, NULL,
-                                            "libdefaults",
-                                            "moduli",
-                                            NULL);
+    if (opt->opt_private->pk_init_ctx->id->certs) {
+       hx509_query *q = NULL;
+       hx509_cert cert = NULL;
+       hx509_context hx509ctx = opt->opt_private->pk_init_ctx->id->hx509ctx;
 
 
-       dh_min_bits =
-           krb5_config_get_int_default(context, NULL, 0,
-                                       "libdefaults",
-                                       "pkinit_dh_min_bits",
-                                       NULL);
-
-       ret = _krb5_parse_moduli(context, moduli_file,
-                                &opt->opt_private->pk_init_ctx->m);
+       ret = hx509_query_alloc(hx509ctx, &q);
        if (ret) {
        if (ret) {
-           _krb5_get_init_creds_opt_free_pkinit(opt);
+           pk_copy_error(context, hx509ctx, ret,
+                         "Allocate query to find signing certificate");
            return ret;
        }
        
            return ret;
        }
        
-       opt->opt_private->pk_init_ctx->dh = DH_new();
-       if (opt->opt_private->pk_init_ctx->dh == NULL) {
-           _krb5_get_init_creds_opt_free_pkinit(opt);
-           krb5_set_error_message(context, ENOMEM,
-                                  N_("malloc: out of memory", ""));
-           return ENOMEM;
-       }
-
-       ret = select_dh_group(context, opt->opt_private->pk_init_ctx->dh,
-                             dh_min_bits,
-                             opt->opt_private->pk_init_ctx->m);
-       if (ret) {
-           _krb5_get_init_creds_opt_free_pkinit(opt);
+       hx509_query_match_option(q, HX509_QUERY_OPTION_PRIVATE_KEY);
+       hx509_query_match_option(q, HX509_QUERY_OPTION_KU_DIGITALSIGNATURE);
+       
+       ret = find_cert(context, opt->opt_private->pk_init_ctx->id, q, &cert);
+       hx509_query_free(hx509ctx, q);
+       if (ret)
            return ret;
            return ret;
-       }
 
 
-       if (DH_generate_key(opt->opt_private->pk_init_ctx->dh) != 1) {
-           _krb5_get_init_creds_opt_free_pkinit(opt);
-           krb5_set_error_message(context, ENOMEM,
-                                  N_("pkinit: failed to generate DH key", ""));
-           return ENOMEM;
+       opt->opt_private->pk_init_ctx->id->cert = cert;
+    } else
+       opt->opt_private->pk_init_ctx->id->cert = NULL;
+
+    if ((flags & 2) == 0) {
+       hx509_context hx509ctx = opt->opt_private->pk_init_ctx->id->hx509ctx;
+       hx509_cert cert = opt->opt_private->pk_init_ctx->id->cert;
+
+       opt->opt_private->pk_init_ctx->keyex = USE_DH;
+
+       /*
+        * If its a ECDSA certs, lets select ECDSA as the keyex algorithm.
+        */
+       if (cert) {
+           AlgorithmIdentifier alg;
+
+           ret = hx509_cert_get_SPKI_AlgorithmIdentifier(hx509ctx, cert, &alg);
+           if (ret == 0) {
+               if (der_heim_oid_cmp(&alg.algorithm, &asn1_oid_id_ecPublicKey) == 0)
+                   opt->opt_private->pk_init_ctx->keyex = USE_ECDH;
+               free_AlgorithmIdentifier(&alg);
+           }
        }
        }
+
+    } else {
+       opt->opt_private->pk_init_ctx->keyex = USE_RSA;
+
+       if (opt->opt_private->pk_init_ctx->id->certs == NULL) {
+           krb5_set_error_message(context, EINVAL,
+                                  N_("No anonymous pkinit support in RSA mode", ""));
+           return EINVAL;
+       }           
     }
 
     return 0;
     }
 
     return 0;
@@ -2152,3 +2357,122 @@ krb5_get_init_creds_opt_set_pkinit(krb5_context context,
     return EINVAL;
 #endif
 }
     return EINVAL;
 #endif
 }
+
+#ifdef PKINIT
+
+static int
+get_ms_san(hx509_context context, hx509_cert cert, char **upn)
+{
+    hx509_octet_string_list list;
+    int ret;
+
+    *upn = NULL;
+
+    ret = hx509_cert_find_subjectAltName_otherName(context,
+                                                  cert,
+                                                  &asn1_oid_id_pkinit_ms_san,
+                                                  &list);
+    if (ret)
+       return 0;
+
+    if (list.len > 0 && list.val[0].length > 0)
+       ret = decode_MS_UPN_SAN(list.val[0].data, list.val[0].length,
+                               upn, NULL);
+    else
+       ret = 1;
+    hx509_free_octet_string_list(&list);          
+
+    return ret;
+}
+
+static int
+find_ms_san(hx509_context context, hx509_cert cert, void *ctx)
+{
+    char *upn;
+    int ret;
+
+    ret = get_ms_san(context, cert, &upn);
+    if (ret == 0)
+       free(upn);
+    return ret;
+}
+
+
+
+#endif
+
+/*
+ * Private since it need to be redesigned using krb5_get_init_creds()
+ */
+
+krb5_error_code  KRB5_LIB_FUNCTION
+_krb5_pk_enterprise_cert(krb5_context context,
+                        const char *user_id,
+                        krb5_const_realm realm,
+                        krb5_principal *principal)
+{
+#ifdef PKINIT
+    krb5_error_code ret;
+    hx509_context hx509ctx;
+    hx509_certs certs, result;
+    hx509_cert cert;
+    hx509_query *q;
+    char *name;
+
+    *principal = NULL;
+    
+    if (user_id == NULL)
+       return ENOENT;
+
+    ret = hx509_context_init(&hx509ctx);
+    if (ret)
+       return ret;
+
+    ret = hx509_certs_init(hx509ctx, user_id, 0, NULL, &certs);
+    if (ret) {
+       pk_copy_error(context, hx509ctx, ret,
+                     "Failed to init cert certs");
+       return ret;
+    }
+
+    ret = hx509_query_alloc(hx509ctx, &q);
+    if (ret) {
+       hx509_certs_free(&certs);
+       return ret;
+    }
+
+    hx509_query_match_option(q, HX509_QUERY_OPTION_PRIVATE_KEY);
+    hx509_query_match_option(q, HX509_QUERY_OPTION_KU_DIGITALSIGNATURE);
+    hx509_query_match_eku(q, &asn1_oid_id_pkinit_ms_eku);
+    hx509_query_match_cmp_func(q, find_ms_san, NULL);
+
+    ret = hx509_certs_filter(hx509ctx, certs, q, &result);
+    hx509_query_free(hx509ctx, q);
+    hx509_certs_free(&certs);
+    if (ret)
+       return ret;
+    
+    ret = hx509_get_one_cert(hx509ctx, result, &cert);
+    hx509_certs_free(&result);
+    if (ret)
+       return ret;
+
+    ret = get_ms_san(hx509ctx, cert, &name);
+    if (ret)
+       return ret;
+
+    ret = krb5_make_principal(context, principal, realm, name, NULL);
+    free(name);
+    hx509_context_free(&hx509ctx);
+    if (ret)
+       return ret;
+
+    krb5_principal_set_type(context, *principal, KRB5_NT_ENTERPRISE_PRINCIPAL);
+    
+    return ret;
+#else
+    krb5_set_error_message(context, EINVAL,
+                          N_("no support for PKINIT compiled in", ""));
+    return EINVAL;
+#endif
+}
index a71dd8b6f7ba1c7716cedf1df12b1de3f39aff79..844cb7ab889a3df800d4d6caf8f0787464299a7c 100644 (file)
@@ -32,7 +32,7 @@
  */
 
 #include "krb5_locl.h"
  */
 
 #include "krb5_locl.h"
-RCSID("$Id$");
+
 #ifdef HAVE_DLFCN_H
 #include <dlfcn.h>
 #endif
 #ifdef HAVE_DLFCN_H
 #include <dlfcn.h>
 #endif
@@ -54,7 +54,13 @@ struct plugin {
 static HEIMDAL_MUTEX plugin_mutex = HEIMDAL_MUTEX_INITIALIZER;
 static struct plugin *registered = NULL;
 
 static HEIMDAL_MUTEX plugin_mutex = HEIMDAL_MUTEX_INITIALIZER;
 static struct plugin *registered = NULL;
 
-static const char *plugin_dir = LIBDIR "/plugin/krb5";
+static const char *sysplugin_dirs[] =  { 
+    LIBDIR "/plugin/krb5",
+#ifdef __APPLE__
+    "/System/Library/KerberosPlugins/KerberosFrameworkPlugins",
+#endif
+    NULL
+};
 
 /*
  *
 
 /*
  *
@@ -93,9 +99,12 @@ loadlib(krb5_context context,
 
 #ifndef RTLD_LAZY
 #define RTLD_LAZY 0
 
 #ifndef RTLD_LAZY
 #define RTLD_LAZY 0
+#endif
+#ifndef RTLD_LOCAL
+#define RTLD_LOCAL 0
 #endif
 
 #endif
 
-    (*e)->dsohandle = dlopen(lib, RTLD_LAZY);
+    (*e)->dsohandle = dlopen(lib, RTLD_LOCAL|RTLD_LAZY);
     if ((*e)->dsohandle == NULL) {
        free(*e);
        *e = NULL;
     if ((*e)->dsohandle == NULL) {
        free(*e);
        *e = NULL;
@@ -173,7 +182,6 @@ _krb5_plugin_find(krb5_context context,
     struct krb5_plugin *e;
     struct plugin *p;
     krb5_error_code ret;
     struct krb5_plugin *e;
     struct plugin *p;
     krb5_error_code ret;
-    char *sysdirs[2] = { NULL, NULL };
     char **dirs = NULL, **di;
     struct dirent *entry;
     char *path;
     char **dirs = NULL, **di;
     struct dirent *entry;
     char *path;
@@ -205,10 +213,8 @@ _krb5_plugin_find(krb5_context context,
 
     dirs = krb5_config_get_strings(context, NULL, "libdefaults",
                                   "plugin_dir", NULL);
 
     dirs = krb5_config_get_strings(context, NULL, "libdefaults",
                                   "plugin_dir", NULL);
-    if (dirs == NULL) {
-       sysdirs[0] = rk_UNCONST(plugin_dir);
-       dirs = sysdirs;
-    }
+    if (dirs == NULL)
+       dirs = rk_UNCONST(sysplugin_dirs);
 
     for (di = dirs; *di != NULL; di++) {
 
 
     for (di = dirs; *di != NULL; di++) {
 
@@ -218,7 +224,23 @@ _krb5_plugin_find(krb5_context context,
        rk_cloexec(dirfd(d));
 
        while ((entry = readdir(d)) != NULL) {
        rk_cloexec(dirfd(d));
 
        while ((entry = readdir(d)) != NULL) {
-           asprintf(&path, "%s/%s", *di, entry->d_name);
+           char *n = entry->d_name;
+
+           /* skip . and .. */
+           if (n[0] == '.' && (n[1] == '\0' || (n[1] == '.' && n[2] == '\0')))
+               continue;
+
+           path = NULL;
+#ifdef __APPLE__
+           { /* support loading bundles on MacOS */
+               size_t len = strlen(n);
+               if (len > 7 && strcmp(&n[len - 7],  ".bundle") == 0)
+                   asprintf(&path, "%s/%s/Contents/MacOS/%.*s", *di, n, (int)(len - 7), n);
+           }
+#endif
+           if (path == NULL)
+               asprintf(&path, "%s/%s", *di, n);
+
            if (path == NULL) {
                ret = ENOMEM;
                krb5_set_error_message(context, ret, "malloc: out of memory");
            if (path == NULL) {
                ret = ENOMEM;
                krb5_set_error_message(context, ret, "malloc: out of memory");
@@ -234,7 +256,7 @@ _krb5_plugin_find(krb5_context context,
        }
        closedir(d);
     }
        }
        closedir(d);
     }
-    if (dirs != sysdirs)
+    if (dirs != rk_UNCONST(sysplugin_dirs))
        krb5_config_free_strings(dirs);
 #endif /* HAVE_DLOPEN */
 
        krb5_config_free_strings(dirs);
 #endif /* HAVE_DLOPEN */
 
@@ -246,7 +268,7 @@ _krb5_plugin_find(krb5_context context,
     return 0;
 
 out:
     return 0;
 
 out:
-    if (dirs && dirs != sysdirs)
+    if (dirs != rk_UNCONST(sysplugin_dirs))
        krb5_config_free_strings(dirs);
     if (d)
        closedir(d);
        krb5_config_free_strings(dirs);
     if (d)
        closedir(d);
index f27355f2d8049428bfe0b5213ea2cccc57a36cea..50b7bb8813239e79aff77468a34fbf568ddbdbfb 100644 (file)
@@ -32,7 +32,7 @@
  */
 
 /**
  */
 
 /**
- * @page page_principal The principal handing functions.
+ * @page krb5_principal_intro The principal handing functions.
  *
  * A Kerberos principal is a email address looking string that
  * contains to parts separeted by a @.  The later part is the kerbero
  *
  * A Kerberos principal is a email address looking string that
  * contains to parts separeted by a @.  The later part is the kerbero
@@ -57,8 +57,6 @@ host/admin@H5L.ORG
 #include <fnmatch.h>
 #include "resolve.h"
 
 #include <fnmatch.h>
 #include "resolve.h"
 
-RCSID("$Id$");
-
 #define princ_num_comp(P) ((P)->name.name_string.len)
 #define princ_type(P) ((P)->name.name_type)
 #define princ_comp(P) ((P)->name.name_string.val)
 #define princ_num_comp(P) ((P)->name.name_string.len)
 #define princ_type(P) ((P)->name.name_type)
 #define princ_comp(P) ((P)->name.name_string.val)
@@ -78,8 +76,6 @@ RCSID("$Id$");
  * @ingroup krb5_principal
  */
 
  * @ingroup krb5_principal
  */
 
-
-
 void KRB5_LIB_FUNCTION
 krb5_free_principal(krb5_context context,
                    krb5_principal p)
 void KRB5_LIB_FUNCTION
 krb5_free_principal(krb5_context context,
                    krb5_principal p)
@@ -90,6 +86,18 @@ krb5_free_principal(krb5_context context,
     }
 }
 
     }
 }
 
+/**
+ * Set the type of the principal
+ *
+ * @param context A Kerberos context.
+ * @param principal principal to set the type for
+ * @param type the new type
+ *
+ * @return An krb5 error code, see krb5_get_error_message().
+ *
+ * @ingroup krb5_principal
+ */
+
 void KRB5_LIB_FUNCTION
 krb5_principal_set_type(krb5_context context,
                        krb5_principal principal,
 void KRB5_LIB_FUNCTION
 krb5_principal_set_type(krb5_context context,
                        krb5_principal principal,
@@ -127,8 +135,10 @@ krb5_principal_get_comp_string(krb5_context context,
  *
  * @param context Kerberos 5 context
  * @param principal principal to query
  *
  * @param context Kerberos 5 context
  * @param principal principal to query
+ *
  * @return number of components in string
  * @return number of components in string
- * @ingroup krb5
+ *
+ * @ingroup krb5_principal
  */
 
 unsigned int KRB5_LIB_FUNCTION
  */
 
 unsigned int KRB5_LIB_FUNCTION
@@ -162,7 +172,7 @@ krb5_parse_name_flags(krb5_context context,
 
     *principal = NULL;
 
 
     *principal = NULL;
 
-#define RFLAGS (KRB5_PRINCIPAL_PARSE_NO_REALM|KRB5_PRINCIPAL_PARSE_MUST_REALM)
+#define RFLAGS (KRB5_PRINCIPAL_PARSE_NO_REALM|KRB5_PRINCIPAL_PARSE_REQUIRE_REALM)
 
     if ((flags & RFLAGS) == RFLAGS) {
        krb5_set_error_message(context, KRB5_ERR_NO_SERVICE,
 
     if ((flags & RFLAGS) == RFLAGS) {
        krb5_set_error_message(context, KRB5_ERR_NO_SERVICE,
@@ -276,7 +286,7 @@ krb5_parse_name_flags(krb5_context context,
        memcpy(realm, start, q - start);
        realm[q - start] = 0;
     }else{
        memcpy(realm, start, q - start);
        realm[q - start] = 0;
     }else{
-       if (flags & KRB5_PRINCIPAL_PARSE_MUST_REALM) {
+       if (flags & KRB5_PRINCIPAL_PARSE_REQUIRE_REALM) {
            ret = KRB5_PARSE_MALFORMED;
            krb5_set_error_message(context, ret,
                                   N_("realm NOT found in principal "
            ret = KRB5_PARSE_MALFORMED;
            krb5_set_error_message(context, ret,
                                   N_("realm NOT found in principal "
@@ -524,22 +534,6 @@ krb5_unparse_name_ext(krb5_context context,
 
 #endif
 
 
 #endif
 
-krb5_realm * KRB5_LIB_FUNCTION
-krb5_princ_realm(krb5_context context,
-                krb5_principal principal)
-{
-    return &princ_realm(principal);
-}
-
-
-void KRB5_LIB_FUNCTION
-krb5_princ_set_realm(krb5_context context,
-                    krb5_principal principal,
-                    krb5_realm *realm)
-{
-    princ_realm(principal) = *realm;
-}
-
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_principal_set_realm(krb5_context context,
                         krb5_principal principal,
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_principal_set_realm(krb5_context context,
                         krb5_principal principal,
@@ -821,6 +815,7 @@ krb5_principal_match(krb5_context context,
     return TRUE;
 }
 
     return TRUE;
 }
 
+#if defined(KRB4) || !defined(HEIMDAL_SMALLER)
 
 static struct v4_name_convert {
     const char *from;
 
 static struct v4_name_convert {
     const char *from;
@@ -835,6 +830,10 @@ static struct v4_name_convert {
     { NULL, NULL }
 };
 
     { NULL, NULL }
 };
 
+#endif
+
+#ifdef KRB4
+
 /*
  * return the converted instance name of `name' in `realm'.
  * look in the configuration file and then in the default set above.
 /*
  * return the converted instance name of `name' in `realm'.
  * look in the configuration file and then in the default set above.
@@ -925,6 +924,8 @@ krb5_425_conv_principal_ext2(krb5_context context,
     if(p){
        instance = p;
        ret = krb5_make_principal(context, &pr, realm, name, instance, NULL);
     if(p){
        instance = p;
        ret = krb5_make_principal(context, &pr, realm, name, instance, NULL);
+       if (ret)
+           return ret;
        if(func == NULL || (*func)(context, funcctx, pr)){
            *princ = pr;
            return 0;
        if(func == NULL || (*func)(context, funcctx, pr)){
            *princ = pr;
            return 0;
@@ -938,23 +939,23 @@ krb5_425_conv_principal_ext2(krb5_context context,
        krb5_boolean passed = FALSE;
        char *inst = NULL;
 #ifdef USE_RESOLVER
        krb5_boolean passed = FALSE;
        char *inst = NULL;
 #ifdef USE_RESOLVER
-       struct dns_reply *r;
+       struct rk_dns_reply *r;
 
 
-       r = dns_lookup(instance, "aaaa");
+       r = rk_dns_lookup(instance, "aaaa");
        if (r) {
        if (r) {
-           if (r->head && r->head->type == T_AAAA) {
+           if (r->head && r->head->type == rk_ns_t_aaaa) {
                inst = strdup(r->head->domain);
                passed = TRUE;
            }
                inst = strdup(r->head->domain);
                passed = TRUE;
            }
-           dns_free_data(r);
+           rk_dns_free_data(r);
        } else {
        } else {
-           r = dns_lookup(instance, "a");
+           r = rk_dns_lookup(instance, "a");
            if (r) {
            if (r) {
-               if(r->head && r->head->type == T_A) {
+               if(r->head && r->head->type == rk_ns_t_a) {
                    inst = strdup(r->head->domain);
                    passed = TRUE;
                }
                    inst = strdup(r->head->domain);
                    passed = TRUE;
                }
-               dns_free_data(r);
+               rk_dns_free_data(r);
            }
        }
 #else
            }
        }
 #else
@@ -998,6 +999,8 @@ krb5_425_conv_principal_ext2(krb5_context context,
        snprintf(host, sizeof(host), "%s.%s", instance, realm);
        strlwr(host);
        ret = krb5_make_principal(context, &pr, realm, name, host, NULL);
        snprintf(host, sizeof(host), "%s.%s", instance, realm);
        strlwr(host);
        ret = krb5_make_principal(context, &pr, realm, name, host, NULL);
+       if (ret)
+           return ret;
        if((*func)(context, funcctx, pr)){
            *princ = pr;
            return 0;
        if((*func)(context, funcctx, pr)){
            *princ = pr;
            return 0;
@@ -1025,6 +1028,10 @@ krb5_425_conv_principal_ext2(krb5_context context,
        for(d = domains; d && *d; d++){
            snprintf(host, sizeof(host), "%s.%s", instance, *d);
            ret = krb5_make_principal(context, &pr, realm, name, host, NULL);
        for(d = domains; d && *d; d++){
            snprintf(host, sizeof(host), "%s.%s", instance, *d);
            ret = krb5_make_principal(context, &pr, realm, name, host, NULL);
+           if (ret) {
+               krb5_config_free_strings(domains);
+               return ret;
+           }
            if(func == NULL || (*func)(context, funcctx, pr)){
                *princ = pr;
                krb5_config_free_strings(domains);
            if(func == NULL || (*func)(context, funcctx, pr)){
                *princ = pr;
                krb5_config_free_strings(domains);
@@ -1049,6 +1056,8 @@ krb5_425_conv_principal_ext2(krb5_context context,
     snprintf(host, sizeof(host), "%s.%s", instance, p);
 local_host:
     ret = krb5_make_principal(context, &pr, realm, name, host, NULL);
     snprintf(host, sizeof(host), "%s.%s", instance, p);
 local_host:
     ret = krb5_make_principal(context, &pr, realm, name, host, NULL);
+    if (ret)
+       return ret;
     if(func == NULL || (*func)(context, funcctx, pr)){
        *princ = pr;
        return 0;
     if(func == NULL || (*func)(context, funcctx, pr)){
        *princ = pr;
        return 0;
@@ -1075,6 +1084,8 @@ no_host:
        name = p;
 
     ret = krb5_make_principal(context, &pr, realm, name, instance, NULL);
        name = p;
 
     ret = krb5_make_principal(context, &pr, realm, name, instance, NULL);
+    if (ret)
+       return ret;
     if(func == NULL || (*func)(context, funcctx, pr)){
        *princ = pr;
        return 0;
     if(func == NULL || (*func)(context, funcctx, pr)){
        *princ = pr;
        return 0;
@@ -1084,51 +1095,9 @@ no_host:
     return HEIM_ERR_V4_PRINC_NO_CONV;
 }
 
     return HEIM_ERR_V4_PRINC_NO_CONV;
 }
 
-static krb5_boolean
-convert_func(krb5_context conxtext, void *funcctx, krb5_principal principal)
-{
-    krb5_boolean (*func)(krb5_context, krb5_principal) = funcctx;
-    return (*func)(conxtext, principal);
-}
-
-krb5_error_code KRB5_LIB_FUNCTION
-krb5_425_conv_principal_ext(krb5_context context,
-                           const char *name,
-                           const char *instance,
-                           const char *realm,
-                           krb5_boolean (*func)(krb5_context, krb5_principal),
-                           krb5_boolean resolve,
-                           krb5_principal *principal)
-{
-    return krb5_425_conv_principal_ext2(context,
-                                       name,
-                                       instance,
-                                       realm,
-                                       func ? convert_func : NULL,
-                                       func,
-                                       resolve,
-                                       principal);
-}
-
-
-
-krb5_error_code KRB5_LIB_FUNCTION
-krb5_425_conv_principal(krb5_context context,
-                       const char *name,
-                       const char *instance,
-                       const char *realm,
-                       krb5_principal *princ)
-{
-    krb5_boolean resolve = krb5_config_get_bool(context,
-                                               NULL,
-                                               "libdefaults",
-                                               "v4_instance_resolve",
-                                               NULL);
-
-    return krb5_425_conv_principal_ext(context, name, instance, realm,
-                                      NULL, resolve, princ);
-}
+#endif /* KRB4 */
 
 
+#ifndef HEIMDAL_SMALLER
 
 static int
 check_list(const krb5_config_binding *l, const char *name, const char **out)
 
 static int
 check_list(const krb5_config_binding *l, const char *name, const char **out)
@@ -1186,6 +1155,7 @@ name_convert(krb5_context context, const char *name, const char *realm,
        return KRB5_NT_UNKNOWN;
 
     /* didn't find it in config file, try built-in list */
        return KRB5_NT_UNKNOWN;
 
     /* didn't find it in config file, try built-in list */
+#ifdef KRB4
     {
        struct v4_name_convert *q;
        for(q = default_v4_name_convert; q->from; q++) {
     {
        struct v4_name_convert *q;
        for(q = default_v4_name_convert; q->from; q++) {
@@ -1195,6 +1165,7 @@ name_convert(krb5_context context, const char *name, const char *realm,
            }
        }
     }
            }
        }
     }
+#endif
     return -1;
 }
 
     return -1;
 }
 
@@ -1273,6 +1244,8 @@ krb5_524_conv_principal(krb5_context context,
     return 0;
 }
 
     return 0;
 }
 
+#endif /* !HEIMDAL_SMALLER */
+
 /**
  * Create a principal for the service running on hostname. If
  * KRB5_NT_SRV_HST is used, the hostname is canonization using DNS (or
 /**
  * Create a principal for the service running on hostname. If
  * KRB5_NT_SRV_HST is used, the hostname is canonization using DNS (or
index b368573b8d93dc8be971abddcf723760bb0d2c3d..4c060973d69de092c5be030b81e27593efc33cf1 100644 (file)
@@ -35,8 +35,6 @@
 #include <getarg.h>
 #include <err.h>
 
 #include <getarg.h>
 #include <err.h>
 
-RCSID("$Id$");
-
 void KRB5_LIB_FUNCTION
 krb5_std_usage(int code, struct getargs *args, int num_args)
 {
 void KRB5_LIB_FUNCTION
 krb5_std_usage(int code, struct getargs *args, int num_args)
 {
index 7d639354236e96db52c6e77094eaa06699626d6a..05deaff525f92606492c805ee5aa062b1f25fa6d 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "krb5_locl.h"
 
 
 #include "krb5_locl.h"
 
-RCSID("$Id$");
-
 int KRB5_LIB_FUNCTION
 krb5_prompter_posix (krb5_context context,
                     void *data,
 int KRB5_LIB_FUNCTION
 krb5_prompter_posix (krb5_context context,
                     void *data,
index dc510330190bcbc4506fc35de3b4e446b64ac969..f41edfa2b51dad58f60128878540443291a84807 100644 (file)
@@ -33,8 +33,6 @@
 
 #include <krb5_locl.h>
 
 
 #include <krb5_locl.h>
 
-RCSID("$Id$");
-
 static krb5_error_code
 compare_addrs(krb5_context context,
              krb5_address *a,
 static krb5_error_code
 compare_addrs(krb5_context context,
              krb5_address *a,
@@ -149,15 +147,18 @@ krb5_rd_cred(krb5_context context,
            goto out;
     }
 
            goto out;
     }
 
-    ret = krb5_decode_EncKrbCredPart (context,
-                                     enc_krb_cred_part_data.data,
-                                     enc_krb_cred_part_data.length,
-                                     &enc_krb_cred_part,
-                                     &len);
+    ret = decode_EncKrbCredPart(enc_krb_cred_part_data.data,
+                               enc_krb_cred_part_data.length,
+                               &enc_krb_cred_part,
+                               &len);
     if (enc_krb_cred_part_data.data != cred.enc_part.cipher.data)
        krb5_data_free(&enc_krb_cred_part_data);
     if (enc_krb_cred_part_data.data != cred.enc_part.cipher.data)
        krb5_data_free(&enc_krb_cred_part_data);
-    if (ret)
+    if (ret) {
+       krb5_set_error_message(context, ret,
+                              N_("Failed to decode "
+                                 "encrypte credential part", ""));
        goto out;
        goto out;
+    }
 
     /* check sender address */
 
 
     /* check sender address */
 
index 75ae8b1e8addd50a92b4e26e5e5c3e758407f567..1561188fade3e96e997246a64678e909d9c6e895 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "krb5_locl.h"
 
 
 #include "krb5_locl.h"
 
-RCSID("$Id$");
-
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_rd_error(krb5_context context,
              const krb5_data *msg,
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_rd_error(krb5_context context,
              const krb5_data *msg,
index 6778ccad88fc5bc5b72898dfd88ba5cb79ab0f7c..fb6cfcee4f7e44e74fd4a27cfde245b9bbb7d5bb 100644 (file)
@@ -33,8 +33,6 @@
 
 #include <krb5_locl.h>
 
 
 #include <krb5_locl.h>
 
-RCSID("$Id$");
-
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_rd_priv(krb5_context context,
             krb5_auth_context auth_context,
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_rd_priv(krb5_context context,
             krb5_auth_context auth_context,
index 010726b180961ee236b998952f9c046e0771a324..2d5792cd404ff34205fea470c467b51f4779a558 100644 (file)
@@ -33,8 +33,6 @@
 
 #include <krb5_locl.h>
 
 
 #include <krb5_locl.h>
 
-RCSID("$Id$");
-
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_rd_rep(krb5_context context,
            krb5_auth_context auth_context,
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_rd_rep(krb5_context context,
            krb5_auth_context auth_context,
@@ -48,7 +46,6 @@ krb5_rd_rep(krb5_context context,
     krb5_crypto crypto;
 
     krb5_data_zero (&data);
     krb5_crypto crypto;
 
     krb5_data_zero (&data);
-    ret = 0;
 
     ret = decode_AP_REP(inbuf->data, inbuf->length, &ap_rep, &len);
     if (ret)
 
     ret = decode_AP_REP(inbuf->data, inbuf->length, &ap_rep, &len);
     if (ret)
@@ -82,13 +79,11 @@ krb5_rd_rep(krb5_context context,
        krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
        goto out;
     }
        krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
        goto out;
     }
-    ret = krb5_decode_EncAPRepPart(context,
-                                  data.data,
-                                  data.length,
-                                  *repl,
-                                  &len);
-    if (ret)
+    ret = decode_EncAPRepPart(data.data, data.length, *repl, &len);
+    if (ret) {
+       krb5_set_error_message(context, ret, N_("Failed to decode EncAPRepPart", ""));
        return ret;
        return ret;
+    }
 
     if (auth_context->flags & KRB5_AUTH_CONTEXT_DO_TIME) {
        if ((*repl)->ctime != auth_context->authenticator->ctime ||
 
     if (auth_context->flags & KRB5_AUTH_CONTEXT_DO_TIME) {
        if ((*repl)->ctime != auth_context->authenticator->ctime ||
index a416f90c10f48336716b4cbeeaa58c874084c71e..784427fe40310ced6a97cfa48bfff93797c115f0 100644 (file)
@@ -33,8 +33,6 @@
 
 #include <krb5_locl.h>
 
 
 #include <krb5_locl.h>
 
-RCSID("$Id$");
-
 static krb5_error_code
 decrypt_tkt_enc_part (krb5_context context,
                      krb5_keyblock *key,
 static krb5_error_code
 decrypt_tkt_enc_part (krb5_context context,
                      krb5_keyblock *key,
@@ -58,8 +56,11 @@ decrypt_tkt_enc_part (krb5_context context,
     if (ret)
        return ret;
 
     if (ret)
        return ret;
 
-    ret = krb5_decode_EncTicketPart(context, plain.data, plain.length,
-                                   decr_part, &len);
+    ret = decode_EncTicketPart(plain.data, plain.length, decr_part, &len);
+    if (ret)
+        krb5_set_error_message(context, ret, 
+                              N_("Failed to decode encrypted "
+                                 "ticket part", ""));
     krb5_data_free (&plain);
     return ret;
 }
     krb5_data_free (&plain);
     return ret;
 }
@@ -95,8 +96,8 @@ decrypt_authenticator (krb5_context context,
     if (ret)
        return ret;
 
     if (ret)
        return ret;
 
-    ret = krb5_decode_Authenticator(context, plain.data, plain.length,
-                                   authenticator, &len);
+    ret = decode_Authenticator(plain.data, plain.length,
+                              authenticator, &len);
     krb5_data_free (&plain);
     return ret;
 }
     krb5_data_free (&plain);
     return ret;
 }
@@ -521,10 +522,20 @@ struct krb5_rd_req_out_ctx_data {
     krb5_keyblock *keyblock;
     krb5_flags ap_req_options;
     krb5_ticket *ticket;
     krb5_keyblock *keyblock;
     krb5_flags ap_req_options;
     krb5_ticket *ticket;
+    krb5_principal server;
 };
 
 };
 
-/*
+/**
+ * Allocate a krb5_rd_req_in_ctx as an input parameter to
+ * krb5_rd_req_ctx(). The caller should free the context with
+ * krb5_rd_req_in_ctx_free() when done with the context.
+ *
+ * @param context Keberos 5 context.
+ * @param ctx in ctx to krb5_rd_req_ctx().
+ *
+ * @return Kerberos 5 error code, see krb5_get_error_message().
  *
  *
+ * @ingroup krb5_auth
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
@@ -540,12 +551,26 @@ krb5_rd_req_in_ctx_alloc(krb5_context context, krb5_rd_req_in_ctx *ctx)
     return 0;
 }
 
     return 0;
 }
 
+/**
+ * Set the keytab that krb5_rd_req_ctx() will use.
+ *
+ * @param context Keberos 5 context.
+ * @param in in ctx to krb5_rd_req_ctx().
+ * @param keytab keytab that krb5_rd_req_ctx() will use, only copy the
+ *        pointer, so the caller must free they keytab after
+ *        krb5_rd_req_in_ctx_free() is called.
+ *
+ * @return Kerberos 5 error code, see krb5_get_error_message().
+ *
+ * @ingroup krb5_auth
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_rd_req_in_set_keytab(krb5_context context,
                          krb5_rd_req_in_ctx in,
                          krb5_keytab keytab)
 {
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_rd_req_in_set_keytab(krb5_context context,
                          krb5_rd_req_in_ctx in,
                          krb5_keytab keytab)
 {
-    in->keytab = keytab; /* XXX should make copy */
+    in->keytab = keytab;
     return 0;
 }
 
     return 0;
 }
 
@@ -558,7 +583,7 @@ krb5_rd_req_in_set_keytab(krb5_context context,
  *
  * @return Kerberos 5 error code, see krb5_get_error_message().
  *
  *
  * @return Kerberos 5 error code, see krb5_get_error_message().
  *
- * @ingroup krb5
+ * @ingroup krb5_auth
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
@@ -605,28 +630,50 @@ krb5_rd_req_out_get_keyblock(krb5_context context,
     return krb5_copy_keyblock(context, out->keyblock, keyblock);
 }
 
     return krb5_copy_keyblock(context, out->keyblock, keyblock);
 }
 
+/**
+ * Get the principal that was used in the request from the
+ * client. Might not match whats in the ticket if krb5_rd_req_ctx()
+ * searched in the keytab for a matching key.
+ *
+ * @param context a Kerberos 5 context.
+ * @param out a krb5_rd_req_out_ctx from krb5_rd_req_ctx().
+ * @param principal return principal, free with krb5_free_principal().
+ *
+ * @ingroup krb5_auth
+ */
+
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_rd_req_out_get_server(krb5_context context,
+                           krb5_rd_req_out_ctx out,
+                           krb5_principal *principal)
+{
+    return krb5_copy_principal(context, out->server, principal);
+}
+
 void  KRB5_LIB_FUNCTION
 krb5_rd_req_in_ctx_free(krb5_context context, krb5_rd_req_in_ctx ctx)
 {
     free(ctx);
 }
 
 void  KRB5_LIB_FUNCTION
 krb5_rd_req_in_ctx_free(krb5_context context, krb5_rd_req_in_ctx ctx)
 {
     free(ctx);
 }
 
-krb5_error_code KRB5_LIB_FUNCTION
-_krb5_rd_req_out_ctx_alloc(krb5_context context, krb5_rd_req_out_ctx *ctx)
-{
-    *ctx = calloc(1, sizeof(**ctx));
-    if (*ctx == NULL) {
-       krb5_set_error_message(context, ENOMEM,
-                              N_("malloc: out of memory", ""));
-       return ENOMEM;
-    }
-    return 0;
-}
+/**
+ * Free the krb5_rd_req_out_ctx.
+ *
+ * @param context Keberos 5 context.
+ * @param ctx krb5_rd_req_out_ctx context to free.
+ *
+ * @ingroup krb5_auth
+ */
 
 void  KRB5_LIB_FUNCTION
 krb5_rd_req_out_ctx_free(krb5_context context, krb5_rd_req_out_ctx ctx)
 {
 
 void  KRB5_LIB_FUNCTION
 krb5_rd_req_out_ctx_free(krb5_context context, krb5_rd_req_out_ctx ctx)
 {
-    krb5_free_keyblock(context, ctx->keyblock);
+    if (ctx->ticket)
+       krb5_free_ticket(context, ctx->ticket);
+    if (ctx->keyblock)
+       krb5_free_keyblock(context, ctx->keyblock);
+    if (ctx->server)
+       krb5_free_principal(context, ctx->server);
     free(ctx);
 }
 
     free(ctx);
 }
 
@@ -726,7 +773,6 @@ out:
 
 static krb5_error_code
 get_key_from_keytab(krb5_context context,
 
 static krb5_error_code
 get_key_from_keytab(krb5_context context,
-                   krb5_auth_context *auth_context,
                    krb5_ap_req *ap_req,
                    krb5_const_principal server,
                    krb5_keytab keytab,
                    krb5_ap_req *ap_req,
                    krb5_const_principal server,
                    krb5_keytab keytab,
@@ -764,8 +810,28 @@ out:
     return ret;
 }
 
     return ret;
 }
 
-/*
+/**
+ * The core server function that verify application authentication
+ * requests from clients.
+ *
+ * @param context Keberos 5 context.
+ * @param auth_context the authentication context, can be NULL, then
+ *        default values for the authentication context will used.
+ * @param inbuf the (AP-REQ) authentication buffer
+ *
+ * @param server the server with authenticate as, if NULL the function
+ *        will try to find any avaiable credentintial in the keytab
+ *        that will verify the reply. The function will prefer the
+ *        server the server client specified in the AP-REQ, but if
+ *        there is no mach, it will try all keytab entries for a
+ *        match. This have serious performance issues for larger keytabs.
  *
  *
+ * @param inctx control the behavior of the function, if NULL, the
+ *        default behavior is used.
+ * @param outctx the return outctx, free with krb5_rd_req_out_ctx_free().
+ * @return Kerberos 5 error code, see krb5_get_error_message().
+ *
+ * @ingroup krb5_auth
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
@@ -778,12 +844,18 @@ krb5_rd_req_ctx(krb5_context context,
 {
     krb5_error_code ret;
     krb5_ap_req ap_req;
 {
     krb5_error_code ret;
     krb5_ap_req ap_req;
-    krb5_principal service = NULL;
     krb5_rd_req_out_ctx o = NULL;
     krb5_rd_req_out_ctx o = NULL;
+    krb5_keytab id = NULL, keytab = NULL;
+    krb5_principal service = NULL;
 
 
-    ret = _krb5_rd_req_out_ctx_alloc(context, &o);
-    if (ret)
-       goto out;
+    *outctx = NULL;
+
+    o = calloc(1, sizeof(*o));
+    if (o == NULL) {
+       krb5_set_error_message(context, ENOMEM,
+                              N_("malloc: out of memory", ""));
+       return ENOMEM;
+    }
 
     if (*auth_context == NULL) {
        ret = krb5_auth_con_init(context, auth_context);
 
     if (*auth_context == NULL) {
        ret = krb5_auth_con_init(context, auth_context);
@@ -795,15 +867,14 @@ krb5_rd_req_ctx(krb5_context context,
     if(ret)
        goto out;
 
     if(ret)
        goto out;
 
-    if(server == NULL){
-       ret = _krb5_principalname2krb5_principal(context,
-                                                &service,
-                                                ap_req.ticket.sname,
-                                                ap_req.ticket.realm);
-       if (ret)
-           goto out;
-       server = service;
-    }
+    /* Save that principal that was in the request */
+    ret = _krb5_principalname2krb5_principal(context,
+                                            &o->server,
+                                            ap_req.ticket.sname,
+                                            ap_req.ticket.realm);
+    if (ret)
+       goto out;
+
     if (ap_req.ap_options.use_session_key &&
        (*auth_context)->keyblock == NULL) {
        ret = KRB5KRB_AP_ERR_NOKEY;
     if (ap_req.ap_options.use_session_key &&
        (*auth_context)->keyblock == NULL) {
        ret = KRB5KRB_AP_ERR_NOKEY;
@@ -813,49 +884,155 @@ krb5_rd_req_ctx(krb5_context context,
        goto out;
     }
 
        goto out;
     }
 
+    if (inctx && inctx->keytab)
+       id = inctx->keytab;
+
     if((*auth_context)->keyblock){
        ret = krb5_copy_keyblock(context,
                                 (*auth_context)->keyblock,
                                 &o->keyblock);
        if (ret)
            goto out;
     if((*auth_context)->keyblock){
        ret = krb5_copy_keyblock(context,
                                 (*auth_context)->keyblock,
                                 &o->keyblock);
        if (ret)
            goto out;
-    } else if(inctx->keyblock){
+    } else if(inctx && inctx->keyblock){
        ret = krb5_copy_keyblock(context,
                                 inctx->keyblock,
                                 &o->keyblock);
        if (ret)
            goto out;
     } else {
        ret = krb5_copy_keyblock(context,
                                 inctx->keyblock,
                                 &o->keyblock);
        if (ret)
            goto out;
     } else {
-       krb5_keytab keytab = NULL;
 
 
-       if (inctx && inctx->keytab)
-           keytab = inctx->keytab;
+       if(id == NULL) {
+           krb5_kt_default(context, &keytab);
+           id = keytab;
+       }
+       if (id == NULL)
+           goto out;
+
+       if (server == NULL) {
+           ret = _krb5_principalname2krb5_principal(context,
+                                                    &service,
+                                                    ap_req.ticket.sname,
+                                                    ap_req.ticket.realm);
+           if (ret)
+               goto out;
+           server = service;
+       }
 
        ret = get_key_from_keytab(context,
 
        ret = get_key_from_keytab(context,
-                                 auth_context,
                                  &ap_req,
                                  server,
                                  &ap_req,
                                  server,
-                                 keytab,
+                                 id,
                                  &o->keyblock);
                                  &o->keyblock);
-       if(ret)
-           goto out;
+       if (ret) {
+           /* If caller specified a server, fail. */
+           if (service == NULL)
+               goto out;
+           /* Otherwise, fall back to iterating over the keytab. This
+            * have serious performace issues for larger keytab.
+            */
+           o->keyblock = NULL;
+       }
     }
 
     }
 
-    ret = krb5_verify_ap_req2(context,
-                             auth_context,
-                             &ap_req,
-                             server,
-                             o->keyblock,
-                             0,
-                             &o->ap_req_options,
-                             &o->ticket,
-                             KRB5_KU_AP_REQ_AUTH);
+    if (o->keyblock) {
+       /*
+        * We got an exact keymatch, use that.
+        */
 
 
-    if (ret)
-       goto out;
+       ret = krb5_verify_ap_req2(context,
+                                 auth_context,
+                                 &ap_req,
+                                 server,
+                                 o->keyblock,
+                                 0,
+                                 &o->ap_req_options,
+                                 &o->ticket,
+                                 KRB5_KU_AP_REQ_AUTH);
+       
+       if (ret)
+           goto out;
+
+    } else {
+       /*
+        * Interate over keytab to find a key that can decrypt the request.
+        */
+
+       krb5_keytab_entry entry;
+       krb5_kt_cursor cursor;
+       int done = 0, kvno = 0;
+
+       memset(&cursor, 0, sizeof(cursor));
+
+       if (ap_req.ticket.enc_part.kvno)
+           kvno = *ap_req.ticket.enc_part.kvno;
+
+       ret = krb5_kt_start_seq_get(context, id, &cursor);
+       if (ret)
+           goto out;
+
+       done = 0;
+       while (!done) { 
+           krb5_principal p;
+
+           ret = krb5_kt_next_entry(context, id, &entry, &cursor);
+           if (ret) {
+               _krb5_kt_principal_not_found(context, ret, id, o->server,
+                                            ap_req.ticket.enc_part.etype,
+                                            kvno);
+               goto out;
+           }
+
+           if (entry.keyblock.keytype != ap_req.ticket.enc_part.etype ||
+               (kvno && kvno != entry.vno)) {
+               krb5_kt_free_entry (context, &entry);
+               continue;
+           }
+
+           ret = krb5_verify_ap_req2(context,
+                                     auth_context,
+                                     &ap_req,
+                                     server,
+                                     &entry.keyblock,
+                                     0,
+                                     &o->ap_req_options,
+                                     &o->ticket,
+                                     KRB5_KU_AP_REQ_AUTH);
+           if (ret) {
+               krb5_kt_free_entry (context, &entry);
+               continue;
+           }
+
+           /*
+            * Found a match, save the keyblock for PAC processing,
+            * and update the service principal in the ticket to match
+            * whatever is in the keytab.
+            */
+           
+           ret = krb5_copy_keyblock(context, 
+                                    &entry.keyblock,
+                                    &o->keyblock);
+           if (ret) {
+               krb5_kt_free_entry (context, &entry);
+               goto out;
+           }       
+
+           ret = krb5_copy_principal(context, entry.principal, &p);
+           if (ret) {
+               krb5_kt_free_entry (context, &entry);
+               goto out;
+           }
+           krb5_free_principal(context, o->ticket->server);
+           o->ticket->server = p;
+           
+           krb5_kt_free_entry (context, &entry);
+
+           done = 1;
+       }
+       krb5_kt_end_seq_get (context, id, &cursor);
+    }
 
     /* If there is a PAC, verify its server signature */
 
     /* If there is a PAC, verify its server signature */
-    if (inctx->check_pac) {
+    if (inctx == NULL || inctx->check_pac) {
        krb5_pac pac;
        krb5_data data;
 
        krb5_pac pac;
        krb5_data data;
 
@@ -878,17 +1055,23 @@ krb5_rd_req_ctx(krb5_context context,
            krb5_pac_free(context, pac);
            if (ret)
                goto out;
            krb5_pac_free(context, pac);
            if (ret)
                goto out;
-       }
-       ret = 0;
+       } else
+         ret = 0;
     }
 out:
     }
 out:
+
     if (ret || outctx == NULL) {
        krb5_rd_req_out_ctx_free(context, o);
     } else
        *outctx = o;
 
     free_AP_REQ(&ap_req);
     if (ret || outctx == NULL) {
        krb5_rd_req_out_ctx_free(context, o);
     } else
        *outctx = o;
 
     free_AP_REQ(&ap_req);
-    if(service)
+
+    if (service)
        krb5_free_principal(context, service);
        krb5_free_principal(context, service);
+
+    if (keytab)
+       krb5_kt_close(context, keytab);
+
     return ret;
 }
     return ret;
 }
index 25a6da026282ba425da06e50ddd0e848413aa987..37556cfbc57a1c3612c7e6be7df333234415414f 100644 (file)
@@ -34,8 +34,6 @@
 #include "krb5_locl.h"
 #include <vis.h>
 
 #include "krb5_locl.h"
 #include <vis.h>
 
-RCSID("$Id$");
-
 struct krb5_rcache_data {
     char *name;
 };
 struct krb5_rcache_data {
     char *name;
 };
index 53c4a69a3f71f0f2f0d55592a503d59c4d77b38e..50b42f2f1095e0ed0c02db8d50d9480cf9f6c18a 100644 (file)
@@ -34,8 +34,6 @@
 #include "krb5_locl.h"
 #include "send_to_kdc_plugin.h"
 
 #include "krb5_locl.h"
 #include "send_to_kdc_plugin.h"
 
-RCSID("$Id$");
-
 struct send_to_kdc {
     krb5_send_to_kdc_func func;
     void *data;
 struct send_to_kdc {
     krb5_send_to_kdc_func func;
     void *data;
@@ -384,8 +382,8 @@ krb5_sendto (krb5_context context,
             if (context->send_to_kdc) {
                 struct send_to_kdc *s = context->send_to_kdc;
 
             if (context->send_to_kdc) {
                 struct send_to_kdc *s = context->send_to_kdc;
 
-                ret = (*s->func)(context, s->data,
-                                 hi, context->kdc_timeout, send_data, receive);
+                ret = (*s->func)(context, s->data, hi,
+                                 context->kdc_timeout, send_data, receive);
                 if (ret == 0 && receive->length != 0)
                     goto out;
                 continue;
                 if (ret == 0 && receive->length != 0)
                     goto out;
                 continue;
index 6907b11d104f932e00fe492e1aa28a674ed7977e..91201eeb53792eee938132c72e39d5e2a334cddc 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "krb5_locl.h"
 
 
 #include "krb5_locl.h"
 
-RCSID("$Id$");
-
 /*
  * Convert the simple string `s' into a NULL-terminated and freshly allocated
  * list in `list'.  Return an error code.
 /*
  * Convert the simple string `s' into a NULL-terminated and freshly allocated
  * list in `list'.  Return an error code.
index 8489f984535a940656c80a99672f4b265d322a00..0b7accb860fff9f0abb46326c938e156eece2ff9 100644 (file)
@@ -39,6 +39,7 @@ struct krb5_storage_data {
     ssize_t (*fetch)(struct krb5_storage_data*, void*, size_t);
     ssize_t (*store)(struct krb5_storage_data*, const void*, size_t);
     off_t (*seek)(struct krb5_storage_data*, off_t, int);
     ssize_t (*fetch)(struct krb5_storage_data*, void*, size_t);
     ssize_t (*store)(struct krb5_storage_data*, const void*, size_t);
     off_t (*seek)(struct krb5_storage_data*, off_t, int);
+    int (*trunc)(struct krb5_storage_data*, off_t);
     void (*free)(struct krb5_storage_data*);
     krb5_flags flags;
     int eof_code;
     void (*free)(struct krb5_storage_data*);
     krb5_flags flags;
     int eof_code;
index 47f9abe1de3aeca5dbe86ac990c2012b793ec386..2ba83ef0d511d95aeac63838831e1029af8c10b2 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 1997-2006 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997-2008 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden).
  * All rights reserved.
  *
  * (Royal Institute of Technology, Stockholm, Sweden).
  * All rights reserved.
  *
@@ -34,8 +34,6 @@
 #include "krb5_locl.h"
 #include "store-int.h"
 
 #include "krb5_locl.h"
 #include "store-int.h"
 
-RCSID("$Id$");
-
 #define BYTEORDER_IS(SP, V) (((SP)->flags & KRB5_STORAGE_BYTEORDER_MASK) == (V))
 #define BYTEORDER_IS_LE(SP) BYTEORDER_IS((SP), KRB5_STORAGE_BYTEORDER_LE)
 #define BYTEORDER_IS_BE(SP) BYTEORDER_IS((SP), KRB5_STORAGE_BYTEORDER_BE)
 #define BYTEORDER_IS(SP, V) (((SP)->flags & KRB5_STORAGE_BYTEORDER_MASK) == (V))
 #define BYTEORDER_IS_LE(SP) BYTEORDER_IS((SP), KRB5_STORAGE_BYTEORDER_LE)
 #define BYTEORDER_IS_BE(SP) BYTEORDER_IS((SP), KRB5_STORAGE_BYTEORDER_BE)
@@ -54,12 +52,36 @@ krb5_storage_clear_flags(krb5_storage *sp, krb5_flags flags)
     sp->flags &= ~flags;
 }
 
     sp->flags &= ~flags;
 }
 
+/**
+ * Return true or false depending on if the storage flags is set or
+ * not. NB testing for the flag 0 always return true.
+ *
+ * @param sp the storage buffer to check flags on
+ * @param flags The flags to test for
+ *
+ * @return true if all the flags are set, false if not.
+ *
+ * @ingroup krb5_storage
+ */
+
 krb5_boolean KRB5_LIB_FUNCTION
 krb5_storage_is_flags(krb5_storage *sp, krb5_flags flags)
 {
     return (sp->flags & flags) == flags;
 }
 
 krb5_boolean KRB5_LIB_FUNCTION
 krb5_storage_is_flags(krb5_storage *sp, krb5_flags flags)
 {
     return (sp->flags & flags) == flags;
 }
 
+/**
+ * Set the new byte order of the storage buffer.
+ *
+ * @param sp the storage buffer to set the byte order for.
+ * @param byteorder the new byte order.
+ *
+ * The byte order are: KRB5_STORAGE_BYTEORDER_BE,
+ * KRB5_STORAGE_BYTEORDER_LE and KRB5_STORAGE_BYTEORDER_HOST.
+ *
+ * @ingroup krb5_storage
+ */
+
 void KRB5_LIB_FUNCTION
 krb5_storage_set_byteorder(krb5_storage *sp, krb5_flags byteorder)
 {
 void KRB5_LIB_FUNCTION
 krb5_storage_set_byteorder(krb5_storage *sp, krb5_flags byteorder)
 {
@@ -67,36 +89,121 @@ krb5_storage_set_byteorder(krb5_storage *sp, krb5_flags byteorder)
     sp->flags |= byteorder;
 }
 
     sp->flags |= byteorder;
 }
 
+/**
+ * Return the current byteorder for the buffer. See krb5_storage_set_byteorder() for the list or byte order contants.
+ *
+ * @ingroup krb5_storage
+ */
+
 krb5_flags KRB5_LIB_FUNCTION
 krb5_flags KRB5_LIB_FUNCTION
-krb5_storage_get_byteorder(krb5_storage *sp, krb5_flags byteorder)
+krb5_storage_get_byteorder(krb5_storage *sp)
 {
     return sp->flags & KRB5_STORAGE_BYTEORDER_MASK;
 }
 
 {
     return sp->flags & KRB5_STORAGE_BYTEORDER_MASK;
 }
 
+/**
+ * Seek to a new offset.
+ *
+ * @param sp the storage buffer to seek in.
+ * @param offset the offset to seek
+ * @param whence relateive searching, SEEK_CUR from the current
+ * position, SEEK_END from the end, SEEK_SET absolute from the start.
+ *
+ * @return The new current offset
+ *
+ * @ingroup krb5_storage
+ */
+
 off_t KRB5_LIB_FUNCTION
 krb5_storage_seek(krb5_storage *sp, off_t offset, int whence)
 {
     return (*sp->seek)(sp, offset, whence);
 }
 
 off_t KRB5_LIB_FUNCTION
 krb5_storage_seek(krb5_storage *sp, off_t offset, int whence)
 {
     return (*sp->seek)(sp, offset, whence);
 }
 
+/**
+ * Truncate the storage buffer in sp to offset.
+ *
+ * @param sp the storage buffer to truncate.
+ * @param offset the offset to truncate too.
+ *
+ * @return An Kerberos 5 error code.
+ *
+ * @ingroup krb5_storage
+ */
+
+int KRB5_LIB_FUNCTION
+krb5_storage_truncate(krb5_storage *sp, off_t offset)
+{
+    return (*sp->trunc)(sp, offset);
+}
+
+/**
+ * Read to the storage buffer.
+ *
+ * @param sp the storage buffer to read from
+ * @param buf the buffer to store the data in
+ * @param len the length to read
+ *
+ * @return The length of data read (can be shorter then len), or negative on error.
+ *
+ * @ingroup krb5_storage
+ */
+
 krb5_ssize_t KRB5_LIB_FUNCTION
 krb5_storage_read(krb5_storage *sp, void *buf, size_t len)
 {
     return sp->fetch(sp, buf, len);
 }
 
 krb5_ssize_t KRB5_LIB_FUNCTION
 krb5_storage_read(krb5_storage *sp, void *buf, size_t len)
 {
     return sp->fetch(sp, buf, len);
 }
 
+/**
+ * Write to the storage buffer.
+ *
+ * @param sp the storage buffer to write to
+ * @param buf the buffer to write to the storage buffer
+ * @param len the length to write
+ *
+ * @return The length of data written (can be shorter then len), or negative on error.
+ *
+ * @ingroup krb5_storage
+ */
+
 krb5_ssize_t KRB5_LIB_FUNCTION
 krb5_storage_write(krb5_storage *sp, const void *buf, size_t len)
 {
     return sp->store(sp, buf, len);
 }
 
 krb5_ssize_t KRB5_LIB_FUNCTION
 krb5_storage_write(krb5_storage *sp, const void *buf, size_t len)
 {
     return sp->store(sp, buf, len);
 }
 
+/**
+ * Set the return code that will be used when end of storage is reached.
+ *
+ * @param sp the storage
+ * @param code the error code to return on end of storage
+ *
+ * @ingroup krb5_storage
+ */
+
 void KRB5_LIB_FUNCTION
 krb5_storage_set_eof_code(krb5_storage *sp, int code)
 {
     sp->eof_code = code;
 }
 
 void KRB5_LIB_FUNCTION
 krb5_storage_set_eof_code(krb5_storage *sp, int code)
 {
     sp->eof_code = code;
 }
 
+/**
+ * Get the return code that will be used when end of storage is reached.
+ *
+ * @param sp the storage
+ *
+ * @return storage error code
+ *
+ * @ingroup krb5_storage
+ */
+
+int KRB5_LIB_FUNCTION
+krb5_storage_get_eof_code(krb5_storage *sp)
+{
+    return sp->eof_code;
+}
+
 krb5_ssize_t KRB5_LIB_FUNCTION
 _krb5_put_int(void *buffer, unsigned long value, size_t size)
 {
 krb5_ssize_t KRB5_LIB_FUNCTION
 _krb5_put_int(void *buffer, unsigned long value, size_t size)
 {
@@ -121,6 +228,16 @@ _krb5_get_int(void *buffer, unsigned long *value, size_t size)
     return size;
 }
 
     return size;
 }
 
+/**
+ * Free a krb5 storage.
+ *
+ * @param sp the storage to free.
+ *
+ * @return An Kerberos 5 error code.
+ *
+ * @ingroup krb5_storage
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_storage_free(krb5_storage *sp)
 {
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_storage_free(krb5_storage *sp)
 {
@@ -131,15 +248,29 @@ krb5_storage_free(krb5_storage *sp)
     return 0;
 }
 
     return 0;
 }
 
+/**
+ * Copy the contnent of storage
+ *
+ * @param sp the storage to copy to a data
+ * @param data the copied data, free with krb5_data_free()
+ *
+ * @return 0 for success, or a Kerberos 5 error code on failure.
+ *
+ * @ingroup krb5_storage
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_storage_to_data(krb5_storage *sp, krb5_data *data)
 {
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_storage_to_data(krb5_storage *sp, krb5_data *data)
 {
-    off_t pos;
-    size_t size;
+    off_t pos, size;
     krb5_error_code ret;
 
     pos = sp->seek(sp, 0, SEEK_CUR);
     krb5_error_code ret;
 
     pos = sp->seek(sp, 0, SEEK_CUR);
+    if (pos < 0)
+       return HEIM_ERR_NOT_SEEKABLE;
     size = (size_t)sp->seek(sp, 0, SEEK_END);
     size = (size_t)sp->seek(sp, 0, SEEK_END);
+    if (size > (size_t)-1)
+       return HEIM_ERR_TOO_BIG;
     ret = krb5_data_alloc (data, size);
     if (ret) {
        sp->seek(sp, pos, SEEK_SET);
     ret = krb5_data_alloc (data, size);
     if (ret) {
        sp->seek(sp, pos, SEEK_SET);
@@ -170,6 +301,18 @@ krb5_store_int(krb5_storage *sp,
     return 0;
 }
 
     return 0;
 }
 
+/**
+ * Store a int32 to storage, byte order is controlled by the settings
+ * on the storage, see krb5_storage_set_byteorder().
+ *
+ * @param sp the storage to write too
+ * @param value the value to store
+ *
+ * @return 0 for success, or a Kerberos 5 error code on failure.
+ *
+ * @ingroup krb5_storage
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_store_int32(krb5_storage *sp,
                 int32_t value)
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_store_int32(krb5_storage *sp,
                 int32_t value)
@@ -181,6 +324,18 @@ krb5_store_int32(krb5_storage *sp,
     return krb5_store_int(sp, value, 4);
 }
 
     return krb5_store_int(sp, value, 4);
 }
 
+/**
+ * Store a uint32 to storage, byte order is controlled by the settings
+ * on the storage, see krb5_storage_set_byteorder().
+ *
+ * @param sp the storage to write too
+ * @param value the value to store
+ *
+ * @return 0 for success, or a Kerberos 5 error code on failure.
+ *
+ * @ingroup krb5_storage
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_store_uint32(krb5_storage *sp,
                  uint32_t value)
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_store_uint32(krb5_storage *sp,
                  uint32_t value)
@@ -232,6 +387,18 @@ krb5_ret_uint32(krb5_storage *sp,
     return ret;
 }
 
     return ret;
 }
 
+/**
+ * Store a int16 to storage, byte order is controlled by the settings
+ * on the storage, see krb5_storage_set_byteorder().
+ *
+ * @param sp the storage to write too
+ * @param value the value to store
+ *
+ * @return 0 for success, or a Kerberos 5 error code on failure.
+ *
+ * @ingroup krb5_storage
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_store_int16(krb5_storage *sp,
                 int16_t value)
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_store_int16(krb5_storage *sp,
                 int16_t value)
@@ -243,6 +410,18 @@ krb5_store_int16(krb5_storage *sp,
     return krb5_store_int(sp, value, 2);
 }
 
     return krb5_store_int(sp, value, 2);
 }
 
+/**
+ * Store a uint16 to storage, byte order is controlled by the settings
+ * on the storage, see krb5_storage_set_byteorder().
+ *
+ * @param sp the storage to write too
+ * @param value the value to store
+ *
+ * @return 0 for success, or a Kerberos 5 error code on failure.
+ *
+ * @ingroup krb5_storage
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_store_uint16(krb5_storage *sp,
                  uint16_t value)
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_store_uint16(krb5_storage *sp,
                  uint16_t value)
@@ -281,6 +460,17 @@ krb5_ret_uint16(krb5_storage *sp,
     return ret;
 }
 
     return ret;
 }
 
+/**
+ * Store a int8 to storage.
+ *
+ * @param sp the storage to write too
+ * @param value the value to store
+ *
+ * @return 0 for success, or a Kerberos 5 error code on failure.
+ *
+ * @ingroup krb5_storage
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_store_int8(krb5_storage *sp,
                int8_t value)
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_store_int8(krb5_storage *sp,
                int8_t value)
@@ -293,6 +483,17 @@ krb5_store_int8(krb5_storage *sp,
     return 0;
 }
 
     return 0;
 }
 
+/**
+ * Store a uint8 to storage.
+ *
+ * @param sp the storage to write too
+ * @param value the value to store
+ *
+ * @return 0 for success, or a Kerberos 5 error code on failure.
+ *
+ * @ingroup krb5_storage
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_store_uint8(krb5_storage *sp,
                 uint8_t value)
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_store_uint8(krb5_storage *sp,
                 uint8_t value)
@@ -326,6 +527,17 @@ krb5_ret_uint8(krb5_storage *sp,
     return ret;
 }
 
     return ret;
 }
 
+/**
+ * Store a data to the storage.
+ *
+ * @param sp the storage buffer to write to
+ * @param data the buffer to store.
+ *
+ * @return 0 on success, a Kerberos 5 error code on failure.
+ *
+ * @ingroup krb5_storage
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_store_data(krb5_storage *sp,
                krb5_data data)
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_store_data(krb5_storage *sp,
                krb5_data data)
@@ -343,6 +555,17 @@ krb5_store_data(krb5_storage *sp,
     return 0;
 }
 
     return 0;
 }
 
+/**
+ * Parse a data from the storage.
+ *
+ * @param sp the storage buffer to read from
+ * @param data the parsed data
+ *
+ * @return 0 on success, a Kerberos 5 error code on failure.
+ *
+ * @ingroup krb5_storage
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_ret_data(krb5_storage *sp,
              krb5_data *data)
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_ret_data(krb5_storage *sp,
              krb5_data *data)
@@ -594,6 +817,17 @@ krb5_ret_principal(krb5_storage *sp,
     return 0;
 }
 
     return 0;
 }
 
+/**
+ * Store a keyblock to the storage.
+ *
+ * @param sp the storage buffer to write to
+ * @param p the keyblock to write
+ *
+ * @return 0 on success, a Kerberos 5 error code on failure.
+ *
+ * @ingroup krb5_storage
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_store_keyblock(krb5_storage *sp, krb5_keyblock p)
 {
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_store_keyblock(krb5_storage *sp, krb5_keyblock p)
 {
@@ -612,6 +846,17 @@ krb5_store_keyblock(krb5_storage *sp, krb5_keyblock p)
     return ret;
 }
 
     return ret;
 }
 
+/**
+ * Read a keyblock from the storage.
+ *
+ * @param sp the storage buffer to write to
+ * @param p the keyblock read from storage, free using krb5_free_keyblock()
+ *
+ * @return 0 on success, a Kerberos 5 error code on failure.
+ *
+ * @ingroup krb5_storage
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_ret_keyblock(krb5_storage *sp, krb5_keyblock *p)
 {
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_ret_keyblock(krb5_storage *sp, krb5_keyblock *p)
 {
@@ -631,6 +876,17 @@ krb5_ret_keyblock(krb5_storage *sp, krb5_keyblock *p)
     return ret;
 }
 
     return ret;
 }
 
+/**
+ * Write a times block to storage.
+ *
+ * @param sp the storage buffer to write to
+ * @param times the times block to write.
+ *
+ * @return 0 on success, a Kerberos 5 error code on failure.
+ *
+ * @ingroup krb5_storage
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_store_times(krb5_storage *sp, krb5_times times)
 {
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_store_times(krb5_storage *sp, krb5_times times)
 {
@@ -645,6 +901,17 @@ krb5_store_times(krb5_storage *sp, krb5_times times)
     return ret;
 }
 
     return ret;
 }
 
+/**
+ * Read a times block from the storage.
+ *
+ * @param sp the storage buffer to write to
+ * @param times the times block read from storage
+ *
+ * @return 0 on success, a Kerberos 5 error code on failure.
+ *
+ * @ingroup krb5_storage
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_ret_times(krb5_storage *sp, krb5_times *times)
 {
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_ret_times(krb5_storage *sp, krb5_times *times)
 {
@@ -903,6 +1170,8 @@ krb5_store_creds_tag(krb5_storage *sp, krb5_creds *creds)
        header |= SC_ADDRESSES;
 
     ret = krb5_store_int32(sp, header);
        header |= SC_ADDRESSES;
 
     ret = krb5_store_int32(sp, header);
+    if (ret)
+       return ret;
 
     if (creds->client) {
        ret = krb5_store_principal(sp, creds->client);
 
     if (creds->client) {
        ret = krb5_store_principal(sp, creds->client);
index 8a587600fdad129fd984c795bf08726257aa654a..4be89b6564bcfeb20a61f008a87d4ccb90386716 100644 (file)
@@ -34,8 +34,6 @@
 #include "krb5_locl.h"
 #include "store-int.h"
 
 #include "krb5_locl.h"
 #include "store-int.h"
 
-RCSID("$Id$");
-
 typedef struct emem_storage{
     unsigned char *base;
     size_t size;
 typedef struct emem_storage{
     unsigned char *base;
     size_t size;
@@ -67,7 +65,7 @@ emem_store(krb5_storage *sp, const void *data, size_t size)
            sz *= 2;
        base = realloc(s->base, sz);
        if(base == NULL)
            sz *= 2;
        base = realloc(s->base, sz);
        if(base == NULL)
-           return 0;
+           return -1;
        s->size = sz;
        s->base = base;
        s->ptr = (unsigned char*)base + off;
        s->size = sz;
        s->base = base;
        s->ptr = (unsigned char*)base + off;
@@ -104,6 +102,34 @@ emem_seek(krb5_storage *sp, off_t offset, int whence)
     return s->ptr - s->base;
 }
 
     return s->ptr - s->base;
 }
 
+static int
+emem_trunc(krb5_storage *sp, off_t offset)
+{
+    emem_storage *s = (emem_storage*)sp->data;
+    /*
+     * If offset is larget then current size, or current size is
+     * shrunk more then half of the current size, adjust buffer.
+     */
+    if (offset > s->size || (s->size / 2) > offset) {
+       void *base;
+       size_t off;
+       off = s->ptr - s->base;
+       base = realloc(s->base, offset);
+       if(base == NULL)
+           return ENOMEM;
+       if (offset > s->size)
+           memset((char *)base + s->size, 0, offset - s->size);
+       s->size = offset;
+       s->base = base;
+       s->ptr = (unsigned char *)base + off;
+    }
+    s->len = offset;
+    if ((s->ptr - s->base) > offset)
+       s->ptr = s->base + offset;
+    return 0;
+}
+
+
 static void
 emem_free(krb5_storage *sp)
 {
 static void
 emem_free(krb5_storage *sp)
 {
@@ -112,6 +138,21 @@ emem_free(krb5_storage *sp)
     free(s->base);
 }
 
     free(s->base);
 }
 
+/**
+ * Create a elastic (allocating) memory storage backend. Memory is
+ * allocated on demand. Free returned krb5_storage with
+ * krb5_storage_free().
+ *
+ * @return A krb5_storage on success, or NULL on out of memory error.
+ *
+ * @ingroup krb5_storage
+ *
+ * @sa krb5_storage_from_mem()
+ * @sa krb5_storage_from_readonly_mem()
+ * @sa krb5_storage_from_fd()
+ * @sa krb5_storage_from_data()
+ */
+
 krb5_storage * KRB5_LIB_FUNCTION
 krb5_storage_emem(void)
 {
 krb5_storage * KRB5_LIB_FUNCTION
 krb5_storage_emem(void)
 {
@@ -142,6 +183,7 @@ krb5_storage_emem(void)
     sp->fetch = emem_fetch;
     sp->store = emem_store;
     sp->seek = emem_seek;
     sp->fetch = emem_fetch;
     sp->store = emem_store;
     sp->seek = emem_seek;
+    sp->trunc = emem_trunc;
     sp->free = emem_free;
     return sp;
 }
     sp->free = emem_free;
     return sp;
 }
index fe3c513ee9a9a1e879a53193df066162d121cc80..38d67ae4d3d0f42a390832bafd62a93f294dc11b 100644 (file)
@@ -34,8 +34,6 @@
 #include "krb5_locl.h"
 #include "store-int.h"
 
 #include "krb5_locl.h"
 #include "store-int.h"
 
-RCSID("$Id$");
-
 typedef struct fd_storage {
     int fd;
 } fd_storage;
 typedef struct fd_storage {
     int fd;
 } fd_storage;
@@ -60,12 +58,33 @@ fd_seek(krb5_storage * sp, off_t offset, int whence)
     return lseek(FD(sp), offset, whence);
 }
 
     return lseek(FD(sp), offset, whence);
 }
 
+static int
+fd_trunc(krb5_storage * sp, off_t offset)
+{
+    if (ftruncate(FD(sp), offset) == -1)
+       return errno;
+    return 0;
+}
+
 static void
 fd_free(krb5_storage * sp)
 {
     close(FD(sp));
 }
 
 static void
 fd_free(krb5_storage * sp)
 {
     close(FD(sp));
 }
 
+/**
+ * 
+ *
+ * @return A krb5_storage on success, or NULL on out of memory error.
+ *
+ * @ingroup krb5_storage
+ *
+ * @sa krb5_storage_from_emem()
+ * @sa krb5_storage_from_mem()
+ * @sa krb5_storage_from_readonly_mem()
+ * @sa krb5_storage_from_data()
+ */
+
 krb5_storage * KRB5_LIB_FUNCTION
 krb5_storage_from_fd(int fd)
 {
 krb5_storage * KRB5_LIB_FUNCTION
 krb5_storage_from_fd(int fd)
 {
@@ -93,6 +112,7 @@ krb5_storage_from_fd(int fd)
     sp->fetch = fd_fetch;
     sp->store = fd_store;
     sp->seek = fd_seek;
     sp->fetch = fd_fetch;
     sp->store = fd_store;
     sp->seek = fd_seek;
+    sp->trunc = fd_trunc;
     sp->free = fd_free;
     return sp;
 }
     sp->free = fd_free;
     return sp;
 }
index 5c7cd17fba95bd19d6052c1bdb9dd2bb58064bff..db1abc1e906ac2a2d027ac0ae02d05baadc7a38f 100644 (file)
@@ -34,8 +34,6 @@
 #include "krb5_locl.h"
 #include "store-int.h"
 
 #include "krb5_locl.h"
 #include "store-int.h"
 
-RCSID("$Id$");
-
 typedef struct mem_storage{
     unsigned char *base;
     size_t size;
 typedef struct mem_storage{
     unsigned char *base;
     size_t size;
@@ -93,6 +91,37 @@ mem_seek(krb5_storage *sp, off_t offset, int whence)
     return s->ptr - s->base;
 }
 
     return s->ptr - s->base;
 }
 
+static int
+mem_trunc(krb5_storage *sp, off_t offset)
+{
+    mem_storage *s = (mem_storage*)sp->data;
+    if(offset > s->size)
+       return ERANGE;
+    s->size = offset;
+    if ((s->ptr - s->base) > offset)
+       s->ptr = s->base + offset;
+    return 0;
+}
+
+static int
+mem_no_trunc(krb5_storage *sp, off_t offset)
+{
+    return EINVAL;
+}
+
+/**
+ * 
+ *
+ * @return A krb5_storage on success, or NULL on out of memory error.
+ *
+ * @ingroup krb5_storage
+ *
+ * @sa krb5_storage_from_emem()
+ * @sa krb5_storage_from_readonly_mem()
+ * @sa krb5_storage_from_data()
+ * @sa krb5_storage_from_fd()
+ */
+
 krb5_storage * KRB5_LIB_FUNCTION
 krb5_storage_from_mem(void *buf, size_t len)
 {
 krb5_storage * KRB5_LIB_FUNCTION
 krb5_storage_from_mem(void *buf, size_t len)
 {
@@ -114,16 +143,43 @@ krb5_storage_from_mem(void *buf, size_t len)
     sp->fetch = mem_fetch;
     sp->store = mem_store;
     sp->seek = mem_seek;
     sp->fetch = mem_fetch;
     sp->store = mem_store;
     sp->seek = mem_seek;
+    sp->trunc = mem_trunc;
     sp->free = NULL;
     return sp;
 }
 
     sp->free = NULL;
     return sp;
 }
 
+/**
+ * 
+ *
+ * @return A krb5_storage on success, or NULL on out of memory error.
+ *
+ * @ingroup krb5_storage
+ *
+ * @sa krb5_storage_from_emem()
+ * @sa krb5_storage_from_mem()
+ * @sa krb5_storage_from_readonly_mem()
+ * @sa krb5_storage_from_fd()
+ */
+
 krb5_storage * KRB5_LIB_FUNCTION
 krb5_storage_from_data(krb5_data *data)
 {
     return krb5_storage_from_mem(data->data, data->length);
 }
 
 krb5_storage * KRB5_LIB_FUNCTION
 krb5_storage_from_data(krb5_data *data)
 {
     return krb5_storage_from_mem(data->data, data->length);
 }
 
+/**
+ * 
+ *
+ * @return A krb5_storage on success, or NULL on out of memory error.
+ *
+ * @ingroup krb5_storage
+ *
+ * @sa krb5_storage_from_emem()
+ * @sa krb5_storage_from_mem()
+ * @sa krb5_storage_from_data()
+ * @sa krb5_storage_from_fd()
+ */
+
 krb5_storage * KRB5_LIB_FUNCTION
 krb5_storage_from_readonly_mem(const void *buf, size_t len)
 {
 krb5_storage * KRB5_LIB_FUNCTION
 krb5_storage_from_readonly_mem(const void *buf, size_t len)
 {
@@ -145,6 +201,7 @@ krb5_storage_from_readonly_mem(const void *buf, size_t len)
     sp->fetch = mem_fetch;
     sp->store = mem_no_store;
     sp->seek = mem_seek;
     sp->fetch = mem_fetch;
     sp->store = mem_no_store;
     sp->seek = mem_seek;
+    sp->trunc = mem_no_trunc;
     sp->free = NULL;
     return sp;
 }
     sp->free = NULL;
     return sp;
 }
index db786265707a02bdced5189b3bf2aa3b5a30a723..86c4924506cafc133163a112ac97ff04a96355b0 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "krb5_locl.h"
 
 
 #include "krb5_locl.h"
 
-RCSID("$Id$");
-
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_free_ticket(krb5_context context,
                 krb5_ticket *ticket)
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_free_ticket(krb5_context context,
                 krb5_ticket *ticket)
@@ -301,3 +299,485 @@ krb5_ticket_get_authorization_data_type(krb5_context context,
     }
     return 0;
 }
     }
     return 0;
 }
+
+static krb5_error_code
+check_server_referral(krb5_context context,
+                     krb5_kdc_rep *rep,
+                     unsigned flags,
+                     krb5_const_principal requested,
+                     krb5_const_principal returned,
+                     krb5_keyblock * key)
+{
+    krb5_error_code ret;
+    PA_ServerReferralData ref;
+    krb5_crypto session;
+    EncryptedData ed;
+    size_t len;
+    krb5_data data;
+    PA_DATA *pa;
+    int i = 0, cmp;
+
+    if (rep->kdc_rep.padata == NULL)
+       goto noreferral;
+
+    pa = krb5_find_padata(rep->kdc_rep.padata->val,
+                         rep->kdc_rep.padata->len,
+                         KRB5_PADATA_SERVER_REFERRAL, &i);
+    if (pa == NULL)
+       goto noreferral;
+
+    memset(&ed, 0, sizeof(ed));
+    memset(&ref, 0, sizeof(ref));
+
+    ret = decode_EncryptedData(pa->padata_value.data,
+                              pa->padata_value.length,
+                              &ed, &len);
+    if (ret)
+       return ret;
+    if (len != pa->padata_value.length) {
+       free_EncryptedData(&ed);
+       krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED,
+                              N_("Referral EncryptedData wrong for realm %s",
+                                 "realm"), requested->realm);
+       return KRB5KRB_AP_ERR_MODIFIED;
+    }
+
+    ret = krb5_crypto_init(context, key, 0, &session);
+    if (ret) {
+       free_EncryptedData(&ed);
+       return ret;
+    }
+
+    ret = krb5_decrypt_EncryptedData(context, session,
+                                    KRB5_KU_PA_SERVER_REFERRAL,
+                                    &ed, &data);
+    free_EncryptedData(&ed);
+    krb5_crypto_destroy(context, session);
+    if (ret)
+       return ret;
+
+    ret = decode_PA_ServerReferralData(data.data, data.length, &ref, &len);
+    if (ret) {
+       krb5_data_free(&data);
+       return ret;
+    }
+    krb5_data_free(&data);
+
+    if (strcmp(requested->realm, returned->realm) != 0) {
+       free_PA_ServerReferralData(&ref);
+       krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED,
+                              N_("server ref realm mismatch, "
+                                 "requested realm %s got back %s", ""),
+                              requested->realm, returned->realm);
+       return KRB5KRB_AP_ERR_MODIFIED;
+    }
+
+    if (returned->name.name_string.len == 2 &&
+       strcmp(returned->name.name_string.val[0], KRB5_TGS_NAME) == 0)
+    {
+       const char *realm = returned->name.name_string.val[1];
+
+       if (ref.referred_realm == NULL
+           || strcmp(*ref.referred_realm, realm) != 0)
+       {
+           free_PA_ServerReferralData(&ref);
+           krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED,
+                                  N_("tgt returned with wrong ref", ""));
+           return KRB5KRB_AP_ERR_MODIFIED;
+       }
+    } else if (krb5_principal_compare(context, returned, requested) == 0) {
+       free_PA_ServerReferralData(&ref);
+       krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED,
+                              N_("req princ no same as returned", ""));
+       return KRB5KRB_AP_ERR_MODIFIED;
+    }
+
+    if (ref.requested_principal_name) {
+       cmp = _krb5_principal_compare_PrincipalName(context,
+                                                   requested,
+                                                   ref.requested_principal_name);
+       if (!cmp) {
+           free_PA_ServerReferralData(&ref);
+           krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED,
+                                  N_("referred principal not same "
+                                     "as requested", ""));
+           return KRB5KRB_AP_ERR_MODIFIED;
+       }
+    } else if (flags & EXTRACT_TICKET_AS_REQ) {
+       free_PA_ServerReferralData(&ref);
+       krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED,
+                              N_("Requested principal missing on AS-REQ", ""));
+       return KRB5KRB_AP_ERR_MODIFIED;
+    }
+
+    free_PA_ServerReferralData(&ref);
+
+    return ret;
+noreferral:
+    if (krb5_principal_compare(context, requested, returned) == FALSE) {
+       krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED,
+                              N_("Not same server principal returned "
+                                 "as requested", ""));
+       return KRB5KRB_AP_ERR_MODIFIED;
+    }
+    return 0;
+}
+
+
+/*
+ * Verify referral data
+ */
+
+
+static krb5_error_code
+check_client_referral(krb5_context context,
+                     krb5_kdc_rep *rep,
+                     krb5_const_principal requested,
+                     krb5_const_principal mapped,
+                     krb5_keyblock const * key)
+{
+    krb5_error_code ret;
+    PA_ClientCanonicalized canon;
+    krb5_crypto crypto;
+    krb5_data data;
+    PA_DATA *pa;
+    size_t len;
+    int i = 0;
+
+    if (rep->kdc_rep.padata == NULL)
+       goto noreferral;
+
+    pa = krb5_find_padata(rep->kdc_rep.padata->val,
+                         rep->kdc_rep.padata->len,
+                         KRB5_PADATA_CLIENT_CANONICALIZED, &i);
+    if (pa == NULL)
+       goto noreferral;
+
+    ret = decode_PA_ClientCanonicalized(pa->padata_value.data,
+                                       pa->padata_value.length,
+                                       &canon, &len);
+    if (ret) {
+       krb5_set_error_message(context, ret,
+                              N_("Failed to decode ClientCanonicalized "
+                                 "from realm %s", ""), requested->realm);
+       return ret;
+    }
+
+    ASN1_MALLOC_ENCODE(PA_ClientCanonicalizedNames, data.data, data.length,
+                      &canon.names, &len, ret);
+    if (ret) {
+       free_PA_ClientCanonicalized(&canon);
+       return ret;
+    }
+    if (data.length != len)
+       krb5_abortx(context, "internal asn.1 error");
+
+    ret = krb5_crypto_init(context, key, 0, &crypto);
+    if (ret) {
+       free(data.data);
+       free_PA_ClientCanonicalized(&canon);
+       return ret;
+    }
+
+    ret = krb5_verify_checksum(context, crypto, KRB5_KU_CANONICALIZED_NAMES,
+                              data.data, data.length,
+                              &canon.canon_checksum);
+    krb5_crypto_destroy(context, crypto);
+    free(data.data);
+    if (ret) {
+       krb5_set_error_message(context, ret,
+                              N_("Failed to verify client canonicalized "
+                                 "data from realm %s", ""),
+                              requested->realm);
+       free_PA_ClientCanonicalized(&canon);
+       return ret;
+    }
+
+    if (!_krb5_principal_compare_PrincipalName(context,
+                                              requested,
+                                              &canon.names.requested_name))
+    {
+       free_PA_ClientCanonicalized(&canon);
+       krb5_set_error_message(context, KRB5_PRINC_NOMATCH,
+                              N_("Requested name doesn't match"
+                                 " in client referral", ""));
+       return KRB5_PRINC_NOMATCH;
+    }
+    if (!_krb5_principal_compare_PrincipalName(context,
+                                              mapped,
+                                              &canon.names.mapped_name))
+    {
+       free_PA_ClientCanonicalized(&canon);
+       krb5_set_error_message(context, KRB5_PRINC_NOMATCH,
+                              N_("Mapped name doesn't match"
+                                 " in client referral", ""));
+       return KRB5_PRINC_NOMATCH;
+    }
+
+    return 0;
+
+noreferral:
+    if (krb5_principal_compare(context, requested, mapped) == FALSE) {
+       krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED,
+                              N_("Not same client principal returned "
+                                 "as requested", ""));
+       return KRB5KRB_AP_ERR_MODIFIED;
+    }
+    return 0;
+}
+
+
+static krb5_error_code
+decrypt_tkt (krb5_context context,
+            krb5_keyblock *key,
+            krb5_key_usage usage,
+            krb5_const_pointer decrypt_arg,
+            krb5_kdc_rep *dec_rep)
+{
+    krb5_error_code ret;
+    krb5_data data;
+    size_t size;
+    krb5_crypto crypto;
+
+    ret = krb5_crypto_init(context, key, 0, &crypto);
+    if (ret)
+       return ret;
+
+    ret = krb5_decrypt_EncryptedData (context,
+                                     crypto,
+                                     usage,
+                                     &dec_rep->kdc_rep.enc_part,
+                                     &data);
+    krb5_crypto_destroy(context, crypto);
+
+    if (ret)
+       return ret;
+
+    ret = decode_EncASRepPart(data.data,
+                             data.length,
+                             &dec_rep->enc_part,
+                             &size);
+    if (ret)
+       ret = decode_EncTGSRepPart(data.data,
+                                  data.length,
+                                  &dec_rep->enc_part,
+                                  &size);
+    krb5_data_free (&data);
+    if (ret) {
+        krb5_set_error_message(context, ret, 
+                              N_("Failed to decode encpart in ticket", ""));
+       return ret;
+    }
+    return 0;
+}
+
+int
+_krb5_extract_ticket(krb5_context context,
+                    krb5_kdc_rep *rep,
+                    krb5_creds *creds,
+                    krb5_keyblock *key,
+                    krb5_const_pointer keyseed,
+                    krb5_key_usage key_usage,
+                    krb5_addresses *addrs,
+                    unsigned nonce,
+                    unsigned flags,
+                    krb5_decrypt_proc decrypt_proc,
+                    krb5_const_pointer decryptarg)
+{
+    krb5_error_code ret;
+    krb5_principal tmp_principal;
+    size_t len;
+    time_t tmp_time;
+    krb5_timestamp sec_now;
+
+    /* decrypt */
+
+    if (decrypt_proc == NULL)
+       decrypt_proc = decrypt_tkt;
+
+    ret = (*decrypt_proc)(context, key, key_usage, decryptarg, rep);
+    if (ret)
+       goto out;
+
+    /* save session key */
+
+    creds->session.keyvalue.length = 0;
+    creds->session.keyvalue.data   = NULL;
+    creds->session.keytype = rep->enc_part.key.keytype;
+    ret = krb5_data_copy (&creds->session.keyvalue,
+                         rep->enc_part.key.keyvalue.data,
+                         rep->enc_part.key.keyvalue.length);
+    if (ret) {
+       krb5_clear_error_message(context);
+       goto out;
+    }
+
+    /*
+     * HACK:
+     * this is really a ugly hack, to support using the Netbios Domain Name
+     * as realm against windows KDC's, they always return the full realm
+     * based on the DNS Name.
+     */
+    flags |= EXTRACT_TICKET_ALLOW_SERVER_MISMATCH;
+    flags |= EXTRACT_TICKET_ALLOW_CNAME_MISMATCH;
+
+    /* compare client and save */
+    ret = _krb5_principalname2krb5_principal (context,
+                                             &tmp_principal,
+                                             rep->kdc_rep.cname,
+                                             rep->kdc_rep.crealm);
+    if (ret)
+       goto out;
+
+    /* check client referral and save principal */
+    /* anonymous here ? */
+    if((flags & EXTRACT_TICKET_ALLOW_CNAME_MISMATCH) == 0) {
+       ret = check_client_referral(context, rep,
+                                   creds->client,
+                                   tmp_principal,
+                                   &creds->session);
+       if (ret) {
+           krb5_free_principal (context, tmp_principal);
+           goto out;
+       }
+    }
+    krb5_free_principal (context, creds->client);
+    creds->client = tmp_principal;
+
+    /* check server referral and save principal */
+    ret = _krb5_principalname2krb5_principal (context,
+                                             &tmp_principal,
+                                             rep->kdc_rep.ticket.sname,
+                                             rep->kdc_rep.ticket.realm);
+    if (ret)
+       goto out;
+    if((flags & EXTRACT_TICKET_ALLOW_SERVER_MISMATCH) == 0){
+       ret = check_server_referral(context,
+                                   rep,
+                                   flags,
+                                   creds->server,
+                                   tmp_principal,
+                                   &creds->session);
+       if (ret) {
+           krb5_free_principal (context, tmp_principal);
+           goto out;
+       }
+    }
+    krb5_free_principal(context, creds->server);
+    creds->server = tmp_principal;
+
+    /* verify names */
+    if(flags & EXTRACT_TICKET_MATCH_REALM){
+       const char *srealm = krb5_principal_get_realm(context, creds->server);
+       const char *crealm = krb5_principal_get_realm(context, creds->client);
+
+       if (strcmp(rep->enc_part.srealm, srealm) != 0 ||
+           strcmp(rep->enc_part.srealm, crealm) != 0)
+       {
+           ret = KRB5KRB_AP_ERR_MODIFIED;
+           krb5_clear_error_message(context);
+           goto out;
+       }
+    }
+
+    /* compare nonces */
+
+    if (nonce != rep->enc_part.nonce) {
+       ret = KRB5KRB_AP_ERR_MODIFIED;
+       krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
+       goto out;
+    }
+
+    /* set kdc-offset */
+
+    krb5_timeofday (context, &sec_now);
+    if (rep->enc_part.flags.initial
+       && context->kdc_sec_offset == 0
+       && krb5_config_get_bool (context, NULL,
+                                "libdefaults",
+                                "kdc_timesync",
+                                NULL)) {
+       context->kdc_sec_offset = rep->enc_part.authtime - sec_now;
+       krb5_timeofday (context, &sec_now);
+    }
+
+    /* check all times */
+
+    if (rep->enc_part.starttime) {
+       tmp_time = *rep->enc_part.starttime;
+    } else
+       tmp_time = rep->enc_part.authtime;
+
+    if (creds->times.starttime == 0
+       && abs(tmp_time - sec_now) > context->max_skew) {
+       ret = KRB5KRB_AP_ERR_SKEW;
+       krb5_set_error_message (context, ret,
+                               N_("time skew (%d) larger than max (%d)", ""),
+                              abs(tmp_time - sec_now),
+                              (int)context->max_skew);
+       goto out;
+    }
+
+    if (creds->times.starttime != 0
+       && tmp_time != creds->times.starttime) {
+       krb5_clear_error_message (context);
+       ret = KRB5KRB_AP_ERR_MODIFIED;
+       goto out;
+    }
+
+    creds->times.starttime = tmp_time;
+
+    if (rep->enc_part.renew_till) {
+       tmp_time = *rep->enc_part.renew_till;
+    } else
+       tmp_time = 0;
+
+    if (creds->times.renew_till != 0
+       && tmp_time > creds->times.renew_till) {
+       krb5_clear_error_message (context);
+       ret = KRB5KRB_AP_ERR_MODIFIED;
+       goto out;
+    }
+
+    creds->times.renew_till = tmp_time;
+
+    creds->times.authtime = rep->enc_part.authtime;
+
+    if (creds->times.endtime != 0
+       && rep->enc_part.endtime > creds->times.endtime) {
+       krb5_clear_error_message (context);
+       ret = KRB5KRB_AP_ERR_MODIFIED;
+       goto out;
+    }
+
+    creds->times.endtime  = rep->enc_part.endtime;
+
+    if(rep->enc_part.caddr)
+       krb5_copy_addresses (context, rep->enc_part.caddr, &creds->addresses);
+    else if(addrs)
+       krb5_copy_addresses (context, addrs, &creds->addresses);
+    else {
+       creds->addresses.len = 0;
+       creds->addresses.val = NULL;
+    }
+    creds->flags.b = rep->enc_part.flags;
+       
+    creds->authdata.len = 0;
+    creds->authdata.val = NULL;
+
+    /* extract ticket */
+    ASN1_MALLOC_ENCODE(Ticket, creds->ticket.data, creds->ticket.length,
+                      &rep->kdc_rep.ticket, &len, ret);
+    if(ret)
+       goto out;
+    if (creds->ticket.length != len)
+       krb5_abortx(context, "internal error in ASN.1 encoder");
+    creds->second_ticket.length = 0;
+    creds->second_ticket.data   = NULL;
+
+
+out:
+    memset (rep->enc_part.key.keyvalue.data, 0,
+           rep->enc_part.key.keyvalue.length);
+    return ret;
+}
index cd786fedde296657fd19e4b3399429c80192c4f8..ed235783a230e5cd979d9dceffacc9dfdfe22c89 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "krb5_locl.h"
 
 
 #include "krb5_locl.h"
 
-RCSID("$Id$");
-
 /**
  * Set the absolute time that the caller knows the kdc has so the
  * kerberos library can calculate the relative diffrence beteen the
 /**
  * Set the absolute time that the caller knows the kdc has so the
  * kerberos library can calculate the relative diffrence beteen the
index 7e11d5579a122acc22e579c8aa0b61e33c2d6696..196ef447ee9ddf6ac0c7e2a47a5194467446fb6f 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "krb5_locl.h"
 
 
 #include "krb5_locl.h"
 
-RCSID("$Id$");
-
 /* this is an attempt at one of the most horrible `compression'
    schemes that has ever been invented; it's so amazingly brain-dead
    that words can not describe it, and all this just to save a few
 /* this is an attempt at one of the most horrible `compression'
    schemes that has ever been invented; it's so amazingly brain-dead
    that words can not describe it, and all this just to save a few
index 6911cb20f8f31bc0647c30243bbf2cc5932764da..168268ceabf1df4a2db88d1115476e0672ce0484 100644 (file)
@@ -32,7 +32,6 @@
  */
 
 #include "krb5_locl.h"
  */
 
 #include "krb5_locl.h"
-RCSID("$Id$");
 
 #include "krb5-v4compat.h"
 
 
 #include "krb5-v4compat.h"
 
@@ -217,14 +216,16 @@ write_v4_cc(krb5_context context, const char *tkfile,
     ret = write(fd, data.data, data.length);
     if (ret != data.length)
        ret = KRB5_CC_IO;
     ret = write(fd, data.data, data.length);
     if (ret != data.length)
        ret = KRB5_CC_IO;
+    else
+       ret = 0;
 
 
-    krb5_free_data_contents(context, &data);
+    krb5_data_free(&data);
 
     flock(fd, LOCK_UN);
     free(path);
     close(fd);
 
 
     flock(fd, LOCK_UN);
     free(path);
     close(fd);
 
-    return 0;
+    return ret;
 }
 
 /*
 }
 
 /*
index d43b83e26ee1c6c9408b3c7184bb4309df56a436..a0e750604e5cccc7f9812854847b8d804c4e9fa9 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "krb5_locl.h"
 
 
 #include "krb5_locl.h"
 
-RCSID("$Id$");
-
 /* this is just to get a version stamp in the library file */
 
 #define heimdal_version __heimdal_version
 /* this is just to get a version stamp in the library file */
 
 #define heimdal_version __heimdal_version
index a00ae80697bda74e8ae2952a1fbf20004c262ca0..58fb73189eff308ae4dfd9d73f881cbb690a1a4f 100644 (file)
@@ -34,8 +34,6 @@
 #include "krb5_locl.h"
 #include <err.h>
 
 #include "krb5_locl.h"
 #include <err.h>
 
-RCSID("$Id$");
-
 static krb5_error_code _warnerr(krb5_context context, int do_errtext,
         krb5_error_code code, int level, const char *fmt, va_list ap)
        __attribute__((__format__(__printf__, 5, 0)));
 static krb5_error_code _warnerr(krb5_context context, int do_errtext,
         krb5_error_code code, int level, const char *fmt, va_list ap)
        __attribute__((__format__(__printf__, 5, 0)));
@@ -96,6 +94,18 @@ _warnerr(krb5_context context, int do_errtext,
 #undef __attribute__
 #define __attribute__(X)
 
 #undef __attribute__
 #define __attribute__(X)
 
+/**
+ * Log a warning to the log, default stderr, include the error from
+ * the last failure.
+ *
+ * @param context A Kerberos 5 context.
+ * @param code error code of the last error
+ * @param fmt message to print
+ * @param ap arguments
+ *
+ * @ingroup krb5_error
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_vwarn(krb5_context context, krb5_error_code code,
           const char *fmt, va_list ap)
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_vwarn(krb5_context context, krb5_error_code code,
           const char *fmt, va_list ap)
@@ -104,6 +114,16 @@ krb5_vwarn(krb5_context context, krb5_error_code code,
     return _warnerr(context, 1, code, 1, fmt, ap);
 }
 
     return _warnerr(context, 1, code, 1, fmt, ap);
 }
 
+/**
+ * Log a warning to the log, default stderr, include the error from
+ * the last failure.
+ *
+ * @param context A Kerberos 5 context.
+ * @param code error code of the last error
+ * @param fmt message to print
+ *
+ * @ingroup krb5_error
+ */
 
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_warn(krb5_context context, krb5_error_code code, const char *fmt, ...)
 
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_warn(krb5_context context, krb5_error_code code, const char *fmt, ...)
@@ -113,6 +133,16 @@ krb5_warn(krb5_context context, krb5_error_code code, const char *fmt, ...)
     return ret;
 }
 
     return ret;
 }
 
+/**
+ * Log a warning to the log, default stderr.
+ *
+ * @param context A Kerberos 5 context.
+ * @param fmt message to print
+ * @param ap arguments
+ *
+ * @ingroup krb5_error
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_vwarnx(krb5_context context, const char *fmt, va_list ap)
      __attribute__ ((format (printf, 2, 0)))
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_vwarnx(krb5_context context, const char *fmt, va_list ap)
      __attribute__ ((format (printf, 2, 0)))
@@ -120,6 +150,15 @@ krb5_vwarnx(krb5_context context, const char *fmt, va_list ap)
     return _warnerr(context, 0, 0, 1, fmt, ap);
 }
 
     return _warnerr(context, 0, 0, 1, fmt, ap);
 }
 
+/**
+ * Log a warning to the log, default stderr.
+ *
+ * @param context A Kerberos 5 context.
+ * @param fmt message to print
+ *
+ * @ingroup krb5_error
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_warnx(krb5_context context, const char *fmt, ...)
      __attribute__ ((format (printf, 2, 3)))
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_warnx(krb5_context context, const char *fmt, ...)
      __attribute__ ((format (printf, 2, 3)))
@@ -128,6 +167,19 @@ krb5_warnx(krb5_context context, const char *fmt, ...)
     return ret;
 }
 
     return ret;
 }
 
+/**
+ * Log a warning to the log, default stderr, include bthe error from
+ * the last failure and then exit.
+ *
+ * @param context A Kerberos 5 context
+ * @param eval the exit code to exit with
+ * @param code error code of the last error
+ * @param fmt message to print
+ * @param ap arguments
+ *
+ * @ingroup krb5_error
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_verr(krb5_context context, int eval, krb5_error_code code,
          const char *fmt, va_list ap)
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_verr(krb5_context context, int eval, krb5_error_code code,
          const char *fmt, va_list ap)
@@ -137,6 +189,17 @@ krb5_verr(krb5_context context, int eval, krb5_error_code code,
     exit(eval);
 }
 
     exit(eval);
 }
 
+/**
+ * Log a warning to the log, default stderr, include bthe error from
+ * the last failure and then exit.
+ *
+ * @param context A Kerberos 5 context
+ * @param eval the exit code to exit with
+ * @param code error code of the last error
+ * @param fmt message to print
+ *
+ * @ingroup krb5_error
+ */
 
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_err(krb5_context context, int eval, krb5_error_code code,
 
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_err(krb5_context context, int eval, krb5_error_code code,
@@ -147,6 +210,17 @@ krb5_err(krb5_context context, int eval, krb5_error_code code,
     exit(eval);
 }
 
     exit(eval);
 }
 
+/**
+ * Log a warning to the log, default stderr, and then exit.
+ *
+ * @param context A Kerberos 5 context
+ * @param eval the exit code to exit with
+ * @param fmt message to print
+ * @param ap arguments
+ *
+ * @ingroup krb5_error
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_verrx(krb5_context context, int eval, const char *fmt, va_list ap)
      __attribute__ ((noreturn, format (printf, 3, 0)))
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_verrx(krb5_context context, int eval, const char *fmt, va_list ap)
      __attribute__ ((noreturn, format (printf, 3, 0)))
@@ -155,6 +229,16 @@ krb5_verrx(krb5_context context, int eval, const char *fmt, va_list ap)
     exit(eval);
 }
 
     exit(eval);
 }
 
+/**
+ * Log a warning to the log, default stderr, and then exit.
+ *
+ * @param context A Kerberos 5 context
+ * @param eval the exit code to exit with
+ * @param fmt message to print
+ *
+ * @ingroup krb5_error
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_errx(krb5_context context, int eval, const char *fmt, ...)
      __attribute__ ((noreturn, format (printf, 3, 4)))
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_errx(krb5_context context, int eval, const char *fmt, ...)
      __attribute__ ((noreturn, format (printf, 3, 4)))
@@ -163,6 +247,18 @@ krb5_errx(krb5_context context, int eval, const char *fmt, ...)
     exit(eval);
 }
 
     exit(eval);
 }
 
+/**
+ * Log a warning to the log, default stderr, include bthe error from
+ * the last failure and then abort.
+ *
+ * @param context A Kerberos 5 context
+ * @param code error code of the last error
+ * @param fmt message to print
+ * @param ap arguments
+ *
+ * @ingroup krb5_error
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_vabort(krb5_context context, krb5_error_code code,
            const char *fmt, va_list ap)
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_vabort(krb5_context context, krb5_error_code code,
            const char *fmt, va_list ap)
@@ -172,6 +268,16 @@ krb5_vabort(krb5_context context, krb5_error_code code,
     abort();
 }
 
     abort();
 }
 
+/**
+ * Log a warning to the log, default stderr, include bthe error from
+ * the last failure and then abort.
+ *
+ * @param context A Kerberos 5 context
+ * @param code error code of the last error
+ * @param fmt message to print
+ *
+ * @ingroup krb5_error
+ */
 
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_abort(krb5_context context, krb5_error_code code, const char *fmt, ...)
 
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_abort(krb5_context context, krb5_error_code code, const char *fmt, ...)
@@ -189,6 +295,16 @@ krb5_vabortx(krb5_context context, const char *fmt, va_list ap)
     abort();
 }
 
     abort();
 }
 
+/**
+ * Log a warning to the log, default stderr, and then abort.
+ *
+ * @param context A Kerberos 5 context
+ * @param code error code of the last error
+ * @param fmt message to print
+ *
+ * @ingroup krb5_error
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_abortx(krb5_context context, const char *fmt, ...)
      __attribute__ ((noreturn, format (printf, 2, 3)))
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_abortx(krb5_context context, const char *fmt, ...)
      __attribute__ ((noreturn, format (printf, 2, 3)))
@@ -197,6 +313,15 @@ krb5_abortx(krb5_context context, const char *fmt, ...)
     abort();
 }
 
     abort();
 }
 
+/**
+ * Set the default logging facility.
+ *
+ * @param context A Kerberos 5 context
+ * @param fac Facility to use for logging.
+ *
+ * @ingroup krb5_error
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_set_warn_dest(krb5_context context, krb5_log_facility *fac)
 {
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_set_warn_dest(krb5_context context, krb5_log_facility *fac)
 {
@@ -204,6 +329,14 @@ krb5_set_warn_dest(krb5_context context, krb5_log_facility *fac)
     return 0;
 }
 
     return 0;
 }
 
+/**
+ * Get the default logging facility.
+ *
+ * @param context A Kerberos 5 context
+ *
+ * @ingroup krb5_error
+ */
+
 krb5_log_facility * KRB5_LIB_FUNCTION
 krb5_get_warn_dest(krb5_context context)
 {
 krb5_log_facility * KRB5_LIB_FUNCTION
 krb5_get_warn_dest(krb5_context context)
 {
index 1002b67cc8d49d213d40ad9ed8da949989080cbd..1fe456d022f065afe4ad727bea79d8ae0d7356bb 100644 (file)
@@ -33,8 +33,6 @@
 
 #include <config.h>
 
 
 #include <config.h>
 
-RCSID("$Id$");
-
 #include <stdio.h>
 #include <stdlib.h>
 #include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <assert.h>
@@ -440,7 +438,8 @@ heim_ntlm_decode_type1(const struct ntlm_buf *buf, struct ntlm_type1 *data)
        CHECK(ret_string(in, 0, &hostname, &data->hostname), 0);
 
 out:
        CHECK(ret_string(in, 0, &hostname, &data->hostname), 0);
 
 out:
-    krb5_storage_free(in);
+    if (in)
+       krb5_storage_free(in);
     if (ret)
        heim_ntlm_free_type1(data);
 
     if (ret)
        heim_ntlm_free_type1(data);
 
@@ -589,7 +588,8 @@ heim_ntlm_decode_type2(const struct ntlm_buf *buf, struct ntlm_type2 *type2)
     ret = 0;
 
 out:
     ret = 0;
 
 out:
-    krb5_storage_free(in);
+    if (in)
+       krb5_storage_free(in);
     if (ret)
        heim_ntlm_free_type2(type2);
 
     if (ret)
        heim_ntlm_free_type2(type2);
 
@@ -748,7 +748,8 @@ heim_ntlm_decode_type3(const struct ntlm_buf *buf,
        CHECK(ret_buf(in, &sessionkey, &type3->sessionkey), 0);
 
 out:
        CHECK(ret_buf(in, &sessionkey, &type3->sessionkey), 0);
 
 out:
-    krb5_storage_free(in);
+    if (in)
+       krb5_storage_free(in);
     if (ret)
        heim_ntlm_free_type3(type3);
 
     if (ret)
        heim_ntlm_free_type3(type3);
 
@@ -1041,15 +1042,18 @@ heim_ntlm_build_ntlm1_master(void *key, size_t len,
  * @param target the name of the target, assumed to be in UTF8.
  * @param ntlmv2 the ntlmv2 session key
  *
  * @param target the name of the target, assumed to be in UTF8.
  * @param ntlmv2 the ntlmv2 session key
  *
+ * @return 0 on success, or an error code on failure.
+ *
  * @ingroup ntlm_core
  */
 
  * @ingroup ntlm_core
  */
 
-void
+int
 heim_ntlm_ntlmv2_key(const void *key, size_t len,
                     const char *username,
                     const char *target,
                     unsigned char ntlmv2[16])
 {
 heim_ntlm_ntlmv2_key(const void *key, size_t len,
                     const char *username,
                     const char *target,
                     unsigned char ntlmv2[16])
 {
+    int ret;
     unsigned int hmaclen;
     HMAC_CTX c;
 
     unsigned int hmaclen;
     HMAC_CTX c;
 
@@ -1058,17 +1062,23 @@ heim_ntlm_ntlmv2_key(const void *key, size_t len,
     {
        struct ntlm_buf buf;
        /* uppercase username and turn it into ucs2-le */
     {
        struct ntlm_buf buf;
        /* uppercase username and turn it into ucs2-le */
-       ascii2ucs2le(username, 1, &buf);
+       ret = ascii2ucs2le(username, 1, &buf);
+       if (ret)
+           goto out;
        HMAC_Update(&c, buf.data, buf.length);
        free(buf.data);
        /* uppercase target and turn into ucs2-le */
        HMAC_Update(&c, buf.data, buf.length);
        free(buf.data);
        /* uppercase target and turn into ucs2-le */
-       ascii2ucs2le(target, 1, &buf);
+       ret = ascii2ucs2le(target, 1, &buf);
+       if (ret)
+           goto out;
        HMAC_Update(&c, buf.data, buf.length);
        free(buf.data);
     }
     HMAC_Final(&c, ntlmv2, &hmaclen);
        HMAC_Update(&c, buf.data, buf.length);
        free(buf.data);
     }
     HMAC_Final(&c, ntlmv2, &hmaclen);
+ out:
     HMAC_CTX_cleanup(&c);
 
     HMAC_CTX_cleanup(&c);
 
+    return ret;
 }
 
 /*
 }
 
 /*
index d0096447b35d864065a5471234e4873fa9800463..5e720eb6d4c95002c819f09817a6c4cba2acc285 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-RCSID("$Id$");
-#endif
+
 #include <stdlib.h>
 #include <string.h>
 #include "base64.h"
 #include <stdlib.h>
 #include <string.h>
 #include "base64.h"
@@ -61,8 +59,10 @@ base64_encode(const void *data, int size, char **str)
     const unsigned char *q;
 
     p = s = (char *) malloc(size * 4 / 3 + 4);
     const unsigned char *q;
 
     p = s = (char *) malloc(size * 4 / 3 + 4);
-    if (p == NULL)
+    if (p == NULL) {
+        *str = NULL;
        return -1;
        return -1;
+    }
     q = (const unsigned char *) data;
 
     for (i = 0; i < size;) {
     q = (const unsigned char *) data;
 
     for (i = 0; i < size;) {
index a87345be3f60e6483efe5835f1f0b191191938c2..67d240c2313db9f89335f55fbe521f7be7d845d8 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-#endif
 #include "roken.h"
 
 #include "roken.h"
 
-RCSID("$Id$");
-
 #ifndef HAVE_BSWAP32
 
 unsigned int ROKEN_LIB_FUNCTION
 #ifndef HAVE_BSWAP32
 
 unsigned int ROKEN_LIB_FUNCTION
index 7a64233309c03c1564bfb725234ec1e3fac93eed..c015b1d8fa742886e1516d90a66228a7fb76f37e 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-RCSID("$Id$");
-#endif
 
 #include <unistd.h>
 #include <fcntl.h>
 
 #include <unistd.h>
 #include <fcntl.h>
index 9198c05e26c5976c75080492bbf58528f992c627..7aa0ef7372a2e823c1ff992133142fcaea76e4f6 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-RCSID("$Id$");
-#endif
 
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
 
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
index 58f5a112f2a3c7738bd1db871f56c666e957ada4..69c1ba40ff89290020bf47895c46cc029d80c19a 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-RCSID("$Id$");
-#endif
 
 #include "roken.h"
 
 
 #include "roken.h"
 
index 88a86815efc779f05d94c50a9d7106db281525f1..c5513c323de1531edaa1e90496d1d416d13b3366 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-RCSID("$Id$");
-#endif
 
 #include <unistd.h>
 
 
 #include <unistd.h>
 
index 6c579e99f3d8a6b2bf33c9322694045cfaa2017c..c8e6504030fee028e0e5562183d7a24b1961320f 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-RCSID("$Id$");
-#endif
 
 #include <stdlib.h>
 #include <err.h>
 
 #include <stdlib.h>
 #include <err.h>
index d033e16a075113e7541301753d8a6734a876e2c4..c937e6d7070c55455eae012402bb5041e29745e5 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-RCSID("$Id$");
-#endif
 
 #include <stdlib.h>
 #include <err.h>
 
 #include <stdlib.h>
 #include <err.h>
index 239d6a0eab46d254ff57c09e686c515854820620..f77c8ec7332242f15f07b10fc600e4193a81ff82 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-RCSID("$Id$");
-#endif
 
 #include <stdlib.h>
 #include <err.h>
 
 #include <stdlib.h>
 #include <err.h>
index fb353d0d8509917cfe94e229a49998439e8ec4f2..ab7f26550b77006ae0cab05ada82ee670f81f0b1 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-RCSID("$Id$");
-#endif
 
 #include <stdlib.h>
 #include <err.h>
 
 #include <stdlib.h>
 #include <err.h>
index 1721d20aafed7fd7414c6c4c2f0f924a4f5c39f1..434e49e888db6f3f0a306e986106ad5486b26436 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-RCSID("$Id$");
-#endif
 
 #include "roken.h"
 
 
 #include "roken.h"
 
index 38c27d33800ec691cbf2dd263b3a3044a233d87a..335504300a6451257f048f43dcad3bd9464b8647 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-RCSID("$Id$");
-#endif
 
 #include "roken.h"
 
 
 #include "roken.h"
 
index 084900a58aafc2c77ba83ba94202ff2c9129107e..10beac05eaddbbac38615a908a0ec6da044b7d42 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-RCSID("$Id$");
-#endif
 
 #include "roken.h"
 
 
 #include "roken.h"
 
index 9b200c115978fa9981ea26a37a4c5c0490d1c368..60fb1764fabda74a352243e87204473f4b16c744 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-RCSID("$Id$");
-#endif
 
 #include <stdlib.h>
 #ifdef HAVE_UNISTD_H
 
 #include <stdlib.h>
 #ifdef HAVE_UNISTD_H
index a8fc029c32258fd0ef729db8f5c03c04307647dc..8c61299763b9bbccd2b57cd68c74e7eba4da8392 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-RCSID("$Id$");
-#endif
 
 #include "roken.h"
 
 
 #include "roken.h"
 
index 3168ccc53d2c5cd68f73b26b898173f95ab73cf9..60b0f645afc085899d6d0937f805f91056b6897e 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-RCSID("$Id$");
-#endif
 
 #include <stdio.h>
 #include <stdlib.h>
 
 #include <stdio.h>
 #include <stdlib.h>
similarity index 50%
rename from source4/heimdal/lib/krb5/get_in_tkt_with_keytab.c
rename to source4/heimdal/lib/roken/getdtablesize.c
index 0dedbefd2c3a253cdbbbd0a675afb98b521fdab0..a515af34545018a85f411b2c3b5e160761f38b90 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
+ * Copyright (c) 1995-2001 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden).
  * All rights reserved.
  *
  * (Royal Institute of Technology, Stockholm, Sweden).
  * All rights reserved.
  *
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#include "krb5_locl.h"
+#include <config.h>
 
 
-RCSID("$Id$");
+#include "roken.h"
 
 
-krb5_error_code KRB5_LIB_FUNCTION
-krb5_keytab_key_proc (krb5_context context,
-                     krb5_enctype enctype,
-                     krb5_salt salt,
-                     krb5_const_pointer keyseed,
-                     krb5_keyblock **key)
-{
-    krb5_keytab_key_proc_args *args  = rk_UNCONST(keyseed);
-    krb5_keytab keytab = args->keytab;
-    krb5_principal principal  = args->principal;
-    krb5_error_code ret;
-    krb5_keytab real_keytab;
-    krb5_keytab_entry entry;
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.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_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
 
 
-    if(keytab == NULL)
-       krb5_kt_default(context, &real_keytab);
-    else
-       real_keytab = keytab;
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
 
 
-    ret = krb5_kt_get_entry (context, real_keytab, principal,
-                            0, enctype, &entry);
+#ifdef HAVE_SYS_SYSCTL_H
+#include <sys/sysctl.h>
+#endif
 
 
-    if (keytab == NULL)
-       krb5_kt_close (context, real_keytab);
+int ROKEN_LIB_FUNCTION
+getdtablesize(void)
+{
+  int files = -1;
+#if defined(HAVE_SYSCONF) && defined(_SC_OPEN_MAX)
+  files = sysconf(_SC_OPEN_MAX);
+#else /* !defined(HAVE_SYSCONF) */
+#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)
+  struct rlimit res;
+  if (getrlimit(RLIMIT_NOFILE, &res) == 0)
+    files = res.rlim_cur;
+#else /* !definded(HAVE_GETRLIMIT) */
+#if defined(HAVE_SYSCTL) && defined(CTL_KERN) && defined(KERN_MAXFILES)
+  int mib[2];
+  size_t len;
 
 
-    if (ret)
-       return ret;
+  mib[0] = CTL_KERN;
+  mib[1] = KERN_MAXFILES;
+  len = sizeof(files);
+  sysctl(&mib, 2, &files, sizeof(files), NULL, 0);
+#endif /* defined(HAVE_SYSCTL) */
+#endif /* !definded(HAVE_GETRLIMIT) */
+#endif /* !defined(HAVE_SYSCONF) */
 
 
-    ret = krb5_copy_keyblock (context, &entry.keyblock, key);
-    krb5_kt_free_entry(context, &entry);
-    return ret;
-}
-
-krb5_error_code KRB5_LIB_FUNCTION
-krb5_get_in_tkt_with_keytab (krb5_context context,
-                            krb5_flags options,
-                            krb5_addresses *addrs,
-                            const krb5_enctype *etypes,
-                            const krb5_preauthtype *pre_auth_types,
-                            krb5_keytab keytab,
-                            krb5_ccache ccache,
-                            krb5_creds *creds,
-                            krb5_kdc_rep *ret_as_reply)
-{
-    krb5_keytab_key_proc_args a;
+#ifdef OPEN_MAX
+  if (files < 0)
+    files = OPEN_MAX;
+#endif
 
 
-    a.principal = creds->client;
-    a.keytab    = keytab;
+#ifdef NOFILE
+  if (files < 0)
+    files = NOFILE;
+#endif
 
 
-    return krb5_get_in_tkt (context,
-                           options,
-                           addrs,
-                           etypes,
-                           pre_auth_types,
-                           krb5_keytab_key_proc,
-                           &a,
-                           NULL,
-                           NULL,
-                           creds,
-                           ccache,
-                           ret_as_reply);
+  return files;
 }
 }
index e3c2b50e3257dfb65a7745095179e67ba5aa1d7b..ddaec03a8914de11f302acbf50895d94309a0661 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-RCSID("$Id$");
-#endif
 
 #include "roken.h"
 
 
 #include "roken.h"
 
index ec578937b7bade14025a4b0076b3d3761da5ca5b..16fdbdd24a661eabd07778cbba837f36cb42b0fa 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-RCSID("$Id$");
-#endif
 
 #include "roken.h"
 
 
 #include "roken.h"
 
index 865cc09dc8bf4012ca19e897dcf409ea15a4f9b6..0621cfeee1cd99ea4935922361d07373cd45223f 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-RCSID("$Id$");
-#endif
 
 #include "roken.h"
 
 
 #include "roken.h"
 
index b01a3d7e45ebd54795f023b767478b38a7186183..933b6dec7997455758300c0c39d97965d31c455a 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-RCSID("$Id$");
-#endif
 
 #include "roken.h"
 
 
 #include "roken.h"
 
index 0cee02d4721abe2910cc0bc74d8fb8afd7d6605b..7e49f8008f9a2f6aaf7bf0b1738c7395f13b52d8 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-RCSID("$Id$");
-#endif
 
 #ifndef HAVE_H_ERRNO
 int h_errno = -17; /* Some magic number */
 
 #ifndef HAVE_H_ERRNO
 int h_errno = -17; /* Some magic number */
index 2167172f9f6e65eb5cf0dfc04ea9214e46032574..95488af5c741b472b7caae63c2e2d527fc5eaf21 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
+
 #include <config.h>
 #include <config.h>
-RCSID("$Id$");
-#endif
 #include "roken.h"
 #include <ctype.h>
 #include "hex.h"
 #include "roken.h"
 #include <ctype.h>
 #include "hex.h"
@@ -60,12 +58,16 @@ hex_encode(const void *data, size_t size, char **str)
     char *p;
 
     /* check for overflow */
     char *p;
 
     /* check for overflow */
-    if (size * 2 < size)
+    if (size * 2 < size) {
+        *str = NULL;
        return -1;
        return -1;
+    }
 
     p = malloc(size * 2 + 1);
 
     p = malloc(size * 2 + 1);
-    if (p == NULL)
+    if (p == NULL) {
+        *str = NULL;
        return -1;
        return -1;
+    }
 
     for (i = 0; i < size; i++) {
        p[i * 2] = hexchar[(*q >> 4) & 0xf];
 
     for (i = 0; i < size; i++) {
        p[i * 2] = hexchar[(*q >> 4) & 0xf];
index 9376c1da3607f2322a112a77e871d31bbcdf8b18..b5f2b42f60aa797dd9145afcd0b55d18aaecbcbb 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-RCSID("$Id$");
-#endif
 
 #include "roken.h"
 
 
 #include "roken.h"
 
index c42697c63c5c01f320c013656fea62a03518312c..c9b21e00f8b55c7497f3d66d3db6506ac1e0d9ac 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-RCSID("$Id$");
-#endif
 
 #include "roken.h"
 
 
 #include "roken.h"
 
index 5e4e4f9dc7682559ab9321e47465df09126d78b9..daf3e926ddc5d2a82e39acfc6810e01fe1344591 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-RCSID("$Id$");
-#endif
 
 #include "roken.h"
 
 
 #include "roken.h"
 
index f2a9af3aa325a45fc77b98489c7ee8b7fda8091b..ad60824f4aa18caa8ae4b0eeaaba6d30a8bff24c 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-RCSID("$Id$");
-#endif
 
 #include "roken.h"
 
 
 #include "roken.h"
 
index 257481cffb125919905e0718a9c5df6378bcf53b..2999e8249cea89074a0bea44e90a3c60861a61fa 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-RCSID("$Id$");
-#endif
 
 #include "roken.h"
 
 
 #include "roken.h"
 
index ae025ffc719c1387314762a34851c3acaca56e31..9d055d0068287420a51610ef195f4ff64e6a8713 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-RCSID("$Id$");
-#endif
 
 #include <sys/types.h>
 #include <unistd.h>
 
 #include <sys/types.h>
 #include <unistd.h>
index 11f5b8d7be8879cd99182aab4b7e926d18ad38d1..515f210973feff3388fddc578045cce85c667b13 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-RCSID("$Id$");
-#endif
 
 #include <sys/types.h>
 #include <unistd.h>
 
 #include <sys/types.h>
 #include <unistd.h>
index 6065eeb42514d839ea5e86b15e4f8effd495b06c..b581970bd7c468a7ccf2da7c9481d28f6811c90f 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-RCSID("$Id$");
-#endif
 
 #include <parse_units.h>
 #include "parse_time.h"
 
 #include <parse_units.h>
 #include "parse_time.h"
index 4dbd7b489bd8c437dcdffea88f367d0ff4efed2a..a848298c57326969f3cfe5a164d3352720df40c4 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-RCSID("$Id$");
-#endif
 
 #include <stdio.h>
 #include <ctype.h>
 
 #include <stdio.h>
 #include <ctype.h>
index f358a5b26621245a53fd85b7699f455528a587c5..a74e438cf8316c3a44c5cfed5003b5d48f17abfb 100644 (file)
@@ -31,9 +31,9 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
+
 #include <config.h>
 #include <config.h>
-#endif
+
 #include "roken.h"
 #ifdef HAVE_ARPA_NAMESER_H
 #include <arpa/nameser.h>
 #include "roken.h"
 #ifdef HAVE_ARPA_NAMESER_H
 #include <arpa/nameser.h>
@@ -41,6 +41,9 @@
 #ifdef HAVE_RESOLV_H
 #include <resolv.h>
 #endif
 #ifdef HAVE_RESOLV_H
 #include <resolv.h>
 #endif
+#ifdef HAVE_DNS_H
+#include <dns.h>
+#endif
 #include "resolve.h"
 
 #include <assert.h>
 #include "resolve.h"
 
 #include <assert.h>
@@ -78,7 +81,7 @@ static struct stot{
 int _resolve_debug = 0;
 
 int ROKEN_LIB_FUNCTION
 int _resolve_debug = 0;
 
 int ROKEN_LIB_FUNCTION
-dns_string_to_type(const char *name)
+rk_dns_string_to_type(const char *name)
 {
     struct stot *p = stot;
     for(p = stot; p->name; p++)
 {
     struct stot *p = stot;
     for(p = stot; p->name; p++)
@@ -88,7 +91,7 @@ dns_string_to_type(const char *name)
 }
 
 const char * ROKEN_LIB_FUNCTION
 }
 
 const char * ROKEN_LIB_FUNCTION
-dns_type_to_string(int type)
+rk_dns_type_to_string(int type)
 {
     struct stot *p = stot;
     for(p = stot; p->name; p++)
 {
     struct stot *p = stot;
     for(p = stot; p->name; p++)
@@ -100,7 +103,7 @@ dns_type_to_string(int type)
 #if (defined(HAVE_RES_SEARCH) || defined(HAVE_RES_NSEARCH)) && defined(HAVE_DN_EXPAND)
 
 static void
 #if (defined(HAVE_RES_SEARCH) || defined(HAVE_RES_NSEARCH)) && defined(HAVE_DN_EXPAND)
 
 static void
-dns_free_rr(struct resource_record *rr)
+dns_free_rr(struct rk_resource_record *rr)
 {
     if(rr->domain)
        free(rr->domain);
 {
     if(rr->domain)
        free(rr->domain);
@@ -110,13 +113,13 @@ dns_free_rr(struct resource_record *rr)
 }
 
 void ROKEN_LIB_FUNCTION
 }
 
 void ROKEN_LIB_FUNCTION
-dns_free_data(struct dns_reply *r)
+rk_dns_free_data(struct rk_dns_reply *r)
 {
 {
-    struct resource_record *rr;
+    struct rk_resource_record *rr;
     if(r->q.domain)
        free(r->q.domain);
     for(rr = r->head; rr;){
     if(r->q.domain)
        free(r->q.domain);
     for(rr = r->head; rr;){
-       struct resource_record *tmp = rr;
+       struct rk_resource_record *tmp = rr;
        rr = rr->next;
        dns_free_rr(tmp);
     }
        rr = rr->next;
        dns_free_rr(tmp);
     }
@@ -125,9 +128,9 @@ dns_free_data(struct dns_reply *r)
 
 static int
 parse_record(const unsigned char *data, const unsigned char *end_data,
 
 static int
 parse_record(const unsigned char *data, const unsigned char *end_data,
-            const unsigned char **pp, struct resource_record **ret_rr)
+            const unsigned char **pp, struct rk_resource_record **ret_rr)
 {
 {
-    struct resource_record *rr;
+    struct rk_resource_record *rr;
     int type, class, ttl;
     unsigned size;
     int status;
     int type, class, ttl;
     unsigned size;
     int status;
@@ -401,7 +404,7 @@ parse_record(const unsigned char *data, const unsigned char *end_data,
 #ifndef TEST_RESOLVE
 static
 #endif
 #ifndef TEST_RESOLVE
 static
 #endif
-struct dns_reply*
+struct rk_dns_reply*
 parse_reply(const unsigned char *data, size_t len)
 {
     const unsigned char *p;
 parse_reply(const unsigned char *data, size_t len)
 {
     const unsigned char *p;
@@ -409,8 +412,8 @@ parse_reply(const unsigned char *data, size_t len)
     int i;
     char host[MAXDNAME];
     const unsigned char *end_data = data + len;
     int i;
     char host[MAXDNAME];
     const unsigned char *end_data = data + len;
-    struct dns_reply *r;
-    struct resource_record **rr;
+    struct rk_dns_reply *r;
+    struct rk_resource_record **rr;
 
     r = calloc(1, sizeof(*r));
     if (r == NULL)
 
     r = calloc(1, sizeof(*r));
     if (r == NULL)
@@ -449,16 +452,16 @@ parse_reply(const unsigned char *data, size_t len)
     }
     status = dn_expand(data, end_data, p, host, sizeof(host));
     if(status < 0){
     }
     status = dn_expand(data, end_data, p, host, sizeof(host));
     if(status < 0){
-       dns_free_data(r);
+       rk_dns_free_data(r);
        return NULL;
     }
     r->q.domain = strdup(host);
     if(r->q.domain == NULL) {
        return NULL;
     }
     r->q.domain = strdup(host);
     if(r->q.domain == NULL) {
-       dns_free_data(r);
+       rk_dns_free_data(r);
        return NULL;
     }
     if (p + status + 4 > end_data) {
        return NULL;
     }
     if (p + status + 4 > end_data) {
-       dns_free_data(r);
+       rk_dns_free_data(r);
        return NULL;
     }
     p += status;
        return NULL;
     }
     p += status;
@@ -470,21 +473,21 @@ parse_reply(const unsigned char *data, size_t len)
     rr = &r->head;
     for(i = 0; i < r->h.ancount; i++) {
        if(parse_record(data, end_data, &p, rr) != 0) {
     rr = &r->head;
     for(i = 0; i < r->h.ancount; i++) {
        if(parse_record(data, end_data, &p, rr) != 0) {
-           dns_free_data(r);
+           rk_dns_free_data(r);
            return NULL;
        }
        rr = &(*rr)->next;
     }
     for(i = 0; i < r->h.nscount; i++) {
        if(parse_record(data, end_data, &p, rr) != 0) {
            return NULL;
        }
        rr = &(*rr)->next;
     }
     for(i = 0; i < r->h.nscount; i++) {
        if(parse_record(data, end_data, &p, rr) != 0) {
-           dns_free_data(r);
+           rk_dns_free_data(r);
            return NULL;
        }
        rr = &(*rr)->next;
     }
     for(i = 0; i < r->h.arcount; i++) {
        if(parse_record(data, end_data, &p, rr) != 0) {
            return NULL;
        }
        rr = &(*rr)->next;
     }
     for(i = 0; i < r->h.arcount; i++) {
        if(parse_record(data, end_data, &p, rr) != 0) {
-           dns_free_data(r);
+           rk_dns_free_data(r);
            return NULL;
        }
        rr = &(*rr)->next;
            return NULL;
        }
        rr = &(*rr)->next;
@@ -501,20 +504,42 @@ parse_reply(const unsigned char *data, size_t len)
 #endif
 #endif
 
 #endif
 #endif
 
-static struct dns_reply *
+#if defined(HAVE_DNS_SEARCH)
+#define resolve_search(h,n,c,t,r,l) \
+       ((int)dns_search(h,n,c,t,r,l,(struct sockaddr *)&from,&fromsize))
+#define resolve_free_handle(h) dns_free(h)
+#elif defined(HAVE_RES_NSEARCH)
+#define resolve_search(h,n,c,t,r,l) res_nsearch(h,n,c,t,r,l)
+#define resolve_free_handle(h) rk_res_free(h);
+#else
+#define resolve_search(h,n,c,t,r,l) res_search(n,c,t,r,l)
+#define handle 0
+#define resolve_free_handle(h)
+#endif
+
+
+static struct rk_dns_reply *
 dns_lookup_int(const char *domain, int rr_class, int rr_type)
 {
 dns_lookup_int(const char *domain, int rr_class, int rr_type)
 {
-    struct dns_reply *r;
-    unsigned char *reply = NULL;
+    struct rk_dns_reply *r;
+    void *reply = NULL;
     int size;
     int len;
     int size;
     int len;
-#ifdef HAVE_RES_NSEARCH
+#if defined(HAVE_DNS_SEARCH)
+    struct sockaddr_storage from;
+    uint32_t fromsize = sizeof(from);
+    dns_handle_t handle;
+    
+    handle = dns_open(NULL);
+    if (handle == NULL)
+       return NULL;
+#elif defined(HAVE_RES_NSEARCH)
     struct __res_state state;
     struct __res_state state;
+    struct __res_state *handle = &state;
+
     memset(&state, 0, sizeof(state));
     memset(&state, 0, sizeof(state));
-    if(res_ninit(&state))
+    if(res_ninit(handle))
        return NULL; /* is this the best we can do? */
        return NULL; /* is this the best we can do? */
-#elif defined(HAVE__RES)
-    u_long old_options = 0;
 #endif
 
     size = 0;
 #endif
 
     size = 0;
@@ -527,45 +552,33 @@ dns_lookup_int(const char *domain, int rr_class, int rr_type)
        if (size <= len)
            size = len;
        if (_resolve_debug) {
        if (size <= len)
            size = len;
        if (_resolve_debug) {
-#ifdef HAVE_RES_NSEARCH
+#if defined(HAVE_DNS_SEARCH)
+           dns_set_debug(handle, 1);
+#elif defined(HAVE_RES_NSEARCH)
            state.options |= RES_DEBUG;
            state.options |= RES_DEBUG;
-#elif defined(HAVE__RES)
-           old_options = _res.options;
-           _res.options |= RES_DEBUG;
 #endif
            fprintf(stderr, "dns_lookup(%s, %d, %s), buffer size %d\n", domain,
 #endif
            fprintf(stderr, "dns_lookup(%s, %d, %s), buffer size %d\n", domain,
-                   rr_class, dns_type_to_string(rr_type), size);
+                   rr_class, rk_dns_type_to_string(rr_type), size);
        }
        reply = malloc(size);
        if (reply == NULL) {
        }
        reply = malloc(size);
        if (reply == NULL) {
-#ifdef HAVE_RES_NSEARCH
-           rk_res_free(&state);
-#endif
+           resolve_free_handle(handle);
            return NULL;
        }
            return NULL;
        }
-#ifdef HAVE_RES_NSEARCH
-       len = res_nsearch(&state, domain, rr_class, rr_type, reply, size);
-#else
-       len = res_search(domain, rr_class, rr_type, reply, size);
-#endif
+
+       len = resolve_search(handle, domain, rr_class, rr_type, reply, size);
+
        if (_resolve_debug) {
        if (_resolve_debug) {
-#if defined(HAVE__RES) && !defined(HAVE_RES_NSEARCH)
-           _res.options = old_options;
-#endif
            fprintf(stderr, "dns_lookup(%s, %d, %s) --> %d\n",
            fprintf(stderr, "dns_lookup(%s, %d, %s) --> %d\n",
-                   domain, rr_class, dns_type_to_string(rr_type), len);
+                   domain, rr_class, rk_dns_type_to_string(rr_type), len);
        }
        }
-       if (len < 0) {
-#ifdef HAVE_RES_NSEARCH
-           rk_res_free(&state);
-#endif
+       if (len <= 0) {
+           resolve_free_handle(handle);
            free(reply);
            return NULL;
        }
     } while (size < len && len < rk_DNS_MAX_PACKET_SIZE);
            free(reply);
            return NULL;
        }
     } while (size < len && len < rk_DNS_MAX_PACKET_SIZE);
-#ifdef HAVE_RES_NSEARCH
-    rk_res_free(&state);
-#endif
+    resolve_free_handle(handle);
 
     len = min(len, size);
     r = parse_reply(reply, len);
 
     len = min(len, size);
     r = parse_reply(reply, len);
@@ -573,25 +586,25 @@ dns_lookup_int(const char *domain, int rr_class, int rr_type)
     return r;
 }
 
     return r;
 }
 
-struct dns_reply * ROKEN_LIB_FUNCTION
-dns_lookup(const char *domain, const char *type_name)
+struct rk_dns_reply * ROKEN_LIB_FUNCTION
+rk_dns_lookup(const char *domain, const char *type_name)
 {
     int type;
 
 {
     int type;
 
-    type = dns_string_to_type(type_name);
+    type = rk_dns_string_to_type(type_name);
     if(type == -1) {
        if(_resolve_debug)
            fprintf(stderr, "dns_lookup: unknown resource type: `%s'\n",
                    type_name);
        return NULL;
     }
     if(type == -1) {
        if(_resolve_debug)
            fprintf(stderr, "dns_lookup: unknown resource type: `%s'\n",
                    type_name);
        return NULL;
     }
-    return dns_lookup_int(domain, C_IN, type);
+    return dns_lookup_int(domain, rk_ns_c_in, type);
 }
 
 static int
 compare_srv(const void *a, const void *b)
 {
 }
 
 static int
 compare_srv(const void *a, const void *b)
 {
-    const struct resource_record *const* aa = a, *const* bb = b;
+    const struct rk_resource_record *const* aa = a, *const* bb = b;
 
     if((*aa)->u.srv->priority == (*bb)->u.srv->priority)
        return ((*aa)->u.srv->weight - (*bb)->u.srv->weight);
 
     if((*aa)->u.srv->priority == (*bb)->u.srv->priority)
        return ((*aa)->u.srv->weight - (*bb)->u.srv->weight);
@@ -604,10 +617,10 @@ compare_srv(const void *a, const void *b)
 
 /* try to rearrange the srv-records by the algorithm in RFC2782 */
 void ROKEN_LIB_FUNCTION
 
 /* try to rearrange the srv-records by the algorithm in RFC2782 */
 void ROKEN_LIB_FUNCTION
-dns_srv_order(struct dns_reply *r)
+rk_dns_srv_order(struct rk_dns_reply *r)
 {
 {
-    struct resource_record **srvs, **ss, **headp;
-    struct resource_record *rr;
+    struct rk_resource_record **srvs, **ss, **headp;
+    struct rk_resource_record *rr;
     int num_srv = 0;
 
 #if defined(HAVE_INITSTATE) && defined(HAVE_SETSTATE)
     int num_srv = 0;
 
 #if defined(HAVE_INITSTATE) && defined(HAVE_SETSTATE)
@@ -648,7 +661,7 @@ dns_srv_order(struct dns_reply *r)
 
     for(ss = srvs; ss < srvs + num_srv; ) {
        int sum, rnd, count;
 
     for(ss = srvs; ss < srvs + num_srv; ) {
        int sum, rnd, count;
-       struct resource_record **ee, **tt;
+       struct rk_resource_record **ee, **tt;
        /* find the last record with the same priority and count the
            sum of all weights */
        for(sum = 0, tt = ss; tt < srvs + num_srv; tt++) {
        /* find the last record with the same priority and count the
            sum of all weights */
        for(sum = 0, tt = ss; tt < srvs + num_srv; tt++) {
@@ -693,19 +706,19 @@ dns_srv_order(struct dns_reply *r)
 
 #else /* NOT defined(HAVE_RES_SEARCH) && defined(HAVE_DN_EXPAND) */
 
 
 #else /* NOT defined(HAVE_RES_SEARCH) && defined(HAVE_DN_EXPAND) */
 
-struct dns_reply * ROKEN_LIB_FUNCTION
-dns_lookup(const char *domain, const char *type_name)
+struct rk_dns_reply * ROKEN_LIB_FUNCTION
+rk_dns_lookup(const char *domain, const char *type_name)
 {
     return NULL;
 }
 
 void ROKEN_LIB_FUNCTION
 {
     return NULL;
 }
 
 void ROKEN_LIB_FUNCTION
-dns_free_data(struct dns_reply *r)
+rk_dns_free_data(struct rk_dns_reply *r)
 {
 }
 
 void ROKEN_LIB_FUNCTION
 {
 }
 
 void ROKEN_LIB_FUNCTION
-dns_srv_order(struct dns_reply *r)
+rk_dns_srv_order(struct rk_dns_reply *r)
 {
 }
 
 {
 }
 
index d181dfa070cd0043087f594226a24565e6a7d74d..91b2afefe7ed0c1d1c731d998f4d2c26f469fc08 100644 (file)
 #endif
 #endif
 
 #endif
 #endif
 
-typedef enum {
+enum {
+    rk_ns_c_in = 1
+};
+
+enum {
        rk_ns_t_invalid = 0,    /* Cookie. */
        rk_ns_t_a = 1,          /* Host address. */
        rk_ns_t_ns = 2,         /* Authoritative server. */
        rk_ns_t_invalid = 0,    /* Cookie. */
        rk_ns_t_a = 1,          /* Host address. */
        rk_ns_t_ns = 2,         /* Authoritative server. */
@@ -99,99 +103,38 @@ typedef enum {
        rk_ns_t_any = 255,      /* Wildcard match. */
        rk_ns_t_zxfr = 256,     /* BIND-specific, nonstandard. */
        rk_ns_t_max = 65536
        rk_ns_t_any = 255,      /* Wildcard match. */
        rk_ns_t_zxfr = 256,     /* BIND-specific, nonstandard. */
        rk_ns_t_max = 65536
-} rk_ns_type;
-
-/* We use these, but they are not always present in <arpa/nameser.h> */
-
-#ifndef C_IN
-#define C_IN           1
-#endif
-
-#ifndef T_A
-#define T_A            1
-#endif
-#ifndef T_NS
-#define T_NS           2
-#endif
-#ifndef T_CNAME
-#define T_CNAME                5
-#endif
-#ifndef T_SOA
-#define T_SOA          5
-#endif
-#ifndef T_PTR
-#define T_PTR          12
-#endif
-#ifndef T_MX
-#define T_MX           15
-#endif
-#ifndef T_TXT
-#define T_TXT          16
-#endif
-#ifndef T_AFSDB
-#define T_AFSDB                18
-#endif
-#ifndef T_SIG
-#define T_SIG          24
-#endif
-#ifndef T_KEY
-#define T_KEY          25
-#endif
-#ifndef T_AAAA
-#define T_AAAA         28
-#endif
-#ifndef T_SRV
-#define T_SRV          33
-#endif
-#ifndef T_NAPTR
-#define T_NAPTR                35
-#endif
-#ifndef T_CERT
-#define T_CERT         37
-#endif
-#ifndef T_SSHFP
-#define T_SSHFP                44
-#endif
+};
 
 #ifndef MAXDNAME
 #define MAXDNAME       1025
 #endif
 
 
 #ifndef MAXDNAME
 #define MAXDNAME       1025
 #endif
 
-#define dns_query              rk_dns_query
 #define mx_record              rk_mx_record
 #define srv_record             rk_srv_record
 #define key_record             rk_key_record
 #define sig_record             rk_sig_record
 #define cert_record            rk_cert_record
 #define sshfp_record           rk_sshfp_record
 #define mx_record              rk_mx_record
 #define srv_record             rk_srv_record
 #define key_record             rk_key_record
 #define sig_record             rk_sig_record
 #define cert_record            rk_cert_record
 #define sshfp_record           rk_sshfp_record
-#define resource_record                rk_resource_record
-#define dns_reply              rk_dns_reply
-
-#define dns_lookup             rk_dns_lookup
-#define dns_free_data          rk_dns_free_data
-#define dns_string_to_type     rk_dns_string_to_type
-#define dns_type_to_string     rk_dns_type_to_string
-#define dns_srv_order          rk_dns_srv_order
 
 
-struct dns_query{
+struct rk_dns_query{
     char *domain;
     unsigned type;
     unsigned class;
 };
 
     char *domain;
     unsigned type;
     unsigned class;
 };
 
-struct mx_record{
+struct rk_mx_record{
     unsigned  preference;
     char domain[1];
 };
 
     unsigned  preference;
     char domain[1];
 };
 
-struct srv_record{
+struct rk_srv_record{
     unsigned priority;
     unsigned weight;
     unsigned port;
     char target[1];
 };
 
     unsigned priority;
     unsigned weight;
     unsigned port;
     char target[1];
 };
 
-struct key_record {
+struct rk_key_record {
     unsigned flags;
     unsigned protocol;
     unsigned algorithm;
     unsigned flags;
     unsigned protocol;
     unsigned algorithm;
@@ -199,7 +142,7 @@ struct key_record {
     u_char   key_data[1];
 };
 
     u_char   key_data[1];
 };
 
-struct sig_record {
+struct rk_sig_record {
     unsigned type;
     unsigned algorithm;
     unsigned labels;
     unsigned type;
     unsigned algorithm;
     unsigned labels;
@@ -212,7 +155,7 @@ struct sig_record {
     char     sig_data[1];      /* also includes signer */
 };
 
     char     sig_data[1];      /* also includes signer */
 };
 
-struct cert_record {
+struct rk_cert_record {
     unsigned type;
     unsigned tag;
     unsigned algorithm;
     unsigned type;
     unsigned tag;
     unsigned algorithm;
@@ -220,14 +163,14 @@ struct cert_record {
     u_char   cert_data[1];
 };
 
     u_char   cert_data[1];
 };
 
-struct sshfp_record {
+struct rk_sshfp_record {
     unsigned algorithm;
     unsigned type;
     size_t   sshfp_len;
     u_char   sshfp_data[1];
 };
 
     unsigned algorithm;
     unsigned type;
     size_t   sshfp_len;
     u_char   sshfp_data[1];
 };
 
-struct ds_record {
+struct rk_ds_record {
     unsigned key_tag;
     unsigned algorithm;
     unsigned digest_type;
     unsigned key_tag;
     unsigned algorithm;
     unsigned digest_type;
@@ -235,7 +178,7 @@ struct ds_record {
     u_char digest_data[1];
 };
 
     u_char digest_data[1];
 };
 
-struct resource_record{
+struct rk_resource_record{
     char *domain;
     unsigned type;
     unsigned class;
     char *domain;
     unsigned type;
     unsigned class;
@@ -243,23 +186,23 @@ struct resource_record{
     unsigned size;
     union {
        void *data;
     unsigned size;
     union {
        void *data;
-       struct mx_record *mx;
-       struct mx_record *afsdb; /* mx and afsdb are identical */
-       struct srv_record *srv;
+       struct rk_mx_record *mx;
+       struct rk_mx_record *afsdb; /* mx and afsdb are identical */
+       struct rk_srv_record *srv;
        struct in_addr *a;
        char *txt;
        struct in_addr *a;
        char *txt;
-       struct key_record *key;
-       struct cert_record *cert;
-       struct sig_record *sig;
-       struct sshfp_record *sshfp;
-       struct ds_record *ds;
+       struct rk_key_record *key;
+       struct rk_cert_record *cert;
+       struct rk_sig_record *sig;
+       struct rk_sshfp_record *sshfp;
+       struct rk_ds_record *ds;
     }u;
     }u;
-    struct resource_record *next;
+    struct rk_resource_record *next;
 };
 
 #define rk_DNS_MAX_PACKET_SIZE         0xffff
 
 };
 
 #define rk_DNS_MAX_PACKET_SIZE         0xffff
 
-struct dns_header {
+struct rk_dns_header {
     unsigned id;
     unsigned flags;
 #define rk_DNS_HEADER_RESPONSE_FLAG            1
     unsigned id;
     unsigned flags;
 #define rk_DNS_HEADER_RESPONSE_FLAG            1
@@ -277,22 +220,30 @@ struct dns_header {
     unsigned arcount;
 };
 
     unsigned arcount;
 };
 
-struct dns_reply{
-    struct dns_header h;
-    struct dns_query q;
-    struct resource_record *head;
+struct rk_dns_reply{
+    struct rk_dns_header h;
+    struct rk_dns_query q;
+    struct rk_resource_record *head;
 };
 
 
 };
 
 
-struct dns_reply* ROKEN_LIB_FUNCTION
-       dns_lookup(const char *, const char *);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct rk_dns_reply* ROKEN_LIB_FUNCTION
+       rk_dns_lookup(const char *, const char *);
 void ROKEN_LIB_FUNCTION
 void ROKEN_LIB_FUNCTION
-       dns_free_data(struct dns_reply *);
+       rk_dns_free_data(struct rk_dns_reply *);
 int ROKEN_LIB_FUNCTION
 int ROKEN_LIB_FUNCTION
-       dns_string_to_type(const char *name);
+       rk_dns_string_to_type(const char *name);
 const char *ROKEN_LIB_FUNCTION
 const char *ROKEN_LIB_FUNCTION
-       dns_type_to_string(int type);
+       rk_dns_type_to_string(int type);
 void ROKEN_LIB_FUNCTION
 void ROKEN_LIB_FUNCTION
-       dns_srv_order(struct dns_reply*);
+       rk_dns_srv_order(struct rk_dns_reply*);
+
+#ifdef __cplusplus
+}
+#endif
 
 #endif /* __RESOLVE_H__ */
 
 #endif /* __RESOLVE_H__ */
index ebc3a5d208c5723b7a63a135d76841161c9552d4..bff632f0f1f3dba2c6c912f2e0dfb1c3b52c7b5d 100644 (file)
 #include <libutil.h>
 #endif
 
 #include <libutil.h>
 #endif
 
+#ifdef STREAMSPTY
+#include <stropts.h>
+#endif /* STREAMPTY */
+
 #include "roken.h"
 #include <getarg.h>
 
 #include "roken.h"
 #include <getarg.h>
 
@@ -93,6 +97,39 @@ open_pty(void)
     if(openpty(&master, &slave, line, 0, 0) == 0)
        return;
 #endif /* HAVE_OPENPTY .... */
     if(openpty(&master, &slave, line, 0, 0) == 0)
        return;
 #endif /* HAVE_OPENPTY .... */
+#ifdef STREAMSPTY
+    {
+       char *clone[] = {
+           "/dev/ptc",
+           "/dev/ptmx", 
+           "/dev/ptm",
+           "/dev/ptym/clone", 
+           NULL
+       };
+       char **q;
+
+       for(q = clone; *q; q++){
+           master = open(*q, O_RDWR);
+           if(master >= 0){
+#ifdef HAVE_GRANTPT
+               grantpt(master);
+#endif
+#ifdef HAVE_UNLOCKPT
+               unlockpt(master);
+#endif
+               strlcpy(line, ptsname(master), sizeof(line));
+               slave = open(line, O_RDWR);
+               if (slave < 0)
+                   errx(1, "failed to open slave when using %s", q);
+               ioctl(slave, I_PUSH, "ptem");
+               ioctl(slave, I_PUSH, "ldterm");
+
+               return;
+           }
+       }
+    }
+#endif /* STREAMSPTY */
+
     /* more cases, like open /dev/ptmx, etc */
 
     exit(77);
     /* more cases, like open /dev/ptmx, etc */
 
     exit(77);
@@ -302,7 +339,6 @@ main(int argc, char **argv)
     parse_configuration(argv[0]);
 
     argv += 1;
     parse_configuration(argv[0]);
 
     argv += 1;
-    argc -= 1;
 
     open_pty();
 
 
     open_pty();
 
index 1d341258fe1f6b7603d9a828c7a2a82adb234c05..1713b6609e67c1d486795f0ee0cf8d2f31674604 100644 (file)
@@ -267,119 +267,154 @@ SigAction signal(int iSig, SigAction pAction); /* BSD compatible */
 #endif
 #endif
 
 #endif
 #endif
 
+#define simple_execve rk_simple_execve
 int ROKEN_LIB_FUNCTION
 simple_execve(const char*, char*const[], char*const[]);
 
 int ROKEN_LIB_FUNCTION
 simple_execve(const char*, char*const[], char*const[]);
 
+#define simple_execve_timed rk_simple_execve_timed
 int ROKEN_LIB_FUNCTION
 simple_execve_timed(const char *, char *const[],
                    char *const [], time_t (*)(void *),
                    void *, time_t);
 int ROKEN_LIB_FUNCTION
 simple_execve_timed(const char *, char *const[],
                    char *const [], time_t (*)(void *),
                    void *, time_t);
+
+#define simple_execvp rk_simple_execvp
 int ROKEN_LIB_FUNCTION
 simple_execvp(const char*, char *const[]);
 
 int ROKEN_LIB_FUNCTION
 simple_execvp(const char*, char *const[]);
 
+#define simple_execvp_timed rk_simple_execvp_timed
 int ROKEN_LIB_FUNCTION
 simple_execvp_timed(const char *, char *const[],
                    time_t (*)(void *), void *, time_t);
 int ROKEN_LIB_FUNCTION
 simple_execvp_timed(const char *, char *const[],
                    time_t (*)(void *), void *, time_t);
+
+#define simple_execlp rk_simple_execlp
 int ROKEN_LIB_FUNCTION
 simple_execlp(const char*, ...);
 
 int ROKEN_LIB_FUNCTION
 simple_execlp(const char*, ...);
 
+#define simple_execle rk_simple_execle
 int ROKEN_LIB_FUNCTION
 simple_execle(const char*, ...);
 
 int ROKEN_LIB_FUNCTION
 simple_execle(const char*, ...);
 
-int ROKEN_LIB_FUNCTION
-simple_execl(const char *file, ...);
-
+#define wait_for_process rk_wait_for_process
 int ROKEN_LIB_FUNCTION
 wait_for_process(pid_t);
 
 int ROKEN_LIB_FUNCTION
 wait_for_process(pid_t);
 
+#define wait_for_process_timed rk_wait_for_process_timed
 int ROKEN_LIB_FUNCTION
 wait_for_process_timed(pid_t, time_t (*)(void *),
                                              void *, time_t);
 int ROKEN_LIB_FUNCTION
 wait_for_process_timed(pid_t, time_t (*)(void *),
                                              void *, time_t);
+#define pipe_execv rk_pipe_execv
 int ROKEN_LIB_FUNCTION
 pipe_execv(FILE**, FILE**, FILE**, const char*, ...);
 
 int ROKEN_LIB_FUNCTION
 pipe_execv(FILE**, FILE**, FILE**, const char*, ...);
 
+#define print_version rk_print_version
 void ROKEN_LIB_FUNCTION
 print_version(const char *);
 
 void ROKEN_LIB_FUNCTION
 print_version(const char *);
 
+#define eread rk_eread
 ssize_t ROKEN_LIB_FUNCTION
 eread (int fd, void *buf, size_t nbytes);
 
 ssize_t ROKEN_LIB_FUNCTION
 eread (int fd, void *buf, size_t nbytes);
 
+#define ewrite rk_ewrite
 ssize_t ROKEN_LIB_FUNCTION
 ewrite (int fd, const void *buf, size_t nbytes);
 
 struct hostent;
 
 ssize_t ROKEN_LIB_FUNCTION
 ewrite (int fd, const void *buf, size_t nbytes);
 
 struct hostent;
 
+#define hostent_find_fqdn rk_hostent_find_fqdn
 const char * ROKEN_LIB_FUNCTION
 hostent_find_fqdn (const struct hostent *);
 
 const char * ROKEN_LIB_FUNCTION
 hostent_find_fqdn (const struct hostent *);
 
+#define esetenv rk_esetenv
 void ROKEN_LIB_FUNCTION
 esetenv(const char *, const char *, int);
 
 void ROKEN_LIB_FUNCTION
 esetenv(const char *, const char *, int);
 
+#define socket_set_address_and_port rk_socket_set_address_and_port
 void ROKEN_LIB_FUNCTION
 socket_set_address_and_port (struct sockaddr *, const void *, int);
 
 void ROKEN_LIB_FUNCTION
 socket_set_address_and_port (struct sockaddr *, const void *, int);
 
+#define socket_addr_size rk_socket_addr_size
 size_t ROKEN_LIB_FUNCTION
 socket_addr_size (const struct sockaddr *);
 
 size_t ROKEN_LIB_FUNCTION
 socket_addr_size (const struct sockaddr *);
 
+#define socket_set_any rk_socket_set_any
 void ROKEN_LIB_FUNCTION
 socket_set_any (struct sockaddr *, int);
 
 void ROKEN_LIB_FUNCTION
 socket_set_any (struct sockaddr *, int);
 
+#define socket_sockaddr_size rk_socket_sockaddr_size
 size_t ROKEN_LIB_FUNCTION
 socket_sockaddr_size (const struct sockaddr *);
 
 size_t ROKEN_LIB_FUNCTION
 socket_sockaddr_size (const struct sockaddr *);
 
+#define socket_get_address rk_socket_get_address
 void * ROKEN_LIB_FUNCTION
 void * ROKEN_LIB_FUNCTION
-socket_get_address (struct sockaddr *);
+socket_get_address (const struct sockaddr *);
 
 
+#define socket_get_port rk_socket_get_port
 int ROKEN_LIB_FUNCTION
 socket_get_port (const struct sockaddr *);
 
 int ROKEN_LIB_FUNCTION
 socket_get_port (const struct sockaddr *);
 
+#define socket_set_port rk_socket_set_port
 void ROKEN_LIB_FUNCTION
 socket_set_port (struct sockaddr *, int);
 
 void ROKEN_LIB_FUNCTION
 socket_set_port (struct sockaddr *, int);
 
+#define socket_set_portrange rk_socket_set_portrange
 void ROKEN_LIB_FUNCTION
 socket_set_portrange (int, int, int);
 
 void ROKEN_LIB_FUNCTION
 socket_set_portrange (int, int, int);
 
+#define socket_set_debug rk_socket_set_debug
 void ROKEN_LIB_FUNCTION
 socket_set_debug (int);
 
 void ROKEN_LIB_FUNCTION
 socket_set_debug (int);
 
+#define socket_set_tos rk_socket_set_tos
 void ROKEN_LIB_FUNCTION
 socket_set_tos (int, int);
 
 void ROKEN_LIB_FUNCTION
 socket_set_tos (int, int);
 
+#define socket_set_reuseaddr rk_socket_set_reuseaddr
 void ROKEN_LIB_FUNCTION
 socket_set_reuseaddr (int, int);
 
 void ROKEN_LIB_FUNCTION
 socket_set_reuseaddr (int, int);
 
+#define socket_set_ipv6only rk_socket_set_ipv6only
 void ROKEN_LIB_FUNCTION
 socket_set_ipv6only (int, int);
 
 void ROKEN_LIB_FUNCTION
 socket_set_ipv6only (int, int);
 
+#define vstrcollect rk_vstrcollect
 char ** ROKEN_LIB_FUNCTION
 vstrcollect(va_list *ap);
 
 char ** ROKEN_LIB_FUNCTION
 vstrcollect(va_list *ap);
 
+#define strcollect rk_strcollect
 char ** ROKEN_LIB_FUNCTION
 strcollect(char *first, ...);
 
 char ** ROKEN_LIB_FUNCTION
 strcollect(char *first, ...);
 
+#define timevalfix rk_timevalfix
 void ROKEN_LIB_FUNCTION
 timevalfix(struct timeval *t1);
 
 void ROKEN_LIB_FUNCTION
 timevalfix(struct timeval *t1);
 
+#define timevaladd rk_timevaladd
 void ROKEN_LIB_FUNCTION
 timevaladd(struct timeval *t1, const struct timeval *t2);
 
 void ROKEN_LIB_FUNCTION
 timevaladd(struct timeval *t1, const struct timeval *t2);
 
+#define timevalsub rk_timevalsub
 void ROKEN_LIB_FUNCTION
 timevalsub(struct timeval *t1, const struct timeval *t2);
 
 void ROKEN_LIB_FUNCTION
 timevalsub(struct timeval *t1, const struct timeval *t2);
 
+#define pid_file_write rk_pid_file_write
 char *ROKEN_LIB_FUNCTION
 pid_file_write (const char *progname);
 
 char *ROKEN_LIB_FUNCTION
 pid_file_write (const char *progname);
 
+#define pid_file_delete rk_pid_file_delete
 void ROKEN_LIB_FUNCTION
 pid_file_delete (char **);
 
 void ROKEN_LIB_FUNCTION
 pid_file_delete (char **);
 
+#define read_environment rk_read_environment
 int ROKEN_LIB_FUNCTION
 read_environment(const char *file, char ***env);
 
 int ROKEN_LIB_FUNCTION
 read_environment(const char *file, char ***env);
 
+#define free_environment rk_free_environment
 void ROKEN_LIB_FUNCTION
 free_environment(char **);
 
 void ROKEN_LIB_FUNCTION
 free_environment(char **);
 
+#define warnerr rk_warnerr
 void ROKEN_LIB_FUNCTION
 void ROKEN_LIB_FUNCTION
-warnerr(int doerrno, const char *fmt, va_list ap)
+rk_warnerr(int doerrno, const char *fmt, va_list ap)
     __attribute__ ((format (printf, 2, 0)));
 
 void * ROKEN_LIB_FUNCTION
     __attribute__ ((format (printf, 2, 0)));
 
 void * ROKEN_LIB_FUNCTION
index d71bee7b46af29c9d0c77d0901ce73aaa32d4d71..3fce136875ebfc6dacf920ec0b9fefe55d6e038f 100644 (file)
@@ -125,9 +125,6 @@ struct sockaddr_dl;
 #else
 #include <time.h>
 #endif
 #else
 #include <time.h>
 #endif
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
 
 #ifdef HAVE_PATHS_H
 #include <paths.h>
 
 #ifdef HAVE_PATHS_H
 #include <paths.h>
@@ -152,82 +149,125 @@ ROKEN_CPP_START
 #endif
 
 #ifndef HAVE_PUTENV
 #endif
 
 #ifndef HAVE_PUTENV
+#define putenv rk_putenv
 int ROKEN_LIB_FUNCTION putenv(const char *);
 #endif
 
 #if !defined(HAVE_SETENV) || defined(NEED_SETENV_PROTO)
 int ROKEN_LIB_FUNCTION putenv(const char *);
 #endif
 
 #if !defined(HAVE_SETENV) || defined(NEED_SETENV_PROTO)
+#ifndef HAVE_SETENV
+#define setenv rk_setenv
+#endif
 int ROKEN_LIB_FUNCTION setenv(const char *, const char *, int);
 #endif
 
 #if !defined(HAVE_UNSETENV) || defined(NEED_UNSETENV_PROTO)
 int ROKEN_LIB_FUNCTION setenv(const char *, const char *, int);
 #endif
 
 #if !defined(HAVE_UNSETENV) || defined(NEED_UNSETENV_PROTO)
+#ifndef HAVE_UNSETENV
+#define unsetenv rk_unsetenv
+#endif
 void ROKEN_LIB_FUNCTION unsetenv(const char *);
 #endif
 
 #if !defined(HAVE_GETUSERSHELL) || defined(NEED_GETUSERSHELL_PROTO)
 void ROKEN_LIB_FUNCTION unsetenv(const char *);
 #endif
 
 #if !defined(HAVE_GETUSERSHELL) || defined(NEED_GETUSERSHELL_PROTO)
+#ifndef HAVE_GETUSERSHELL
+#define getusershell rk_getusershell
+#define endusershell rk_endusershell
+#endif
 char * ROKEN_LIB_FUNCTION getusershell(void);
 void ROKEN_LIB_FUNCTION endusershell(void);
 #endif
 
 #if !defined(HAVE_SNPRINTF) || defined(NEED_SNPRINTF_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 *, ...)
+#ifndef HAVE_SNPRINTF
+#define snprintf rk_snprintf
+#endif
+int ROKEN_LIB_FUNCTION
+     rk_snprintf (char *, size_t, const char *, ...)
      __attribute__ ((format (printf, 3, 4)));
 #endif
 
 #if !defined(HAVE_VSNPRINTF) || defined(NEED_VSNPRINTF_PROTO)
      __attribute__ ((format (printf, 3, 4)));
 #endif
 
 #if !defined(HAVE_VSNPRINTF) || defined(NEED_VSNPRINTF_PROTO)
+#ifndef HAVE_VSNPRINTF
+#define vsnprintf rk_vsnprintf
+#endif
 int ROKEN_LIB_FUNCTION 
 int ROKEN_LIB_FUNCTION 
-     vsnprintf (char *, size_t, const char *, va_list)
+     rk_vsnprintf (char *, size_t, const char *, va_list)
      __attribute__((format (printf, 3, 0)));
 #endif
 
 #if !defined(HAVE_ASPRINTF) || defined(NEED_ASPRINTF_PROTO)
      __attribute__((format (printf, 3, 0)));
 #endif
 
 #if !defined(HAVE_ASPRINTF) || defined(NEED_ASPRINTF_PROTO)
+#ifndef HAVE_ASPRINTF
+#define asprintf rk_asprintf
+#endif
 int ROKEN_LIB_FUNCTION
 int ROKEN_LIB_FUNCTION
-     asprintf (char **, const char *, ...)
+     rk_asprintf (char **, const char *, ...)
      __attribute__ ((format (printf, 2, 3)));
 #endif
 
 #if !defined(HAVE_VASPRINTF) || defined(NEED_VASPRINTF_PROTO)
      __attribute__ ((format (printf, 2, 3)));
 #endif
 
 #if !defined(HAVE_VASPRINTF) || defined(NEED_VASPRINTF_PROTO)
+#ifndef HAVE_VASPRINTF
+#define vasprintf rk_vasprintf
+#endif
 int ROKEN_LIB_FUNCTION
 int ROKEN_LIB_FUNCTION
-    vasprintf (char **, const char *, va_list)
+    rk_vasprintf (char **, const char *, va_list)
      __attribute__((format (printf, 2, 0)));
 #endif
 
 #if !defined(HAVE_ASNPRINTF) || defined(NEED_ASNPRINTF_PROTO)
      __attribute__((format (printf, 2, 0)));
 #endif
 
 #if !defined(HAVE_ASNPRINTF) || defined(NEED_ASNPRINTF_PROTO)
+#ifndef HAVE_ASNPRINTF
+#define asnprintf rk_asnprintf
+#endif
 int ROKEN_LIB_FUNCTION
 int ROKEN_LIB_FUNCTION
-    asnprintf (char **, size_t, const char *, ...)
+    rk_asnprintf (char **, size_t, const char *, ...)
      __attribute__ ((format (printf, 3, 4)));
 #endif
 
 #if !defined(HAVE_VASNPRINTF) || defined(NEED_VASNPRINTF_PROTO)
      __attribute__ ((format (printf, 3, 4)));
 #endif
 
 #if !defined(HAVE_VASNPRINTF) || defined(NEED_VASNPRINTF_PROTO)
+#ifndef HAVE_VASNPRINTF
+#define vasnprintf rk_vasnprintf
+#endif
 int ROKEN_LIB_FUNCTION
     vasnprintf (char **, size_t, const char *, va_list)
      __attribute__((format (printf, 3, 0)));
 #endif
 
 #ifndef HAVE_STRDUP
 int ROKEN_LIB_FUNCTION
     vasnprintf (char **, size_t, const char *, va_list)
      __attribute__((format (printf, 3, 0)));
 #endif
 
 #ifndef HAVE_STRDUP
+#define strdup rk_strdup
 char * ROKEN_LIB_FUNCTION strdup(const char *);
 #endif
 
 #if !defined(HAVE_STRNDUP) || defined(NEED_STRNDUP_PROTO)
 char * ROKEN_LIB_FUNCTION strdup(const char *);
 #endif
 
 #if !defined(HAVE_STRNDUP) || defined(NEED_STRNDUP_PROTO)
+#ifndef HAVE_STRNDUP
+#define strndup rk_strndup
+#endif
 char * ROKEN_LIB_FUNCTION strndup(const char *, size_t);
 #endif
 
 #ifndef HAVE_STRLWR
 char * ROKEN_LIB_FUNCTION strndup(const char *, size_t);
 #endif
 
 #ifndef HAVE_STRLWR
+#define strlwr rk_strlwr
 char * ROKEN_LIB_FUNCTION strlwr(char *);
 #endif
 
 #ifndef HAVE_STRNLEN
 char * ROKEN_LIB_FUNCTION strlwr(char *);
 #endif
 
 #ifndef HAVE_STRNLEN
+#define strnlen rk_strnlen
 size_t ROKEN_LIB_FUNCTION strnlen(const char*, size_t);
 #endif
 
 #if !defined(HAVE_STRSEP) || defined(NEED_STRSEP_PROTO)
 size_t ROKEN_LIB_FUNCTION strnlen(const char*, size_t);
 #endif
 
 #if !defined(HAVE_STRSEP) || defined(NEED_STRSEP_PROTO)
+#ifndef HAVE_STRSEP
+#define strsep rk_strsep
+#endif
 char * ROKEN_LIB_FUNCTION strsep(char**, const char*);
 #endif
 
 #if !defined(HAVE_STRSEP_COPY) || defined(NEED_STRSEP_COPY_PROTO)
 char * ROKEN_LIB_FUNCTION strsep(char**, const char*);
 #endif
 
 #if !defined(HAVE_STRSEP_COPY) || defined(NEED_STRSEP_COPY_PROTO)
+#ifndef HAVE_STRSEP_COPY
+#define strsep_copy rk_strsep_copy
+#endif
 ssize_t ROKEN_LIB_FUNCTION strsep_copy(const char**, const char*, char*, size_t);
 #endif
 
 #ifndef HAVE_STRCASECMP
 ssize_t ROKEN_LIB_FUNCTION strsep_copy(const char**, const char*, char*, size_t);
 #endif
 
 #ifndef HAVE_STRCASECMP
+#define strcasecmp rk_strcasecmp
 int ROKEN_LIB_FUNCTION strcasecmp(const char *, const char *);
 #endif
 
 int ROKEN_LIB_FUNCTION strcasecmp(const char *, const char *);
 #endif
 
@@ -240,26 +280,34 @@ char * ROKEN_LIB_FUNCTION strtok_r(char *, const char *, char **);
 #endif
 
 #ifndef HAVE_STRUPR
 #endif
 
 #ifndef HAVE_STRUPR
+#define strupr rk_strupr
 char * ROKEN_LIB_FUNCTION strupr(char *);
 #endif
 
 #ifndef HAVE_STRLCPY
 char * ROKEN_LIB_FUNCTION strupr(char *);
 #endif
 
 #ifndef HAVE_STRLCPY
+#define strlcpy rk_strlcpy
 size_t ROKEN_LIB_FUNCTION strlcpy (char *, const char *, size_t);
 #endif
 
 #ifndef HAVE_STRLCAT
 size_t ROKEN_LIB_FUNCTION strlcpy (char *, const char *, size_t);
 #endif
 
 #ifndef HAVE_STRLCAT
+#define strlcat rk_strlcat
 size_t ROKEN_LIB_FUNCTION strlcat (char *, const char *, size_t);
 #endif
 
 #ifndef HAVE_GETDTABLESIZE
 size_t ROKEN_LIB_FUNCTION strlcat (char *, const char *, size_t);
 #endif
 
 #ifndef HAVE_GETDTABLESIZE
+#define getdtablesize rk_getdtablesize
 int ROKEN_LIB_FUNCTION getdtablesize(void);
 #endif
 
 #if !defined(HAVE_STRERROR) && !defined(strerror)
 int ROKEN_LIB_FUNCTION getdtablesize(void);
 #endif
 
 #if !defined(HAVE_STRERROR) && !defined(strerror)
+#define strerror rk_strerror
 char * ROKEN_LIB_FUNCTION strerror(int);
 #endif
 
 #if !defined(HAVE_HSTRERROR) || defined(NEED_HSTRERROR_PROTO)
 char * ROKEN_LIB_FUNCTION strerror(int);
 #endif
 
 #if !defined(HAVE_HSTRERROR) || defined(NEED_HSTRERROR_PROTO)
+#ifndef HAVE_HSTRERROR
+#define hstrerror rk_hstrerror
+#endif
 /* This causes a fatal error under Psoriasis */
 #if !(defined(SunOS) && (SunOS >= 50))
 const char * ROKEN_LIB_FUNCTION hstrerror(int);
 /* This causes a fatal error under Psoriasis */
 #if !(defined(SunOS) && (SunOS >= 50))
 const char * ROKEN_LIB_FUNCTION hstrerror(int);
@@ -271,20 +319,26 @@ extern int h_errno;
 #endif
 
 #if !defined(HAVE_INET_ATON) || defined(NEED_INET_ATON_PROTO)
 #endif
 
 #if !defined(HAVE_INET_ATON) || defined(NEED_INET_ATON_PROTO)
+#ifndef HAVE_INET_ATON
+#define inet_aton rk_inet_aton
+#endif
 int ROKEN_LIB_FUNCTION inet_aton(const char *, struct in_addr *);
 #endif
 
 #ifndef HAVE_INET_NTOP
 int ROKEN_LIB_FUNCTION inet_aton(const char *, struct in_addr *);
 #endif
 
 #ifndef HAVE_INET_NTOP
+#define inet_ntop rk_inet_ntop
 const char * ROKEN_LIB_FUNCTION
 inet_ntop(int af, const void *src, char *dst, size_t size);
 #endif
 
 #ifndef HAVE_INET_PTON
 const char * ROKEN_LIB_FUNCTION
 inet_ntop(int af, const void *src, char *dst, size_t size);
 #endif
 
 #ifndef HAVE_INET_PTON
+#define inet_pton rk_inet_pton
 int ROKEN_LIB_FUNCTION
 inet_pton(int, const char *, void *);
 #endif
 
 #if !defined(HAVE_GETCWD)
 int ROKEN_LIB_FUNCTION
 inet_pton(int, const char *, void *);
 #endif
 
 #if !defined(HAVE_GETCWD)
+#define getcwd rk_getcwd
 char* ROKEN_LIB_FUNCTION getcwd(char *, size_t);
 #endif
 
 char* ROKEN_LIB_FUNCTION getcwd(char *, size_t);
 #endif
 
@@ -297,91 +351,108 @@ struct passwd * ROKEN_LIB_FUNCTION k_getpwuid (uid_t);
 const char * ROKEN_LIB_FUNCTION get_default_username (void);
 
 #ifndef HAVE_SETEUID
 const char * ROKEN_LIB_FUNCTION get_default_username (void);
 
 #ifndef HAVE_SETEUID
+#define seteuid rk_seteuid
 int ROKEN_LIB_FUNCTION seteuid(uid_t);
 #endif
 
 #ifndef HAVE_SETEGID
 int ROKEN_LIB_FUNCTION seteuid(uid_t);
 #endif
 
 #ifndef HAVE_SETEGID
+#define setegid rk_setegid
 int ROKEN_LIB_FUNCTION setegid(gid_t);
 #endif
 
 #ifndef HAVE_LSTAT
 int ROKEN_LIB_FUNCTION setegid(gid_t);
 #endif
 
 #ifndef HAVE_LSTAT
+#define lstat rk_lstat
 int ROKEN_LIB_FUNCTION lstat(const char *, struct stat *);
 #endif
 
 #if !defined(HAVE_MKSTEMP) || defined(NEED_MKSTEMP_PROTO)
 int ROKEN_LIB_FUNCTION lstat(const char *, struct stat *);
 #endif
 
 #if !defined(HAVE_MKSTEMP) || defined(NEED_MKSTEMP_PROTO)
+#ifndef HAVE_MKSTEMP
+#define mkstemp rk_mkstemp
+#endif
 int ROKEN_LIB_FUNCTION mkstemp(char *);
 #endif
 
 #ifndef HAVE_CGETENT
 int ROKEN_LIB_FUNCTION mkstemp(char *);
 #endif
 
 #ifndef HAVE_CGETENT
+#define cgetent rk_cgetent
+#define cgetstr rk_cgetstr
 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 cgetent(char **, char **, const char *);
 int ROKEN_LIB_FUNCTION cgetstr(char *, const char *, char **);
 #endif
 
 #ifndef HAVE_INITGROUPS
+#define initgroups rk_initgroups
 int ROKEN_LIB_FUNCTION initgroups(const char *, gid_t);
 #endif
 
 #ifndef HAVE_FCHOWN
 int ROKEN_LIB_FUNCTION initgroups(const char *, gid_t);
 #endif
 
 #ifndef HAVE_FCHOWN
+#define fchown rk_fchown
 int ROKEN_LIB_FUNCTION fchown(int, uid_t, gid_t);
 #endif
 
 #if !defined(HAVE_DAEMON) || defined(NEED_DAEMON_PROTO)
 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);
+#ifndef HAVE_DAEMON
+#define daemon rk_daemon
 #endif
 #endif
-
-#ifndef HAVE_INNETGR
-int ROKEN_LIB_FUNCTION innetgr(const char *, const char *, 
-           const char *, const char *);
+int ROKEN_LIB_FUNCTION daemon(int, int);
 #endif
 
 #ifndef HAVE_CHOWN
 #endif
 
 #ifndef HAVE_CHOWN
+#define chown rk_chown
 int ROKEN_LIB_FUNCTION chown(const char *, uid_t, gid_t);
 #endif
 
 #ifndef HAVE_RCMD
 int ROKEN_LIB_FUNCTION chown(const char *, uid_t, gid_t);
 #endif
 
 #ifndef HAVE_RCMD
+#define rcmd rk_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
     rcmd(char **, unsigned short, const char *,
         const char *, const char *, int *);
 #endif
 
 #if !defined(HAVE_INNETGR) || defined(NEED_INNETGR_PROTO)
+#ifndef HAVE_INNETGR
+#define innetgr rk_innetgr
+#endif
 int ROKEN_LIB_FUNCTION innetgr(const char*, const char*,
     const char*, const char*);
 #endif
 
 #ifndef HAVE_IRUSEROK
 int ROKEN_LIB_FUNCTION innetgr(const char*, const char*,
     const char*, const char*);
 #endif
 
 #ifndef HAVE_IRUSEROK
+#define iruserok rk_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 iruserok(unsigned, int, 
     const char *, const char *);
 #endif
 
 #if !defined(HAVE_GETHOSTNAME) || defined(NEED_GETHOSTNAME_PROTO)
+#ifndef HAVE_GETHOSTNAME
+#define gethostname rk_gethostname
+#endif
 int ROKEN_LIB_FUNCTION gethostname(char *, int);
 #endif
 
 #ifndef HAVE_WRITEV
 int ROKEN_LIB_FUNCTION gethostname(char *, int);
 #endif
 
 #ifndef HAVE_WRITEV
+#define writev rk_writev
 ssize_t ROKEN_LIB_FUNCTION
 writev(int, const struct iovec *, int);
 #endif
 
 #ifndef HAVE_READV
 ssize_t ROKEN_LIB_FUNCTION
 writev(int, const struct iovec *, int);
 #endif
 
 #ifndef HAVE_READV
+#define readv rk_readv
 ssize_t ROKEN_LIB_FUNCTION
 readv(int, const struct iovec *, int);
 #endif
 
 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
 #ifndef HAVE_PIDFILE
+#define pidfile rk_pidfile
 void ROKEN_LIB_FUNCTION pidfile (const char*);
 #endif
 
 #ifndef HAVE_BSWAP32
 void ROKEN_LIB_FUNCTION pidfile (const char*);
 #endif
 
 #ifndef HAVE_BSWAP32
+#define bswap32 rk_bswap32
 unsigned int ROKEN_LIB_FUNCTION bswap32(unsigned int);
 #endif
 
 #ifndef HAVE_BSWAP16
 unsigned int ROKEN_LIB_FUNCTION bswap32(unsigned int);
 #endif
 
 #ifndef HAVE_BSWAP16
+#define bswap16 rk_bswap16
 unsigned short ROKEN_LIB_FUNCTION bswap16(unsigned short);
 #endif
 
 unsigned short ROKEN_LIB_FUNCTION bswap16(unsigned short);
 #endif
 
@@ -399,6 +470,7 @@ unsigned short ROKEN_LIB_FUNCTION bswap16(unsigned short);
 #define LOCK_UN   8            /* Unlock */
 #endif
 
 #define LOCK_UN   8            /* Unlock */
 #endif
 
+#define flock rk_flock
 int flock(int fd, int operation);
 #endif /* HAVE_FLOCK */
 
 int flock(int fd, int operation);
 #endif /* HAVE_FLOCK */
 
@@ -431,6 +503,7 @@ struct winsize {
 int ROKEN_LIB_FUNCTION get_window_size(int fd, struct winsize *);
 
 #ifndef HAVE_VSYSLOG
 int ROKEN_LIB_FUNCTION get_window_size(int fd, struct winsize *);
 
 #ifndef HAVE_VSYSLOG
+#define vsyslog rk_vsyslog
 void ROKEN_LIB_FUNCTION vsyslog(int, const char *, va_list);
 #endif
 
 void ROKEN_LIB_FUNCTION vsyslog(int, const char *, va_list);
 #endif
 
@@ -445,21 +518,25 @@ extern int opterr;
 #endif
 
 #ifndef HAVE_GETIPNODEBYNAME
 #endif
 
 #ifndef HAVE_GETIPNODEBYNAME
+#define getipnodebyname rk_getipnodebyname
 struct hostent * ROKEN_LIB_FUNCTION
 getipnodebyname (const char *, int, int, int *);
 #endif
 
 #ifndef HAVE_GETIPNODEBYADDR
 struct hostent * ROKEN_LIB_FUNCTION
 getipnodebyname (const char *, int, int, int *);
 #endif
 
 #ifndef HAVE_GETIPNODEBYADDR
+#define getipnodebyaddr rk_getipnodebyaddr
 struct hostent * ROKEN_LIB_FUNCTION
 getipnodebyaddr (const void *, size_t, int, int *);
 #endif
 
 #ifndef HAVE_FREEHOSTENT
 struct hostent * ROKEN_LIB_FUNCTION
 getipnodebyaddr (const void *, size_t, int, int *);
 #endif
 
 #ifndef HAVE_FREEHOSTENT
+#define freehostent rk_freehostent
 void ROKEN_LIB_FUNCTION
 freehostent (struct hostent *);
 #endif
 
 #ifndef HAVE_COPYHOSTENT
 void ROKEN_LIB_FUNCTION
 freehostent (struct hostent *);
 #endif
 
 #ifndef HAVE_COPYHOSTENT
+#define copyhostent rk_copyhostent
 struct hostent * ROKEN_LIB_FUNCTION
 copyhostent (const struct hostent *);
 #endif
 struct hostent * ROKEN_LIB_FUNCTION
 copyhostent (const struct hostent *);
 #endif
@@ -527,6 +604,7 @@ struct addrinfo {
 #endif
 
 #ifndef HAVE_GETADDRINFO
 #endif
 
 #ifndef HAVE_GETADDRINFO
+#define getaddrinfo rk_getaddrinfo
 int ROKEN_LIB_FUNCTION
 getaddrinfo(const char *,
            const char *,
 int ROKEN_LIB_FUNCTION
 getaddrinfo(const char *,
            const char *,
@@ -535,6 +613,7 @@ getaddrinfo(const char *,
 #endif
 
 #ifndef HAVE_GETNAMEINFO
 #endif
 
 #ifndef HAVE_GETNAMEINFO
+#define getnameinfo rk_getnameinfo
 int ROKEN_LIB_FUNCTION
 getnameinfo(const struct sockaddr *, socklen_t,
                char *, size_t,
 int ROKEN_LIB_FUNCTION
 getnameinfo(const struct sockaddr *, socklen_t,
                char *, size_t,
@@ -543,11 +622,13 @@ getnameinfo(const struct sockaddr *, socklen_t,
 #endif
 
 #ifndef HAVE_FREEADDRINFO
 #endif
 
 #ifndef HAVE_FREEADDRINFO
+#define freeaddrinfo rk_freeaddrinfo
 void ROKEN_LIB_FUNCTION
 freeaddrinfo(struct addrinfo *);
 #endif
 
 #ifndef HAVE_GAI_STRERROR
 void ROKEN_LIB_FUNCTION
 freeaddrinfo(struct addrinfo *);
 #endif
 
 #ifndef HAVE_GAI_STRERROR
+#define gai_strerror rk_gai_strerror
 const char * ROKEN_LIB_FUNCTION
 gai_strerror(int);
 #endif
 const char * ROKEN_LIB_FUNCTION
 gai_strerror(int);
 #endif
@@ -564,25 +645,31 @@ int ROKEN_LIB_FUNCTION
 roken_getaddrinfo_hostspec2(const char *, int, int, struct addrinfo **);
 
 #ifndef HAVE_STRFTIME
 roken_getaddrinfo_hostspec2(const char *, int, int, struct addrinfo **);
 
 #ifndef HAVE_STRFTIME
+#define strftime rk_strftime
 size_t ROKEN_LIB_FUNCTION
 strftime (char *, size_t, const char *, const struct tm *);
 #endif
 
 #ifndef HAVE_STRPTIME
 size_t ROKEN_LIB_FUNCTION
 strftime (char *, size_t, const char *, const struct tm *);
 #endif
 
 #ifndef HAVE_STRPTIME
+#define strptime rk_strptime
 char * ROKEN_LIB_FUNCTION
 strptime (const char *, const char *, struct tm *);
 #endif
 
 #ifndef HAVE_EMALLOC
 char * ROKEN_LIB_FUNCTION
 strptime (const char *, const char *, struct tm *);
 #endif
 
 #ifndef HAVE_EMALLOC
+#define emalloc rk_emalloc
 void * ROKEN_LIB_FUNCTION emalloc (size_t);
 #endif
 #ifndef HAVE_ECALLOC
 void * ROKEN_LIB_FUNCTION emalloc (size_t);
 #endif
 #ifndef HAVE_ECALLOC
+#define ecalloc rk_ecalloc
 void * ROKEN_LIB_FUNCTION ecalloc(size_t, size_t);
 #endif
 #ifndef HAVE_EREALLOC
 void * ROKEN_LIB_FUNCTION ecalloc(size_t, size_t);
 #endif
 #ifndef HAVE_EREALLOC
+#define erealloc rk_erealloc
 void * ROKEN_LIB_FUNCTION erealloc (void *, size_t);
 #endif
 #ifndef HAVE_ESTRDUP
 void * ROKEN_LIB_FUNCTION erealloc (void *, size_t);
 #endif
 #ifndef HAVE_ESTRDUP
+#define estrdup rk_estrdup
 char * ROKEN_LIB_FUNCTION estrdup (const char *);
 #endif
 
 char * ROKEN_LIB_FUNCTION estrdup (const char *);
 #endif
 
@@ -630,10 +717,12 @@ roken_gethostbyaddr(const void*, size_t, int);
 #endif
 
 #ifndef HAVE_SETPROGNAME
 #endif
 
 #ifndef HAVE_SETPROGNAME
+#define setprogname rk_setprogname
 void ROKEN_LIB_FUNCTION setprogname(const char *);
 #endif
 
 #ifndef HAVE_GETPROGNAME
 void ROKEN_LIB_FUNCTION setprogname(const char *);
 #endif
 
 #ifndef HAVE_GETPROGNAME
+#define getprogname rk_getprogname
 const char * ROKEN_LIB_FUNCTION getprogname(void);
 #endif
 
 const char * ROKEN_LIB_FUNCTION getprogname(void);
 #endif
 
@@ -645,46 +734,69 @@ void ROKEN_LIB_FUNCTION mini_inetd_addrinfo (struct addrinfo*);
 void ROKEN_LIB_FUNCTION mini_inetd (int);
 
 #ifndef HAVE_LOCALTIME_R
 void ROKEN_LIB_FUNCTION mini_inetd (int);
 
 #ifndef HAVE_LOCALTIME_R
+#define localtime_r rk_localtime_r
 struct tm * ROKEN_LIB_FUNCTION
 localtime_r(const time_t *, struct tm *);
 #endif
 
 #if !defined(HAVE_STRSVIS) || defined(NEED_STRSVIS_PROTO)
 struct tm * ROKEN_LIB_FUNCTION
 localtime_r(const time_t *, struct tm *);
 #endif
 
 #if !defined(HAVE_STRSVIS) || defined(NEED_STRSVIS_PROTO)
+#ifndef HAVE_STRSVIS
+#define strsvis rk_strsvis
+#endif
 int ROKEN_LIB_FUNCTION
 strsvis(char *, const char *, int, const char *);
 #endif
 
 #if !defined(HAVE_STRUNVIS) || defined(NEED_STRUNVIS_PROTO)
 int ROKEN_LIB_FUNCTION
 strsvis(char *, const char *, int, const char *);
 #endif
 
 #if !defined(HAVE_STRUNVIS) || defined(NEED_STRUNVIS_PROTO)
+#ifndef HAVE_STRUNVIS
+#define strunvis rk_strunvis
+#endif
 int ROKEN_LIB_FUNCTION
 strunvis(char *, const char *);
 #endif
 
 #if !defined(HAVE_STRVIS) || defined(NEED_STRVIS_PROTO)
 int ROKEN_LIB_FUNCTION
 strunvis(char *, const char *);
 #endif
 
 #if !defined(HAVE_STRVIS) || defined(NEED_STRVIS_PROTO)
+#ifndef HAVE_STRVIS
+#define strvis rk_strvis
+#endif
 int ROKEN_LIB_FUNCTION
 strvis(char *, const char *, int);
 #endif
 
 #if !defined(HAVE_STRVISX) || defined(NEED_STRVISX_PROTO)
 int ROKEN_LIB_FUNCTION
 strvis(char *, const char *, int);
 #endif
 
 #if !defined(HAVE_STRVISX) || defined(NEED_STRVISX_PROTO)
+#ifndef HAVE_STRVISX
+#define strvisx rk_strvisx
+#endif
 int ROKEN_LIB_FUNCTION
 strvisx(char *, const char *, size_t, int);
 #endif
 
 #if !defined(HAVE_SVIS) || defined(NEED_SVIS_PROTO)
 int ROKEN_LIB_FUNCTION
 strvisx(char *, const char *, size_t, int);
 #endif
 
 #if !defined(HAVE_SVIS) || defined(NEED_SVIS_PROTO)
+#ifndef HAVE_SVIS
+#define svis rk_svis
+#endif
 char * ROKEN_LIB_FUNCTION
 svis(char *, int, int, int, const char *);
 #endif
 
 #if !defined(HAVE_UNVIS) || defined(NEED_UNVIS_PROTO)
 char * ROKEN_LIB_FUNCTION
 svis(char *, int, int, int, const char *);
 #endif
 
 #if !defined(HAVE_UNVIS) || defined(NEED_UNVIS_PROTO)
+#ifndef HAVE_UNVIS
+#define unvis rk_unvis
+#endif
 int ROKEN_LIB_FUNCTION
 unvis(char *, int, int *, int);
 #endif
 
 #if !defined(HAVE_VIS) || defined(NEED_VIS_PROTO)
 int ROKEN_LIB_FUNCTION
 unvis(char *, int, int *, int);
 #endif
 
 #if !defined(HAVE_VIS) || defined(NEED_VIS_PROTO)
+#ifndef HAVE_VIS
+#define vis rk_vis
+#endif
 char * ROKEN_LIB_FUNCTION
 vis(char *, int, int, int);
 #endif
 
 #if !defined(HAVE_CLOSEFROM)
 char * ROKEN_LIB_FUNCTION
 vis(char *, int, int, int);
 #endif
 
 #if !defined(HAVE_CLOSEFROM)
+#define closefrom rk_closefrom
 int ROKEN_LIB_FUNCTION
 closefrom(int);
 #endif
 int ROKEN_LIB_FUNCTION
 closefrom(int);
 #endif
index 12760456a43920350742f16924bf9be4391a81d0..d87a49a04b2d63d338c45a51a54ca54d568724c7 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-RCSID("$Id$");
-#endif
 
 #include "roken.h"
 
 
 #include "roken.h"
 
index cfb7657091ddf753dea0849d174d7a4f4f4b3724..7d11a487cff6dda8ba265d994c0cc2924ecd1f90 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-RCSID ("$Id$");
-#endif
+
 #include "roken.h"
 #include "rtbl.h"
 
 #include "roken.h"
 #include "rtbl.h"
 
index 9beb07afe9ee9fe04e2ba6cb1e57dfd6a1aa10cc..225e6ae0924db97214cfb35b964c786acbaa9a32 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-RCSID("$Id$");
-#endif
 
 #include "roken.h"
 
 
 #include "roken.h"
 
index 9141ca2bb1884e28446d448387ba9b967d6bd315..19a4845435254136f10fb0bc487032d614cd9ff6 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-RCSID("$Id$");
-#endif
 
 #include <signal.h>
 #include "roken.h"
 
 #include <signal.h>
 #include "roken.h"
index 7060cb8d37dd52a0fe48d21dfa6429f2bc950a95..86dde1bad22df5913f077e85288953fd4a5370fd 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-RCSID("$Id$");
-#endif
 
 #include <stdarg.h>
 #include <stdlib.h>
 
 #include <stdarg.h>
 #include <stdlib.h>
@@ -51,10 +48,6 @@ RCSID("$Id$");
 
 #include "roken.h"
 
 
 #include "roken.h"
 
-#if !HAVE_DECL_ENVIRON
-extern char **environ;
-#endif
-
 #define EX_NOEXEC      126
 #define EX_NOTFOUND    127
 
 #define EX_NOEXEC      126
 #define EX_NOTFOUND    127
 
@@ -316,20 +309,3 @@ simple_execle(const char *file, ... /* ,char *const envp[] */)
     free(argv);
     return ret;
 }
     free(argv);
     return ret;
 }
-
-int ROKEN_LIB_FUNCTION
-simple_execl(const char *file, ...)
-{
-    va_list ap;
-    char **argv;
-    int ret;
-
-    va_start(ap, file);
-    argv = vstrcollect(&ap);
-    va_end(ap);
-    if(argv == NULL)
-       return -1;
-    ret = simple_execve(file, argv, environ);
-    free(argv);
-    return ret;
-}
index a373eb7ed2a7f156665b2ec5dc3de8729522fe8c..ab1b7ff34407f8147870d6ef7b8b5fe00bc28c5b 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-RCSID("$Id$");
-#endif
 
 #include "roken.h"
 #include <err.h>
 
 #include "roken.h"
 #include <err.h>
@@ -152,17 +149,17 @@ socket_sockaddr_size (const struct sockaddr *sa)
  */
 
 void * ROKEN_LIB_FUNCTION
  */
 
 void * ROKEN_LIB_FUNCTION
-socket_get_address (struct sockaddr *sa)
+socket_get_address (const struct sockaddr *sa)
 {
     switch (sa->sa_family) {
     case AF_INET : {
 {
     switch (sa->sa_family) {
     case AF_INET : {
-       struct sockaddr_in *sin4 = (struct sockaddr_in *)sa;
-       return &sin4->sin_addr;
+       const struct sockaddr_in *sin4 = (const struct sockaddr_in *)sa;
+       return rk_UNCONST(&sin4->sin_addr);
     }
 #ifdef HAVE_IPV6
     case AF_INET6 : {
     }
 #ifdef HAVE_IPV6
     case AF_INET6 : {
-       struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
-       return &sin6->sin6_addr;
+       const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sa;
+       return rk_UNCONST(&sin6->sin6_addr);
     }
 #endif
     default :
     }
 #endif
     default :
index a33d52134a0f32bbce02b53a17073f6128144fe9..f444d05e2546962a51c34e75be6d212ec91b5fbc 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-RCSID("$Id$");
-#endif
 
 #include <stdarg.h>
 #include <stdlib.h>
 
 #include <stdarg.h>
 #include <stdlib.h>
index ea787d81840002b2e76d3e5d8b6edcffc6473cdd..1a6634b73685495f0d3acf40c6bdfeaf76d33cd1 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-RCSID("$Id$");
-#endif
 #include <string.h>
 #include <ctype.h>
 
 #include <string.h>
 #include <ctype.h>
 
index aa80996946eb79021008ce99829a7d4316e07b0b..dc56892144ba3bc36c99be3e426604c8210d18a8 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-RCSID("$Id$");
-#endif
 
 #include <stdarg.h>
 #include <stdlib.h>
 
 #include <stdarg.h>
 #include <stdlib.h>
index 7a93fb17aa62df7462b14e5c9430555fbdfeed8e..5cbf8557a54075742b5452af51d5b671db3ad3a9 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-RCSID("$Id$");
-#endif
 
 #include <string.h>
 
 
 #include <string.h>
 
index 61b7d39c579df98118710b6fedc24da73fe53aa4..908e37ca405919eab83e6c6099d69cbc82e5b734 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-RCSID("$Id$");
-#endif
 
 #include <string.h>
 
 
 #include <string.h>
 
index d67dd20dd0eb27dccd4aad985a83bcef92241e75..db2d987f9f73ada6080879d30ca6c5314a4c2e8f 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-RCSID("$Id$");
-#endif
 #include <string.h>
 #include <ctype.h>
 
 #include <string.h>
 #include <ctype.h>
 
index 43705e4d50d97688473d26093af53a145884bbb0..c8d19a44557c06b1a899fdf1e1308ace3c613cad 100644 (file)
  */
 
 #if 1
  */
 
 #if 1
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-RCSID("$Id$");
-#endif
 #include "roken.h"
 #ifndef _DIAGASSERT
 #define _DIAGASSERT(X)
 #include "roken.h"
 #ifndef _DIAGASSERT
 #define _DIAGASSERT(X)
index 5f6d86ee5692b59a8360706f37d80558026c0e33..13366ce1327e1822fcc5bd0f3cf4137008ccf5d6 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-RCSID("$Id$");
-#endif
 
 #include <unistd.h>
 
 
 #include <unistd.h>
 
index 63e016174a73b01fc631ca03184f3971cf839dca..9d102c7dc58c4d6b03f29951e5ebd51d47e53ea3 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
+
 #include <config.h>
 #include <config.h>
-RCSID("$Id$");
-#endif
+
 #include "roken.h"
 
 #include "roken.h"
 
-#include "print_version.h"
+#include "version.h"
 
 
-void
+void ROKEN_LIB_FUNCTION
 print_version(const char *progname)
 {
 print_version(const char *progname)
 {
-    const char *package_list = VERSIONLIST;
+    const char *package_list = heimdal_version;
 
     if(progname == NULL)
        progname = getprogname();
 
     if(progname == NULL)
        progname = getprogname();
index c7af0e4958ffa12c65264d09424dcf7b285b90b7..3f71449fac5d15788bff1c15eeecb907bc111c45 100644 (file)
@@ -235,10 +235,9 @@ combine(const uint32_t *in, size_t in_len,
     int ostarter;
     unsigned o = 0;
     int old_cc;
     int ostarter;
     unsigned o = 0;
     int old_cc;
-    int cc;
 
     for (i = 0; i < in_len;) {
 
     for (i = 0; i < in_len;) {
-       while (i < in_len && (cc = _wind_combining_class(in[i])) != 0) {
+       while (i < in_len && _wind_combining_class(in[i]) != 0) {
            out[o++] = in[i++];
        }
        if (i < in_len) {
            out[o++] = in[i++];
        }
        if (i < in_len) {
@@ -251,6 +250,7 @@ combine(const uint32_t *in, size_t in_len,
            while (i < in_len) {
                uint32_t comb;
                uint32_t v[2];
            while (i < in_len) {
                uint32_t comb;
                uint32_t v[2];
+               int cc;
 
                v[0] = out[ostarter];
                v[1] = in[i];
 
                v[0] = out[ostarter];
                v[1] = in[i];
index 6e99cfc86b8daaae9ef5cc9c33e695faf6ea2bbf..aa04b3fd1d403b532f058ee5190bd4cc2f16f311 100644 (file)
@@ -107,7 +107,7 @@ wind_stringprep(const uint32_t *in, size_t in_len,
     return ret;
 }
 
     return ret;
 }
 
-static struct {
+const static struct {
     const char *name;
     wind_profile_flags flags;
 } profiles[] = {
     const char *name;
     wind_profile_flags flags;
 } profiles[] = {
index f563b79107063fc99be7762d7fae2000c7e6fa64..ed944b4c7d28dd5e90ccbd2e34ff1965f8701175 100644 (file)
@@ -31,9 +31,7 @@
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
 #include <config.h>
-#endif
 #include "windlocl.h"
 
 RCSID("$Id$");
 #include "windlocl.h"
 
 RCSID("$Id$");
index f90c252e7dd8da94f1fdb6740ccaa52976497769..01c0d0f1c5f29a6aeb845f394e50ecf676f2907f 100644 (file)
@@ -12,8 +12,8 @@ error_code NONE,              "No error"
 error_code NO_PROFILE,         "No such profile"
 error_code OVERRUN,            "Buffer overrun"
 error_code UNDERUN,            "Buffer underrun"
 error_code NO_PROFILE,         "No such profile"
 error_code OVERRUN,            "Buffer overrun"
 error_code UNDERUN,            "Buffer underrun"
-error_code LENGTH_NOT_MOD2,    "Lenght not mod2"
-error_code LENGTH_NOT_MOD4,    "Lenght not mod4"
+error_code LENGTH_NOT_MOD2,    "Length not mod2"
+error_code LENGTH_NOT_MOD4,    "Length not mod4"
 error_code INVALID_UTF8,       "Invalid UTF-8 combination in string"
 error_code INVALID_UTF16,      "Invalid UTF-16 combination in string"
 error_code INVALID_UTF32,      "Invalid UTF-32 combination in string"
 error_code INVALID_UTF8,       "Invalid UTF-8 combination in string"
 error_code INVALID_UTF16,      "Invalid UTF-16 combination in string"
 error_code INVALID_UTF32,      "Invalid UTF-32 combination in string"
index 6c4d10d262b9c7c193971c1789ddb6d984c92af5..9da0787012b3560c9a694b082c46f63f7ee5f941 100755 (executable)
@@ -28,9 +28,12 @@ if (not defined $options) {
 }
 
 my $header = "$dirname/$prefix.h";
 }
 
 my $header = "$dirname/$prefix.h";
+my $headerx = "$dirname/$prefix.hx";
 
 print "basics:: $header\n";
 
 print "basics:: $header\n";
-print "$header: \$(heimdalsrcdir)/$file \$(ASN1C)\n";
+print "$header: $headerx\n";
+print "\t\@cp $headerx $header\n";
+print "$headerx: \$(heimdalsrcdir)/$file \$(ASN1C)\n";
 print "\t\@echo \"Compiling ASN1 file \$(heimdalsrcdir)/$file\"\n";
 print "\t\@\$(heimdalbuildsrcdir)/asn1_compile_wrapper.sh \$(builddir) $dirname \$(ASN1C) \$(call abspath,\$(heimdalsrcdir)/$file) $prefix $options\n\n";
 
 print "\t\@echo \"Compiling ASN1 file \$(heimdalsrcdir)/$file\"\n";
 print "\t\@\$(heimdalbuildsrcdir)/asn1_compile_wrapper.sh \$(builddir) $dirname \$(ASN1C) \$(call abspath,\$(heimdalsrcdir)/$file) $prefix $options\n\n";
 
index ea8d4731dbf95976e2c06054861af7fef22ddb25..d3b7264c2c7b3d78f06e200b3a2efb678da7b69c 100644 (file)
@@ -36,8 +36,6 @@ HEIMDAL_KDC_OBJ_FILES = \
        $(heimdalsrcdir)/kdc/pkinit.o \
        $(heimdalsrcdir)/kdc/log.o \
        $(heimdalsrcdir)/kdc/misc.o \
        $(heimdalsrcdir)/kdc/pkinit.o \
        $(heimdalsrcdir)/kdc/log.o \
        $(heimdalsrcdir)/kdc/misc.o \
-       $(heimdalsrcdir)/kdc/524.o \
-       $(heimdalsrcdir)/kdc/kerberos4.o \
        $(heimdalsrcdir)/kdc/kaserver.o \
        $(heimdalsrcdir)/kdc/digest.o \
        $(heimdalsrcdir)/kdc/process.o \
        $(heimdalsrcdir)/kdc/kaserver.o \
        $(heimdalsrcdir)/kdc/digest.o \
        $(heimdalsrcdir)/kdc/process.o \
@@ -179,7 +177,8 @@ HEIMDAL_GSSAPI_KRB5_OBJ_FILES = \
        $(heimdalsrcdir)/lib/gssapi/krb5/accept_sec_context.o \
        $(heimdalsrcdir)/lib/gssapi/krb5/set_sec_context_option.o \
        $(heimdalsrcdir)/lib/gssapi/krb5/process_context_token.o \
        $(heimdalsrcdir)/lib/gssapi/krb5/accept_sec_context.o \
        $(heimdalsrcdir)/lib/gssapi/krb5/set_sec_context_option.o \
        $(heimdalsrcdir)/lib/gssapi/krb5/process_context_token.o \
-       $(heimdalsrcdir)/lib/gssapi/krb5/prf.o
+       $(heimdalsrcdir)/lib/gssapi/krb5/prf.o \
+       $(heimdalsrcdir)/lib/gssapi/krb5/aeap.o
 
 $(eval $(call heimdal_proto_header_template, \
   $(heimdalsrcdir)/lib/gssapi/krb5/gsskrb5-private.h, \
 
 $(eval $(call heimdal_proto_header_template, \
   $(heimdalsrcdir)/lib/gssapi/krb5/gsskrb5-private.h, \
@@ -196,6 +195,7 @@ HEIMDAL_GSSAPI_OBJ_FILES = \
        $(heimdalsrcdir)/lib/gssapi/mech/gss_mech_switch.o \
        $(heimdalsrcdir)/lib/gssapi/mech/gss_process_context_token.o \
        $(heimdalsrcdir)/lib/gssapi/mech/gss_buffer_set.o \
        $(heimdalsrcdir)/lib/gssapi/mech/gss_mech_switch.o \
        $(heimdalsrcdir)/lib/gssapi/mech/gss_process_context_token.o \
        $(heimdalsrcdir)/lib/gssapi/mech/gss_buffer_set.o \
+       $(heimdalsrcdir)/lib/gssapi/mech/gss_aeap.o \
        $(heimdalsrcdir)/lib/gssapi/mech/gss_add_cred.o \
        $(heimdalsrcdir)/lib/gssapi/mech/gss_add_oid_set_member.o \
        $(heimdalsrcdir)/lib/gssapi/mech/gss_compare_name.o \
        $(heimdalsrcdir)/lib/gssapi/mech/gss_add_cred.o \
        $(heimdalsrcdir)/lib/gssapi/mech/gss_add_oid_set_member.o \
        $(heimdalsrcdir)/lib/gssapi/mech/gss_compare_name.o \
@@ -273,7 +273,6 @@ HEIMDAL_KRB5_OBJ_FILES = \
        $(heimdalsrcdir)/lib/krb5/changepw.o \
        $(heimdalsrcdir)/lib/krb5/codec.o \
        $(heimdalsrcdir)/lib/krb5/config_file.o \
        $(heimdalsrcdir)/lib/krb5/changepw.o \
        $(heimdalsrcdir)/lib/krb5/codec.o \
        $(heimdalsrcdir)/lib/krb5/config_file.o \
-       $(heimdalsrcdir)/lib/krb5/config_file_netinfo.o \
        $(heimdalsrcdir)/lib/krb5/constants.o \
        $(heimdalsrcdir)/lib/krb5/context.o \
        $(heimdalsrcdir)/lib/krb5/convert_creds.o \
        $(heimdalsrcdir)/lib/krb5/constants.o \
        $(heimdalsrcdir)/lib/krb5/context.o \
        $(heimdalsrcdir)/lib/krb5/convert_creds.o \
@@ -297,7 +296,6 @@ HEIMDAL_KRB5_OBJ_FILES = \
        $(heimdalsrcdir)/lib/krb5/get_for_creds.o \
        $(heimdalsrcdir)/lib/krb5/get_host_realm.o \
        $(heimdalsrcdir)/lib/krb5/get_in_tkt.o \
        $(heimdalsrcdir)/lib/krb5/get_for_creds.o \
        $(heimdalsrcdir)/lib/krb5/get_host_realm.o \
        $(heimdalsrcdir)/lib/krb5/get_in_tkt.o \
-       $(heimdalsrcdir)/lib/krb5/get_in_tkt_with_keytab.o \
        $(heimdalsrcdir)/lib/krb5/get_port.o \
        $(heimdalsrcdir)/lib/krb5/init_creds.o \
        $(heimdalsrcdir)/lib/krb5/init_creds_pw.o \
        $(heimdalsrcdir)/lib/krb5/get_port.o \
        $(heimdalsrcdir)/lib/krb5/init_creds.o \
        $(heimdalsrcdir)/lib/krb5/init_creds_pw.o \
@@ -595,7 +593,7 @@ $(HEIMDAL_ROKEN_CLOSEFROM_H_OBJ_FILES): CFLAGS+=-I$(heimdalbuildsrcdir) -I$(heim
 #######################
 # Start SUBSYSTEM HEIMDAL_ROKEN
 [SUBSYSTEM::HEIMDAL_ROKEN]
 #######################
 # Start SUBSYSTEM HEIMDAL_ROKEN
 [SUBSYSTEM::HEIMDAL_ROKEN]
-CFLAGS =  -I$(heimdalbuildsrcdir) -I$(heimdalsrcdir)/lib/roken -I$(socketwrappersrcdir)
+CFLAGS =  -I$(heimdalbuildsrcdir) -I$(heimdalsrcdir)/lib/roken -I$(heimdalsrcdir)/include -I$(socketwrappersrcdir)
 PRIVATE_DEPENDENCIES = \
                        HEIMDAL_ROKEN_PROGNAME \
                        HEIMDAL_ROKEN_CLOSEFROM \
 PRIVATE_DEPENDENCIES = \
                        HEIMDAL_ROKEN_PROGNAME \
                        HEIMDAL_ROKEN_CLOSEFROM \
@@ -613,6 +611,7 @@ HEIMDAL_ROKEN_OBJ_FILES = \
        $(heimdalsrcdir)/lib/roken/ecalloc.o \
        $(heimdalsrcdir)/lib/roken/getarg.o \
        $(heimdalsrcdir)/lib/roken/get_window_size.o \
        $(heimdalsrcdir)/lib/roken/ecalloc.o \
        $(heimdalsrcdir)/lib/roken/getarg.o \
        $(heimdalsrcdir)/lib/roken/get_window_size.o \
+       $(heimdalsrcdir)/lib/roken/getdtablesize.o \
        $(heimdalsrcdir)/lib/roken/h_errno.o \
        $(heimdalsrcdir)/lib/roken/issuid.o \
        $(heimdalsrcdir)/lib/roken/net_read.o \
        $(heimdalsrcdir)/lib/roken/h_errno.o \
        $(heimdalsrcdir)/lib/roken/issuid.o \
        $(heimdalsrcdir)/lib/roken/net_read.o \
@@ -735,14 +734,14 @@ dist:: $(heimdalsrcdir)/lib/com_err/lex.c
 mkinclude perl_path_wrapper.sh asn1_deps.pl lib/hdb/hdb.asn1 hdb_asn1 \$\(heimdalsrcdir\)/lib/hdb |
 mkinclude perl_path_wrapper.sh asn1_deps.pl lib/gssapi/spnego/spnego.asn1 spnego_asn1 \$\(heimdalsrcdir\)/lib/gssapi --sequence=MechTypeList |
 mkinclude perl_path_wrapper.sh asn1_deps.pl lib/gssapi/mech/gssapi.asn1 gssapi_asn1 \$\(heimdalsrcdir\)/lib/gssapi|
 mkinclude perl_path_wrapper.sh asn1_deps.pl lib/hdb/hdb.asn1 hdb_asn1 \$\(heimdalsrcdir\)/lib/hdb |
 mkinclude perl_path_wrapper.sh asn1_deps.pl lib/gssapi/spnego/spnego.asn1 spnego_asn1 \$\(heimdalsrcdir\)/lib/gssapi --sequence=MechTypeList |
 mkinclude perl_path_wrapper.sh asn1_deps.pl lib/gssapi/mech/gssapi.asn1 gssapi_asn1 \$\(heimdalsrcdir\)/lib/gssapi|
-mkinclude perl_path_wrapper.sh asn1_deps.pl lib/asn1/k5.asn1 krb5_asn1 \$\(heimdalsrcdir\)/lib/asn1 --encode-rfc1510-bit-string --sequence=KRB5SignedPathPrincipals --sequence=AuthorizationData --sequence=METHOD-DATA|
+mkinclude perl_path_wrapper.sh asn1_deps.pl lib/asn1/krb5.asn1 krb5_asn1 \$\(heimdalsrcdir\)/lib/asn1 --option-file=krb5.opt|
 mkinclude perl_path_wrapper.sh asn1_deps.pl lib/asn1/digest.asn1 digest_asn1 \$\(heimdalsrcdir\)/lib/asn1|
 mkinclude perl_path_wrapper.sh asn1_deps.pl lib/asn1/pkcs8.asn1 pkcs8_asn1 \$\(heimdalsrcdir\)/lib/asn1|
 mkinclude perl_path_wrapper.sh asn1_deps.pl lib/asn1/pkcs9.asn1 pkcs9_asn1 \$\(heimdalsrcdir\)/lib/asn1|
 mkinclude perl_path_wrapper.sh asn1_deps.pl lib/asn1/pkcs12.asn1 pkcs12_asn1 \$\(heimdalsrcdir\)/lib/asn1|
 mkinclude perl_path_wrapper.sh asn1_deps.pl lib/asn1/rfc2459.asn1 rfc2459_asn1 \$\(heimdalsrcdir\)/lib/asn1 --preserve-binary=TBSCertificate --preserve-binary=TBSCRLCertList --preserve-binary=Name --sequence=GeneralNames --sequence=Extensions --sequence=CRLDistributionPoints|
 mkinclude perl_path_wrapper.sh asn1_deps.pl lib/asn1/pkinit.asn1 pkinit_asn1 \$\(heimdalsrcdir\)/lib/asn1|
 mkinclude perl_path_wrapper.sh asn1_deps.pl lib/asn1/digest.asn1 digest_asn1 \$\(heimdalsrcdir\)/lib/asn1|
 mkinclude perl_path_wrapper.sh asn1_deps.pl lib/asn1/pkcs8.asn1 pkcs8_asn1 \$\(heimdalsrcdir\)/lib/asn1|
 mkinclude perl_path_wrapper.sh asn1_deps.pl lib/asn1/pkcs9.asn1 pkcs9_asn1 \$\(heimdalsrcdir\)/lib/asn1|
 mkinclude perl_path_wrapper.sh asn1_deps.pl lib/asn1/pkcs12.asn1 pkcs12_asn1 \$\(heimdalsrcdir\)/lib/asn1|
 mkinclude perl_path_wrapper.sh asn1_deps.pl lib/asn1/rfc2459.asn1 rfc2459_asn1 \$\(heimdalsrcdir\)/lib/asn1 --preserve-binary=TBSCertificate --preserve-binary=TBSCRLCertList --preserve-binary=Name --sequence=GeneralNames --sequence=Extensions --sequence=CRLDistributionPoints|
 mkinclude perl_path_wrapper.sh asn1_deps.pl lib/asn1/pkinit.asn1 pkinit_asn1 \$\(heimdalsrcdir\)/lib/asn1|
-mkinclude perl_path_wrapper.sh asn1_deps.pl lib/asn1/CMS.asn1 cms_asn1 \$\(heimdalsrcdir\)/lib/asn1|
+mkinclude perl_path_wrapper.sh asn1_deps.pl lib/asn1/cms.asn1 cms_asn1 \$\(heimdalsrcdir\)/lib/asn1 --option-file=cms.opt|
 mkinclude perl_path_wrapper.sh asn1_deps.pl lib/hx509/ocsp.asn1 ocsp_asn1 \$\(heimdalsrcdir\)/lib/hx509 --preserve-binary=OCSPTBSRequest --preserve-binary=OCSPResponseData|
 mkinclude perl_path_wrapper.sh asn1_deps.pl lib/asn1/kx509.asn1 kx509_asn1 \$\(heimdalsrcdir\)/lib/asn1|
 mkinclude perl_path_wrapper.sh asn1_deps.pl lib/hx509/pkcs10.asn1 pkcs10_asn1 \$\(heimdalsrcdir\)/lib/hx509 --preserve-binary=CertificationRequestInfo|
 mkinclude perl_path_wrapper.sh asn1_deps.pl lib/hx509/ocsp.asn1 ocsp_asn1 \$\(heimdalsrcdir\)/lib/hx509 --preserve-binary=OCSPTBSRequest --preserve-binary=OCSPResponseData|
 mkinclude perl_path_wrapper.sh asn1_deps.pl lib/asn1/kx509.asn1 kx509_asn1 \$\(heimdalsrcdir\)/lib/asn1|
 mkinclude perl_path_wrapper.sh asn1_deps.pl lib/hx509/pkcs10.asn1 pkcs10_asn1 \$\(heimdalsrcdir\)/lib/hx509 --preserve-binary=CertificationRequestInfo|
index 28a82bcf61c179c5a49650be2adba9e47661d9da..c0fa5132d16f912015f82c754640e950614c443d 100644 (file)
@@ -282,23 +282,23 @@ static krb5_error_code LDB_message2entry_keys(krb5_context context,
                ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, iconv_convenience, &_pkb,
                                               (ndr_pull_flags_fn_t)ndr_pull_package_PrimaryKerberosBlob);
                if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
                ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, iconv_convenience, &_pkb,
                                               (ndr_pull_flags_fn_t)ndr_pull_package_PrimaryKerberosBlob);
                if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-                       krb5_set_error_string(context, "LDB_message2entry_keys: could not parse package_PrimaryKerberosBlob");
-                       krb5_warnx(context, "LDB_message2entry_keys: could not parse package_PrimaryKerberosBlob");
                        ret = EINVAL;
                        ret = EINVAL;
+                       krb5_set_error_message(context, ret, "LDB_message2entry_keys: could not parse package_PrimaryKerberosBlob");
+                       krb5_warnx(context, "LDB_message2entry_keys: could not parse package_PrimaryKerberosBlob");
                        goto out;
                }
 
                if (newer_keys && _pkb.version != 4) {
                        goto out;
                }
 
                if (newer_keys && _pkb.version != 4) {
-                       krb5_set_error_string(context, "LDB_message2entry_keys: Primary:Kerberos-Newer-Keys not version 4");
-                       krb5_warnx(context, "LDB_message2entry_keys: Primary:Kerberos-Newer-Keys not version 4");
                        ret = EINVAL;
                        ret = EINVAL;
+                       krb5_set_error_message(context, ret, "LDB_message2entry_keys: Primary:Kerberos-Newer-Keys not version 4");
+                       krb5_warnx(context, "LDB_message2entry_keys: Primary:Kerberos-Newer-Keys not version 4");
                        goto out;
                }
 
                if (!newer_keys && _pkb.version != 3) {
                        goto out;
                }
 
                if (!newer_keys && _pkb.version != 3) {
-                       krb5_set_error_string(context, "LDB_message2entry_keys: could not parse Primary:Kerberos not version 3");
-                       krb5_warnx(context, "LDB_message2entry_keys: could not parse Primary:Kerberos not version 3");
                        ret = EINVAL;
                        ret = EINVAL;
+                       krb5_set_error_message(context, ret, "LDB_message2entry_keys: could not parse Primary:Kerberos not version 3");
+                       krb5_warnx(context, "LDB_message2entry_keys: could not parse Primary:Kerberos not version 3");
                        goto out;
                }
 
                        goto out;
                }
 
@@ -510,8 +510,8 @@ static krb5_error_code LDB_message2entry(krb5_context context, HDB *db,
        computer_val.length = strlen((const char *)computer_val.data);
        
        if (!samAccountName) {
        computer_val.length = strlen((const char *)computer_val.data);
        
        if (!samAccountName) {
-               krb5_set_error_string(context, "LDB_message2entry: no samAccountName present");
                ret = ENOENT;
                ret = ENOENT;
+               krb5_set_error_message(context, ret, "LDB_message2entry: no samAccountName present");
                goto out;
        }
 
                goto out;
        }
 
@@ -524,8 +524,8 @@ static krb5_error_code LDB_message2entry(krb5_context context, HDB *db,
        memset(entry_ex, 0, sizeof(*entry_ex));
 
        if (!realm) {
        memset(entry_ex, 0, sizeof(*entry_ex));
 
        if (!realm) {
-               krb5_set_error_string(context, "talloc_strdup: out of memory");
                ret = ENOMEM;
                ret = ENOMEM;
+               krb5_set_error_message(context, ret, "talloc_strdup: out of memory");
                goto out;
        }
                        
                goto out;
        }
                        
@@ -556,10 +556,9 @@ static krb5_error_code LDB_message2entry(krb5_context context, HDB *db,
        if (ent_type == HDB_SAMBA4_ENT_TYPE_ANY && principal == NULL) {
                krb5_make_principal(context, &entry_ex->entry.principal, realm, samAccountName, NULL);
        } else {
        if (ent_type == HDB_SAMBA4_ENT_TYPE_ANY && principal == NULL) {
                krb5_make_principal(context, &entry_ex->entry.principal, realm, samAccountName, NULL);
        } else {
-               char *strdup_realm;
                ret = copy_Principal(principal, entry_ex->entry.principal);
                if (ret) {
                ret = copy_Principal(principal, entry_ex->entry.principal);
                if (ret) {
-                       krb5_clear_error_string(context);
+                       krb5_clear_error_message(context);
                        goto out;
                }
 
                        goto out;
                }
 
@@ -570,14 +569,7 @@ static krb5_error_code LDB_message2entry(krb5_context context, HDB *db,
                 * we determine from our records */
                
                /* this has to be with malloc() */
                 * we determine from our records */
                
                /* this has to be with malloc() */
-               strdup_realm = strdup(realm);
-               if (!strdup_realm) {
-                       ret = ENOMEM;
-                       krb5_clear_error_string(context);
-                       goto out;
-               }
-               free(*krb5_princ_realm(context, entry_ex->entry.principal));
-               krb5_princ_set_realm(context, entry_ex->entry.principal, &strdup_realm);
+               krb5_principal_set_realm(context, entry_ex->entry.principal, realm);
        }
 
        /* First try and figure out the flags based on the userAccountControl */
        }
 
        /* First try and figure out the flags based on the userAccountControl */
@@ -608,8 +600,8 @@ static krb5_error_code LDB_message2entry(krb5_context context, HDB *db,
                
                entry_ex->entry.modified_by = (Event *) malloc(sizeof(Event));
                if (entry_ex->entry.modified_by == NULL) {
                
                entry_ex->entry.modified_by = (Event *) malloc(sizeof(Event));
                if (entry_ex->entry.modified_by == NULL) {
-                       krb5_set_error_string(context, "malloc: out of memory");
                        ret = ENOMEM;
                        ret = ENOMEM;
+                       krb5_set_error_message(context, ret, "malloc: out of memory");
                        goto out;
                }
                
                        goto out;
                }
                
@@ -695,14 +687,14 @@ static krb5_error_code LDB_message2entry(krb5_context context, HDB *db,
 
        entry_ex->entry.etypes = malloc(sizeof(*(entry_ex->entry.etypes)));
        if (entry_ex->entry.etypes == NULL) {
 
        entry_ex->entry.etypes = malloc(sizeof(*(entry_ex->entry.etypes)));
        if (entry_ex->entry.etypes == NULL) {
-               krb5_clear_error_string(context);
+               krb5_clear_error_message(context);
                ret = ENOMEM;
                goto out;
        }
        entry_ex->entry.etypes->len = entry_ex->entry.keys.len;
        entry_ex->entry.etypes->val = calloc(entry_ex->entry.etypes->len, sizeof(int));
        if (entry_ex->entry.etypes->val == NULL) {
                ret = ENOMEM;
                goto out;
        }
        entry_ex->entry.etypes->len = entry_ex->entry.keys.len;
        entry_ex->entry.etypes->val = calloc(entry_ex->entry.etypes->len, sizeof(int));
        if (entry_ex->entry.etypes->val == NULL) {
-               krb5_clear_error_string(context);
+               krb5_clear_error_message(context);
                ret = ENOMEM;
                goto out;
        }
                ret = ENOMEM;
                goto out;
        }
@@ -739,7 +731,6 @@ static krb5_error_code LDB_trust_message2entry(krb5_context context, HDB *db,
        
        const char *dnsdomain;
        char *realm;
        
        const char *dnsdomain;
        char *realm;
-       char *strdup_realm;
        DATA_BLOB password_utf16;
        struct samr_Password password_hash;
        const struct ldb_val *password_val;
        DATA_BLOB password_utf16;
        struct samr_Password password_hash;
        const struct ldb_val *password_val;
@@ -849,7 +840,7 @@ static krb5_error_code LDB_trust_message2entry(krb5_context context, HDB *db,
 
        ret = copy_Principal(principal, entry_ex->entry.principal);
        if (ret) {
 
        ret = copy_Principal(principal, entry_ex->entry.principal);
        if (ret) {
-               krb5_clear_error_string(context);
+               krb5_clear_error_message(context);
                goto out;
        }
        
                goto out;
        }
        
@@ -859,16 +850,7 @@ static krb5_error_code LDB_trust_message2entry(krb5_context context, HDB *db,
         * replace the client principal's realm with the one
         * we determine from our records */
        
         * replace the client principal's realm with the one
         * we determine from our records */
        
-       /* this has to be with malloc() */
-       strdup_realm = strdup(realm);
-       if (!strdup_realm) {
-               ret = ENOMEM;
-               krb5_clear_error_string(context);
-               goto out;
-       }
-       free(*krb5_princ_realm(context, entry_ex->entry.principal));
-       krb5_princ_set_realm(context, entry_ex->entry.principal, &strdup_realm);
-       
+       krb5_principal_set_realm(context, entry_ex->entry.principal, realm);
        entry_ex->entry.flags = int2HDBFlags(0);
        entry_ex->entry.flags.immutable = 1;
        entry_ex->entry.flags.invalid = 0;
        entry_ex->entry.flags = int2HDBFlags(0);
        entry_ex->entry.flags.immutable = 1;
        entry_ex->entry.flags.invalid = 0;
@@ -885,14 +867,14 @@ static krb5_error_code LDB_trust_message2entry(krb5_context context, HDB *db,
 
        entry_ex->entry.etypes = malloc(sizeof(*(entry_ex->entry.etypes)));
        if (entry_ex->entry.etypes == NULL) {
 
        entry_ex->entry.etypes = malloc(sizeof(*(entry_ex->entry.etypes)));
        if (entry_ex->entry.etypes == NULL) {
-               krb5_clear_error_string(context);
+               krb5_clear_error_message(context);
                ret = ENOMEM;
                goto out;
        }
        entry_ex->entry.etypes->len = entry_ex->entry.keys.len;
        entry_ex->entry.etypes->val = calloc(entry_ex->entry.etypes->len, sizeof(int));
        if (entry_ex->entry.etypes->val == NULL) {
                ret = ENOMEM;
                goto out;
        }
        entry_ex->entry.etypes->len = entry_ex->entry.keys.len;
        entry_ex->entry.etypes->val = calloc(entry_ex->entry.etypes->len, sizeof(int));
        if (entry_ex->entry.etypes->val == NULL) {
-               krb5_clear_error_string(context);
+               krb5_clear_error_message(context);
                ret = ENOMEM;
                goto out;
        }
                ret = ENOMEM;
                goto out;
        }
@@ -933,7 +915,7 @@ static krb5_error_code LDB_lookup_principal(krb5_context context, struct ldb_con
        ret = krb5_unparse_name_flags(context, principal,  KRB5_PRINCIPAL_UNPARSE_NO_REALM, &short_princ);
 
        if (ret != 0) {
        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");
+               krb5_set_error_message(context, ret, "LDB_lookup_principal: could not parse principal");
                krb5_warnx(context, "LDB_lookup_principal: could not parse principal");
                return ret;
        }
                krb5_warnx(context, "LDB_lookup_principal: could not parse principal");
                return ret;
        }
@@ -941,8 +923,9 @@ static krb5_error_code LDB_lookup_principal(krb5_context context, struct ldb_con
        short_princ_talloc = talloc_strdup(mem_ctx, short_princ);
        free(short_princ);
        if (!short_princ_talloc) {
        short_princ_talloc = talloc_strdup(mem_ctx, short_princ);
        free(short_princ);
        if (!short_princ_talloc) {
-               krb5_set_error_string(context, "LDB_lookup_principal: talloc_strdup() failed!");
-               return ENOMEM;
+               ret = ENOMEM;
+               krb5_set_error_message(context, ret, "LDB_lookup_principal: talloc_strdup() failed!");
+               return ret;
        }
 
        switch (ent_type) {
        }
 
        switch (ent_type) {
@@ -962,8 +945,9 @@ static krb5_error_code LDB_lookup_principal(krb5_context context, struct ldb_con
        }
 
        if (!filter) {
        }
 
        if (!filter) {
-               krb5_set_error_string(context, "talloc_asprintf: out of memory");
-               return ENOMEM;
+               ret = ENOMEM;
+               krb5_set_error_message(context, ret, "talloc_asprintf: out of memory");
+               return ret;
        }
 
        lret = gendb_search_single_extended_dn(ldb_ctx, mem_ctx, 
        }
 
        lret = gendb_search_single_extended_dn(ldb_ctx, mem_ctx, 
@@ -988,6 +972,7 @@ static krb5_error_code LDB_lookup_trust(krb5_context context, struct ldb_context
                                        struct ldb_message **pmsg)
 {
        int lret;
                                        struct ldb_message **pmsg)
 {
        int lret;
+       krb5_error_code ret;
        char *filter = NULL;
        const char * const *attrs = trust_attrs;
 
        char *filter = NULL;
        const char * const *attrs = trust_attrs;
 
@@ -995,8 +980,9 @@ static krb5_error_code LDB_lookup_trust(krb5_context context, struct ldb_context
        filter = talloc_asprintf(mem_ctx, "(&(objectClass=trustedDomain)(|(flatname=%s)(trustPartner=%s)))", realm, realm);
 
        if (!filter) {
        filter = talloc_asprintf(mem_ctx, "(&(objectClass=trustedDomain)(|(flatname=%s)(trustPartner=%s)))", realm, realm);
 
        if (!filter) {
-               krb5_set_error_string(context, "talloc_asprintf: out of memory");
-               return ENOMEM;
+               ret = ENOMEM;
+               krb5_set_error_message(context, ret, "talloc_asprintf: out of memory");
+               return ret;
        }
 
        lret = ldb_search(ldb_ctx, mem_ctx, &res,
        }
 
        lret = ldb_search(ldb_ctx, mem_ctx, &res,
@@ -1019,9 +1005,10 @@ static krb5_error_code LDB_lookup_trust(krb5_context context, struct ldb_context
 static krb5_error_code LDB_open(krb5_context context, HDB *db, int flags, mode_t mode)
 {
        if (db->hdb_master_key_set) {
 static krb5_error_code LDB_open(krb5_context context, HDB *db, int flags, mode_t mode)
 {
        if (db->hdb_master_key_set) {
+               krb5_error_code ret = HDB_ERR_NOENTRY;
                krb5_warnx(context, "LDB_open: use of a master key incompatible with LDB\n");
                krb5_warnx(context, "LDB_open: use of a master key incompatible with LDB\n");
-               krb5_set_error_string(context, "LDB_open: use of a master key incompatible with LDB\n");
-               return HDB_ERR_NOENTRY;
+               krb5_set_error_message(context, ret, "LDB_open: use of a master key incompatible with LDB\n");
+               return ret;
        }               
 
        return 0;
        }               
 
        return 0;
@@ -1112,8 +1099,9 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db,
                
                char *realm_fixed = strupper_talloc(mem_ctx, lp_realm(lp_ctx));
                if (!realm_fixed) {
                
                char *realm_fixed = strupper_talloc(mem_ctx, lp_realm(lp_ctx));
                if (!realm_fixed) {
-                       krb5_set_error_string(context, "strupper_talloc: out of memory");
-                       return ENOMEM;
+                       ret = ENOMEM;
+                       krb5_set_error_message(context, ret, "strupper_talloc: out of memory");
+                       return ret;
                }
                
                ret = krb5_copy_principal(context, principal, &alloc_principal);
                }
                
                ret = krb5_copy_principal(context, principal, &alloc_principal);
@@ -1125,8 +1113,9 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db,
                alloc_principal->name.name_string.val[1] = strdup(realm_fixed);
                talloc_free(realm_fixed);
                if (!alloc_principal->name.name_string.val[1]) {
                alloc_principal->name.name_string.val[1] = strdup(realm_fixed);
                talloc_free(realm_fixed);
                if (!alloc_principal->name.name_string.val[1]) {
-                       krb5_set_error_string(context, "LDB_fetch: strdup() failed!");
-                       return ENOMEM;
+                       ret = ENOMEM;
+                       krb5_set_error_message(context, ret, "LDB_fetch: strdup() failed!");
+                       return ret;
                }
                principal = alloc_principal;
 
                }
                principal = alloc_principal;
 
@@ -1136,7 +1125,7 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db,
                
                if (ret != 0) {
                        krb5_warnx(context, "LDB_fetch: could not find principal in DB");
                
                if (ret != 0) {
                        krb5_warnx(context, "LDB_fetch: could not find principal in DB");
-                       krb5_set_error_string(context, "LDB_fetch: could not find principal in DB");
+                       krb5_set_error_message(context, ret, "LDB_fetch: could not find principal in DB");
                        return ret;
                }
                
                        return ret;
                }
                
@@ -1173,7 +1162,7 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db,
                
                if (ret != 0) {
                        krb5_warnx(context, "LDB_fetch: could not find principal in DB");
                
                if (ret != 0) {
                        krb5_warnx(context, "LDB_fetch: could not find principal in DB");
-                       krb5_set_error_string(context, "LDB_fetch: could not find principal in DB");
+                       krb5_set_error_message(context, ret, "LDB_fetch: could not find principal in DB");
                        return ret;
                }
                
                        return ret;
                }
                
@@ -1273,8 +1262,9 @@ static krb5_error_code LDB_fetch(krb5_context context, HDB *db,
        TALLOC_CTX *mem_ctx = talloc_named(db, 0, "LDB_fetch context");
 
        if (!mem_ctx) {
        TALLOC_CTX *mem_ctx = talloc_named(db, 0, "LDB_fetch context");
 
        if (!mem_ctx) {
-               krb5_set_error_string(context, "LDB_fetch: talloc_named() failed!");
-               return ENOMEM;
+               ret = ENOMEM;
+               krb5_set_error_message(context, ret, "LDB_fetch: talloc_named() failed!");
+               return ret;
        }
 
        if (flags & HDB_F_GET_CLIENT) {
        }
 
        if (flags & HDB_F_GET_CLIENT) {
@@ -1333,8 +1323,9 @@ static krb5_error_code LDB_seq(krb5_context context, HDB *db, unsigned flags, hd
        mem_ctx = talloc_named(priv, 0, "LDB_seq context");
 
        if (!mem_ctx) {
        mem_ctx = talloc_named(priv, 0, "LDB_seq context");
 
        if (!mem_ctx) {
-               krb5_set_error_string(context, "LDB_seq: talloc_named() failed!");
-               return ENOMEM;
+               ret = ENOMEM;
+               krb5_set_error_message(context, ret, "LDB_seq: talloc_named() failed!");
+               return ret;
        }
 
        if (priv->index < priv->count) {
        }
 
        if (priv->index < priv->count) {
@@ -1373,8 +1364,9 @@ static krb5_error_code LDB_firstkey(krb5_context context, HDB *db, unsigned flag
 
        priv = (struct hdb_ldb_seq *) talloc(db, struct hdb_ldb_seq);
        if (!priv) {
 
        priv = (struct hdb_ldb_seq *) talloc(db, struct hdb_ldb_seq);
        if (!priv) {
-               krb5_set_error_string(context, "talloc: out of memory");
-               return ENOMEM;
+               ret = ENOMEM;
+               krb5_set_error_message(context, ret, "talloc: out of memory");
+               return ret;
        }
 
        priv->ctx = ldb_ctx;
        }
 
        priv->ctx = ldb_ctx;
@@ -1386,8 +1378,9 @@ static krb5_error_code LDB_firstkey(krb5_context context, HDB *db, unsigned flag
        mem_ctx = talloc_named(priv, 0, "LDB_firstkey context");
 
        if (!mem_ctx) {
        mem_ctx = talloc_named(priv, 0, "LDB_firstkey context");
 
        if (!mem_ctx) {
-               krb5_set_error_string(context, "LDB_firstkey: talloc_named() failed!");
-               return ENOMEM;
+               ret = ENOMEM;
+               krb5_set_error_message(context, ret, "LDB_firstkey: talloc_named() failed!");
+               return ret;
        }
 
        ret = krb5_get_default_realm(context, &realm);
        }
 
        ret = krb5_get_default_realm(context, &realm);
@@ -1448,7 +1441,7 @@ NTSTATUS kdc_hdb_samba4_create(TALLOC_CTX *mem_ctx,
        struct auth_session_info *session_info;
        *db = talloc(mem_ctx, HDB);
        if (!*db) {
        struct auth_session_info *session_info;
        *db = talloc(mem_ctx, HDB);
        if (!*db) {
-               krb5_set_error_string(context, "malloc: out of memory");
+               krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
                return NT_STATUS_NO_MEMORY;
        }
 
                return NT_STATUS_NO_MEMORY;
        }
 
index 3d1144106213fe75f7d254ef3fa870a04b8d1b54..ad74e102270c31a87e5b55b887d983109ffeb827 100644 (file)
@@ -661,7 +661,9 @@ static NTSTATUS kdc_check_generic_kerberos(struct irpc_message *msg,
 
 static struct hdb_method hdb_samba4 = {
        .interface_version = HDB_INTERFACE_VERSION,
 
 static struct hdb_method hdb_samba4 = {
        .interface_version = HDB_INTERFACE_VERSION,
-       .prefix = "samba4:",
+       .prefix = "samba4", /* Only used in the hdb-backed keytab code
+                            * for a keytab of 'samba4:', to find
+                            * kpasswd's key in the main DB */
        .create = hdb_samba4_create
 };
 
        .create = hdb_samba4_create
 };
 
@@ -722,7 +724,7 @@ static void kdc_task_init(struct task_server *task)
                task_server_terminate(task, "kdc: failed to get KDC configuration");
                return;
        }
                task_server_terminate(task, "kdc: failed to get KDC configuration");
                return;
        }
-
        kdc->config->logf = kdc->smb_krb5_context->logf;
        kdc->config->db = talloc(kdc, struct HDB *);
        if (!kdc->config->db) {
        kdc->config->logf = kdc->smb_krb5_context->logf;
        kdc->config->db = talloc(kdc, struct HDB *);
        if (!kdc->config->db) {
index ce41d0cea83eda5284c2bf61a4ee113a58aa2f8e..617b179956b344ea5b38e184be67b5f6a74c3bad 100644 (file)
@@ -81,13 +81,13 @@ static int dns_ex_destructor(struct dns_ex_state *state)
 */
 static void run_child_dns_lookup(struct dns_ex_state *state, int fd)
 {
 */
 static void run_child_dns_lookup(struct dns_ex_state *state, int fd)
 {
-       struct dns_reply *reply;
-       struct resource_record *rr;
+       struct rk_dns_reply *reply;
+       struct rk_resource_record *rr;
        uint32_t count = 0;
        uint32_t srv_valid = 0;
        uint32_t count = 0;
        uint32_t srv_valid = 0;
-       struct resource_record **srv_rr;
+       struct rk_resource_record **srv_rr;
        uint32_t addrs_valid = 0;
        uint32_t addrs_valid = 0;
-       struct resource_record **addrs_rr;
+       struct rk_resource_record **addrs_rr;
        char *addrs;
        bool first;
        uint32_t i;
        char *addrs;
        bool first;
        uint32_t i;
@@ -95,25 +95,25 @@ static void run_child_dns_lookup(struct dns_ex_state *state, int fd)
 
        /* this is the blocking call we are going to lots of trouble
           to avoid in the parent */
 
        /* this is the blocking call we are going to lots of trouble
           to avoid in the parent */
-       reply = dns_lookup(state->name.name, do_srv?"SRV":"A");
+       reply = rk_dns_lookup(state->name.name, do_srv?"SRV":"A");
        if (!reply) {
                goto done;
        }
 
        if (do_srv) {
        if (!reply) {
                goto done;
        }
 
        if (do_srv) {
-               dns_srv_order(reply);
+               rk_dns_srv_order(reply);
        }
 
        /* Loop over all returned records and pick the "srv" records */
        for (rr=reply->head; rr; rr=rr->next) {
                /* we are only interested in the IN class */
        }
 
        /* Loop over all returned records and pick the "srv" records */
        for (rr=reply->head; rr; rr=rr->next) {
                /* we are only interested in the IN class */
-               if (rr->class != C_IN) {
+               if (rr->class != rk_ns_c_in) {
                        continue;
                }
 
                if (do_srv) {
                        /* we are only interested in SRV records */
                        continue;
                }
 
                if (do_srv) {
                        /* we are only interested in SRV records */
-                       if (rr->type != T_SRV) {
+                       if (rr->type != rk_ns_t_srv) {
                                continue;
                        }
 
                                continue;
                        }
 
@@ -129,7 +129,7 @@ static void run_child_dns_lookup(struct dns_ex_state *state, int fd)
                } else {
                        /* we are only interested in A records */
                        /* TODO: add AAAA support */
                } else {
                        /* we are only interested in A records */
                        /* TODO: add AAAA support */
-                       if (rr->type != T_A) {
+                       if (rr->type != rk_ns_t_a) {
                                continue;
                        }
 
                                continue;
                        }
 
@@ -146,14 +146,14 @@ static void run_child_dns_lookup(struct dns_ex_state *state, int fd)
        }
 
        srv_rr = talloc_zero_array(state,
        }
 
        srv_rr = talloc_zero_array(state,
-                                  struct resource_record *,
+                                  struct rk_resource_record *,
                                   count);
        if (!srv_rr) {
                goto done;
        }
 
        addrs_rr = talloc_zero_array(state,
                                   count);
        if (!srv_rr) {
                goto done;
        }
 
        addrs_rr = talloc_zero_array(state,
-                                    struct resource_record *,
+                                    struct rk_resource_record *,
                                     count);
        if (!addrs_rr) {
                goto done;
                                     count);
        if (!addrs_rr) {
                goto done;
@@ -162,13 +162,13 @@ static void run_child_dns_lookup(struct dns_ex_state *state, int fd)
        /* Loop over all returned records and pick the records */
        for (rr=reply->head;rr;rr=rr->next) {
                /* we are only interested in the IN class */
        /* Loop over all returned records and pick the records */
        for (rr=reply->head;rr;rr=rr->next) {
                /* we are only interested in the IN class */
-               if (rr->class != C_IN) {
+               if (rr->class != rk_ns_c_in) {
                        continue;
                }
 
                if (do_srv) {
                        /* we are only interested in SRV records */
                        continue;
                }
 
                if (do_srv) {
                        /* we are only interested in SRV records */
-                       if (rr->type != T_SRV) {
+                       if (rr->type != rk_ns_c_in) {
                                continue;
                        }
 
                                continue;
                        }
 
@@ -187,7 +187,7 @@ static void run_child_dns_lookup(struct dns_ex_state *state, int fd)
                } else {
                        /* we are only interested in A records */
                        /* TODO: add AAAA support */
                } else {
                        /* we are only interested in A records */
                        /* TODO: add AAAA support */
-                       if (rr->type != T_A) {
+                       if (rr->type != rk_ns_t_a) {
                                continue;
                        }
 
                                continue;
                        }
 
@@ -204,12 +204,12 @@ static void run_child_dns_lookup(struct dns_ex_state *state, int fd)
        for (i=0; i < srv_valid; i++) {
                for (rr=reply->head;rr;rr=rr->next) {
 
        for (i=0; i < srv_valid; i++) {
                for (rr=reply->head;rr;rr=rr->next) {
 
-                       if (rr->class != C_IN) {
+                       if (rr->class != rk_ns_c_in) {
                                continue;
                        }
 
                        /* we are only interested in SRV records */
                                continue;
                        }
 
                        /* we are only interested in SRV records */
-                       if (rr->type != T_A) {
+                       if (rr->type != rk_ns_t_a) {
                                continue;
                        }
 
                                continue;
                        }