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 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. */
@@ -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 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. */
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;
-       char **realm;
 
        if (cred->ccache_obtained > obtained) {
                return 0;
@@ -98,8 +97,6 @@ static int cli_credentials_set_from_ccache(struct cli_credentials *cred,
                return ret;
        }
 
-       realm = krb5_princ_realm(ccache->smb_krb5_context->krb5_context, princ);
-
        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;
+       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;
        }
index 68e7eb90cc19540198c3c1405ca17b80c9f0926d..3314cbc5910b15a6541d2cf1cacf4e4d78e4ddcc 100644 (file)
 {
        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);
-               krb5_free_error_string(context, context_error);
+               krb5_free_error_message(context, context_error);
                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_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)
index 1889dcab4dac573a7d3804b158813738988dd0f7..a0b21c891a1cc992aa541ebe37ee5bcecd697d76 100644 (file)
 {
        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,
-                                                0, NULL, &options))) {
+                                                0, NULL, options))) {
                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_get_init_creds_opt_free(ctx, options);
                krb5_free_cred_contents(ctx, &my_creds);
                return code;
        }
@@ -69,6 +73,7 @@
                *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_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, 
-                                                NULL, 0, NULL, &options))) {
+                                                NULL, 0, NULL, options))) {
                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_get_init_creds_opt_free(ctx, options);
                krb5_free_cred_contents(ctx, &my_creds);
                return code;
        }
                *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;
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_clear_error_string(context);
+       krb5_clear_error_message(context);
 
        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 */
-       char **realm;
+       char *realm;
        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 */
-       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);
@@ -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;
-       char **realm;
+       char *realm;
        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, 
-                                   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;
        }
        
-       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_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)));
index 3b938248fcb7c159523686182682d5b66263db41..f130698597c86861fce9d59cf180d2a553377f8e 100644 (file)
@@ -1,4 +1,3 @@
-$Id$
 
 Heimdal is a Kerberos 5 implementation.
 
index b89ef790670b4b7fce0e306bc689e1359b4fd748..04733e12811d40531ee6040bc48fb27a55f790d2 100644 (file)
@@ -100,13 +100,16 @@ while(<>) {
        s/^\s*//;
        s/\s*$//;
        s/\s+/ /g;
-       if($_ =~ /\)$/){
+       if($_ =~ /\)$/ or $_ =~ /DEPRECATED$/){
            if(!/^static/ && !/^PRIVATE/){
-               if(/(.*)(__attribute__\s?\(.*\))/) {
-                   $attr = $2;
+               $attr = "";
+               if(m/(.*)(__attribute__\s?\(.*\))/) {
+                   $attr .= " $2";
+                   $_ = $1;
+               }
+               if(m/(.*)\s(\w+DEPRECATED)/) {
+                   $attr .= " $2";
                    $_ = $1;
-               } else {
-                   $attr = "";
                }
                # remove outer ()
                s/\s*\(/</;
@@ -308,7 +311,7 @@ extern \"C\" {
 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
@@ -320,7 +323,7 @@ if ($opt_E) {
     
     $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
index b4045094d8026522e0dee0671f66379eb44ed372..49c868ab0ec6042ead5b2e3d0999d1c62a919348 100644 (file)
@@ -5,7 +5,7 @@ dnl
 
 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
@@ -73,6 +73,15 @@ AC_FIND_FUNC(res_ndestroy, resolv,
 ],
 [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>
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);
+#ifdef DIGEST
     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;
        }
     }
+#endif
 
+#ifdef KX509
     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;
        }
     }
+#endif
 
     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) {
-       const char *user_id, *anchors, *ocsp_file;
+       const char *user_id, *anchors, *file;
        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);
 
-       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");
        }
 
+       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);
 
index 96986c1a877d3ab20582d884bb46967e10d7fc74..d13507fc1f80b8f55f5c8a70bab825b4f289ecfe 100644 (file)
@@ -34,7 +34,7 @@
 #include "kdc_locl.h"
 #include <hex.h>
 
-RCSID("$Id$");
+#ifdef DIGEST
 
 #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,
-              const DigestREQ *req, krb5_data *reply,
+              const struct DigestREQ *req, krb5_data *reply,
               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(&res, 0, sizeof(res));
 
     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);
+       krb5_data_zero(&buf);
        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);
+       krb5_data_zero(&buf);
        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;
        }
        
@@ -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);
+       free_Checksum(&res);
+       krb5_data_free(&buf);
        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_storage_free(sp);
+       sp = NULL;
        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_Checksum(&res);
     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>
+#ifdef DIGEST
 #include <digest_asn1.h>
+#endif
+#ifdef KX509
 #include <kx509_asn1.h>
+#endif
 #include <hdb.h>
 #include <hdb_err.h>
 #include <der.h>
 
+#ifndef NO_NTLM
 #include <heimntlm.h>
+#endif
 #include <windc_plugin.h>
 
 #undef ALLOC
index 9226ae115db0b9353679a6bf4d40bc20f3daae17..3702ab9281291836d18a78fa8bf31b6643edebd5 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "kdc_locl.h"
 
-RCSID("$Id$");
+#ifdef KRB4
 
 #include <krb5-v4compat.h>
 #include <rx.h>
@@ -949,3 +949,5 @@ out:
     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;
+    char *pkinit_kdc_friendly_name;
     int pkinit_dh_min_bits;
     int pkinit_require_binding;
+    int pkinit_allow_proxy_certs;
 
     krb5_log_facility *logf;
 
@@ -91,6 +93,20 @@ typedef struct 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
index 8e34c50049aa267b701c246494dec3b9ff713fab..9b291ac896511314b51cd1cdbde617c4a10098f7 100644 (file)
@@ -42,6 +42,8 @@
 #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;
@@ -52,9 +54,12 @@ extern krb5_addresses explicit_addresses;
 
 extern int enable_http;
 
+#ifdef SUPPORT_DETACH
+
 #define DETACH_IS_DEFAULT FALSE
 
 extern int detach_from_console;
+#endif
 
 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
-_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 &&
@@ -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 &&
-           !_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) {
@@ -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,
-                 int ckvno, const EncryptionKey *ckey,
+                 int ckvno, const EncryptionKey *reply_key,
                  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;
     }
-    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",
@@ -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,
-                 METHOD_DATA *md, hdb_entry *client,
-                 ENCTYPE *etypes, unsigned int etypes_len)
+                 METHOD_DATA *md, Key *ckey)
 {
     krb5_error_code ret = 0;
-    int i, j;
-    unsigned int n = 0;
     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;
-    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);
@@ -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,
-                  METHOD_DATA *md, hdb_entry *client,
-                  ENCTYPE *etypes, unsigned int etypes_len)
+                  METHOD_DATA *md, Key *ckey)
 {
     krb5_error_code ret = 0;
-    int i, j;
-    unsigned int n = 0;
     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;
-    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);
@@ -712,10 +607,12 @@ log_as_req(krb5_context context,
           const KDC_REQ_BODY *b)
 {
     krb5_error_code ret;
-    struct rk_strpool *p = NULL;
+    struct rk_strpool *p;
     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) {
@@ -733,10 +630,6 @@ log_as_req(krb5_context context,
     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;
@@ -745,21 +638,26 @@ log_as_req(krb5_context context,
        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)
-           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)
-           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;
 }
 
+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;
        }
+
        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);
 
+    /*
+     *
+     */
+
+    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){
@@ -1069,19 +1001,27 @@ _kdc_as_rep(krb5_context context,
        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;
+    }
 
-    memset(&et, 0, sizeof(et));
-    memset(&ek, 0, sizeof(ek));
+    /*
+     * Pre-auth processing
+     */
 
     if(req->padata){
        int i;
@@ -1097,17 +1037,15 @@ _kdc_as_rep(krb5_context context,
        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 = _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;
 
-           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,
@@ -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);
-
+               
                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,
@@ -1158,6 +1097,12 @@ _kdc_as_rep(krb5_context context,
        
            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,
@@ -1206,6 +1151,11 @@ _kdc_as_rep(krb5_context context,
                                              &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,
@@ -1298,6 +1248,7 @@ _kdc_as_rep(krb5_context context,
            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;
@@ -1310,6 +1261,10 @@ _kdc_as_rep(krb5_context context,
        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;
@@ -1317,12 +1272,20 @@ _kdc_as_rep(krb5_context context,
 
 #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);
+       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;
@@ -1330,22 +1293,37 @@ _kdc_as_rep(krb5_context context,
 #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);
@@ -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;
-    }
-       
+
+    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);
@@ -1449,12 +1433,14 @@ _kdc_as_rep(krb5_context context,
 
     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,
@@ -1500,11 +1486,12 @@ _kdc_as_rep(krb5_context context,
        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;
-    copy_PrincipalName(&rep.cname, &et.cname);
-    copy_Realm(&rep.crealm, &et.crealm);
 
     {
        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);
 
-    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.
@@ -1637,12 +1622,12 @@ _kdc_as_rep(krb5_context context,
     rep.padata->len = 0;
     rep.padata->val = NULL;
 
-    reply_key = &ckey->key;
 #if PKINIT
     if (pkp) {
+        e_text = "Failed to build PK-INIT reply";
        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,
@@ -1651,10 +1636,25 @@ _kdc_as_rep(krb5_context context,
                                           &et);
        if (ret)
            goto out;
-    }
+    } else
 #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) {
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,
-                       KRB5SignedPathPrincipals *principals,
+                       krb5_principals principals,
                        EncTicketPart *tkt)
 {
     krb5_error_code ret;
@@ -117,7 +117,7 @@ _kdc_add_KRB5SignedPath(krb5_context context,
     size_t size;
 
     if (server && principals) {
-       ret = add_KRB5SignedPathPrincipals(principals, server);
+       ret = add_Principals(principals, server);
        if (ret)
            return ret;
     }
@@ -186,7 +186,7 @@ check_KRB5SignedPath(krb5_context context,
                     krb5_kdc_configuration *config,
                     hdb_entry_ex *krbtgt,
                     EncTicketPart *tkt,
-                    KRB5SignedPathPrincipals **delegated,
+                    krb5_principals *delegated,
                     int *signedpath)
 {
     krb5_error_code ret;
@@ -255,7 +255,7 @@ check_KRB5SignedPath(krb5_context context,
                return ENOMEM;
            }
 
-           ret = copy_KRB5SignedPathPrincipals(*delegated, sp.delegated);
+           ret = copy_Principals(*delegated, sp.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,
-              KRB5SignedPathPrincipals *spp,
+              krb5_principals spp,
               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,
-                                *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;
 
-    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);
 /*
@@ -888,7 +887,7 @@ tgs_make_reply(krb5_context context,
     }
 
     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;
@@ -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)
+    else if (server->name.name_string.len > 1)
        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;
 
-       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",
@@ -1232,6 +1229,7 @@ tgs_parse_request(krb5_context context,
            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",
@@ -1251,7 +1249,6 @@ tgs_parse_request(krb5_context context,
            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);
@@ -1365,8 +1362,7 @@ tgs_build_reply(krb5_context context,
                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;
@@ -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;
-    KRB5SignedPathPrincipals *spp = NULL;
-    Key *tkey;
+    krb5_principals spp = NULL;
     const EncryptionKey *ekey;
     krb5_keyblock sessionkey;
     krb5_kvno kvno;
     krb5_data rspac;
-    int cross_realm = 0;
 
     METHOD_DATA enc_pa_data;
 
@@ -1392,6 +1386,8 @@ tgs_build_reply(krb5_context context,
     char opt_str[128];
     int signedpath = 0;
 
+    Key *tkey;
+
     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));
-
-       cross_realm = 1;
     }
 
     /*
@@ -1578,9 +1572,10 @@ server_lookup:
                    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);
-               return KRB5KDC_ERR_ETYPE_NOSUPP;
+               ret = KRB5KDC_ERR_ETYPE_NOSUPP;
+               goto out;
            }
            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);
-               return ret;
+               goto out;
            }
            ekey = &skey->key;
            kvno = server->entry.kvno;
@@ -1603,10 +1598,6 @@ server_lookup:
            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
@@ -1628,13 +1619,15 @@ server_lookup:
        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,
-               "Failed to find key for krbtgt PAC check");
+                   "Failed to find key for krbtgt PAC check");
        goto out;
     }
 
@@ -1672,7 +1665,7 @@ server_lookup:
        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;
@@ -2044,8 +2037,7 @@ _kdc_tgs_rep(krb5_context context,
                          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);
index 83e05b81c5952ed2d2f26240d7140eb2410c6df4..8f7f3a27fb0d71c46dab9eb30727496a7b807b87 100644 (file)
 #include <rfc2459_asn1.h>
 #include <hx509.h>
 
-RCSID("$Id$");
+#ifdef KX509
 
 /*
  *
  */
 
 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;
@@ -97,16 +97,15 @@ calculate_reply_hash(krb5_context context,
                     krb5_keyblock *key,
                     Kx509Response *rep)
 {
+    krb5_error_code ret;
     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);
-    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;
@@ -208,7 +207,7 @@ build_certificate(krb5_context context,
        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";
@@ -289,7 +288,7 @@ out:
 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;
@@ -385,8 +384,10 @@ _kdc_do_kx509(krb5_context context,
        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);
@@ -458,3 +459,5 @@ out:
 
     return 0;
 }
+
+#endif /* KX509 */
index 82358682d8d9f9cb5f6bf6a97794932bd7241107..22734be811e379f486bef3a01df6d80becfaa071 100644 (file)
@@ -47,14 +47,26 @@ RCSID("$Id$");
 
 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;
-    DH *dh;
     EncryptionKey reply_key;
     char *dh_group_name;
     hx509_peer_info peer;
     hx509_certs client_anchors;
+    hx509_verify_ctx verify_ctx;
 };
 
 struct pk_principal_mapping {
@@ -155,29 +167,43 @@ out:
 }
 
 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
-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;
@@ -186,36 +212,84 @@ generate_dh_keyblock(krb5_context context, pk_client_params *client_params,
 
     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;
-       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;
     }
 
@@ -223,7 +297,7 @@ generate_dh_keyblock(krb5_context context, pk_client_params *client_params,
                                   enctype,
                                   dh_gen_key, dh_gen_keylen,
                                   NULL, NULL,
-                                  reply_key);
+                                  &client_params->reply_key);
 
  out:
     if (dh_gen_key)
@@ -261,10 +335,12 @@ get_dh_param(krb5_context context,
 
     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) {
@@ -284,15 +360,6 @@ get_dh_param(krb5_context context,
        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);
@@ -331,17 +398,17 @@ get_dh_param(krb5_context context,
            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);
-       if (client_params->dh_public_key == NULL) {
+       if (client_params->u.dh.public_key == NULL) {
            ret = KRB5_BADMSGTYPE;
            goto out;
        }
     }
 
-    client_params->dh = dh;
+    client_params->u.dh.key = dh;
     dh = NULL;
     ret = 0;
 
@@ -352,20 +419,88 @@ get_dh_param(krb5_context context,
     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,
+                 hdb_entry_ex *client,
                  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";
+    hx509_certs trust_anchors;
     int have_data = 0;
+    const HDB_Ext_PKINIT_cert *pc;
 
     *ret_params = NULL;
 
@@ -375,20 +510,73 @@ _kdc_pk_rd_padata(krb5_context context,
        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;
     }
 
+    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 (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,
@@ -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,
-                                  "Can't decode PK-AS-REQ: %d", ret);
+                                  "Can't unwrap ContentInfo(win): %d", ret);
            goto out;
        }
 
@@ -420,25 +608,35 @@ _kdc_pk_rd_padata(krb5_context context,
                                  &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;
-           unsigned int i;
+           unsigned int i, maxedi;
 
            ret = hx509_certs_init(kdc_identity->hx509ctx,
                                   "MEMORY:client-anchors",
                                   0, NULL,
-                                  &client_params->client_anchors);
+                                  &cp->client_anchors);
            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;
 
            }
-           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;
@@ -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);
-               if (ret)
+               if (ret) {
+                   hx509_query_free(kdc_identity->hx509ctx, q);
                    continue;
+               }
 
                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,
-                               client_params->client_anchors, cert);
+                               cp->client_anchors, cert);
                hx509_cert_free(cert);
            }
        }
@@ -497,7 +697,7 @@ _kdc_pk_rd_padata(krb5_context context,
        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,
@@ -514,9 +714,14 @@ _kdc_pk_rd_padata(krb5_context context,
 
     {
        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,
-                                     kdc_identity->verify_ctx,
+                                     cp->verify_ctx,
+                                     flags,
                                      signed_content.data,
                                      signed_content.length,
                                      NULL,
@@ -532,16 +737,18 @@ _kdc_pk_rd_padata(krb5_context context,
            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 (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");
@@ -556,7 +763,8 @@ _kdc_pk_rd_padata(krb5_context context,
                                    &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;
        }
 
@@ -568,12 +776,13 @@ _kdc_pk_rd_padata(krb5_context context,
            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;
-           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);
@@ -586,11 +795,21 @@ _kdc_pk_rd_padata(krb5_context context,
                              &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;
        }
 
+       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);
@@ -599,33 +818,55 @@ _kdc_pk_rd_padata(krb5_context context,
            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) {
-           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;
            }
-       }
+       } 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) {
-           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,
-                                              client_params->peer,
+                                              cp->peer,
                                               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
@@ -642,10 +883,10 @@ out:
     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;
 }
 
@@ -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,
-                     pk_client_params *client_params,
+                     pk_client_params *cp,
                      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;
@@ -685,13 +927,15 @@ pk_mk_pa_reply_enckey(krb5_context context,
     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.
      */
 
-    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
@@ -699,14 +943,14 @@ pk_mk_pa_reply_enckey(krb5_context context,
        {
            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:
-       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");
@@ -721,7 +965,7 @@ pk_mk_pa_reply_enckey(krb5_context context,
            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,
@@ -777,7 +1021,8 @@ pk_mk_pa_reply_enckey(krb5_context context,
            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,
@@ -794,19 +1039,19 @@ pk_mk_pa_reply_enckey(krb5_context context,
                                        buf.length,
                                        NULL,
                                        cert,
-                                       client_params->peer,
-                                       client_params->client_anchors,
+                                       cp->peer,
+                                       cp->client_anchors,
                                        kdc_identity->certpool,
                                        &signed_data);
-       hx509_cert_free(cert);
+       *kdc_cert = cert;
     }
 
     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)
@@ -816,8 +1061,8 @@ pk_mk_pa_reply_enckey(krb5_context context,
     }
 
     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);
@@ -826,9 +1071,14 @@ pk_mk_pa_reply_enckey(krb5_context context,
 
     ret = _krb5_pk_mk_ContentInfo(context,
                                  &buf,
-                                 oid_id_pkcs7_envelopedData(),
+                                 &asn1_oid_id_pkcs7_envelopedData,
                                  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;
@@ -840,9 +1090,8 @@ out:
 
 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)
 {
@@ -850,33 +1099,63 @@ pk_mk_pa_reply_dh(krb5_context context,
     krb5_data signed_data, buf;
     ContentInfo contentinfo;
     krb5_error_code ret;
+    hx509_cert cert;
+    hx509_query *q;
     size_t size;
-    heim_integer i;
 
     memset(&contentinfo, 0, sizeof(contentinfo));
     memset(&dh_info, 0, sizeof(dh_info));
-    krb5_data_zero(&buf);
     krb5_data_zero(&signed_data);
+    krb5_data_zero(&buf);
 
     *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);
@@ -893,44 +1172,42 @@ pk_mk_pa_reply_dh(krb5_context context,
      * 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;
+    
+    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,
-                                 oid_id_pkcs7_signedData(),
+                                 &asn1_oid_id_pkcs7_signedData,
                                  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,
-                   pk_client_params *client_params,
+                   pk_client_params *cp,
                    const hdb_entry_ex *client,
+                   krb5_enctype sessionetype,
                    const KDC_REQ *req,
                    const krb5_data *req_buffer,
                    krb5_keyblock **reply_key,
+                   krb5_keyblock *sessionkey,
                    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;
 
-    if (client_params->type == PKINIT_27) {
+    if (cp->type == PKINIT_27) {
        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;
 
-       if (client_params->dh == NULL) {
+       if (cp->keyex == USE_RSA) {
            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,
-                                               &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,
-                                       client_params,
+                                       cp,
                                        req,
                                        req_buffer,
-                                       &client_params->reply_key,
-                                       &info);
+                                       &cp->reply_key,
+                                       &info,
+                                       &kdc_cert);
            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");
 
+           ret = krb5_generate_random_keyblock(context, sessionetype, 
+                                               sessionkey);
+           if (ret) {
+               free_PA_PK_AS_REP(&rep);
+               goto out;
+           }
+
        } 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;
 
-           ret = generate_dh_keyblock(context, client_params, enctype,
-                                      &client_params->reply_key);
+           ret = generate_dh_keyblock(context, cp, enctype);
            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);
+           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) {
-               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;
@@ -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 (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) {
-           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)
@@ -1085,13 +1391,14 @@ _kdc_pk_mk_pa_reply(krb5_context context,
 
        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;
 
-       if (client_params->dh) {
+       if (cp->keyex != USE_RSA) {
            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;
        }
 
@@ -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,
-                                           &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,
-                                   client_params,
+                                   cp,
                                    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;
@@ -1140,13 +1448,19 @@ _kdc_pk_mk_pa_reply(krb5_context context,
        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) {
-       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;
     }
@@ -1232,7 +1546,7 @@ out:
        hx509_cert_free(kdc_cert);
 
     if (ret == 0)
-       *reply_key = &client_params->reply_key;
+       *reply_key = &cp->reply_key;
     return ret;
 }
 
@@ -1250,7 +1564,7 @@ match_rfc_san(krb5_context context,
 
     ret = hx509_cert_find_subjectAltName_otherName(hx509ctx,
                                                   client_cert,
-                                                  oid_id_pkinit_san(),
+                                                  &asn1_oid_id_pkinit_san,
                                                   &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,
-                                                  oid_id_pkinit_ms_san(),
+                                                  &asn1_oid_id_pkinit_ms_san,
                                                   &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,
-                    pk_client_params *client_params,
+                    pk_client_params *cp,
                     char **subject_name)
 {
     const HDB_Ext_PKINIT_acl *acl;
+    const HDB_Ext_PKINIT_cert *pc;
     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,
-                                     client_params->cert,
+                                     cp->cert,
                                      &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);
 
+    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,
-                           client_params->cert,
+                           cp->cert,
                            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,
-                              client_params->cert,
+                              cp->cert,
                               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,
-                            pk_client_params *params,
+                            pk_client_params *cp,
                             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,
+                          0,
                           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_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,
@@ -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,
-                                    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 "
-                          "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");
     }
 
-    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,
index a27911914b52434fba48ae7463275a830335fb06..d3557ee6c9e45af0733ba5006d73f0c09bfcd251 100644 (file)
@@ -34,8 +34,6 @@
 
 #include "kdc_locl.h"
 
-RCSID("$Id$");
-
 /*
  *
  */
@@ -49,6 +47,209 @@ krb5_kdc_update_time(struct timeval *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'.
@@ -65,50 +266,25 @@ krb5_kdc_process_request(krb5_context context,
                         struct sockaddr *addr,
                         int datagram_reply)
 {
-    KDC_REQ req;
-    Ticket ticket;
-    DigestREQ digestreq;
-    Kx509Request kx509req;
     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;
 }
 
@@ -129,25 +305,24 @@ krb5_kdc_process_krb5_request(krb5_context context,
                              struct sockaddr *addr,
                              int datagram_reply)
 {
-    KDC_REQ req;
     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;
 }
 
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 {
-       ret = krb5_cc_gen_new(context, &krb5_mcc_ops, &id);
+       ret = krb5_cc_new_unique(context, krb5_cc_type_memory, NULL, &id);
        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) {
index fbb2d2287bcd012b4b2d7cda162b98742b768ae7..350988dbac9667e06c091e9a2764c093851d8359 100644 (file)
  */
 
 #include "kuser_locl.h"
-RCSID("$Id$");
 
+#ifndef HEIMDAL_SMALLER
 #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"
+#endif
 
 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;
+static int switch_cache_flags = 1;
 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 pk_enterprise_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;
+#ifndef NO_NTLM
 static char *ntlm_domain;
+#endif
 
 
 static struct getargs args[] = {
@@ -154,7 +167,13 @@ static struct getargs args[] = {
 
     { "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
+    { "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" },
 
@@ -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
+#ifndef NO_NTLM
     { "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", "") },
@@ -198,13 +222,13 @@ get_server(krb5_context context,
           const char *server,
           krb5_principal *princ)
 {
-    krb5_realm *client_realm;
+    krb5_const_realm realm;
     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
@@ -301,7 +325,7 @@ renew_validate(krb5_context context,
     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;
@@ -337,8 +361,10 @@ renew_validate(krb5_context context,
        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);
+#endif
     }
 
     krb5_free_creds (context, out);
@@ -351,6 +377,8 @@ out:
     return ret;
 }
 
+#ifndef NO_NTLM
+
 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;
 }
+#endif
 
 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;
-    struct ntlm_buf ntlmkey;
     krb5_ccache tempccache;
-
+#ifndef NO_NTLM
+    struct ntlm_buf ntlmkey;
     memset(&ntlmkey, 0, sizeof(ntlmkey));
+#endif
     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);
-    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);
-    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,
-                                                pk_use_enckey ? 2 : 0,
+                                                pk_use_enckey ? 2 : 0 |
+                                                anonymous_flag ? 4 : 0,
                                                 krb5_prompter_posix,
                                                 NULL,
                                                 passwd);
@@ -510,7 +543,7 @@ get_new_tickets(krb5_context context,
                                          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,
@@ -552,8 +585,10 @@ get_new_tickets(krb5_context context,
                                            opt);
     }
     krb5_get_init_creds_opt_free(context, opt);
+#ifndef NO_NTLM
     if (ntlm_domain && passwd[0])
        heim_ntlm_nt_key(passwd, &ntlmkey);
+#endif
     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 (switch_cache_flags)
+       krb5_cc_switch(context, ccache);
+
+#ifndef NO_NTLM
     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;
@@ -704,8 +744,10 @@ renew_func(void *ptr)
     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);
+#endif
 
     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;
 
-    if (canonicalize_flag)
+    if (canonicalize_flag || enterprise_flag)
        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)
-           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)
-           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)
@@ -788,7 +848,7 @@ main (int argc, char **argv)
     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",
@@ -818,8 +878,10 @@ main (int argc, char **argv)
     if (ret)
        krb5_err (context, 1, ret, N_("resolving credentials cache", ""));
 
+#ifndef NO_AFS
     if(argc > 1 && k_hasafs ())
        k_setpag();
+#endif
 
     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
+#ifndef NO_AFS
     if(do_afslog && k_hasafs())
        krb5_afslog(context, ccache, NULL, NULL);
+#endif
     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 NO_AFS
        if(k_hasafs())
            k_unlog();
+#endif
     } 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__
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
-#endif
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -81,7 +79,9 @@
 #ifdef HAVE_SYS_IOCCOM_H
 #include <sys/ioccom.h>
 #endif
+#ifndef NO_AFS
 #include <kafs.h>
+#endif
 #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 INDEF_OVERRUN,      "ASN.1 BER indefinte encoding overrun"
+error_code INDEF_UNDERRUN,     "ASN.1 BER indefinte encoding underun"
 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);
-       
+
        if (fwrite(p + sizeof(p) - sz , sz, 1, fout) != 1)
            err(1, "fwrite length/tag failed");
        offset += sz;
-       
+
        if (data) {
            size_t datalen;
-       
+
            datalen = strlen(data) / 2;
            pdata = emalloc(sz);
-       
+
            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;
-       
+
            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
 
-Kaka2  ::= SEQUENCE { 
+Kaka2  ::= SEQUENCE {
         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 {
-          CMSVersion_v0(0), 
-          CMSVersion_v1(1), 
+          CMSVersion_v0(0),
+          CMSVersion_v1(1),
           CMSVersion_v2(2),
           CMSVersion_v3(3),
           CMSVersion_v4(4)
@@ -34,7 +34,7 @@ MessageDigest ::= OCTET STRING
 
 ContentInfo ::= SEQUENCE {
        contentType ContentType,
-       content [0] EXPLICIT heim_any OPTIONAL --  DEFINED BY contentType 
+       content [0] EXPLICIT heim_any OPTIONAL --  DEFINED BY contentType
 }
 
 EncapsulatedContentInfo ::= SEQUENCE {
@@ -53,7 +53,7 @@ IssuerAndSerialNumber ::= SEQUENCE {
        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 {
@@ -67,7 +67,7 @@ RecipientIdentifier ::= CMSIdentifier
 --- 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
 
@@ -79,7 +79,7 @@ SignerInfo ::= SEQUENCE {
                SET OF Attribute OPTIONAL,
        signatureAlgorithm SignatureAlgorithmIdentifier,
        signature SignatureValue,
-       unsignedAttrs [1] IMPLICIT -- CMSAttributes -- 
+       unsignedAttrs [1] IMPLICIT -- CMSAttributes --
                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,
-    UT_Integer         = 2,    
+    UT_Integer         = 2,
     UT_BitString       = 3,
     UT_OctetString     = 4,
     UT_Null            = 5,
index 8a709664133d3ab28990045a596afe6624a99cd8..8144639b9a940fb41f853eaa16e7f8a4a1c9f7ea 100644 (file)
 
 #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
@@ -251,6 +247,75 @@ der_get_octet_string (const unsigned char *p, size_t len,
     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)
@@ -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;
-       
+
        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_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;
-    Der_type thistype;
     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 (class != thisclass || type != thistype)
+    if (class != thisclass)
        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,
-                         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;
 
-    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;
-    p += l;
-    len -= l;
-    ret += l;
-    if(size) *size = ret;
+    if(size) *size = ret + l;
     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
@@ -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;
-    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;
 }
index f8a21de71c1d78ab7493bf230fd46d4fb253111d..1f27e7290304d2f6002c9dff31764f6db5df6cc1 100644 (file)
@@ -36,9 +36,9 @@
 #ifndef __DER_LOCL_H__
 #define __DER_LOCL_H__
 
-#ifdef HAVE_CONFIG_H
+
 #include <config.h>
-#endif
+
 #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;
-       
+
        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
--- 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))))
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;
-    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);
-
+   
     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");
     }
+
+    /* public header file */
     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)
-       err (1, "open %s", header);
+       err (1, "open %s", fn);
+    free(fn);
+
     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;
@@ -267,7 +274,7 @@ generate_header_of_codefile(const char *name)
 
 }
 
-static void
+void
 close_codefile(void)
 {
     if (codefile == NULL)
@@ -296,7 +303,8 @@ generate_constant (const Symbol *s)
        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)
@@ -320,9 +328,13 @@ generate_constant (const Symbol *s)
        }
 
        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);
 
+
        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, "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"
-                "return &oid_%s_variable;\n"
+                "return &asn1_oid_%s;\n"
                 "}\n\n",
                 s->gen_name, s->gen_name);
 
-       close_codefile();
+       free(list);
+
+       if (!one_code_file)
+           close_codefile();
 
        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;
-               
+       
                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)
 {
-    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);
@@ -798,5 +814,9 @@ generate_type (const Symbol *s)
     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++;
            }
-           fprintf(codefile, "}\n");   
+           fprintf(codefile, "}\n");
        }
        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,
-            const char *forwstr, const char *tmpstr)
+            const char *forwstr, const char *tmpstr, const char *dertype)
 {
     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:
+       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);
+       if (dertype)
+           fprintf(codefile, "}\n");
        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");
-           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);
        }
-       
+
        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);
-           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);
@@ -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");
-       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"
@@ -480,21 +490,37 @@ decode_type (const char *name, const Type *t, int optional,
        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"
-               "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,
-                   "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),
-               is_primitive_type(t->subtype->type) ? "PRIM" : "CONS",
+               typestring,
                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"
@@ -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);
-       if(dce_fix)
+       if(support_ber)
            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"
@@ -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");
-       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,
-                   "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"
-                   "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);
@@ -540,6 +574,7 @@ decode_type (const char *name, const Type *t, int optional,
        fprintf(codefile,
                "}\n");
        free(tname);
+       free(typestring);
        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;
-       
+
            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");
-           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);
@@ -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' */
 
-       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"
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;
-       
+
        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)
-           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"
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) {
            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;
-       
+
            if (m->ellipsis) {
                have_ellipsis = m;
                continue;
index c8b38963141ac36d2b5f3c1649391d15aff75767..2bb64b5a38590c5cbc6f3241de3cbd6636a00c70 100644 (file)
@@ -36,9 +36,8 @@
 #ifndef __GEN_LOCL_H__
 #define __GEN_LOCL_H__
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
-#endif
+
 #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 *);
 
+void generate_header_of_codefile(const char *);
+void close_codefile(void);
+
+
 extern FILE *headerfile, *codefile, *logfile;
-extern int dce_fix;
+extern int support_ber;
 extern int rfc1510_bitstring;
+extern int one_code_file;
 
 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_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
@@ -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-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
@@ -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-S4U2SELF(129),
-       KRB5-PADATA-EPAC(130),                  -- EPAK
-       KRB5-PADATA-PK-AS-09-BINDING(132),      -- client send this to 
-