heimdal: update to lorikeet-heimdal rev 801
authorStefan Metzmacher <metze@samba.org>
Fri, 1 Aug 2008 05:08:51 +0000 (07:08 +0200)
committerStefan Metzmacher <metze@samba.org>
Fri, 1 Aug 2008 14:11:00 +0000 (16:11 +0200)
metze
(This used to be commit d6c54a66fb23c784ef221a3c1cf766b72bdb5a0b)

233 files changed:
source4/heimdal/README
source4/heimdal/cf/check-var.m4
source4/heimdal/cf/find-func-no-libs.m4
source4/heimdal/cf/find-func-no-libs2.m4
source4/heimdal/cf/find-func.m4
source4/heimdal/cf/resolv.m4
source4/heimdal/kdc/default_config.c
source4/heimdal/kdc/digest.c
source4/heimdal/kdc/kaserver.c
source4/heimdal/kdc/kerberos5.c
source4/heimdal/kdc/krb5tgs.c
source4/heimdal/kdc/kx509.c
source4/heimdal/kdc/misc.c
source4/heimdal/kdc/pkinit.c
source4/heimdal/kdc/process.c
source4/heimdal/kdc/windc.c
source4/heimdal/kdc/windc_plugin.h
source4/heimdal/kuser/kinit.c
source4/heimdal/lib/asn1/der.h
source4/heimdal/lib/asn1/der_free.c
source4/heimdal/lib/asn1/gen.c
source4/heimdal/lib/asn1/k5.asn1
source4/heimdal/lib/asn1/lex.c
source4/heimdal/lib/asn1/lex.l
source4/heimdal/lib/asn1/pkinit.asn1
source4/heimdal/lib/asn1/test.gen
source4/heimdal/lib/com_err/lex.c
source4/heimdal/lib/com_err/lex.l
source4/heimdal/lib/gssapi/gssapi/gssapi.h
source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h
source4/heimdal/lib/gssapi/gssapi/gssapi_spnego.h
source4/heimdal/lib/gssapi/krb5/accept_sec_context.c
source4/heimdal/lib/gssapi/krb5/delete_sec_context.c
source4/heimdal/lib/gssapi/krb5/display_status.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_sec_context.c
source4/heimdal/lib/gssapi/krb5/init_sec_context.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/gss_acquire_cred.c
source4/heimdal/lib/gssapi/mech/gss_add_cred.c
source4/heimdal/lib/gssapi/mech/gss_add_oid_set_member.c
source4/heimdal/lib/gssapi/mech/gss_buffer_set.c
source4/heimdal/lib/gssapi/mech/gss_canonicalize_name.c
source4/heimdal/lib/gssapi/mech/gss_compare_name.c
source4/heimdal/lib/gssapi/mech/gss_context_time.c
source4/heimdal/lib/gssapi/mech/gss_create_empty_oid_set.c
source4/heimdal/lib/gssapi/mech/gss_decapsulate_token.c
source4/heimdal/lib/gssapi/mech/gss_delete_sec_context.c
source4/heimdal/lib/gssapi/mech/gss_display_name.c
source4/heimdal/lib/gssapi/mech/gss_display_status.c
source4/heimdal/lib/gssapi/mech/gss_encapsulate_token.c
source4/heimdal/lib/gssapi/mech/gss_export_name.c
source4/heimdal/lib/gssapi/mech/gss_export_sec_context.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_import_sec_context.c
source4/heimdal/lib/gssapi/mech/gss_indicate_mechs.c
source4/heimdal/lib/gssapi/mech/gss_init_sec_context.c
source4/heimdal/lib/gssapi/mech/gss_inquire_context.c
source4/heimdal/lib/gssapi/mech/gss_inquire_cred.c
source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_mech.c
source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_oid.c
source4/heimdal/lib/gssapi/mech/gss_inquire_mechs_for_name.c
source4/heimdal/lib/gssapi/mech/gss_inquire_names_for_mech.c
source4/heimdal/lib/gssapi/mech/gss_inquire_sec_context_by_oid.c
source4/heimdal/lib/gssapi/mech/gss_krb5.c
source4/heimdal/lib/gssapi/mech/gss_mech_switch.c
source4/heimdal/lib/gssapi/mech/gss_oid_equal.c
source4/heimdal/lib/gssapi/mech/gss_oid_to_str.c
source4/heimdal/lib/gssapi/mech/gss_process_context_token.c
source4/heimdal/lib/gssapi/mech/gss_release_buffer.c
source4/heimdal/lib/gssapi/mech/gss_release_cred.c
source4/heimdal/lib/gssapi/mech/gss_release_name.c
source4/heimdal/lib/gssapi/mech/gss_release_oid.c
source4/heimdal/lib/gssapi/mech/gss_release_oid_set.c
source4/heimdal/lib/gssapi/mech/gss_seal.c
source4/heimdal/lib/gssapi/mech/gss_set_cred_option.c
source4/heimdal/lib/gssapi/mech/gss_set_sec_context_option.c
source4/heimdal/lib/gssapi/mech/gss_sign.c
source4/heimdal/lib/gssapi/mech/gss_test_oid_set_member.c
source4/heimdal/lib/gssapi/mech/gss_unseal.c
source4/heimdal/lib/gssapi/mech/gss_unwrap.c
source4/heimdal/lib/gssapi/mech/gss_verify.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/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/spnego-private.h
source4/heimdal/lib/gssapi/spnego/spnego_locl.h
source4/heimdal/lib/hcrypto/aes.c [changed mode: 0755->0644]
source4/heimdal/lib/hcrypto/aes.h [changed mode: 0755->0644]
source4/heimdal/lib/hcrypto/bn.c
source4/heimdal/lib/hcrypto/camellia-ntt.c
source4/heimdal/lib/hcrypto/camellia-ntt.h
source4/heimdal/lib/hcrypto/camellia.h
source4/heimdal/lib/hcrypto/des.c
source4/heimdal/lib/hcrypto/des.h
source4/heimdal/lib/hcrypto/evp.c
source4/heimdal/lib/hcrypto/evp.h
source4/heimdal/lib/hcrypto/imath/LICENSE
source4/heimdal/lib/hcrypto/pkcs12.c
source4/heimdal/lib/hcrypto/pkcs5.c
source4/heimdal/lib/hcrypto/rand-egd.c
source4/heimdal/lib/hcrypto/rand-fortuna.c
source4/heimdal/lib/hcrypto/rand-unix.c
source4/heimdal/lib/hcrypto/rand.c
source4/heimdal/lib/hcrypto/rc2.c [changed mode: 0755->0644]
source4/heimdal/lib/hcrypto/rc2.h [changed mode: 0755->0644]
source4/heimdal/lib/hcrypto/rc4.c [changed mode: 0755->0644]
source4/heimdal/lib/hcrypto/rijndael-alg-fst.c [changed mode: 0755->0644]
source4/heimdal/lib/hcrypto/rijndael-alg-fst.h [changed mode: 0755->0644]
source4/heimdal/lib/hcrypto/rnd_keys.c
source4/heimdal/lib/hcrypto/ui.c
source4/heimdal/lib/hdb/db.c
source4/heimdal/lib/hdb/dbinfo.c
source4/heimdal/lib/hdb/ext.c
source4/heimdal/lib/hdb/hdb.c
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/crypto.c
source4/heimdal/lib/hx509/env.c
source4/heimdal/lib/hx509/file.c
source4/heimdal/lib/hx509/hx509-private.h
source4/heimdal/lib/hx509/hx509-protos.h
source4/heimdal/lib/hx509/hx509.h
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_p11.c
source4/heimdal/lib/hx509/ks_p12.c
source4/heimdal/lib/hx509/name.c
source4/heimdal/lib/hx509/req.c
source4/heimdal/lib/hx509/revoke.c
source4/heimdal/lib/hx509/sel-gram.c [new file with mode: 0644]
source4/heimdal/lib/hx509/sel-gram.h [new file with mode: 0644]
source4/heimdal/lib/hx509/sel-gram.y [new file with mode: 0644]
source4/heimdal/lib/hx509/sel-lex.c [new file with mode: 0644]
source4/heimdal/lib/hx509/sel-lex.l [new file with mode: 0644]
source4/heimdal/lib/hx509/sel.c [new file with mode: 0644]
source4/heimdal/lib/hx509/sel.h [new file with mode: 0644]
source4/heimdal/lib/hx509/test_name.c
source4/heimdal/lib/krb5/acache.c
source4/heimdal/lib/krb5/addr_families.c
source4/heimdal/lib/krb5/auth_context.c
source4/heimdal/lib/krb5/build_auth.c
source4/heimdal/lib/krb5/cache.c
source4/heimdal/lib/krb5/changepw.c
source4/heimdal/lib/krb5/config_file.c
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/error_string.c
source4/heimdal/lib/krb5/expand_hostname.c
source4/heimdal/lib/krb5/fcache.c
source4/heimdal/lib/krb5/generate_subkey.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/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-private.h
source4/heimdal/lib/krb5/krb5-protos.h
source4/heimdal/lib/krb5/krb5.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/mk_priv.c
source4/heimdal/lib/krb5/mk_rep.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/rd_cred.c
source4/heimdal/lib/krb5/rd_error.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/send_to_kdc_plugin.h [new file with mode: 0644]
source4/heimdal/lib/krb5/set_default_realm.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/warn.c
source4/heimdal/lib/ntlm/ntlm.c
source4/heimdal/lib/roken/dumpdata.c
source4/heimdal/lib/roken/err.hin
source4/heimdal/lib/roken/resolve.c
source4/heimdal/lib/roken/roken-common.h
source4/heimdal/lib/roken/roken.h.in
source4/heimdal/lib/roken/vis.hin
source4/heimdal/lib/wind/stringprep.c
source4/heimdal/lib/wind/utf8.c
source4/heimdal/lib/wind/wind.h
source4/heimdal/lib/wind/wind_err.et
source4/heimdal/lib/wind/windlocl.h

index 131cc574fb7c9b03b18520356e52499fc2509841..88ab7fd12135aef1117c8534cef0c3a36d8787ef 100644 (file)
@@ -1,6 +1,19 @@
-This directory contains a copy of portions of a project known as
-'lorikeet-heimdal', a branch of the Heimdal Kerberos distribution.
+$Id: README 8839 2000-07-27 02:33:54Z assar $
 
-The purpose of these files is to provide kerberos support to Samba4 in
-a predicatable manner, without reliance on the system kerberos
-libraries.
+Heimdal is a Kerberos 5 implementation.
+
+Please see the manual in doc, by default installed in
+/usr/heimdal/info/heimdal.info for information on how to install.
+There are also briefer man pages for most of the commands.
+
+Bug reports and bugs are appreciated, see more under Bug reports in
+the manual on how we prefer them.
+
+For more information see the web-page at
+<http://www.pdc.kth.se/heimdal/> or the mailing lists:
+
+heimdal-announce@sics.se       low-volume announcement
+heimdal-discuss@sics.se                high-volume discussion
+
+send a mail to heimdal-announce-request@sics.se and
+heimdal-discuss-request@sics.se respectively to subscribe.
index 1f06b479c6cba1f35634ac0bb21e17b8c4c2403f..ffa61915e9a2f35c3ea9d5271a0881d9c13e94d3 100644 (file)
@@ -1,4 +1,4 @@
-dnl $Id: check-var.m4,v 1.12 2005/06/16 18:59:10 lha Exp $
+dnl $Id: check-var.m4 15422 2005-06-16 18:59:29Z lha $
 dnl
 dnl rk_CHECK_VAR(variable, includes)
 AC_DEFUN([rk_CHECK_VAR], [
@@ -23,4 +23,5 @@ if test "$ac_foo" = yes; then
 fi
 ])
 
+dnl AC_WARNING_ENABLE([obsolete])
 AU_DEFUN([AC_CHECK_VAR], [rk_CHECK_VAR([$2], [$1])], [foo])
index 03ff6dc02be5caf37b5fff9e617bf4ffc1d6fb7b..76965a84ee8aa7942f0c8b8fa5d81327cd6a1f8e 100644 (file)
@@ -1,4 +1,4 @@
-dnl $Id: find-func-no-libs.m4,v 1.6 2004/02/12 14:20:45 lha Exp $
+dnl $Id: find-func-no-libs.m4 13338 2004-02-12 14:21:14Z lha $
 dnl
 dnl
 dnl Look for function in any of the specified libraries
index 2e7c8b7d4b569018f43ebd02388667d18af9f215..617a09e8da1b8f7d10ca13d7f6570d91e4629442 100644 (file)
@@ -1,4 +1,4 @@
-dnl $Id: find-func-no-libs2.m4,v 1.9 2004/08/26 12:35:42 joda Exp $
+dnl $Id: find-func-no-libs2.m4 14166 2004-08-26 12:35:42Z joda $
 dnl
 dnl
 dnl Look for function in any of the specified libraries
index aa500283f29a17515abf85e9b46d7ea785723883..2354f38e5e4bb6fe95fb6c7dbb54046e7564c9c7 100644 (file)
@@ -1,4 +1,4 @@
-dnl $Id: find-func.m4,v 1.2 2004/02/12 14:20:47 lha Exp $
+dnl $Id: find-func.m4 13338 2004-02-12 14:21:14Z lha $
 dnl
 dnl AC_FIND_FUNC(func, libraries, includes, arguments)
 AC_DEFUN([AC_FIND_FUNC], [
index 20e85a8400bb8a884fb30963477d4d512d00c397..8bb5e4ecbb0f8752b7b32be7123386d875a729b4 100644 (file)
@@ -1,6 +1,6 @@
 dnl stuff used by DNS resolv code in roken
 dnl
-dnl $Id: resolv.m4,v 1.1 2005/09/02 10:17:38 lha Exp $
+dnl $Id: resolv.m4 16009 2005-09-02 10:17:38Z lha $
 dnl
 
 AC_DEFUN([rk_RESOLV],[
index 5f336e3275db23a1efa1076cda23db6a18e61fc8..33a2c297fa11fc9891f726e54847035ae82d3a9e 100644 (file)
@@ -36,7 +36,7 @@
 #include <getarg.h>
 #include <parse_bytes.h>
 
-RCSID("$Id: default_config.c 21405 2007-07-04 10:35:45Z lha $");
+RCSID("$Id: default_config.c 23316 2008-06-23 04:32:32Z lha $");
 
 krb5_error_code
 krb5_kdc_get_config(krb5_context context, krb5_kdc_configuration **config)
@@ -45,7 +45,7 @@ krb5_kdc_get_config(krb5_context context, krb5_kdc_configuration **config)
 
     c = calloc(1, sizeof(*c));
     if (c == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
 
index b845b0f9a894e03760881a35d009e2647cdd95e5..bf1e45b328a17e188da00f595400c212570cf616 100644 (file)
@@ -34,7 +34,7 @@
 #include "kdc_locl.h"
 #include <hex.h>
 
-RCSID("$Id: digest.c 22374 2007-12-28 18:36:52Z lha $");
+RCSID("$Id: digest.c 23316 2008-06-23 04:32:32Z lha $");
 
 #define MS_CHAP_V2     0x20
 #define CHAP_MD5       0x10
@@ -44,13 +44,13 @@ RCSID("$Id: digest.c 22374 2007-12-28 18:36:52Z lha $");
 #define NTLM_V1                0x01
 
 const struct units _kdc_digestunits[] = {
-       {"ms-chap-v2",          1U << 5},
-       {"chap-md5",            1U << 4},
-       {"digest-md5",          1U << 3},
-       {"ntlm-v2",             1U << 2},
-       {"ntlm-v1-session",     1U << 1},
-       {"ntlm-v1",             1U << 0},
-       {NULL,  0}
+    {"ms-chap-v2",             1U << 5},
+    {"chap-md5",               1U << 4},
+    {"digest-md5",             1U << 3},
+    {"ntlm-v2",                1U << 2},
+    {"ntlm-v1-session",        1U << 1},
+    {"ntlm-v1",                1U << 0},
+    {NULL,     0}
 };
 
 
@@ -121,10 +121,10 @@ fill_targetinfo(krb5_context context,
         strcmp("imap", str) == 0 ||
         strcmp("pop", str) == 0 ||
         strcmp("smtp", str)))
-    {
-       str = krb5_principal_get_comp_string(context, p, 1);
-       ti.dnsservername = rk_UNCONST(str);
-    }
+       {
+           str = krb5_principal_get_comp_string(context, p, 1);
+           ti.dnsservername = rk_UNCONST(str);
+       }
     
     ret = heim_ntlm_encode_targetinfo(&ti, 1, &d);
     if (ret)
@@ -186,7 +186,7 @@ get_password_entry(krb5_context context,
     if (ret || password == NULL) {
        if (ret == 0) {
            ret = EINVAL;
-           krb5_set_error_string(context, "password missing");
+           krb5_set_error_message(context, ret, "password missing");
        }
        memset(user, 0, sizeof(*user));
     }
@@ -263,7 +263,7 @@ _kdc_do_digest(krb5_context context,
            goto out;
 
        ret = EINVAL;
-       krb5_set_error_string(context, "Wrong digest server principal used");
+       krb5_set_error_message(context, ret, "Wrong digest server principal used");
        p = krb5_principal_get_comp_string(context, principal, 0);
        if (p == NULL) {
            krb5_free_principal(context, principal);
@@ -323,9 +323,9 @@ _kdc_do_digest(krb5_context context,
                    "Client %s tried to use digest "
                    "but is not allowed to", 
                    client_name);
-           krb5_set_error_string(context, 
-                                 "Client is not permitted to use digest");
            ret = KRB5KDC_ERR_POLICY;
+           krb5_set_error_message(context, ret,
+                                  "Client is not permitted to use digest");
            goto out;
        }
     }
@@ -338,8 +338,8 @@ _kdc_do_digest(krb5_context context,
        if (ret)
            goto out;
        if (key == NULL) {
-           krb5_set_error_string(context, "digest: remote subkey not found");
            ret = EINVAL;
+           krb5_set_error_message(context, ret, "digest: remote subkey not found");
            goto out;
        }
 
@@ -359,7 +359,7 @@ _kdc_do_digest(krb5_context context,
     ret = decode_DigestReqInner(buf.data, buf.length, &ireq, NULL);
     krb5_data_free(&buf);
     if (ret) {
-       krb5_set_error_string(context, "Failed to decode digest inner request");
+       krb5_set_error_message(context, ret, "Failed to decode digest inner request");
        goto out;
     }
 
@@ -386,15 +386,15 @@ _kdc_do_digest(krb5_context context,
 
        hex_encode(server_nonce, sizeof(server_nonce), &r.u.initReply.nonce);
        if (r.u.initReply.nonce == NULL) {
-           krb5_set_error_string(context, "Failed to decode server nonce");
            ret = ENOMEM;
+           krb5_set_error_message(context, ret, "Failed to decode server nonce");
            goto out;
        }
 
        sp = krb5_storage_emem();
        if (sp == NULL) {
            ret = ENOMEM;
-           krb5_set_error_string(context, "out of memory");
+           krb5_set_error_message(context, ret, "malloc: out of memory");
            goto out;
        }
        ret = krb5_store_stringz(sp, ireq.u.init.type);
@@ -410,9 +410,9 @@ _kdc_do_digest(krb5_context context,
                     ireq.u.init.channel->cb_type,
                     ireq.u.init.channel->cb_binding);
            if (s == NULL) {
-               krb5_set_error_string(context, "Failed to allocate "
-                                     "channel binding");
                ret = ENOMEM;
+               krb5_set_error_message(context, ret,
+                                      "Failed to allocate channel binding");
                goto out;
            }
            free(r.u.initReply.nonce);
@@ -429,15 +429,15 @@ _kdc_do_digest(krb5_context context,
            r.u.initReply.identifier = 
                malloc(sizeof(*r.u.initReply.identifier));
            if (r.u.initReply.identifier == NULL) {
-               krb5_set_error_string(context, "out of memory");
                ret = ENOMEM;
+               krb5_set_error_message(context, ret, "malloc: out of memory");
                goto out;
            }
 
            asprintf(r.u.initReply.identifier, "%02X", identifier & 0xff);
            if (*r.u.initReply.identifier == NULL) {
-               krb5_set_error_string(context, "out of memory");
                ret = ENOMEM;
+               krb5_set_error_message(context, ret, "malloc: out of memory");
                goto out;
            }
 
@@ -478,8 +478,8 @@ _kdc_do_digest(krb5_context context,
        ASN1_MALLOC_ENCODE(Checksum, buf.data, buf.length, &res, &size, ret);
        free_Checksum(&res);
        if (ret) {
-           krb5_set_error_string(context, "Failed to encode "
-                                 "checksum in digest request");
+           krb5_set_error_message(context, ret, "Failed to encode "
+                                  "checksum in digest request");
            goto out;
        }
        if (size != buf.length)
@@ -502,7 +502,7 @@ _kdc_do_digest(krb5_context context,
        sp = krb5_storage_emem();
        if (sp == NULL) {
            ret = ENOMEM;
-           krb5_set_error_string(context, "out of memory");
+           krb5_set_error_message(context, ret, "malloc: out of memory");
            goto out;
        }
        ret = krb5_store_stringz(sp, ireq.u.digestRequest.type);
@@ -524,15 +524,15 @@ _kdc_do_digest(krb5_context context,
        buf.length = strlen(ireq.u.digestRequest.opaque);
        buf.data = malloc(buf.length);
        if (buf.data == NULL) {
-           krb5_set_error_string(context, "out of memory");
            ret = ENOMEM;
+           krb5_set_error_message(context, ret, "malloc: out of memory");
            goto out;
        }
 
        ret = hex_decode(ireq.u.digestRequest.opaque, buf.data, buf.length);
        if (ret <= 0) {
-           krb5_set_error_string(context, "Failed to decode opaque");
            ret = ENOMEM;
+           krb5_set_error_message(context, ret, "Failed to decode opaque");
            goto out;
        }
        buf.length = ret;
@@ -540,7 +540,7 @@ _kdc_do_digest(krb5_context context,
        ret = decode_Checksum(buf.data, buf.length, &res, NULL);
        free(buf.data);
        if (ret) {
-           krb5_set_error_string(context, "Failed to decode digest Checksum");
+           krb5_set_error_message(context, ret, "Failed to decode digest Checksum");
            goto out;
        }
        
@@ -553,8 +553,8 @@ _kdc_do_digest(krb5_context context,
        serverNonce.length = strlen(ireq.u.digestRequest.serverNonce);
        serverNonce.data = malloc(serverNonce.length);
        if (serverNonce.data == NULL) {
-           krb5_set_error_string(context, "out of memory");
            ret = ENOMEM;
+           krb5_set_error_message(context, ret, "malloc: out of memory");
            goto out;
        }
            
@@ -568,8 +568,8 @@ _kdc_do_digest(krb5_context context,
            ssize = hex_decode(ireq.u.digestRequest.serverNonce, 
                               serverNonce.data, serverNonce.length);
            if (ssize <= 0) {
-               krb5_set_error_string(context, "Failed to decode serverNonce");
                ret = ENOMEM;
+               krb5_set_error_message(context, ret, "Failed to decode serverNonce");
                goto out;
            }
            serverNonce.length = ssize;
@@ -593,15 +593,15 @@ _kdc_do_digest(krb5_context context,
            uint32_t t;
            
            if (serverNonce.length < 4) {
-               krb5_set_error_string(context, "server nonce too short");
                ret = EINVAL;
+               krb5_set_error_message(context, ret, "server nonce too short");
                goto out;
            }
            t = p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
 
            if (abs((kdc_time & 0xffffffff) - t) > context->max_skew) {
-               krb5_set_error_string(context, "time screw in server nonce ");
                ret = EINVAL;
+               krb5_set_error_message(context, ret, "time screw in server nonce ");
                goto out;
            }
        }
@@ -618,15 +618,15 @@ _kdc_do_digest(krb5_context context,
            }
 
            if (ireq.u.digestRequest.identifier == NULL) {
-               krb5_set_error_string(context, "Identifier missing "
-                                     "from CHAP request");
                ret = EINVAL;
+               krb5_set_error_message(context, ret, "Identifier missing "
+                                      "from CHAP request");
                goto out;
            }
            
            if (hex_decode(*ireq.u.digestRequest.identifier, &id, 1) != 1) {
-               krb5_set_error_string(context, "failed to decode identifier");
                ret = EINVAL;
+               krb5_set_error_message(context, ret, "failed to decode identifier");
                goto out;
            }
            
@@ -714,8 +714,8 @@ _kdc_do_digest(krb5_context context,
            MD5_Final(md, &ctx);
            hex_encode(md, sizeof(md), &A1);
            if (A1 == NULL) {
-               krb5_set_error_string(context, "out of memory");
                ret = ENOMEM;
+               krb5_set_error_message(context, ret, "malloc: out of memory");
                goto failed;
            }
            
@@ -733,8 +733,8 @@ _kdc_do_digest(krb5_context context,
            MD5_Final(md, &ctx);
            hex_encode(md, sizeof(md), &A2);
            if (A2 == NULL) {
-               krb5_set_error_string(context, "out of memory");
                ret = ENOMEM;
+               krb5_set_error_message(context, ret, "malloc: out of memory");
                free(A1);
                goto failed;
            }
@@ -795,15 +795,15 @@ _kdc_do_digest(krb5_context context,
            }
 
            if (ireq.u.digestRequest.clientNonce == NULL)  {
-               krb5_set_error_string(context, 
-                                     "MS-CHAP-V2 clientNonce missing");
                ret = EINVAL;
+               krb5_set_error_message(context, ret, 
+                                      "MS-CHAP-V2 clientNonce missing");
                goto failed;
            }       
            if (serverNonce.length != 16) {
-               krb5_set_error_string(context, 
-                                     "MS-CHAP-V2 serverNonce wrong length");
                ret = EINVAL;
+               krb5_set_error_message(context, ret, 
+                                      "MS-CHAP-V2 serverNonce wrong length");
                goto failed;
            }
 
@@ -824,16 +824,16 @@ _kdc_do_digest(krb5_context context,
                clientNonce.data = malloc(clientNonce.length);
                if (clientNonce.data == NULL) {
                    ret = ENOMEM;
-                   krb5_set_error_string(context, "out of memory");
+                   krb5_set_error_message(context, ret, "malloc: out of memory");
                    goto out;
                }
 
                ssize = hex_decode(*ireq.u.digestRequest.clientNonce, 
                                   clientNonce.data, clientNonce.length);
                if (ssize != 16) {
-                   krb5_set_error_string(context, 
-                                         "Failed to decode clientNonce");
                    ret = ENOMEM;
+                   krb5_set_error_message(context, ret, 
+                                          "Failed to decode clientNonce");
                    goto out;
                }
                SHA1_Update(&ctx, clientNonce.data, ssize);
@@ -852,18 +852,18 @@ _kdc_do_digest(krb5_context context,
                                HDB_F_GET_CLIENT, NULL, &user);
            krb5_free_principal(context, clientprincipal);
            if (ret) {
-               krb5_set_error_string(context, 
-                                     "MS-CHAP-V2 user %s not in database",
-                                     username);
+               krb5_set_error_message(context, ret, 
+                                      "MS-CHAP-V2 user %s not in database",
+                                      username);
                goto failed;
            }
 
            ret = hdb_enctype2key(context, &user->entry, 
                                  ETYPE_ARCFOUR_HMAC_MD5, &key);
            if (ret) {
-               krb5_set_error_string(context, 
-                                     "MS-CHAP-V2 missing arcfour key %s",
-                                     username);
+               krb5_set_error_message(context, ret, 
+                                      "MS-CHAP-V2 missing arcfour key %s",
+                                      username);
                goto failed;
            }
 
@@ -872,7 +872,7 @@ _kdc_do_digest(krb5_context context,
                                            key->key.keyvalue.length,
                                            challange, &answer);
            if (ret) {
-               krb5_set_error_string(context, "NTLM missing arcfour key");
+               krb5_set_error_message(context, ret, "NTLM missing arcfour key");
                goto failed;
            }
            
@@ -967,8 +967,8 @@ _kdc_do_digest(krb5_context context,
            asprintf(&r.u.error.reason, "Unsupported digest type %s", 
                     ireq.u.digestRequest.type);
            if (r.u.error.reason == NULL) {
-               krb5_set_error_string(context, "out of memory");
                ret = ENOMEM;
+               krb5_set_error_message(context, ret, "malloc: out of memory");
                goto out;
            }
            r.u.error.code = EINVAL;
@@ -1021,29 +1021,29 @@ _kdc_do_digest(krb5_context context,
        r.u.ntlmInitReply.targetname = 
            get_ntlm_targetname(context, client);
        if (r.u.ntlmInitReply.targetname == NULL) {
-           krb5_set_error_string(context, "out of memory");
            ret = ENOMEM;
+           krb5_set_error_message(context, ret, "malloc: out of memory");
            goto out;
        }
        r.u.ntlmInitReply.challange.data = malloc(8);
        if (r.u.ntlmInitReply.challange.data == NULL) {
-           krb5_set_error_string(context, "out of memory");
            ret = ENOMEM;
+           krb5_set_error_message(context, ret, "malloc: out of memory");
            goto out;
        }
        r.u.ntlmInitReply.challange.length = 8;
        if (RAND_bytes(r.u.ntlmInitReply.challange.data,
                       r.u.ntlmInitReply.challange.length) != 1) 
-       {
-           krb5_set_error_string(context, "out of random error");
-           ret = ENOMEM;
-           goto out;
-       }
+           {
+               ret = ENOMEM;
+               krb5_set_error_message(context, ret, "out of random error");
+               goto out;
+           }
        /* XXX fix targetinfo */
        ALLOC(r.u.ntlmInitReply.targetinfo);
        if (r.u.ntlmInitReply.targetinfo == NULL) {
-           krb5_set_error_string(context, "out of memory");
            ret = ENOMEM;
+           krb5_set_error_message(context, ret, "malloc: out of memory");
            goto out;
        }
 
@@ -1052,8 +1052,8 @@ _kdc_do_digest(krb5_context context,
                              client,
                              r.u.ntlmInitReply.targetinfo);
        if (ret) {
-           krb5_set_error_string(context, "out of memory");
            ret = ENOMEM;
+           krb5_set_error_message(context, ret, "malloc: out of memory");
            goto out;
        }
 
@@ -1064,14 +1064,14 @@ _kdc_do_digest(krb5_context context,
        sp = krb5_storage_emem();
        if (sp == NULL) {
            ret = ENOMEM;
-           krb5_set_error_string(context, "out of memory");
+           krb5_set_error_message(context, ret, "malloc: out of memory");
            goto out;
        }
        
        ret = krb5_storage_write(sp, r.u.ntlmInitReply.challange.data, 8);
        if (ret != 8) {
            ret = ENOMEM;
-           krb5_set_error_string(context, "storage write challange");
+           krb5_set_error_message(context, ret, "storage write challange");
            goto out;
        }
        ret = krb5_store_uint32(sp, r.u.ntlmInitReply.flags);
@@ -1127,8 +1127,8 @@ _kdc_do_digest(krb5_context context,
                            HDB_F_GET_CLIENT, NULL, &user);
        krb5_free_principal(context, clientprincipal);
        if (ret) {
-           krb5_set_error_string(context, "NTLM user %s not in database",
-                                 ireq.u.ntlmRequest.username);
+           krb5_set_error_message(context, ret, "NTLM user %s not in database",
+                                  ireq.u.ntlmRequest.username);
            goto failed;
        }
 
@@ -1150,33 +1150,33 @@ _kdc_do_digest(krb5_context context,
        sp = krb5_storage_from_data(&buf);
        if (sp == NULL) {
            ret = ENOMEM;
-           krb5_set_error_string(context, "out of memory");
+           krb5_set_error_message(context, ret, "malloc: out of memory");
            goto out;
        }
        
        ret = krb5_storage_read(sp, challange, sizeof(challange));
        if (ret != sizeof(challange)) {
-           krb5_set_error_string(context, "NTLM storage read challange");
            ret = ENOMEM;
+           krb5_set_error_message(context, ret, "NTLM storage read challange");
            goto out;
        }
        ret = krb5_ret_uint32(sp, &flags);
        if (ret) {
-           krb5_set_error_string(context, "NTLM storage read flags");
+           krb5_set_error_message(context, ret, "NTLM storage read flags");
            goto out;
        }
        krb5_data_free(&buf);
 
        if ((flags & NTLM_NEG_NTLM) == 0) {
            ret = EINVAL;
-           krb5_set_error_string(context, "NTLM not negotiated");
+           krb5_set_error_message(context, ret, "NTLM not negotiated");
            goto out;
        }
 
        ret = hdb_enctype2key(context, &user->entry, 
                              ETYPE_ARCFOUR_HMAC_MD5, &key);
        if (ret) {
-           krb5_set_error_string(context, "NTLM missing arcfour key");
+           krb5_set_error_message(context, ret, "NTLM missing arcfour key");
            goto out;
        }
 
@@ -1194,8 +1194,8 @@ _kdc_do_digest(krb5_context context,
 
            targetname = get_ntlm_targetname(context, client);
            if (targetname == NULL) {
-               krb5_set_error_string(context, "out of memory");
                ret = ENOMEM;
+               krb5_set_error_message(context, ret, "malloc: out of memory");
                goto out;
            }
 
@@ -1213,7 +1213,7 @@ _kdc_do_digest(krb5_context context,
                                         sessionkey);
            free(targetname);
            if (ret) {
-               krb5_set_error_string(context, "NTLM v2 verify failed");
+               krb5_set_error_message(context, ret, "NTLM v2 verify failed");
                goto failed;
            }
 
@@ -1238,9 +1238,9 @@ _kdc_do_digest(krb5_context context,
                }
 
                if (ireq.u.ntlmRequest.lm.length != 24) {
-                   krb5_set_error_string(context, "LM hash have wrong length "
-                                         "for NTLM session key");
                    ret = EINVAL;
+                   krb5_set_error_message(context, ret, "LM hash have wrong length "
+                                          "for NTLM session key");
                    goto failed;
                }
                
@@ -1260,18 +1260,18 @@ _kdc_do_digest(krb5_context context,
                                            key->key.keyvalue.length,
                                            challange, &answer);
            if (ret) {
-               krb5_set_error_string(context, "NTLM missing arcfour key");
+               krb5_set_error_message(context, ret, "NTLM missing arcfour key");
                goto failed;
            }
            
            if (ireq.u.ntlmRequest.ntlm.length != answer.length ||
                memcmp(ireq.u.ntlmRequest.ntlm.data, answer.data, answer.length) != 0)
-           {
-               free(answer.data);
-               ret = EINVAL;
-               krb5_set_error_string(context, "NTLM hash mismatch");
-               goto failed;
-           }
+               {
+                   free(answer.data);
+                   ret = EINVAL;
+                   krb5_set_error_message(context, ret, "NTLM hash mismatch");
+                   goto failed;
+               }
            free(answer.data);
 
            {
@@ -1290,18 +1290,19 @@ _kdc_do_digest(krb5_context context,
            size_t len;
            
            if ((flags & NTLM_NEG_KEYEX) == 0) {
-               krb5_set_error_string(context,
-                                     "NTLM client failed to neg key "
-                                     "exchange but still sent key");
                ret = EINVAL;
+               krb5_set_error_message(context, ret,
+                                      "NTLM client failed to neg key "
+                                      "exchange but still sent key");
                goto failed;
            }
            
            len = ireq.u.ntlmRequest.sessionkey->length;
            if (len != sizeof(masterkey)){
-               krb5_set_error_string(context,
-                                     "NTLM master key wrong length: %lu",
-                                     (unsigned long)len);
+               ret = EINVAL;
+               krb5_set_error_message(context, ret,
+                                      "NTLM master key wrong length: %lu",
+                                      (unsigned long)len);
                goto failed;
            }
            
@@ -1315,14 +1316,15 @@ _kdc_do_digest(krb5_context context,
            r.u.ntlmResponse.sessionkey = 
                malloc(sizeof(*r.u.ntlmResponse.sessionkey));
            if (r.u.ntlmResponse.sessionkey == NULL) {
-               krb5_set_error_string(context, "out of memory");
+               ret = EINVAL;
+               krb5_set_error_message(context, ret, "malloc: out of memory");
                goto out;
            }
            
            ret = krb5_data_copy(r.u.ntlmResponse.sessionkey,
                                 masterkey, sizeof(masterkey));
            if (ret) {
-               krb5_set_error_string(context, "out of memory");
+               krb5_set_error_message(context, ret, "malloc: out of memory");
                goto out;
            }
        }
@@ -1354,11 +1356,11 @@ _kdc_do_digest(krb5_context context,
        break;
 
     default: {
-       char *s;
-       krb5_set_error_string(context, "unknown operation to digest");
+       const char *s;
        ret = EINVAL;
+       krb5_set_error_message(context, ret, "unknown operation to digest");
 
-    failed:
+       failed:
 
        s = krb5_get_error_message(context, ret);
        if (s == NULL) {
@@ -1370,10 +1372,10 @@ _kdc_do_digest(krb5_context context,
 
        r.element = choice_DigestRepInner_error;
        r.u.error.reason = strdup("unknown error");
-       krb5_free_error_string(context, s);
+       krb5_free_error_message(context, s);
        if (r.u.error.reason == NULL) {
-           krb5_set_error_string(context, "out of memory");
            ret = ENOMEM;
+           krb5_set_error_message(context, ret, "malloc: out of memory");
            goto out;
        }
        r.u.error.code = EINVAL;
@@ -1383,7 +1385,7 @@ _kdc_do_digest(krb5_context context,
 
     ASN1_MALLOC_ENCODE(DigestRepInner, buf.data, buf.length, &r, &size, ret);
     if (ret) {
-       krb5_set_error_string(context, "Failed to encode inner digest reply");
+       krb5_set_error_message(context, ret, "Failed to encode inner digest reply");
        goto out;
     }
     if (size != buf.length)
@@ -1414,14 +1416,14 @@ _kdc_do_digest(krb5_context context,
     
     ASN1_MALLOC_ENCODE(DigestREP, reply->data, reply->length, &rep, &size, ret);
     if (ret) {
-       krb5_set_error_string(context, "Failed to encode digest reply");
+       krb5_set_error_message(context, ret, "Failed to encode digest reply");
        goto out;
     }
     if (size != reply->length)
        krb5_abortx(context, "ASN1 internal error");
 
     
-out:
+ out:
     if (ac)
        krb5_auth_con_free(context, ac);
     if (ret)
index 27f497ea6643c5ecc485160061b5e0840e28fbec..4f257d717ee35b1162d9f3817113087e963b3feb 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "kdc_locl.h"
 
-RCSID("$Id: kaserver.c 21654 2007-07-21 17:30:18Z lha $");
+RCSID("$Id: kaserver.c 23110 2008-04-27 18:51:17Z lha $");
 
 #include <krb5-v4compat.h>
 #include <rx.h>
@@ -366,7 +366,7 @@ create_reply_ticket (krb5_context context,
        DES_cblock deskey;
        
        memcpy (&deskey, key->keyvalue.data, sizeof(deskey));
-       DES_set_key (&deskey, &schedule);
+       DES_set_key_unchecked (&deskey, &schedule);
        DES_pcbc_encrypt (enc_data.data,
                          enc_data.data,
                          enc_data.length,
@@ -524,7 +524,7 @@ do_authenticate (krb5_context context,
        
        /* try to decode the `request' */
        memcpy (&key, ckey->key.keyvalue.data, sizeof(key));
-       DES_set_key (&key, &schedule);
+       DES_set_key_unchecked (&key, &schedule);
        DES_pcbc_encrypt (request.data,
                          request.data,
                          request.length,
@@ -801,7 +801,7 @@ do_getticket (krb5_context context,
 
     /* decrypt the times */
     memcpy(&session, ad.session.keyvalue.data, sizeof(session));
-    DES_set_key (&session, &schedule);
+    DES_set_key_unchecked (&session, &schedule);
     DES_ecb_encrypt (times.data,
                     times.data,
                     &schedule,
index f1dea6499df0252d71c15d4c64dcb27e7da02f65..2a2c48c233a657d3138b29b37865e2a05155e6b8 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "kdc_locl.h"
 
-RCSID("$Id: kerberos5.c 22071 2007-11-14 20:04:50Z lha $");
+RCSID("$Id: kerberos5.c 23316 2008-06-23 04:32:32Z lha $");
 
 #define MAX_TIME ((time_t)((1U << 31) - 1))
 
@@ -1648,7 +1648,7 @@ _kdc_as_rep(krb5_context context,
        memset(&canon, 0, sizeof(canon));
 
        canon.names.requested_name = *b->cname;
-       canon.names.real_name = client->entry.principal->name;
+       canon.names.mapped_name = client->entry.principal->name;
 
        ASN1_MALLOC_ENCODE(PA_ClientCanonicalizedNames, data.data, data.length,
                           &canon.names, &len, ret);
@@ -1807,7 +1807,7 @@ _kdc_tkt_add_if_relevant_ad(krb5_context context,
     if (tkt->authorization_data == NULL) {
        tkt->authorization_data = calloc(1, sizeof(*tkt->authorization_data));
        if (tkt->authorization_data == NULL) {
-           krb5_set_error_string(context, "out of memory");
+           krb5_set_error_message(context, ENOMEM, "out of memory");
            return ENOMEM;
        }
     }
@@ -1822,7 +1822,7 @@ _kdc_tkt_add_if_relevant_ad(krb5_context context,
 
        ret = add_AuthorizationData(&ad, &ade);
        if (ret) {
-           krb5_set_error_string(context, "add AuthorizationData failed");
+           krb5_set_error_message(context, ret, "add AuthorizationData failed");
            return ret;
        }
 
@@ -1833,8 +1833,8 @@ _kdc_tkt_add_if_relevant_ad(krb5_context context,
                           &ad, &size, ret);
        free_AuthorizationData(&ad);
        if (ret) {
-           krb5_set_error_string(context, "ASN.1 encode of "
-                                 "AuthorizationData failed");
+           krb5_set_error_message(context, ret, "ASN.1 encode of "
+                                  "AuthorizationData failed");
            return ret;
        }
        if (ade.ad_data.length != size)
@@ -1843,7 +1843,7 @@ _kdc_tkt_add_if_relevant_ad(krb5_context context,
        ret = add_AuthorizationData(tkt->authorization_data, &ade);
        der_free_octet_string(&ade.ad_data);
        if (ret) {
-           krb5_set_error_string(context, "add AuthorizationData failed");
+           krb5_set_error_message(context, ret, "add AuthorizationData failed");
            return ret;
        }
     }
index 32bdee9799ca8407852b3ac2881465645839eaa2..071a30d5a78a674d1ce126683f4dc5e3185c7615 100644 (file)
@@ -1,45 +1,45 @@
 /*
- * Copyright (c) 1997-2007 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden). 
- * All rights reserved. 
+ * Copyright (c) 1997-2008 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
  *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions 
- * are met: 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
  *
- * 1. Redistributions of source code must retain the above copyright 
- *    notice, this list of conditions and the following disclaimer. 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
  *
- * 2. Redistributions in binary form must reproduce the above copyright 
- *    notice, this list of conditions and the following disclaimer in the 
- *    documentation and/or other materials provided with the distribution. 
+ * 2. Redistributions in binary form must 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. 
+ * 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. 
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
  */
 
 #include "kdc_locl.h"
 
-RCSID("$Id: krb5tgs.c 22071 2007-11-14 20:04:50Z lha $");
+RCSID("$Id: krb5tgs.c 23316 2008-06-23 04:32:32Z lha $");
 
 /*
  * return the realm of a krbtgt-ticket or NULL
  */
 
-static Realm 
+static Realm
 get_krbtgt_realm(const PrincipalName *p)
 {
     if(p->name_string.len == 2
@@ -80,8 +80,8 @@ find_KRB5SignedPath(krb5_context context,
                                   &child,
                                   NULL);
     if (ret) {
-       krb5_set_error_string(context, "Failed to decode "
-                             "IF_RELEVANT with %d", ret);
+       krb5_set_error_message(context, ret, "Failed to decode "
+                              "IF_RELEVANT with %d", ret);
        return ret;
     }
 
@@ -168,7 +168,7 @@ _kdc_add_KRB5SignedPath(krb5_context context,
     if (data.length != size)
        krb5_abortx(context, "internal asn.1 encoder error");
 
-    
+
     /*
      * Add IF-RELEVANT(KRB5SignedPath) to the last slot in
      * authorization data field.
@@ -187,13 +187,14 @@ check_KRB5SignedPath(krb5_context context,
                     hdb_entry_ex *krbtgt,
                     EncTicketPart *tkt,
                     KRB5SignedPathPrincipals **delegated,
-                    int require_signedpath)
+                    int *signedpath)
 {
     krb5_error_code ret;
     krb5_data data;
     krb5_crypto crypto = NULL;
 
-    *delegated = NULL;
+    if (delegated)
+       *delegated = NULL;
 
     ret = find_KRB5SignedPath(context, tkt->authorization_data, &data);
     if (ret == 0) {
@@ -236,8 +237,8 @@ check_KRB5SignedPath(krb5_context context,
                return ret;
            }
        }
-       ret = krb5_verify_checksum(context, crypto, KRB5_KU_KRB5SIGNEDPATH, 
-                                  data.data, data.length, 
+       ret = krb5_verify_checksum(context, crypto, KRB5_KU_KRB5SIGNEDPATH,
+                                  data.data, data.length,
                                   &sp.cksum);
        krb5_crypto_destroy(context, crypto);
        free(data.data);
@@ -246,7 +247,7 @@ check_KRB5SignedPath(krb5_context context,
            return ret;
        }
 
-       if (sp.delegated) {
+       if (delegated && sp.delegated) {
 
            *delegated = malloc(sizeof(*sp.delegated));
            if (*delegated == NULL) {
@@ -263,10 +264,8 @@ check_KRB5SignedPath(krb5_context context,
            }
        }
        free_KRB5SignedPath(&sp);
-       
-    } else {
-       if (require_signedpath)
-           return KRB5KDC_ERR_BADOPTION;
+
+       *signedpath = 1;
     }
 
     return 0;
@@ -286,7 +285,7 @@ check_PAC(krb5_context context,
          const EncryptionKey *krbtgt_key,
          EncTicketPart *tkt,
          krb5_data *rspac,
-         int *require_signedpath)
+         int *signedpath)
 {
     AuthorizationData *ad = tkt->authorization_data;
     unsigned i, j;
@@ -306,8 +305,8 @@ check_PAC(krb5_context context,
                                       &child,
                                       NULL);
        if (ret) {
-           krb5_set_error_string(context, "Failed to decode "
-                                 "IF_RELEVANT with %d", ret);
+           krb5_set_error_message(context, ret, "Failed to decode "
+                                  "IF_RELEVANT with %d", ret);
            return ret;
        }
        for (j = 0; j < child.len; j++) {
@@ -324,7 +323,7 @@ check_PAC(krb5_context context,
                if (ret)
                    return ret;
 
-               ret = krb5_pac_verify(context, pac, tkt->authtime, 
+               ret = krb5_pac_verify(context, pac, tkt->authtime,
                                      client_principal,
                                      krbtgt_key, NULL);
                if (ret) {
@@ -332,13 +331,13 @@ check_PAC(krb5_context context,
                    return ret;
                }
 
-               ret = _kdc_pac_verify(context, client_principal, 
+               ret = _kdc_pac_verify(context, client_principal,
                                      client, server, &pac);
                if (ret) {
                    krb5_pac_free(context, pac);
                    return ret;
                }
-               *require_signedpath = 0;
+               *signedpath = 1;
 
                ret = _krb5_pac_sign(context, pac, tkt->authtime,
                                     client_principal,
@@ -359,7 +358,7 @@ check_PAC(krb5_context context,
  */
 
 static krb5_error_code
-check_tgs_flags(krb5_context context,        
+check_tgs_flags(krb5_context context,
                krb5_kdc_configuration *config,
                KDC_REQ_BODY *b, const EncTicketPart *tgt, EncTicketPart *et)
 {
@@ -379,7 +378,7 @@ check_tgs_flags(krb5_context context,
        /* XXX  tkt = tgt */
        et->flags.invalid = 0;
     }else if(tgt->flags.invalid){
-       kdc_log(context, config, 0, 
+       kdc_log(context, config, 0,
                "Ticket-granting ticket has INVALID flag set");
        return KRB5KRB_AP_ERR_TKT_INVALID;
     }
@@ -473,8 +472,8 @@ check_tgs_flags(krb5_context context,
        et->endtime = *et->starttime + old_life;
        if (et->renew_till != NULL)
            et->endtime = min(*et->renew_till, et->endtime);
-    }      
-    
+    }  
+
 #if 0
     /* checks for excess flags */
     if(f.request_anonymous && !config->allow_anonymous){
@@ -491,7 +490,7 @@ check_tgs_flags(krb5_context context,
  */
 
 static krb5_error_code
-check_constrained_delegation(krb5_context context, 
+check_constrained_delegation(krb5_context context,
                             krb5_kdc_configuration *config,
                             hdb_entry_ex *client,
                             krb5_const_principal server)
@@ -522,7 +521,7 @@ check_constrained_delegation(krb5_context context,
  */
 
 static krb5_error_code
-verify_flags (krb5_context context, 
+verify_flags (krb5_context context,
              krb5_kdc_configuration *config,
              const EncTicketPart *et,
              const char *pstr)
@@ -543,18 +542,18 @@ verify_flags (krb5_context context,
  */
 
 static krb5_error_code
-fix_transited_encoding(krb5_context context, 
+fix_transited_encoding(krb5_context context,
                       krb5_kdc_configuration *config,
                       krb5_boolean check_policy,
-                      const TransitedEncoding *tr, 
-                      EncTicketPart *et, 
-                      const char *client_realm, 
-                      const char *server_realm, 
+                      const TransitedEncoding *tr,
+                      EncTicketPart *et,
+                      const char *client_realm,
+                      const char *server_realm,
                       const char *tgt_realm)
 {
     krb5_error_code ret = 0;
     char **realms, **tmp;
-    int num_realms;
+    unsigned int num_realms;
     int i;
 
     switch (tr->tr_type) {
@@ -576,9 +575,9 @@ fix_transited_encoding(krb5_context context,
        return KRB5KDC_ERR_TRTYPE_NOSUPP;
     }
 
-    ret = krb5_domain_x500_decode(context, 
+    ret = krb5_domain_x500_decode(context,
                                  tr->contents,
-                                 &realms, 
+                                 &realms,
                                  &num_realms,
                                  client_realm,
                                  server_realm);
@@ -589,7 +588,7 @@ fix_transited_encoding(krb5_context context,
     }
     if(strcmp(client_realm, tgt_realm) && strcmp(server_realm, tgt_realm)) {
        /* not us, so add the previous realm to transited set */
-       if (num_realms < 0 || num_realms + 1 > UINT_MAX/sizeof(*realms)) {
+       if (num_realms + 1 > UINT_MAX/sizeof(*realms)) {
            ret = ERANGE;
            goto free_realms;
        }
@@ -607,7 +606,7 @@ fix_transited_encoding(krb5_context context,
        num_realms++;
     }
     if(num_realms == 0) {
-       if(strcmp(client_realm, server_realm)) 
+       if(strcmp(client_realm, server_realm))
            kdc_log(context, config, 0,
                    "cross-realm %s -> %s", client_realm, server_realm);
     } else {
@@ -630,11 +629,11 @@ fix_transited_encoding(krb5_context context,
        }
     }
     if(check_policy) {
-       ret = krb5_check_transited(context, client_realm, 
-                                  server_realm, 
+       ret = krb5_check_transited(context, client_realm,
+                                  server_realm,
                                   realms, num_realms, NULL);
        if(ret) {
-           krb5_warn(context, ret, "cross-realm %s -> %s", 
+           krb5_warn(context, ret, "cross-realm %s -> %s",
                      client_realm, server_realm);
            goto free_realms;
        }
@@ -653,23 +652,24 @@ fix_transited_encoding(krb5_context context,
 
 
 static krb5_error_code
-tgs_make_reply(krb5_context context, 
+tgs_make_reply(krb5_context context,
               krb5_kdc_configuration *config,
-              KDC_REQ_BODY *b, 
+              KDC_REQ_BODY *b,
               krb5_const_principal tgt_name,
-              const EncTicketPart *tgt, 
+              const EncTicketPart *tgt,
               const EncryptionKey *serverkey,
               const krb5_keyblock *sessionkey,
               krb5_kvno kvno,
               AuthorizationData *auth_data,
-              hdb_entry_ex *server, 
-              const char *server_name, 
-              hdb_entry_ex *client, 
-              krb5_principal client_principal, 
+              hdb_entry_ex *server,
+              const char *server_name,
+              hdb_entry_ex *client,
+              krb5_principal client_principal,
               hdb_entry_ex *krbtgt,
               krb5_enctype krbtgt_etype,
               KRB5SignedPathPrincipals *spp,
               const krb5_data *rspac,
+              const METHOD_DATA *enc_pa_data,
               const char **e_text,
               krb5_data *reply)
 {
@@ -678,11 +678,11 @@ tgs_make_reply(krb5_context context,
     EncTicketPart et;
     KDCOptions f = b->kdc_options;
     krb5_error_code ret;
-    
+
     memset(&rep, 0, sizeof(rep));
     memset(&et, 0, sizeof(et));
     memset(&ek, 0, sizeof(ek));
-    
+
     rep.pvno = 5;
     rep.msg_type = krb_tgs_rep;
 
@@ -691,7 +691,7 @@ tgs_make_reply(krb5_context context,
     et.endtime = min(tgt->endtime, *b->till);
     ALLOC(et.starttime);
     *et.starttime = kdc_time;
-    
+
     ret = check_tgs_flags(context, config, b, tgt, &et);
     if(ret)
        goto out;
@@ -715,11 +715,11 @@ tgs_make_reply(krb5_context context,
 #define PRINCIPAL_FORCE_TRANSITED_CHECK(P)             0
 #define PRINCIPAL_ALLOW_DISABLE_TRANSITED_CHECK(P)     0
 
-    ret = fix_transited_encoding(context, config, 
+    ret = fix_transited_encoding(context, config,
                                 !f.disable_transited_check ||
                                 GLOBAL_FORCE_TRANSITED_CHECK ||
                                 PRINCIPAL_FORCE_TRANSITED_CHECK(server) ||
-                                !((GLOBAL_ALLOW_PER_PRINCIPAL && 
+                                !((GLOBAL_ALLOW_PER_PRINCIPAL &&
                                    PRINCIPAL_ALLOW_DISABLE_TRANSITED_CHECK(server)) ||
                                   GLOBAL_ALLOW_DISABLE_TRANSITED_CHECK),
                                 &tgt->transited, &et,
@@ -729,7 +729,7 @@ tgs_make_reply(krb5_context context,
     if(ret)
        goto out;
 
-    copy_Realm(krb5_princ_realm(context, server->entry.principal), 
+    copy_Realm(krb5_princ_realm(context, server->entry.principal),
               &rep.ticket.realm);
     _krb5_principal2principalname(&rep.ticket.sname, server->entry.principal);
     copy_Realm(&tgt_name->realm, &rep.crealm);
@@ -754,7 +754,7 @@ tgs_make_reply(krb5_context context,
            life = min(life, *server->entry.max_life);
        et.endtime = *et.starttime + life;
     }
-    if(f.renewable_ok && tgt->flags.renewable && 
+    if(f.renewable_ok && tgt->flags.renewable &&
        et.renew_till == NULL && et.endtime < *b->till){
        et.flags.renewable = 1;
        ALLOC(et.renew_till);
@@ -769,13 +769,13 @@ tgs_make_reply(krb5_context context,
            renew = min(renew, *server->entry.max_renew);
        *et.renew_till = et.authtime + renew;
     }
-           
+       
     if(et.renew_till){
        *et.renew_till = min(*et.renew_till, *tgt->renew_till);
        *et.starttime = min(*et.starttime, *et.renew_till);
        et.endtime = min(et.endtime, *et.renew_till);
     }
-    
+
     *et.starttime = min(*et.starttime, et.endtime);
 
     if(*et.starttime == et.endtime){
@@ -787,12 +787,12 @@ tgs_make_reply(krb5_context context,
        et.renew_till = NULL;
        et.flags.renewable = 0;
     }
-    
+
     et.flags.pre_authent = tgt->flags.pre_authent;
     et.flags.hw_authent  = tgt->flags.hw_authent;
     et.flags.anonymous   = tgt->flags.anonymous;
     et.flags.ok_as_delegate = server->entry.flags.ok_as_delegate;
-           
+       
     if (auth_data) {
        /* XXX Check enc-authorization-data */
        et.authorization_data = calloc(1, sizeof(*et.authorization_data));
@@ -836,7 +836,7 @@ tgs_make_reply(krb5_context context,
        goto out;
     et.crealm = tgt->crealm;
     et.cname = tgt_name->name;
-           
+       
     ek.key = et.key;
     /* MIT must have at least one last_req */
     ek.last_req.len = 1;
@@ -853,8 +853,8 @@ tgs_make_reply(krb5_context context,
     ek.renew_till = et.renew_till;
     ek.srealm = rep.ticket.realm;
     ek.sname = rep.ticket.sname;
-    
-    _kdc_log_timestamp(context, config, "TGS-REQ", et.authtime, et.starttime, 
+
+    _kdc_log_timestamp(context, config, "TGS-REQ", et.authtime, et.starttime,
                       et.endtime, et.renew_till);
 
     /* Don't sign cross realm tickets, they can't be checked anyway */
@@ -874,6 +874,17 @@ tgs_make_reply(krb5_context context,
        }
     }
 
+    if (enc_pa_data->len) {
+       rep.padata = calloc(1, sizeof(*rep.padata));
+       if (rep.padata == NULL) {
+           ret = ENOMEM;
+           goto out;
+       }
+       ret = copy_METHOD_DATA(enc_pa_data, rep.padata);
+       if (ret)
+           goto out;
+    }
+
     /* It is somewhat unclear where the etype in the following
        encryption should come from. What we have is a session
        key in the passed tgt, and a list of preferred etypes
@@ -884,9 +895,9 @@ tgs_make_reply(krb5_context context,
        CAST session key. Should the DES3 etype be added to the
        etype list, even if we don't want a session key with
        DES3? */
-    ret = _kdc_encode_reply(context, config, 
+    ret = _kdc_encode_reply(context, config,
                            &rep, &et, &ek, et.key.keytype,
-                           kvno, 
+                           kvno,
                            serverkey, 0, &tgt->key, e_text, reply);
 out:
     free_TGS_REP(&rep);
@@ -906,10 +917,10 @@ out:
 }
 
 static krb5_error_code
-tgs_check_authenticator(krb5_context context, 
+tgs_check_authenticator(krb5_context context,
                        krb5_kdc_configuration *config,
                        krb5_auth_context ac,
-                       KDC_REQ_BODY *b, 
+                       KDC_REQ_BODY *b,
                        const char **e_text,
                        krb5_keyblock *key)
 {
@@ -919,7 +930,7 @@ tgs_check_authenticator(krb5_context context,
     size_t buf_size;
     krb5_error_code ret;
     krb5_crypto crypto;
-    
+
     krb5_auth_con_getauthenticator(context, ac, &auth);
     if(auth->cksum == NULL){
        kdc_log(context, config, 0, "No authenticator in request");
@@ -936,7 +947,7 @@ tgs_check_authenticator(krb5_context context,
        ||
 #endif
  !krb5_checksum_is_collision_proof(context, auth->cksum->cksumtype)) {
-       kdc_log(context, config, 0, "Bad checksum type in authenticator: %d", 
+       kdc_log(context, config, 0, "Bad checksum type in authenticator: %d",
                auth->cksum->cksumtype);
        ret =  KRB5KRB_AP_ERR_INAPP_CKSUM;
        goto out;
@@ -945,7 +956,7 @@ tgs_check_authenticator(krb5_context context,
     /* XXX should not re-encode this */
     ASN1_MALLOC_ENCODE(KDC_REQ_BODY, buf, buf_size, b, &len, ret);
     if(ret){
-       kdc_log(context, config, 0, "Failed to encode KDC-REQ-BODY: %s", 
+       kdc_log(context, config, 0, "Failed to encode KDC-REQ-BODY: %s",
                krb5_get_err_text(context, ret));
        goto out;
     }
@@ -966,14 +977,14 @@ tgs_check_authenticator(krb5_context context,
     ret = krb5_verify_checksum(context,
                               crypto,
                               KRB5_KU_TGS_REQ_AUTH_CKSUM,
-                              buf, 
+                              buf,
                               len,
                               auth->cksum);
     free(buf);
     krb5_crypto_destroy(context, crypto);
     if(ret){
        kdc_log(context, config, 0,
-               "Failed to verify authenticator checksum: %s", 
+               "Failed to verify authenticator checksum: %s",
                krb5_get_err_text(context, ret));
     }
 out:
@@ -991,27 +1002,38 @@ find_rpath(krb5_context context, Realm crealm, Realm srealm)
 {
     const char *new_realm = krb5_config_get_string(context,
                                                   NULL,
-                                                  "capaths", 
+                                                  "capaths",
                                                   crealm,
                                                   srealm,
                                                   NULL);
     return new_realm;
 }
-           
+       
 
 static krb5_boolean
-need_referral(krb5_context context, krb5_principal server, krb5_realm **realms)
+need_referral(krb5_context context, krb5_kdc_configuration *config,
+             const KDCOptions * const options, krb5_principal server,
+             krb5_realm **realms)
 {
-    if(server->name.name_type != KRB5_NT_SRV_INST ||
-       server->name.name_string.len != 2)
+    const char *name;
+
+    if(!options->canonicalize && server->name.name_type != KRB5_NT_SRV_INST)
+       return FALSE;
+
+    if (server->name.name_string.len == 1)
+       name = server->name.name_string.val[0];
+    if (server->name.name_string.len > 1)
+       name = server->name.name_string.val[1];
+    else
        return FALSE;
-    return _krb5_get_host_realm_int(context, server->name.name_string.val[1],
-                                   FALSE, realms) == 0;
+
+    kdc_log(context, config, 0, "Searching referral for %s", name);
+
+    return _krb5_get_host_realm_int(context, name, FALSE, realms) == 0;
 }
 
 static krb5_error_code
-tgs_parse_request(krb5_context context, 
+tgs_parse_request(krb5_context context,
                  krb5_kdc_configuration *config,
                  KDC_REQ_BODY *b,
                  const PA_DATA *tgs_req,
@@ -1041,7 +1063,7 @@ tgs_parse_request(krb5_context context,
     memset(&ap_req, 0, sizeof(ap_req));
     ret = krb5_decode_ap_req(context, &tgs_req->padata_value, &ap_req);
     if(ret){
-       kdc_log(context, config, 0, "Failed to decode AP-REQ: %s", 
+       kdc_log(context, config, 0, "Failed to decode AP-REQ: %s",
                krb5_get_err_text(context, ret));
        goto out;
     }
@@ -1052,12 +1074,12 @@ tgs_parse_request(krb5_context context,
        ret = KRB5KDC_ERR_POLICY; /* ? */
        goto out;
     }
-    
+
     _krb5_principalname2krb5_principal(context,
                                       &princ,
                                       ap_req.ticket.sname,
                                       ap_req.ticket.realm);
-    
+
     ret = _kdc_db_fetch(context, config, princ, HDB_F_GET_KRBTGT, NULL, krbtgt);
 
     if(ret) {
@@ -1074,8 +1096,8 @@ tgs_parse_request(krb5_context context,
        ret = KRB5KRB_AP_ERR_NOT_US;
        goto out;
     }
-    
-    if(ap_req.ticket.enc_part.kvno && 
+
+    if(ap_req.ticket.enc_part.kvno &&
        *ap_req.ticket.enc_part.kvno != (*krbtgt)->entry.kvno){
        char *p;
 
@@ -1084,7 +1106,7 @@ tgs_parse_request(krb5_context context,
        if (ret != 0)
            p = "<unparse_name failed>";
        kdc_log(context, config, 0,
-               "Ticket kvno = %d, DB kvno = %d (%s)", 
+               "Ticket kvno = %d, DB kvno = %d (%s)",
                *ap_req.ticket.enc_part.kvno,
                (*krbtgt)->entry.kvno,
                p);
@@ -1096,7 +1118,7 @@ tgs_parse_request(krb5_context context,
 
     *krbtgt_etype = ap_req.ticket.enc_part.etype;
 
-    ret = hdb_enctype2key(context, &(*krbtgt)->entry, 
+    ret = hdb_enctype2key(context, &(*krbtgt)->entry,
                          ap_req.ticket.enc_part.etype, &tkey);
     if(ret){
        char *str = NULL, *p = NULL;
@@ -1112,7 +1134,7 @@ tgs_parse_request(krb5_context context,
        ret = KRB5KRB_AP_ERR_BADKEYVER;
        goto out;
     }
-    
+
     if (b->kdc_options.validate)
        verify_ap_req_flags = KRB5_VERIFY_AP_REQ_IGNORE_INVALID;
     else
@@ -1127,10 +1149,10 @@ tgs_parse_request(krb5_context context,
                              &ap_req_options,
                              ticket,
                              KRB5_KU_TGS_REQ_AUTH);
-                            
+                       
     krb5_free_principal(context, princ);
     if(ret) {
-       kdc_log(context, config, 0, "Failed to verify AP-REQ: %s", 
+       kdc_log(context, config, 0, "Failed to verify AP-REQ: %s",
                krb5_get_err_text(context, ret));
        goto out;
     }
@@ -1158,7 +1180,7 @@ tgs_parse_request(krb5_context context,
        }
     }
 
-    ret = tgs_check_authenticator(context, config, 
+    ret = tgs_check_authenticator(context, config,
                                  ac, b, e_text, &(*ticket)->ticket.key);
     if (ret) {
        krb5_auth_con_free(context, ac);
@@ -1175,7 +1197,7 @@ tgs_parse_request(krb5_context context,
                                            &subkey);
        if(ret){
            krb5_auth_con_free(context, ac);
-           kdc_log(context, config, 0, "Failed to get remote subkey: %s", 
+           kdc_log(context, config, 0, "Failed to get remote subkey: %s",
                    krb5_get_err_text(context, ret));
            goto out;
        }
@@ -1184,7 +1206,7 @@ tgs_parse_request(krb5_context context,
            ret = krb5_auth_con_getkey(context, ac, &subkey);
            if(ret) {
                krb5_auth_con_free(context, ac);
-               kdc_log(context, config, 0, "Failed to get session key: %s", 
+               kdc_log(context, config, 0, "Failed to get session key: %s",
                        krb5_get_err_text(context, ret));
                goto out;
            }
@@ -1211,7 +1233,7 @@ tgs_parse_request(krb5_context context,
        krb5_crypto_destroy(context, crypto);
        if(ret){
            krb5_auth_con_free(context, ac);
-           kdc_log(context, config, 0, 
+           kdc_log(context, config, 0,
                    "Failed to decrypt enc-authorization-data");
            ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */
            goto out;
@@ -1235,17 +1257,95 @@ tgs_parse_request(krb5_context context,
     }
 
     krb5_auth_con_free(context, ac);
-    
+
 out:
     free_AP_REQ(&ap_req);
-    
+
     return ret;
 }
 
 static krb5_error_code
-tgs_build_reply(krb5_context context, 
+build_server_referral(krb5_context context,
+                     krb5_kdc_configuration *config,
+                     krb5_crypto session,
+                     krb5_const_realm referred_realm,
+                     const PrincipalName *true_principal_name,
+                     const PrincipalName *requested_principal,
+                     krb5_data *outdata)
+{              
+    PA_ServerReferralData ref;
+    krb5_error_code ret;
+    EncryptedData ed;
+    krb5_data data;
+    size_t size;
+
+    memset(&ref, 0, sizeof(ref));
+
+    if (referred_realm) {
+       ref.referred_realm = malloc(sizeof(ref.referred_realm));
+       if (ref.referred_realm == NULL)
+           goto eout;
+       *ref.referred_realm = strdup(referred_realm);
+       if (*ref.referred_realm == NULL)
+           goto eout;
+    }
+    if (true_principal_name) {
+       ref.true_principal_name =
+           malloc(sizeof(ref.true_principal_name));
+       if (ref.true_principal_name == NULL)
+           goto eout;
+       ret = copy_PrincipalName(true_principal_name, ref.true_principal_name);
+       if (ret)
+           goto eout;
+    }
+    if (requested_principal) {
+       ref.requested_principal_name =
+           malloc(sizeof(ref.requested_principal_name));
+       if (ref.requested_principal_name == NULL)
+           goto eout;
+       ret = copy_PrincipalName(requested_principal,
+                                ref.requested_principal_name);
+       if (ret)
+           goto eout;
+    }
+
+    ASN1_MALLOC_ENCODE(PA_ServerReferralData,
+                      data.data, data.length,
+                      &ref, &size, ret);
+    free_PA_ServerReferralData(&ref);
+    if (ret)
+       return ret;
+    if (data.length != size)
+       krb5_abortx(context, "internal asn.1 encoder error");
+
+    ret = krb5_encrypt_EncryptedData(context, session,
+                                    KRB5_KU_PA_SERVER_REFERRAL,
+                                    data.data, data.length,
+                                    0 /* kvno */, &ed);
+    free(data.data);
+    if (ret)
+       return ret;
+
+    ASN1_MALLOC_ENCODE(EncryptedData,
+                      outdata->data, outdata->length,
+                      &ed, &size, ret);
+    free_EncryptedData(&ed);
+    if (ret)
+       return ret;
+    if (outdata->length != size)
+       krb5_abortx(context, "internal asn.1 encoder error");
+
+    return 0;
+eout:
+    free_PA_ServerReferralData(&ref);
+    krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
+    return ENOMEM;
+}
+
+static krb5_error_code
+tgs_build_reply(krb5_context context,
                krb5_kdc_configuration *config,
-               KDC_REQ *req, 
+               KDC_REQ *req,
                KDC_REQ_BODY *b,
                hdb_entry_ex *krbtgt,
                krb5_enctype krbtgt_etype,
@@ -1253,7 +1353,7 @@ tgs_build_reply(krb5_context context,
                krb5_data *reply,
                const char *from,
                const char **e_text,
-               AuthorizationData *auth_data,
+               AuthorizationData **auth_data,
                const struct sockaddr *from_addr,
                int datagram_reply)
 {
@@ -1262,6 +1362,7 @@ tgs_build_reply(krb5_context context,
     krb5_principal client_principal = NULL;
     char *spn = NULL, *cpn = NULL;
     hdb_entry_ex *server = NULL, *client = NULL;
+    krb5_realm ref_realm = NULL;
     EncTicketPart *tgt = &ticket->ticket;
     KRB5SignedPathPrincipals *spp = NULL;
     const EncryptionKey *ekey;
@@ -1270,16 +1371,19 @@ tgs_build_reply(krb5_context context,
     krb5_data rspac;
     int cross_realm = 0;
 
+    METHOD_DATA enc_pa_data;
+
     PrincipalName *s;
     Realm r;
     int nloop = 0;
     EncTicketPart adtkt;
     char opt_str[128];
-    int require_signedpath = 0;
+    int signedpath = 0;
 
     memset(&sessionkey, 0, sizeof(sessionkey));
     memset(&adtkt, 0, sizeof(adtkt));
     krb5_data_zero(&rspac);
+    memset(&enc_pa_data, 0, sizeof(enc_pa_data));
 
     s = b->sname;
     r = b->realm;
@@ -1289,8 +1393,8 @@ tgs_build_reply(krb5_context context,
        hdb_entry_ex *uu;
        krb5_principal p;
        Key *uukey;
-           
-       if(b->additional_tickets == NULL || 
+       
+       if(b->additional_tickets == NULL ||
           b->additional_tickets->len == 0){
            ret = KRB5KDC_ERR_BADOPTION; /* ? */
            kdc_log(context, config, 0,
@@ -1305,8 +1409,8 @@ tgs_build_reply(krb5_context context,
            goto out;
        }
        _krb5_principalname2krb5_principal(context, &p, t->sname, t->realm);
-       ret = _kdc_db_fetch(context, config, p, 
-                           HDB_F_GET_CLIENT|HDB_F_GET_SERVER, 
+       ret = _kdc_db_fetch(context, config, p,
+                           HDB_F_GET_CLIENT|HDB_F_GET_SERVER,
                            NULL, &uu);
        krb5_free_principal(context, p);
        if(ret){
@@ -1314,7 +1418,7 @@ tgs_build_reply(krb5_context context,
                ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
            goto out;
        }
-       ret = hdb_enctype2key(context, &uu->entry, 
+       ret = hdb_enctype2key(context, &uu->entry,
                              t->enc_part.etype, &uukey);
        if(ret){
            _kdc_free_ent(context, uu);
@@ -1347,7 +1451,7 @@ tgs_build_reply(krb5_context context,
                   opt_str, sizeof(opt_str));
     if(*opt_str)
        kdc_log(context, config, 0,
-               "TGS-REQ %s from %s for %s [%s]", 
+               "TGS-REQ %s from %s for %s [%s]",
                cpn, from, spn, opt_str);
     else
        kdc_log(context, config, 0,
@@ -1370,20 +1474,23 @@ server_lookup:
                new_rlm = find_rpath(context, tgt->crealm, req_rlm);
                if(new_rlm) {
                    kdc_log(context, config, 5, "krbtgt for realm %s "
-                           "not found, trying %s", 
+                           "not found, trying %s",
                            req_rlm, new_rlm);
                    krb5_free_principal(context, sp);
                    free(spn);
-                   krb5_make_principal(context, &sp, r, 
+                   krb5_make_principal(context, &sp, r,
                                        KRB5_TGS_NAME, new_rlm, NULL);
                    ret = krb5_unparse_name(context, sp, &spn); 
                    if (ret)
                        goto out;
-                   auth_data = NULL; /* ms don't handle AD in referals */
+
+                   if (ref_realm)
+                       free(ref_realm);
+                   ref_realm = strdup(new_rlm);
                    goto server_lookup;
                }
            }
-       } else if(need_referral(context, sp, &realms)) {
+       } else if(need_referral(context, config, &b->kdc_options, sp, &realms)) {
            if (strcmp(realms[0], sp->realm) != 0) {
                kdc_log(context, config, 5,
                        "Returning a referral to realm %s for "
@@ -1396,8 +1503,12 @@ server_lookup:
                ret = krb5_unparse_name(context, sp, &spn);
                if (ret)
                    goto out;
+
+               if (ref_realm)
+                   free(ref_realm);
+               ref_realm = strdup(realms[0]);
+
                krb5_free_host_realm(context, realms);
-               auth_data = NULL; /* ms don't handle AD in referals */
                goto server_lookup;
            }
            krb5_free_host_realm(context, realms);
@@ -1412,7 +1523,7 @@ server_lookup:
 
     ret = _kdc_db_fetch(context, config, cp, HDB_F_GET_CLIENT, NULL, &client);
     if(ret) {
-       const char *krbtgt_realm; 
+       const char *krbtgt_realm;
 
        /*
         * If the client belongs to the same realm as our krbtgt, it
@@ -1420,8 +1531,8 @@ server_lookup:
         *
         */
 
-       krbtgt_realm = 
-           krb5_principal_get_comp_string(context, 
+       krbtgt_realm =
+           krb5_principal_get_comp_string(context,
                                           krbtgt->entry.principal, 1);
 
        if(strcmp(krb5_principal_get_realm(context, cp), krbtgt_realm) == 0) {
@@ -1437,16 +1548,60 @@ server_lookup:
 
        cross_realm = 1;
     }
-    
+
+    /*
+     * Select enctype, return key and kvno.
+     */
+
+    {
+       krb5_enctype etype;
+
+       if(b->kdc_options.enc_tkt_in_skey) {
+           int i;
+           ekey = &adtkt.key;
+           for(i = 0; i < b->etype.len; i++)
+               if (b->etype.val[i] == adtkt.key.keytype)
+                   break;
+           if(i == b->etype.len) {
+               kdc_log(context, config, 0,
+                       "Addition ticket have not matching etypes", spp);
+               krb5_clear_error_string(context);
+               return KRB5KDC_ERR_ETYPE_NOSUPP;
+           }
+           etype = b->etype.val[i];
+           kvno = 0;
+       } else {
+           Key *skey;
+       
+           ret = _kdc_find_etype(context, server, b->etype.val, b->etype.len,
+                                 &skey, &etype);
+           if(ret) {
+               kdc_log(context, config, 0,
+                       "Server (%s) has no support for etypes", spn);
+               return ret;
+           }
+           ekey = &skey->key;
+           kvno = server->entry.kvno;
+       }
+       
+       ret = krb5_generate_random_keyblock(context, etype, &sessionkey);
+       if (ret)
+           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
      * backward.
      */
-    
+
     if (strcmp(krb5_principal_get_realm(context, sp),
-              krb5_principal_get_comp_string(context, 
-                                             krbtgt->entry.principal, 
+              krb5_principal_get_comp_string(context,
+                                             krbtgt->entry.principal,
                                              1)) != 0) {
        char *tpn;
        ret = krb5_unparse_name(context, krbtgt->entry.principal, &tpn);
@@ -1459,8 +1614,45 @@ server_lookup:
        goto out;
     }
 
+    /* check PAC if not cross realm and if there is one */
+    if (!cross_realm) {
+       Key *tkey;
+
+       ret = hdb_enctype2key(context, &krbtgt->entry,
+                             krbtgt_etype, &tkey);
+       if(ret) {
+           kdc_log(context, config, 0,
+                   "Failed to find key for krbtgt PAC check");
+           goto out;
+       }
+
+       ret = check_PAC(context, config, cp,
+                       client, server, ekey, &tkey->key,
+                       tgt, &rspac, &signedpath);
+       if (ret) {
+           kdc_log(context, config, 0,
+                   "Verify PAC failed for %s (%s) from %s with %s",
+                   spn, cpn, from, krb5_get_err_text(context, ret));
+           goto out;
+       }
+    }
+
+    /* also check the krbtgt for signature */
+    ret = check_KRB5SignedPath(context,
+                              config,
+                              krbtgt,
+                              tgt,
+                              &spp,
+                              &signedpath);
+    if (ret) {
+       kdc_log(context, config, 0,
+               "KRB5SignedPath check failed for %s (%s) from %s with %s",
+               spn, cpn, from, krb5_get_err_text(context, ret));
+       goto out;
+    }
+
     /*
-     *
+     * Process request
      */
 
     client_principal = cp;
@@ -1477,7 +1669,7 @@ server_lookup:
            char *selfcpn = NULL;
            const char *str;
 
-           ret = decode_PA_S4U2Self(sdata->padata_value.data, 
+           ret = decode_PA_S4U2Self(sdata->padata_value.data,
                                     sdata->padata_value.length,
                                     &self, NULL);
            if (ret) {
@@ -1501,14 +1693,14 @@ server_lookup:
            ret = krb5_verify_checksum(context,
                                       crypto,
                                       KRB5_KU_OTHER_CKSUM,
-                                      datack.data, 
-                                      datack.length, 
+                                      datack.data,
+                                      datack.length,
                                       &self.cksum);
            krb5_data_free(&datack);
            krb5_crypto_destroy(context, crypto);
            if (ret) {
                free_PA_S4U2Self(&self);
-               kdc_log(context, config, 0, 
+               kdc_log(context, config, 0,
                        "krb5_verify_checksum failed for S4U2Self: %s",
                        krb5_get_err_text(context, ret));
                goto out;
@@ -1566,13 +1758,26 @@ server_lookup:
        && b->additional_tickets->len != 0
        && b->kdc_options.enc_tkt_in_skey == 0)
     {
+       int ad_signedpath = 0;
        Key *clientkey;
        Ticket *t;
        char *str;
 
+       /*
+        * Require that the KDC have issued the service's krbtgt (not
+        * self-issued ticket with kimpersonate(1).
+        */
+       if (!signedpath) {
+           ret = KRB5KDC_ERR_BADOPTION;
+           kdc_log(context, config, 0,
+                   "Constrained delegation done on service ticket %s/%s",
+                   cpn, spn);
+           goto out;
+       }
+
        t = &b->additional_tickets->val[0];
 
-       ret = hdb_enctype2key(context, &client->entry, 
+       ret = hdb_enctype2key(context, &client->entry,
                              t->enc_part.etype, &clientkey);
        if(ret){
            ret = KRB5KDC_ERR_ETYPE_NOSUPP; /* XXX */
@@ -1588,19 +1793,18 @@ server_lookup:
        }
 
        /* check that ticket is valid */
-
        if (adtkt.flags.forwardable == 0) {
            kdc_log(context, config, 0,
                    "Missing forwardable flag on ticket for "
                    "constrained delegation from %s to %s ", spn, cpn);
-           ret = KRB5KDC_ERR_ETYPE_NOSUPP; /* XXX */
+           ret = KRB5KDC_ERR_BADOPTION;
            goto out;
        }
 
        ret = check_constrained_delegation(context, config, client, sp);
        if (ret) {
            kdc_log(context, config, 0,
-                   "constrained delegation from %s to %s not allowed", 
+                   "constrained delegation from %s to %s not allowed",
                    spn, cpn);
            goto out;
        }
@@ -1623,16 +1827,16 @@ server_lookup:
        }
 
        /*
-        * Check KRB5SignedPath in authorization data and add new entry to
-        * make sure servers can't fake a ticket to us.
+        * Check that the KDC issued the user's ticket.
         */
-
        ret = check_KRB5SignedPath(context,
                                   config,
                                   krbtgt,
                                   &adtkt,
-                                  &spp,
-                                  1);
+                                  NULL,
+                                  &ad_signedpath);
+       if (ret == 0 && !ad_signedpath)
+           ret = KRB5KDC_ERR_BADOPTION;
        if (ret) {
            kdc_log(context, config, 0,
                    "KRB5SignedPath check from service %s failed "
@@ -1646,27 +1850,21 @@ server_lookup:
        kdc_log(context, config, 0, "constrained delegation for %s "
                "from %s to %s", str, cpn, spn);
        free(str);
-
-       /* 
-        * Also require that the KDC have issue the service's krbtgt
-        * used to do the request. 
-        */
-       require_signedpath = 1;
     }
 
     /*
      * Check flags
      */
 
-    ret = _kdc_check_flags(context, config, 
+    ret = _kdc_check_flags(context, config,
                           client, cpn,
                           server, spn,
                           FALSE);
     if(ret)
        goto out;
 
-    if((b->kdc_options.validate || b->kdc_options.renew) && 
-       !krb5_principal_compare(context, 
+    if((b->kdc_options.validate || b->kdc_options.renew) &&
+       !krb5_principal_compare(context,
                               krbtgt->entry.principal,
                               server->entry.principal)){
        kdc_log(context, config, 0, "Inconsistent request.");
@@ -1682,108 +1880,68 @@ server_lookup:
     }
        
     /*
-     * Select enctype, return key and kvno.
+     * If this is an referral, add server referral data to the
+     * auth_data reply .
      */
+    if (ref_realm) {
+       PA_DATA pa;
+       krb5_crypto crypto;
 
-    {
-       krb5_enctype etype;
+       kdc_log(context, config, 0,
+               "Adding server referral to %s", ref_realm);
 
-       if(b->kdc_options.enc_tkt_in_skey) {
-           int i;
-           ekey = &adtkt.key;
-           for(i = 0; i < b->etype.len; i++)
-               if (b->etype.val[i] == adtkt.key.keytype)
-                   break;
-           if(i == b->etype.len) {
-               krb5_clear_error_string(context);
-               return KRB5KDC_ERR_ETYPE_NOSUPP;
-           }
-           etype = b->etype.val[i];
-           kvno = 0;
-       } else {
-           Key *skey;
-           
-           ret = _kdc_find_etype(context, server, b->etype.val, b->etype.len,
-                                 &skey, &etype);
-           if(ret) {
-               kdc_log(context, config, 0, 
-                       "Server (%s) has no support for etypes", spp);
-               return ret;
-           }
-           ekey = &skey->key;
-           kvno = server->entry.kvno;
-       }
-       
-       ret = krb5_generate_random_keyblock(context, etype, &sessionkey);
+       ret = krb5_crypto_init(context, &sessionkey, 0, &crypto);
        if (ret)
            goto out;
-    }
-
-    /* check PAC if not cross realm and if there is one */
-    if (!cross_realm) {
-       Key *tkey;
 
-       ret = hdb_enctype2key(context, &krbtgt->entry, 
-                             krbtgt_etype, &tkey);
-       if(ret) {
+       ret = build_server_referral(context, config, crypto, ref_realm,
+                                   NULL, s, &pa.padata_value);
+       krb5_crypto_destroy(context, crypto);
+       if (ret) {
            kdc_log(context, config, 0,
-                   "Failed to find key for krbtgt PAC check");
+                   "Failed building server referral");
            goto out;
        }
+       pa.padata_type = KRB5_PADATA_SERVER_REFERRAL;
 
-       ret = check_PAC(context, config, client_principal, 
-                       client, server, ekey, &tkey->key,
-                       tgt, &rspac, &require_signedpath);
+       ret = add_METHOD_DATA(&enc_pa_data, &pa);
+       krb5_data_free(&pa.padata_value);
        if (ret) {
            kdc_log(context, config, 0,
-                   "Verify PAC failed for %s (%s) from %s with %s",
-                   spn, cpn, from, krb5_get_err_text(context, ret));
+                   "Add server referral METHOD-DATA failed");
            goto out;
        }
     }
 
-    /* also check the krbtgt for signature */
-    ret = check_KRB5SignedPath(context,
-                              config,
-                              krbtgt,
-                              tgt,
-                              &spp,
-                              require_signedpath);
-    if (ret) {
-       kdc_log(context, config, 0,
-               "KRB5SignedPath check failed for %s (%s) from %s with %s",
-               spn, cpn, from, krb5_get_err_text(context, ret));
-       goto out;
-    }
-
     /*
      *
      */
 
     ret = tgs_make_reply(context,
-                        config, 
-                        b, 
+                        config,
+                        b,
                         client_principal,
-                        tgt, 
+                        tgt,
                         ekey,
                         &sessionkey,
                         kvno,
-                        auth_data,
-                        server, 
+                        *auth_data,
+                        server,
                         spn,
-                        client, 
-                        cp, 
-                        krbtgt, 
+                        client,
+                        cp,
+                        krbtgt,
                         krbtgt_etype,
                         spp,
                         &rspac,
+                        &enc_pa_data,
                         e_text,
                         reply);
        
 out:
     free(spn);
     free(cpn);
-           
+       
     krb5_data_free(&rspac);
     krb5_free_keyblock_contents(context, &sessionkey);
     if(server)
@@ -1797,6 +1955,9 @@ out:
        krb5_free_principal(context, cp);
     if (sp)
        krb5_free_principal(context, sp);
+    if (ref_realm)
+       free(ref_realm);
+    free_METHOD_DATA(&enc_pa_data);
 
     free_EncTicketPart(&adtkt);
 
@@ -1808,9 +1969,9 @@ out:
  */
 
 krb5_error_code
-_kdc_tgs_rep(krb5_context context, 
+_kdc_tgs_rep(krb5_context context,
             krb5_kdc_configuration *config,
-            KDC_REQ *req, 
+            KDC_REQ *req,
             krb5_data *data,
             const char *from,
             struct sockaddr *from_addr,
@@ -1835,17 +1996,17 @@ _kdc_tgs_rep(krb5_context context,
                "TGS-REQ from %s without PA-DATA", from);
        goto out;
     }
-    
+
     tgs_req = _kdc_find_padata(req, &i, KRB5_PADATA_TGS_REQ);
 
     if(tgs_req == NULL){
        ret = KRB5KDC_ERR_PADATA_TYPE_NOSUPP;
        
-       kdc_log(context, config, 0, 
+       kdc_log(context, config, 0,
                "TGS-REQ from %s without PA-TGS-REQ", from);
        goto out;
     }
-    ret = tgs_parse_request(context, config, 
+    ret = tgs_parse_request(context, config,
                            &req->req_body, tgs_req,
                            &krbtgt,
                            &krbtgt_etype,
@@ -1855,7 +2016,7 @@ _kdc_tgs_rep(krb5_context context,
                            &csec, &cusec,
                            &auth_data);
     if (ret) {
-       kdc_log(context, config, 0, 
+       kdc_log(context, config, 0,
                "Failed parsing TGS-REQ from %s", from);
        goto out;
     }
@@ -1870,11 +2031,11 @@ _kdc_tgs_rep(krb5_context context,
                          data,
                          from,
                          &e_text,
-                         auth_data,
+                         &auth_data,
                          from_addr,
                          datagram_reply);
     if (ret) {
-       kdc_log(context, config, 0, 
+       kdc_log(context, config, 0,
                "Failed building TGS-REP to %s", from);
        goto out;
     }
index b1b861efef88efe507e624119d595669a32a1dee..8f117cebc0507b03d0b46ef07d10c1f288b5c666 100644 (file)
@@ -36,7 +36,7 @@
 #include <rfc2459_asn1.h>
 #include <hx509.h>
 
-RCSID("$Id: kx509.c 21607 2007-07-17 07:04:52Z lha $");
+RCSID("$Id: kx509.c 23316 2008-06-23 04:32:32Z lha $");
 
 /*
  *
@@ -67,8 +67,9 @@ verify_req_hash(krb5_context context,
     HMAC_CTX ctx;
     
     if (req->pk_hash.length != sizeof(digest)) {
-       krb5_set_error_string(context, "pk-hash have wrong length: %lu",
-                             (unsigned long)req->pk_hash.length);
+       krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED,
+                              "pk-hash have wrong length: %lu",
+                              (unsigned long)req->pk_hash.length);
        return KRB5KDC_ERR_PREAUTH_FAILED;
     }
 
@@ -84,7 +85,8 @@ verify_req_hash(krb5_context context,
     HMAC_CTX_cleanup(&ctx);
 
     if (memcmp(req->pk_hash.data, digest, sizeof(digest)) != 0) {
-       krb5_set_error_string(context, "pk-hash is not correct");
+       krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED,
+                              "pk-hash is not correct");
        return KRB5KDC_ERR_PREAUTH_FAILED;
     }
     return 0;
@@ -106,7 +108,7 @@ calculate_reply_hash(krb5_context context,
     rep->hash->data = malloc(rep->hash->length);
     if (rep->hash->data == NULL) {
        HMAC_CTX_cleanup(&ctx);
-       krb5_set_error_string(context, "out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
 
@@ -157,12 +159,8 @@ build_certificate(krb5_context context,
     ret = hx509_context_init(&hxctx);
     if (ret)
        goto out;
-
-    ret = hx509_env_init(hxctx, &env);
-    if (ret)
-       goto out;
-
-    ret = hx509_env_add(hxctx, env, "principal-name", 
+    
+    ret = hx509_env_add(hxctx, &env, "principal-name", 
                        krb5_principal_get_comp_string(context, principal, 0));
     if (ret)
        goto out;
@@ -280,7 +278,7 @@ out:
        hx509_cert_free(signer);
     if (hxctx)
        hx509_context_free(&hxctx);
-    krb5_set_error_string(context, "cert creation failed");
+    krb5_set_error_message(context, ret, "cert creation failed");
     return ret;
 }
 
@@ -358,16 +356,18 @@ _kdc_do_kx509(krb5_context context,
        krb5_free_principal(context, principal);
        if (ret != TRUE) {
            ret = KRB5KDC_ERR_SERVER_NOMATCH;
-           krb5_set_error_string(context, 
-                                 "User %s used wrong Kx509 service principal",
-                                 cname);
+           krb5_set_error_message(context, ret,
+                                  "User %s used wrong Kx509 service principal",
+                                  cname);
            goto out;
        }
     }
     
     ret = krb5_auth_con_getkey(context, ac, &key);
-    if (ret || key == NULL) {
-       krb5_set_error_string(context, "Kx509 can't get session key");
+    if (ret == 0 && key == NULL)
+       ret = KRB5KDC_ERR_NULL_KEY;
+    if (ret) {
+       krb5_set_error_message(context, ret, "Kx509 can't get session key");
        goto out;
     }
     
@@ -418,7 +418,7 @@ _kdc_do_kx509(krb5_context context,
        ASN1_MALLOC_ENCODE(Kx509Response, data.data, data.length, &rep,
                           &size, ret);
        if (ret) {
-           krb5_set_error_string(context, "Failed to encode kx509 reply");
+           krb5_set_error_message(context, ret, "Failed to encode kx509 reply");
            goto out;
        }
        if (size != data.length)
index 072df44042979c06116d83fcfb0ec4b6fc9fac6c..528b9e6a3b674220731463f2a9fc0d13332177b6 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "kdc_locl.h"
 
-RCSID("$Id: misc.c 21106 2007-06-18 10:18:11Z lha $");
+RCSID("$Id: misc.c 23316 2008-06-23 04:32:32Z lha $");
 
 struct timeval _kdc_now;
 
@@ -51,7 +51,7 @@ _kdc_db_fetch(krb5_context context,
 
     ent = calloc (1, sizeof (*ent));
     if (ent == NULL) {
-       krb5_set_error_string(context, "out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
 
@@ -76,8 +76,8 @@ _kdc_db_fetch(krb5_context context,
        }
     }
     free(ent);
-    krb5_set_error_string(context, "no such entry found in hdb");
-    return  HDB_ERR_NOENTRY;
+    krb5_set_error_message(context, HDB_ERR_NOENTRY, "no such entry found in hdb");
+    return HDB_ERR_NOENTRY;
 }
 
 void
@@ -116,7 +116,8 @@ _kdc_get_preferred_key(krb5_context context,
        }
     }
 
-    krb5_set_error_string(context, "No valid kerberos key found for %s", name);
+    krb5_set_error_message(context, EINVAL, 
+                          "No valid kerberos key found for %s", name);
     return EINVAL;
 }
 
index bf248af588fcbbb81d6ae7abfeabfcec81c551cc..9f6d57f588feae5661a39c3d1eaad1979e3a0e67 100755 (executable)
@@ -33,7 +33,7 @@
 
 #include "kdc_locl.h"
 
-RCSID("$Id: pkinit.c 22243 2007-12-08 23:39:30Z lha $");
+RCSID("$Id: pkinit.c 23316 2008-06-23 04:32:32Z lha $");
 
 #ifdef PKINIT
 
@@ -45,23 +45,8 @@ RCSID("$Id: pkinit.c 22243 2007-12-08 23:39:30Z lha $");
 #include <hx509.h>
 #include "crypto-headers.h"
 
-/* XXX copied from lib/krb5/pkinit.c */
-struct krb5_pk_identity {
-    hx509_context hx509ctx;
-    hx509_verify_ctx verify_ctx;
-    hx509_certs certs;
-    hx509_certs anchors;
-    hx509_certs certpool;
-    hx509_revoke_ctx revoke;
-};
-
-enum pkinit_type {
-    PKINIT_COMPAT_WIN2K = 1,
-    PKINIT_COMPAT_27 = 3
-};
-
 struct pk_client_params {
-    enum pkinit_type type;
+    enum krb5_pk_type type;
     BIGNUM *dh_public_key;
     hx509_cert cert;
     unsigned nonce;
@@ -202,13 +187,13 @@ generate_dh_keyblock(krb5_context context, pk_client_params *client_params,
     memset(&key, 0, sizeof(key));
 
     if (!DH_generate_key(client_params->dh)) {
-       krb5_set_error_string(context, "Can't generate Diffie-Hellman keys");
        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) {
-       krb5_set_error_string(context, "dh_public_key");
        ret = KRB5KRB_ERR_GENERIC;
+       krb5_set_error_message(context, ret, "dh_public_key");
        goto out;
     }
 
@@ -219,8 +204,8 @@ generate_dh_keyblock(krb5_context context, pk_client_params *client_params,
 
     dh_gen_key = malloc(size);
     if (dh_gen_key == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
        ret = ENOMEM;
+       krb5_set_error_message(context, ret, "malloc: out of memory");
        goto out;
     }
     memset(dh_gen_key, 0, size - dh_gen_keylen);
@@ -229,8 +214,8 @@ generate_dh_keyblock(krb5_context context, pk_client_params *client_params,
                                   client_params->dh_public_key,
                                   client_params->dh);
     if (dh_gen_keylen == -1) {
-       krb5_set_error_string(context, "Can't compute Diffie-Hellman key");
        ret = KRB5KRB_ERR_GENERIC;
+       krb5_set_error_message(context, ret, "Can't compute Diffie-Hellman key");
        goto out;
     }
 
@@ -256,7 +241,8 @@ integer_to_BN(krb5_context context, const char *field, heim_integer *f)
 
     bn = BN_bin2bn((const unsigned char *)f->data, f->length, NULL);
     if (bn == NULL) {
-       krb5_set_error_string(context, "PKINIT: parsing BN failed %s", field);
+       krb5_set_error_message(context, KRB5_BADMSGTYPE,
+                              "PKINIT: parsing BN failed %s", field);
        return NULL;
     }
     BN_set_negative(bn, f->negative);
@@ -276,13 +262,14 @@ 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_string(context,
-                             "PKINIT invalid oid in clientPublicValue");
+       krb5_set_error_message(context, KRB5_BADMSGTYPE,
+                              "PKINIT invalid oid in clientPublicValue");
        return KRB5_BADMSGTYPE;
     }
 
     if (dh_key_info->algorithm.parameters == NULL) {
-       krb5_set_error_string(context, "PKINIT missing algorithm parameter "
+       krb5_set_error_message(context, KRB5_BADMSGTYPE,
+                              "PKINIT missing algorithm parameter "
                              "in clientPublicValue");
        return KRB5_BADMSGTYPE;
     }
@@ -292,15 +279,16 @@ get_dh_param(krb5_context context,
                                  &dhparam,
                                  NULL);
     if (ret) {
-       krb5_set_error_string(context, "Can't decode algorithm "
-                             "parameters in clientPublicValue");
+       krb5_set_error_message(context, ret, "Can't decode algorithm "
+                              "parameters in clientPublicValue");
        goto out;
     }
 
     if ((dh_key_info->subjectPublicKey.length % 8) != 0) {
        ret = KRB5_BADMSGTYPE;
-       krb5_set_error_string(context, "PKINIT: subjectPublicKey not aligned "
-                             "to 8 bit boundary");
+       krb5_set_error_message(context, ret,
+                              "PKINIT: subjectPublicKey not aligned "
+                              "to 8 bit boundary");
        goto out;
     }
 
@@ -315,8 +303,8 @@ get_dh_param(krb5_context context,
 
     dh = DH_new();
     if (dh == NULL) {
-       krb5_set_error_string(context, "Cannot create DH structure");
        ret = ENOMEM;
+       krb5_set_error_message(context, ret, "Cannot create DH structure");
        goto out;
     }
     ret = KRB5_BADMSGTYPE;
@@ -347,8 +335,10 @@ get_dh_param(krb5_context context,
                                                     "subjectPublicKey",
                                                     &glue);
        der_free_heim_integer(&glue);
-       if (client_params->dh_public_key == NULL)
+       if (client_params->dh_public_key == NULL) {
+           ret = KRB5_BADMSGTYPE;
            goto out;
+       }
     }
 
     client_params->dh = dh;
@@ -385,7 +375,7 @@ _kdc_pk_rd_padata(krb5_context context,
        return 0;
     }
 
-    hx509_verify_set_time(kdc_identity->verify_ctx, _kdc_now.tv_sec);
+    hx509_verify_set_time(kdc_identity->verify_ctx, kdc_time);
 
     client_params = calloc(1, sizeof(*client_params));
     if (client_params == NULL) {
@@ -404,8 +394,8 @@ _kdc_pk_rd_padata(krb5_context context,
                                        &r,
                                        NULL);
        if (ret) {
-           krb5_set_error_string(context, "Can't decode "
-                                 "PK-AS-REQ-Win2k: %d", ret);
+           krb5_set_error_message(context, ret, "Can't decode "
+                                  "PK-AS-REQ-Win2k: %d", ret);
            goto out;
        }
        
@@ -415,7 +405,8 @@ _kdc_pk_rd_padata(krb5_context context,
                                           &have_data);
        free_PA_PK_AS_REQ_Win2k(&r);
        if (ret) {
-           krb5_set_error_string(context, "Can't decode PK-AS-REQ: %d", ret);
+           krb5_set_error_message(context, ret, 
+                                  "Can't decode PK-AS-REQ: %d", ret);
            goto out;
        }
 
@@ -429,7 +420,7 @@ _kdc_pk_rd_padata(krb5_context context,
                                  &r,
                                  NULL);
        if (ret) {
-           krb5_set_error_string(context, "Can't decode PK-AS-REQ: %d", ret);
+           krb5_set_error_message(context, ret, "Can't decode PK-AS-REQ: %d", ret);
            goto out;
        }
        
@@ -443,7 +434,7 @@ _kdc_pk_rd_padata(krb5_context context,
                                   0, NULL,
                                   &client_params->client_anchors);
            if (ret) {
-               krb5_set_error_string(context, "Can't allocate client anchors: %d", ret);
+               krb5_set_error_message(context, ret, "Can't allocate client anchors: %d", ret);
                goto out;
 
            }
@@ -458,7 +449,7 @@ _kdc_pk_rd_padata(krb5_context context,
 
                ret = hx509_query_alloc(kdc_identity->hx509ctx, &q);
                if (ret) {
-                   krb5_set_error_string(context, 
+                   krb5_set_error_message(context, ret,
                                          "Failed to allocate hx509_query");
                    goto out;
                }
@@ -495,7 +486,8 @@ _kdc_pk_rd_padata(krb5_context context,
                                           &have_data);
        free_PA_PK_AS_REQ(&r);
        if (ret) {
-           krb5_set_error_string(context, "Can't unwrap ContentInfo: %d", ret);
+           krb5_set_error_message(context, ret, 
+                                  "Can't unwrap ContentInfo: %d", ret);
            goto out;
        }
 
@@ -507,16 +499,16 @@ _kdc_pk_rd_padata(krb5_context context,
 
     ret = der_heim_oid_cmp(&contentInfoOid, oid_id_pkcs7_signedData());
     if (ret != 0) {
-       krb5_set_error_string(context, "PK-AS-REQ-Win2k invalid content "
-                             "type oid");
        ret = KRB5KRB_ERR_GENERIC;
+       krb5_set_error_message(context, ret, 
+                              "PK-AS-REQ-Win2k invalid content type oid");
        goto out;
     }
        
     if (!have_data) {
-       krb5_set_error_string(context,
-                             "PK-AS-REQ-Win2k no signed auth pack");
        ret = KRB5KRB_ERR_GENERIC;
+       krb5_set_error_message(context, ret,
+                             "PK-AS-REQ-Win2k no signed auth pack");
        goto out;
     }
 
@@ -551,8 +543,8 @@ _kdc_pk_rd_padata(krb5_context context,
     if (der_heim_oid_cmp(&eContentType, oid_id_pkcs7_data()) != 0 &&
        der_heim_oid_cmp(&eContentType, oid_id_pkauthdata()) != 0)
     {
-       krb5_set_error_string(context, "got wrong oid for pkauthdata");
        ret = KRB5_BADMSGTYPE;
+       krb5_set_error_message(context, ret, "got wrong oid for pkauthdata");
        goto out;
     }
 
@@ -564,7 +556,7 @@ _kdc_pk_rd_padata(krb5_context context,
                                    &ap,
                                    NULL);
        if (ret) {
-           krb5_set_error_string(context, "can't decode AuthPack: %d", ret);
+           krb5_set_error_message(context, ret, "can't decode AuthPack: %d", ret);
            goto out;
        }
   
@@ -576,12 +568,12 @@ _kdc_pk_rd_padata(krb5_context context,
            goto out;
        }
 
-       client_params->type = PKINIT_COMPAT_WIN2K;
+       client_params->type = PKINIT_WIN2K;
        client_params->nonce = ap.pkAuthenticator.nonce;
 
        if (ap.clientPublicValue) {
-           krb5_set_error_string(context, "DH not supported for windows");
            ret = KRB5KRB_ERR_GENERIC;
+           krb5_set_error_message(context, ret, "DH not supported for windows");
            goto out;
        }
        free_AuthPack_Win2k(&ap);
@@ -594,7 +586,7 @@ _kdc_pk_rd_padata(krb5_context context,
                              &ap,
                              NULL);
        if (ret) {
-           krb5_set_error_string(context, "can't decode AuthPack: %d", ret);
+           krb5_set_error_message(context, ret, "can't decode AuthPack: %d", ret);
            free_AuthPack(&ap);
            goto out;
        }
@@ -607,7 +599,7 @@ _kdc_pk_rd_padata(krb5_context context,
            goto out;
        }
 
-       client_params->type = PKINIT_COMPAT_27;
+       client_params->type = PKINIT_27;
        client_params->nonce = ap.pkAuthenticator.nonce;
 
        if (ap.clientPublicValue) {
@@ -700,7 +692,7 @@ pk_mk_pa_reply_enckey(krb5_context context,
      */
 
     switch (client_params->type) {
-    case PKINIT_COMPAT_WIN2K: {
+    case PKINIT_WIN2K: {
        int i = 0;
        if (_kdc_find_padata(req, &i, KRB5_PADATA_PK_AS_09_BINDING) == NULL
            && config->pkinit_require_binding == 0)
@@ -709,7 +701,7 @@ pk_mk_pa_reply_enckey(krb5_context context,
        }
        break;
     }
-    case PKINIT_COMPAT_27:
+    case PKINIT_27:
        break;
     default:
        krb5_abortx(context, "internal pkinit error");
@@ -769,8 +761,8 @@ pk_mk_pa_reply_enckey(krb5_context context,
        free_ReplyKeyPack(&kp);
     }
     if (ret) {
-       krb5_set_error_string(context, "ASN.1 encoding of ReplyKeyPack "
-                             "failed (%d)", ret);
+       krb5_set_error_message(context, ret, "ASN.1 encoding of ReplyKeyPack "
+                              "failed (%d)", ret);
        goto out;
     }
     if (buf.length != size)
@@ -813,7 +805,7 @@ pk_mk_pa_reply_enckey(krb5_context context,
     if (ret) 
        goto out;
 
-    if (client_params->type == PKINIT_COMPAT_WIN2K) {
+    if (client_params->type == PKINIT_WIN2K) {
        ret = hx509_cms_wrap_ContentInfo(oid_id_pkcs7_signedData(),
                                         &signed_data,
                                         &buf);
@@ -874,9 +866,8 @@ pk_mk_pa_reply_dh(krb5_context context,
 
     ASN1_MALLOC_ENCODE(DHPublicKey, buf.data, buf.length, &i, &size, ret);
     if (ret) {
-       krb5_set_error_string(context, "ASN.1 encoding of "
-                             "DHPublicKey failed (%d)", ret);
-       krb5_clear_error_string(context);
+       krb5_set_error_message(context, ret, "ASN.1 encoding of "
+                              "DHPublicKey failed (%d)", ret);
        return ret;
     }
     if (buf.length != size)
@@ -890,8 +881,8 @@ pk_mk_pa_reply_dh(krb5_context context,
     ASN1_MALLOC_ENCODE(KDCDHKeyInfo, buf.data, buf.length, &dh_info, &size, 
                       ret);
     if (ret) {
-       krb5_set_error_string(context, "ASN.1 encoding of "
-                             "KdcDHKeyInfo failed (%d)", ret);
+       krb5_set_error_message(context, ret, "ASN.1 encoding of "
+                              "KdcDHKeyInfo failed (%d)", ret);
        goto out;
     }
     if (buf.length != size)
@@ -990,15 +981,15 @@ _kdc_pk_mk_pa_reply(krb5_context context,
                break;
        if (req->req_body.etype.len <= i) {
            ret = KRB5KRB_ERR_GENERIC;
-           krb5_set_error_string(context,
-                                 "No valid enctype available from client");
+           krb5_set_error_message(context, ret,
+                                  "No valid enctype available from client");
            goto out;
        }       
        enctype = req->req_body.etype.val[i];
     } else
        enctype = ETYPE_DES3_CBC_SHA1;
 
-    if (client_params->type == PKINIT_COMPAT_27) {
+    if (client_params->type == PKINIT_27) {
        PA_PK_AS_REP rep;
        const char *type, *other = "";
 
@@ -1035,8 +1026,8 @@ _kdc_pk_mk_pa_reply(krb5_context context,
                               ret);
            free_ContentInfo(&info);
            if (ret) {
-               krb5_set_error_string(context, "encoding of Key ContentInfo "
-                                     "failed %d", ret);
+               krb5_set_error_message(context, ret, "encoding of Key ContentInfo "
+                                      "failed %d", ret);
                free_PA_PK_AS_REP(&rep);
                goto out;
            }
@@ -1068,8 +1059,8 @@ _kdc_pk_mk_pa_reply(krb5_context context,
                               ret);
            free_ContentInfo(&info);
            if (ret) {
-               krb5_set_error_string(context, "encoding of Key ContentInfo "
-                                     "failed %d", ret);
+               krb5_set_error_message(context, ret, "encoding of Key ContentInfo "
+                                      "failed %d", ret);
                free_PA_PK_AS_REP(&rep);
                goto out;
            }
@@ -1085,8 +1076,8 @@ _kdc_pk_mk_pa_reply(krb5_context context,
        ASN1_MALLOC_ENCODE(PA_PK_AS_REP, buf, len, &rep, &size, ret);
        free_PA_PK_AS_REP(&rep);
        if (ret) {
-           krb5_set_error_string(context, "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)
@@ -1094,13 +1085,13 @@ _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_COMPAT_WIN2K) {
+    } else if (client_params->type == PKINIT_WIN2K) {
        PA_PK_AS_REP_Win2k rep;
        ContentInfo info;
 
        if (client_params->dh) {
-           krb5_set_error_string(context, "Windows PK-INIT doesn't support DH");
            ret = KRB5KRB_ERR_GENERIC;
+           krb5_set_error_message(context, ret, "Windows PK-INIT doesn't support DH");
            goto out;
        }
 
@@ -1131,7 +1122,7 @@ _kdc_pk_mk_pa_reply(krb5_context context,
                           ret);
        free_ContentInfo(&info);
        if (ret) {
-           krb5_set_error_string(context, "encoding of Key ContentInfo "
+           krb5_set_error_message(context, ret, "encoding of Key ContentInfo "
                                  "failed %d", ret);
            free_PA_PK_AS_REP_Win2k(&rep);
            goto out;
@@ -1142,7 +1133,7 @@ _kdc_pk_mk_pa_reply(krb5_context context,
        ASN1_MALLOC_ENCODE(PA_PK_AS_REP_Win2k, buf, len, &rep, &size, ret);
        free_PA_PK_AS_REP_Win2k(&rep);
        if (ret) {
-           krb5_set_error_string(context, 
+           krb5_set_error_message(context, ret,
                                  "encode PA-PK-AS-REP-Win2k failed %d", ret);
            goto out;
        }
@@ -1155,7 +1146,7 @@ _kdc_pk_mk_pa_reply(krb5_context context,
 
     ret = krb5_padata_add(context, md, pa_type, buf, len);
     if (ret) {
-       krb5_set_error_string(context, "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;
     }
@@ -1229,8 +1220,8 @@ _kdc_pk_mk_pa_reply(krb5_context context,
                                  KRB5_PADATA_PA_PK_OCSP_RESPONSE,
                                  ocsp.data.data, ocsp.data.length);
            if (ret) {
-               krb5_set_error_string(context, 
-                                     "Failed adding OCSP response %d", ret);
+               krb5_set_error_message(context, ret,
+                                      "Failed adding OCSP response %d", ret);
                goto out;
            }
        }
@@ -1453,7 +1444,8 @@ _kdc_pk_check_client(krb5_context context,
        return 0;
     }
 
-    krb5_set_error_string(context,
+    ret = KRB5_KDC_ERR_CLIENT_NAME_MISMATCH;
+    krb5_set_error_message(context, ret,
                          "PKINIT no matching principals for %s",
                          *subject_name);
 
@@ -1464,7 +1456,7 @@ _kdc_pk_check_client(krb5_context context,
     free(*subject_name);
     *subject_name = NULL;
 
-    return KRB5_KDC_ERR_CLIENT_NAME_MISMATCH;
+    return ret;
 }
 
 static krb5_error_code
index 1d0a01a215d10caa162ca62a6e1a4b4c55d6368e..550bfb04b2a15db05f3ede316cb7c3325d01de00 100644 (file)
@@ -34,7 +34,7 @@
 
 #include "kdc_locl.h"
 
-RCSID("$Id: process.c 20959 2007-06-07 04:46:06Z lha $");
+RCSID("$Id: process.c 23316 2008-06-23 04:32:32Z lha $");
 
 /*
  *
@@ -177,14 +177,15 @@ krb5_kdc_save_request(krb5_context context,
 
     fd = open(fn, O_WRONLY|O_CREAT|O_APPEND, 0600);
     if (fd < 0) {
-       krb5_set_error_string(context, "Failed to open: %s", fn);
-       return errno;
+       int saved_errno = errno;
+       krb5_set_error_message(context, saved_errno, "Failed to open: %s", fn);
+       return saved_errno;
     }
     
     sp = krb5_storage_from_fd(fd);
     close(fd);
     if (sp == NULL) {
-       krb5_set_error_string(context, "Storage failed to open fd");
+       krb5_set_error_message(context, ENOMEM, "Storage failed to open fd");
        return ENOMEM;
     }
 
index 85e4d7f725cb415d036409b8a675d9823d0bef78..621757f6dcf972c493c6517a9c3a68ab9fe404b8 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "kdc_locl.h"
 
-RCSID("$Id: windc.c 20559 2007-04-24 16:00:07Z lha $");
+RCSID("$Id: windc.c 23316 2008-06-23 04:32:32Z lha $");
 
 static krb5plugin_windc_ftable *windcft;
 static void *windcctx;
@@ -63,7 +63,7 @@ krb5_kdc_windc_init(krb5_context context)
     }
     if (e == NULL) {
        _krb5_plugin_free(list);
-       krb5_set_error_string(context, "Did not find any WINDC plugin");
+       krb5_set_error_message(context, ENOENT, "Did not find any WINDC plugin");
        windcft = NULL;
        return ENOENT;
     }
@@ -91,7 +91,7 @@ _kdc_pac_verify(krb5_context context,
                krb5_pac *pac)
 {
     if (windcft == NULL) {
-       krb5_set_error_string(context, "Can't verify PAC, no function");
+       krb5_set_error_message(context, EINVAL, "Can't verify PAC, no function");
        return EINVAL;
     }
     return (windcft->pac_verify)(windcctx, context, 
index 3ae0c94681e785cd28cdf9eaf3d2db456c361de4..44aab9e22b7ada10492764af98628350548fed9f 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE. 
  */
 
-/* $Id: windc_plugin.h 19798 2007-01-10 15:24:51Z lha $ */
+/* $Id: windc_plugin.h 22693 2008-03-19 08:57:49Z lha $ */
 
 #ifndef HEIMDAL_KRB5_PAC_PLUGIN_H
 #define HEIMDAL_KRB5_PAC_PLUGIN_H 1
@@ -67,7 +67,7 @@ typedef krb5_error_code
     void *, krb5_context, struct hdb_entry_ex *, KDC_REQ *, krb5_data *);
 
 
-#define KRB5_WINDC_PLUGING_MINOR               2
+#define KRB5_WINDC_PLUGING_MINOR               3
 
 typedef struct krb5plugin_windc_ftable {
     int                        minor_version;
index 2676309859089bda9136eeaa0d157e9c48cad707..0e03dc4d377e7588206d243fc156d01d583a2ec6 100644 (file)
@@ -32,7 +32,7 @@
  */
 
 #include "kuser_locl.h"
-RCSID("$Id: kinit.c 22116 2007-12-03 21:22:58Z lha $");
+RCSID("$Id: kinit.c 23418 2008-07-26 18:36:48Z lha $");
 
 #include "krb5-v4compat.h"
 
@@ -66,6 +66,8 @@ char *pk_user_id      = NULL;
 char *pk_x509_anchors  = NULL;
 int pk_use_enckey      = 0;
 static int canonicalize_flag = 0;
+static int ok_as_delegate_flag = 0;
+static int windows_flag = 0;
 static char *ntlm_domain;
 
 static char *krb4_cc_name;
@@ -161,6 +163,12 @@ static struct getargs args[] = {
     { "ntlm-domain",   0,  arg_string, &ntlm_domain,
       "NTLM domain", "domain" },
 
+    { "ok-as-delegate",        0,  arg_flag, &ok_as_delegate_flag,
+      "honor ok-as-delegate on tickets" },
+
+    { "windows",       0,  arg_flag, &windows_flag,
+      "get windows behavior" },
+
     { "version",       0,   arg_flag, &version_flag },
     { "help",          0,   arg_flag, &help_flag }
 };
@@ -329,36 +337,25 @@ out:
 }
 
 static krb5_error_code
-store_ntlmkey(krb5_context context, krb5_ccache id, 
-             const char *domain, krb5_const_principal client,
-             struct ntlm_buf *buf)
+store_ntlmkey(krb5_context context, krb5_ccache id,
+             const char *domain, struct ntlm_buf *buf)
 {
     krb5_error_code ret;
-    krb5_creds cred;
-    
-    memset(&cred, 0, sizeof(cred));
+    krb5_data data;
+    char *name;
 
-    ret = krb5_make_principal(context, &cred.server,
-                             krb5_principal_get_realm(context, client),
-                             "@ntlm-key", domain, NULL);
-    if (ret)
-       goto out;
-    ret = krb5_copy_principal(context, client, &cred.client);
-    if (ret)
-       goto out;
+    asprintf(&name, "ntlm-key-%s", domain);
+    if (name == NULL) {
+       krb5_clear_error_string(context);
+       return ENOMEM;
+    }
     
-    cred.times.authtime = time(NULL);
-    cred.times.endtime = time(NULL) + 3600 * 24 * 30; /* XXX */
-    cred.session.keytype = ENCTYPE_ARCFOUR_HMAC_MD5;
-    ret = krb5_data_copy(&cred.session.keyvalue, buf->data, buf->length);
-    if (ret)
-       goto out;
-
-    ret = krb5_cc_store_cred(context, id, &cred);
+    data.length = buf->length;
+    data.data = buf->data;
 
-out:
-    krb5_free_cred_contents (context, &cred);
-    return 0;
+    ret = krb5_cc_set_config(context, id, NULL, name, &data);
+    free(name);
+    return ret;
 }
 
 static krb5_error_code
@@ -598,7 +595,17 @@ get_new_tickets(krb5_context context,
        krb5_err (context, 1, ret, "krb5_cc_move");
 
     if (ntlm_domain && ntlmkey.data)
-       store_ntlmkey(context, ccache, ntlm_domain, principal, &ntlmkey);
+       store_ntlmkey(context, ccache, ntlm_domain, &ntlmkey);
+
+    if (ok_as_delegate_flag || windows_flag) {
+       krb5_data data;
+
+       data.length = 1;
+       data.data = "\x01";
+
+       krb5_cc_set_config(context, ccache, NULL, "realm-config", &data);
+    }
+
 
     if (enctype)
        free(enctype);
index 13e39320d4ecdcb910eacd604a110b175579c385..0484137192c47a24e363cf062bbe083b5bb80f04 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE. 
  */
 
-/* $Id: der.h 18437 2006-10-14 05:16:08Z lha $ */
+/* $Id: der.h 23183 2008-05-22 09:56:51Z lha $ */
 
 #ifndef __DER_H__
 #define __DER_H__
index 851cb1d40775f8b5ad9218cb1f5e195815f021dd..f59ec72eb7f5c0040af819f61bbc595178fa5405 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "der_locl.h"
 
-RCSID("$Id: der_free.c 19539 2006-12-28 17:15:05Z lha $");
+RCSID("$Id: der_free.c 23182 2008-05-22 02:59:04Z lha $");
 
 void
 der_free_general_string (heim_general_string *str)
index 499f8eab363b56f51392a5f0977c3a894b90b795..39dba89e4e1cb847a242b6e16f2bc67c4af34600 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "gen_locl.h"
 
-RCSID("$Id: gen.c 22429 2008-01-13 10:25:50Z lha $");
+RCSID("$Id: gen.c 22896 2008-04-07 18:52:24Z lha $");
 
 FILE *headerfile, *codefile, *logfile;
 
@@ -294,13 +294,18 @@ generate_constant (const Symbol *s)
        break;
     case objectidentifiervalue: {
        struct objid *o, **list;
-       int i, len;
+       unsigned int i, len;
 
        generate_header_of_codefile(s->gen_name);
 
        len = 0;
        for (o = s->value->u.objectidentifiervalue; o != NULL; o = o->next)
            len++;
+       if (len == 0) {
+           printf("s->gen_name: %s",s->gen_name);
+           fflush(stdout);
+           break;
+       }
        list = emalloc(sizeof(*list) * len);
 
        i = 0;
@@ -308,8 +313,8 @@ generate_constant (const Symbol *s)
            list[i++] = o;
 
        fprintf (headerfile, "/* OBJECT IDENTIFIER %s ::= { ", s->name);
-       for (i = len - 1 ; i >= 0; i--) {
-           o = list[i];
+       for (i = len ; i > 0; i--) {
+           o = list[i - 1];
            fprintf(headerfile, "%s(%d) ",
                    o->label ? o->label : "label-less", o->value);
        }
@@ -320,8 +325,8 @@ generate_constant (const Symbol *s)
 
        fprintf (codefile, "static unsigned oid_%s_variable_num[%d] =  {",
                 s->gen_name, len);
-       for (i = len - 1 ; i >= 0; i--) {
-           fprintf(codefile, "%d%s ", list[i]->value, i > 0 ? "," : "");
+       for (i = len ; i > 0; i--) {
+           fprintf(codefile, "%d%s ", list[i - 1]->value, i > 1 ? "," : "");
        }
        fprintf(codefile, "};\n");
 
index 18f1e1541b5f6723b256ac89645abab219cc52a3..ea20eb99d24ba87ba90e12629109ef088d2d17e4 100644 (file)
@@ -1,4 +1,4 @@
--- $Id: k5.asn1 21965 2007-10-18 18:24:36Z lha $
+-- $Id: k5.asn1 22745 2008-03-24 12:07:54Z lha $
 
 KERBEROS5 DEFINITIONS ::=
 BEGIN
@@ -634,18 +634,18 @@ KRB5SignedPath ::= SEQUENCE {
 }
 
 PA-ClientCanonicalizedNames ::= SEQUENCE{
-       requested-name [0] PrincipalName,
-       real-name      [1] PrincipalName
+       requested-name  [0] PrincipalName,
+       mapped-name     [1] PrincipalName
 }
 
 PA-ClientCanonicalized ::= SEQUENCE {
-       names          [0] PA-ClientCanonicalizedNames,
-       canon-checksum [1] Checksum
+       names           [0] PA-ClientCanonicalizedNames,
+       canon-checksum  [1] Checksum
 }
 
 AD-LoginAlias ::= SEQUENCE { -- ad-type number TBD --
-       login-alias  [0] PrincipalName,
-       checksum     [1] Checksum
+       login-alias     [0] PrincipalName,
+       checksum        [1] Checksum
 }
 
 -- old ms referral
@@ -654,6 +654,16 @@ PA-SvrReferralData ::= SEQUENCE {
        referred-realm  [0] Realm
 }
 
+PA-SERVER-REFERRAL-DATA ::= EncryptedData
+
+PA-ServerReferralData ::= SEQUENCE {
+       referred-realm          [0] Realm OPTIONAL,
+       true-principal-name     [1] PrincipalName OPTIONAL,
+       requested-principal-name [2] PrincipalName OPTIONAL,
+       referral-valid-until     [3] KerberosTime OPTIONAL,
+       ...
+}
+
 END
 
 -- etags -r '/\([A-Za-z][-A-Za-z0-9]*\).*::=/\1/' k5.asn1
index da4f729c3d6966e6026ada705541fea8c93ac16a..175760be4406d1c45cbbc790776b9d6cbe69a4e5 100644 (file)
@@ -1,5 +1,6 @@
+#include "config.h"
 
-#line 3 "lex.c"
+#line 3 "heimdal/lib/asn1/lex.c"
 
 #define  YY_INT_ALIGNED short int
 
@@ -8,7 +9,7 @@
 #define FLEX_SCANNER
 #define YY_FLEX_MAJOR_VERSION 2
 #define YY_FLEX_MINOR_VERSION 5
-#define YY_FLEX_SUBMINOR_VERSION 33
+#define YY_FLEX_SUBMINOR_VERSION 34
 #if YY_FLEX_SUBMINOR_VERSION > 0
 #define FLEX_BETA
 #endif
@@ -30,7 +31,7 @@
 
 /* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
 
-#if __STDC_VERSION__ >= 199901L
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
 
 /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
  * if you want the limit (max/min) macros for int types. 
@@ -93,11 +94,12 @@ typedef unsigned int flex_uint32_t;
 
 #else  /* ! __cplusplus */
 
-#if __STDC__
+/* C99 requires __STDC__ to be defined as 1. */
+#if defined (__STDC__)
 
 #define YY_USE_CONST
 
-#endif /* __STDC__ */
+#endif /* defined (__STDC__) */
 #endif /* ! __cplusplus */
 
 #ifdef YY_USE_CONST
@@ -180,11 +182,13 @@ extern FILE *yyin, *yyout;
 /* The following is because we cannot portably get our hands on size_t
  * (without autoconf's help, which isn't available because we want
  * flex-generated scanners to compile on their own).
+ * Given that the standard has decreed that size_t exists since 1989,
+ * I guess we can afford to depend on it. Manoj.
  */
 
 #ifndef YY_TYPEDEF_YY_SIZE_T
 #define YY_TYPEDEF_YY_SIZE_T
-typedef unsigned int yy_size_t;
+typedef size_t yy_size_t;
 #endif
 
 #ifndef YY_STRUCT_YY_BUFFER_STATE
@@ -851,7 +855,7 @@ static unsigned lineno = 1;
 static void unterminated(const char *, unsigned);
 
 /* This is for broken old lexes (solaris 10 and hpux) */
-#line 855 "lex.c"
+#line 858 "heimdal/lib/asn1/lex.c"
 
 #define INITIAL 0
 
@@ -869,35 +873,6 @@ static void unterminated(const char *, unsigned);
 
 static int yy_init_globals (void );
 
-/* Accessor methods to globals.
-   These are made visible to non-reentrant scanners for convenience. */
-
-int yylex_destroy (void );
-
-int yyget_debug (void );
-
-void yyset_debug (int debug_flag  );
-
-YY_EXTRA_TYPE yyget_extra (void );
-
-void yyset_extra (YY_EXTRA_TYPE user_defined  );
-
-FILE *yyget_in (void );
-
-void yyset_in  (FILE * in_str  );
-
-FILE *yyget_out (void );
-
-void yyset_out  (FILE * out_str  );
-
-int yyget_leng (void );
-
-char *yyget_text (void );
-
-int yyget_lineno (void );
-
-void yyset_lineno (int line_number  );
-
 /* Macros after this point can all be overridden by user definitions in
  * section 1.
  */
@@ -940,7 +915,7 @@ static int input (void );
 /* This used to be an fputs(), but since the string might contain NUL's,
  * we now use fwrite().
  */
-#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
+#define ECHO fwrite( yytext, yyleng, 1, yyout )
 #endif
 
 /* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
@@ -951,7 +926,7 @@ static int input (void );
        if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
                { \
                int c = '*'; \
-               size_t n; \
+               int n; \
                for ( n = 0; n < max_size && \
                             (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
                        buf[n] = (char) c; \
@@ -1035,7 +1010,7 @@ YY_DECL
     
 #line 68 "lex.l"
 
-#line 1039 "lex.c"
+#line 1013 "heimdal/lib/asn1/lex.c"
 
        if ( !(yy_init) )
                {
@@ -1704,7 +1679,7 @@ YY_RULE_SETUP
 #line 274 "lex.l"
 ECHO;
        YY_BREAK
-#line 1708 "lex.c"
+#line 1682 "heimdal/lib/asn1/lex.c"
 case YY_STATE_EOF(INITIAL):
        yyterminate();
 
@@ -1935,7 +1910,7 @@ static int yy_get_next_buffer (void)
 
                /* Read in more data. */
                YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
-                       (yy_n_chars), num_to_read );
+                       (yy_n_chars), (size_t) num_to_read );
 
                YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
                }
@@ -1959,6 +1934,14 @@ static int yy_get_next_buffer (void)
        else
                ret_val = EOB_ACT_CONTINUE_SCAN;
 
+       if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+               /* Extend the array by 50%, plus the number we really need. */
+               yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
+               YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size  );
+               if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+                       YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+       }
+
        (yy_n_chars) += number_to_move;
        YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
        YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
@@ -2374,7 +2357,9 @@ static void yyensure_buffer_stack (void)
                (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
                                                                (num_to_alloc * sizeof(struct yy_buffer_state*)
                                                                );
-               
+               if ( ! (yy_buffer_stack) )
+                       YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+                                                                 
                memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
                                
                (yy_buffer_stack_max) = num_to_alloc;
@@ -2392,6 +2377,8 @@ static void yyensure_buffer_stack (void)
                                                                ((yy_buffer_stack),
                                                                num_to_alloc * sizeof(struct yy_buffer_state*)
                                                                );
+               if ( ! (yy_buffer_stack) )
+                       YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
 
                /* zero only the new slots.*/
                memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
@@ -2436,7 +2423,7 @@ YY_BUFFER_STATE yy_scan_buffer  (char * base, yy_size_t  size )
 
 /** Setup the input buffer state to scan a string. The next call to yylex() will
  * scan from a @e copy of @a str.
- * @param str a NUL-terminated string to scan
+ * @param yystr a NUL-terminated string to scan
  * 
  * @return the newly allocated buffer state object.
  * @note If you want to scan bytes that may contain NUL values, then use
index 6ec7b67bb9cdd65fdd2eb2ccdd072d366ebba9a3..ec744220e9c0a353e41653156792971d54f16ed1 100644 (file)
@@ -32,7 +32,7 @@
  * SUCH DAMAGE. 
  */
 
-/* $Id: lex.l,v 1.31 2006/10/21 11:57:22 lha Exp $ */
+/* $Id: lex.l 18738 2006-10-21 11:57:22Z lha $ */
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
index 989b26581b3a1b69eea569b96e37bbef624da33a..758af6f86e8734879b75c562113762c993f4a239 100644 (file)
@@ -17,6 +17,11 @@ id-pkrkeydata  OBJECT IDENTIFIER  ::= { id-pkinit 3 }
 id-pkekuoid    OBJECT IDENTIFIER  ::= { id-pkinit 4 }
 id-pkkdcekuoid OBJECT IDENTIFIER  ::= { id-pkinit 5 }
 
+id-pkinit-kdf OBJECT IDENTIFIER           ::= { id-pkinit 6 }
+id-pkinit-kdf-ah-sha1 OBJECT IDENTIFIER   ::= { id-pkinit-kdf 1 }
+id-pkinit-kdf-ah-sha256 OBJECT IDENTIFIER ::= { id-pkinit-kdf 2 }
+id-pkinit-kdf-ah-sha512 OBJECT IDENTIFIER ::= { id-pkinit-kdf 3 }
+
 id-pkinit-san  OBJECT IDENTIFIER ::=
   { iso(1) org(3) dod(6) internet(1) security(5) kerberosv5(2)
     x509-sanan(2) }
@@ -171,6 +176,14 @@ ReplyKeyPack-Win2k ::= SEQUENCE {
        ...
 }
 
+PkinitSP80056AOtherInfo ::= SEQUENCE { 
+       algorithmID   AlgorithmIdentifier, 
+       partyUInfo     [0] OCTET STRING, 
+       partyVInfo     [1] OCTET STRING, 
+       suppPubInfo    [2] OCTET STRING OPTIONAL, 
+       suppPrivInfo   [3] OCTET STRING OPTIONAL 
+}
+
 PkinitSuppPubInfo ::= SEQUENCE {
        enctype           [0] INTEGER (-2147483648..2147483647),
        as-REQ            [1] OCTET STRING,
index 9a1f3547917dd6cd4a728f6197f3e87e3d8e83ca..d0fc7d98a44b6cebe2b9a49ae18d51793fd93156 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: test.gen,v 1.2 2005/07/12 06:27:41 lha Exp $
+# $Id: test.gen 15617 2005-07-12 06:27:42Z lha $
 # Sample for TESTSeq in test.asn1
 #
 
index 3c6ea3beb71dfa4a8e78a718bfcb93c0c1234d3d..b70ef4749f86ea0336b736ffcc1b65e2fb84ff54 100644 (file)
@@ -1,5 +1,6 @@
+#include "config.h"
 
-#line 3 "lex.c"
+#line 3 "heimdal/lib/com_err/lex.c"
 
 #define  YY_INT_ALIGNED short int
 
@@ -8,7 +9,7 @@
 #define FLEX_SCANNER
 #define YY_FLEX_MAJOR_VERSION 2
 #define YY_FLEX_MINOR_VERSION 5
-#define YY_FLEX_SUBMINOR_VERSION 33
+#define YY_FLEX_SUBMINOR_VERSION 34
 #if YY_FLEX_SUBMINOR_VERSION > 0
 #define FLEX_BETA
 #endif
@@ -30,7 +31,7 @@
 
 /* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
 
-#if __STDC_VERSION__ >= 199901L
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
 
 /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
  * if you want the limit (max/min) macros for int types. 
@@ -93,11 +94,12 @@ typedef unsigned int flex_uint32_t;
 
 #else  /* ! __cplusplus */
 
-#if __STDC__
+/* C99 requires __STDC__ to be defined as 1. */
+#if defined (__STDC__)
 
 #define YY_USE_CONST
 
-#endif /* __STDC__ */
+#endif /* defined (__STDC__) */
 #endif /* ! __cplusplus */
 
 #ifdef YY_USE_CONST
@@ -180,11 +182,13 @@ extern FILE *yyin, *yyout;
 /* The following is because we cannot portably get our hands on size_t
  * (without autoconf's help, which isn't available because we want
  * flex-generated scanners to compile on their own).
+ * Given that the standard has decreed that size_t exists since 1989,
+ * I guess we can afford to depend on it. Manoj.
  */
 
 #ifndef YY_TYPEDEF_YY_SIZE_T
 #define YY_TYPEDEF_YY_SIZE_T
-typedef unsigned int yy_size_t;
+typedef size_t yy_size_t;
 #endif
 
 #ifndef YY_STRUCT_YY_BUFFER_STATE
@@ -532,7 +536,7 @@ static int getstring(void);
 
 #undef ECHO
 
-#line 536 "lex.c"
+#line 539 "heimdal/lib/com_err/lex.c"
 
 #define INITIAL 0
 
@@ -550,35 +554,6 @@ static int getstring(void);
 
 static int yy_init_globals (void );
 
-/* Accessor methods to globals.
-   These are made visible to non-reentrant scanners for convenience. */
-
-int yylex_destroy (void );
-
-int yyget_debug (void );
-
-void yyset_debug (int debug_flag  );
-
-YY_EXTRA_TYPE yyget_extra (void );
-
-void yyset_extra (YY_EXTRA_TYPE user_defined  );
-
-FILE *yyget_in (void );
-
-void yyset_in  (FILE * in_str  );
-
-FILE *yyget_out (void );
-
-void yyset_out  (FILE * out_str  );
-
-int yyget_leng (void );
-
-char *yyget_text (void );
-
-int yyget_lineno (void );
-
-void yyset_lineno (int line_number  );
-
 /* Macros after this point can all be overridden by user definitions in
  * section 1.
  */
@@ -621,7 +596,7 @@ static int input (void );
 /* This used to be an fputs(), but since the string might contain NUL's,
  * we now use fwrite().
  */
-#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
+#define ECHO fwrite( yytext, yyleng, 1, yyout )
 #endif
 
 /* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
@@ -632,7 +607,7 @@ static int input (void );
        if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
                { \
                int c = '*'; \
-               size_t n; \
+               int n; \
                for ( n = 0; n < max_size && \
                             (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
                        buf[n] = (char) c; \
@@ -716,7 +691,7 @@ YY_DECL
     
 #line 59 "lex.l"
 
-#line 720 "lex.c"
+#line 694 "heimdal/lib/com_err/lex.c"
 
        if ( !(yy_init) )
                {
@@ -880,7 +855,7 @@ YY_RULE_SETUP
 #line 75 "lex.l"
 ECHO;
        YY_BREAK
-#line 884 "lex.c"
+#line 858 "heimdal/lib/com_err/lex.c"
 case YY_STATE_EOF(INITIAL):
        yyterminate();
 
@@ -1111,7 +1086,7 @@ static int yy_get_next_buffer (void)
 
                /* Read in more data. */
                YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
-                       (yy_n_chars), num_to_read );
+                       (yy_n_chars), (size_t) num_to_read );
 
                YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
                }
@@ -1135,6 +1110,14 @@ static int yy_get_next_buffer (void)
        else
                ret_val = EOB_ACT_CONTINUE_SCAN;
 
+       if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+               /* Extend the array by 50%, plus the number we really need. */
+               yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
+               YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size  );
+               if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+                       YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+       }
+
        (yy_n_chars) += number_to_move;
        YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
        YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
@@ -1550,7 +1533,9 @@ static void yyensure_buffer_stack (void)
                (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
                                                                (num_to_alloc * sizeof(struct yy_buffer_state*)
                                                                );
-               
+               if ( ! (yy_buffer_stack) )
+                       YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+                                                                 
                memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
                                
                (yy_buffer_stack_max) = num_to_alloc;
@@ -1568,6 +1553,8 @@ static void yyensure_buffer_stack (void)
                                                                ((yy_buffer_stack),
                                                                num_to_alloc * sizeof(struct yy_buffer_state*)
                                                                );
+               if ( ! (yy_buffer_stack) )
+                       YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
 
                /* zero only the new slots.*/
                memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
@@ -1612,7 +1599,7 @@ YY_BUFFER_STATE yy_scan_buffer  (char * base, yy_size_t  size )
 
 /** Setup the input buffer state to scan a string. The next call to yylex() will
  * scan from a @e copy of @a str.
- * @param str a NUL-terminated string to scan
+ * @param yystr a NUL-terminated string to scan
  * 
  * @return the newly allocated buffer state object.
  * @note If you want to scan bytes that may contain NUL values, then use
index d60e67c136e9fde6d56c1bc82e0d8df4adaf5c17..08aef516b304bce23e0de098a5125998b4cc281e 100644 (file)
@@ -44,7 +44,7 @@
 #include "parse.h"
 #include "lex.h"
 
-RCSID("$Id: lex.l,v 1.8 2005/05/16 08:52:54 lha Exp $");
+RCSID("$Id: lex.l 15143 2005-05-16 08:52:54Z lha $");
 
 static unsigned lineno = 1;
 static int getstring(void);
index fbc638c48fca41dd47fcd1de525cc875c02a0bee..63f66f73133e2ec1d8883cd46ea23f242cb756bd 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE. 
  */
 
-/* $Id: gssapi.h 21004 2007-06-08 01:53:10Z lha $ */
+/* $Id: gssapi.h 23025 2008-04-17 10:01:57Z lha $ */
 
 #ifndef GSSAPI_GSSAPI_H_
 #define GSSAPI_GSSAPI_H_
 
 #include <krb5-types.h>
 
+#ifndef BUILD_GSSAPI_LIB
+#if defined(_WIN32)
+#define GSSAPI_LIB_FUNCTION _stdcall __declspec(dllimport)
+#define GSSAPI_LIB_VARIABLE __declspec(dllimport)
+#else
+#define GSSAPI_LIB_FUNCTION
+#define GSSAPI_LIB_VARIABLE
+#endif
+#endif
+
 /*
  * Now define the three implementation-dependent types.
  */
@@ -210,7 +220,7 @@ extern "C" {
  * GSS_C_NT_USER_NAME should be initialized to point
  * to that gss_OID_desc.
  */
-extern gss_OID GSS_C_NT_USER_NAME;
+extern GSSAPI_LIB_VARIABLE gss_OID GSS_C_NT_USER_NAME;
 
 /*
  * The implementation must reserve static storage for a
@@ -223,7 +233,7 @@ extern gss_OID GSS_C_NT_USER_NAME;
  * The constant GSS_C_NT_MACHINE_UID_NAME should be
  * initialized to point to that gss_OID_desc.
  */
-extern gss_OID GSS_C_NT_MACHINE_UID_NAME;
+extern GSSAPI_LIB_VARIABLE gss_OID GSS_C_NT_MACHINE_UID_NAME;
 
 /*
  * The implementation must reserve static storage for a
@@ -236,7 +246,7 @@ extern gss_OID GSS_C_NT_MACHINE_UID_NAME;
  * The constant GSS_C_NT_STRING_UID_NAME should be
  * initialized to point to that gss_OID_desc.
  */
-extern gss_OID GSS_C_NT_STRING_UID_NAME;
+extern GSSAPI_LIB_VARIABLE gss_OID GSS_C_NT_STRING_UID_NAME;
 
 /*
  * The implementation must reserve static storage for a
@@ -255,7 +265,7 @@ extern gss_OID GSS_C_NT_STRING_UID_NAME;
  * parameter, but should not be emitted by GSS-API
  * implementations
  */
-extern gss_OID GSS_C_NT_HOSTBASED_SERVICE_X;
+extern GSSAPI_LIB_VARIABLE gss_OID GSS_C_NT_HOSTBASED_SERVICE_X;
 
 /*
  * The implementation must reserve static storage for a
@@ -268,7 +278,7 @@ extern gss_OID GSS_C_NT_HOSTBASED_SERVICE_X;
  * GSS_C_NT_HOSTBASED_SERVICE should be initialized
  * to point to that gss_OID_desc.
  */
-extern gss_OID GSS_C_NT_HOSTBASED_SERVICE;
+extern GSSAPI_LIB_VARIABLE gss_OID GSS_C_NT_HOSTBASED_SERVICE;
 
 /*
  * The implementation must reserve static storage for a
@@ -280,7 +290,7 @@ extern gss_OID GSS_C_NT_HOSTBASED_SERVICE;
  * and GSS_C_NT_ANONYMOUS should be initialized to point
  * to that gss_OID_desc.
  */
-extern gss_OID GSS_C_NT_ANONYMOUS;
+extern GSSAPI_LIB_VARIABLE gss_OID GSS_C_NT_ANONYMOUS;
 
 /*
  * The implementation must reserve static storage for a
@@ -292,19 +302,19 @@ extern gss_OID GSS_C_NT_ANONYMOUS;
  * GSS_C_NT_EXPORT_NAME should be initialized to point
  * to that gss_OID_desc.
  */
-extern gss_OID GSS_C_NT_EXPORT_NAME;
+extern GSSAPI_LIB_VARIABLE gss_OID GSS_C_NT_EXPORT_NAME;
 
 /*
  * Digest mechanism
  */
 
-extern gss_OID GSS_SASL_DIGEST_MD5_MECHANISM;
+extern GSSAPI_LIB_VARIABLE gss_OID GSS_SASL_DIGEST_MD5_MECHANISM;
 
 /*
  * NTLM mechanism
  */
 
-extern gss_OID GSS_NTLM_MECHANISM;
+extern GSSAPI_LIB_VARIABLE gss_OID GSS_NTLM_MECHANISM;
 
 /* Major status codes */
 
@@ -387,7 +397,7 @@ extern gss_OID GSS_NTLM_MECHANISM;
  * Finally, function prototypes for the GSS-API routines.
  */
 
-OM_uint32 gss_acquire_cred
+OM_uint32 GSSAPI_LIB_FUNCTION gss_acquire_cred
            (OM_uint32 * /*minor_status*/,
             const gss_name_t /*desired_name*/,
             OM_uint32 /*time_req*/,
@@ -398,12 +408,12 @@ OM_uint32 gss_acquire_cred
             OM_uint32 * /*time_rec*/
            );
 
-OM_uint32 gss_release_cred
+OM_uint32 GSSAPI_LIB_FUNCTION gss_release_cred
            (OM_uint32 * /*minor_status*/,
             gss_cred_id_t * /*cred_handle*/
            );
 
-OM_uint32 gss_init_sec_context
+OM_uint32 GSSAPI_LIB_FUNCTION gss_init_sec_context
            (OM_uint32 * /*minor_status*/,
             const gss_cred_id_t /*initiator_cred_handle*/,
             gss_ctx_id_t * /*context_handle*/,
@@ -419,7 +429,7 @@ OM_uint32 gss_init_sec_context
             OM_uint32 * /*time_rec*/
            );
 
-OM_uint32 gss_accept_sec_context
+OM_uint32 GSSAPI_LIB_FUNCTION gss_accept_sec_context
            (OM_uint32 * /*minor_status*/,
             gss_ctx_id_t * /*context_handle*/,
             const gss_cred_id_t /*acceptor_cred_handle*/,
@@ -433,25 +443,25 @@ OM_uint32 gss_accept_sec_context
             gss_cred_id_t * /*delegated_cred_handle*/
            );
 
-OM_uint32 gss_process_context_token
+OM_uint32 GSSAPI_LIB_FUNCTION gss_process_context_token
            (OM_uint32 * /*minor_status*/,
             const gss_ctx_id_t /*context_handle*/,
             const gss_buffer_t /*token_buffer*/
            );
 
-OM_uint32 gss_delete_sec_context
+OM_uint32 GSSAPI_LIB_FUNCTION gss_delete_sec_context
            (OM_uint32 * /*minor_status*/,
             gss_ctx_id_t * /*context_handle*/,
             gss_buffer_t /*output_token*/
            );
 
-OM_uint32 gss_context_time
+OM_uint32 GSSAPI_LIB_FUNCTION gss_context_time
            (OM_uint32 * /*minor_status*/,
             const gss_ctx_id_t /*context_handle*/,
             OM_uint32 * /*time_rec*/
            );
 
-OM_uint32 gss_get_mic
+OM_uint32 GSSAPI_LIB_FUNCTION gss_get_mic
            (OM_uint32 * /*minor_status*/,
             const gss_ctx_id_t /*context_handle*/,
             gss_qop_t /*qop_req*/,
@@ -459,7 +469,7 @@ OM_uint32 gss_get_mic
             gss_buffer_t /*message_token*/
            );
 
-OM_uint32 gss_verify_mic
+OM_uint32 GSSAPI_LIB_FUNCTION gss_verify_mic
            (OM_uint32 * /*minor_status*/,
             const gss_ctx_id_t /*context_handle*/,
             const gss_buffer_t /*message_buffer*/,
@@ -467,7 +477,7 @@ OM_uint32 gss_verify_mic
             gss_qop_t * /*qop_state*/
            );
 
-OM_uint32 gss_wrap
+OM_uint32 GSSAPI_LIB_FUNCTION gss_wrap
            (OM_uint32 * /*minor_status*/,
             const gss_ctx_id_t /*context_handle*/,
             int /*conf_req_flag*/,
@@ -477,7 +487,7 @@ OM_uint32 gss_wrap
             gss_buffer_t /*output_message_buffer*/
            );
 
-OM_uint32 gss_unwrap
+OM_uint32 GSSAPI_LIB_FUNCTION gss_unwrap
            (OM_uint32 * /*minor_status*/,
             const gss_ctx_id_t /*context_handle*/,
             const gss_buffer_t /*input_message_buffer*/,
@@ -486,7 +496,7 @@ OM_uint32 gss_unwrap
             gss_qop_t * /*qop_state*/
            );
 
-OM_uint32 gss_display_status
+OM_uint32 GSSAPI_LIB_FUNCTION gss_display_status
            (OM_uint32 * /*minor_status*/,
             OM_uint32 /*status_value*/,
             int /*status_type*/,
@@ -495,54 +505,54 @@ OM_uint32 gss_display_status
             gss_buffer_t /*status_string*/
            );
 
-OM_uint32 gss_indicate_mechs
+OM_uint32 GSSAPI_LIB_FUNCTION gss_indicate_mechs
            (OM_uint32 * /*minor_status*/,
             gss_OID_set * /*mech_set*/
            );
 
-OM_uint32 gss_compare_name
+OM_uint32 GSSAPI_LIB_FUNCTION gss_compare_name
            (OM_uint32 * /*minor_status*/,
             const gss_name_t /*name1*/,
             const gss_name_t /*name2*/,
             int * /*name_equal*/
            );
 
-OM_uint32 gss_display_name
+OM_uint32 GSSAPI_LIB_FUNCTION gss_display_name
            (OM_uint32 * /*minor_status*/,
             const gss_name_t /*input_name*/,
             gss_buffer_t /*output_name_buffer*/,
             gss_OID * /*output_name_type*/
            );
 
-OM_uint32 gss_import_name
+OM_uint32 GSSAPI_LIB_FUNCTION gss_import_name
            (OM_uint32 * /*minor_status*/,
             const gss_buffer_t /*input_name_buffer*/,
             const gss_OID /*input_name_type*/,
             gss_name_t * /*output_name*/
            );
 
-OM_uint32 gss_export_name
+OM_uint32 GSSAPI_LIB_FUNCTION gss_export_name
            (OM_uint32  * /*minor_status*/,
             const gss_name_t /*input_name*/,
             gss_buffer_t /*exported_name*/
            );
 
-OM_uint32 gss_release_name
+OM_uint32 GSSAPI_LIB_FUNCTION gss_release_name
            (OM_uint32 * /*minor_status*/,
             gss_name_t * /*input_name*/
            );
 
-OM_uint32 gss_release_buffer
+OM_uint32 GSSAPI_LIB_FUNCTION gss_release_buffer
            (OM_uint32 * /*minor_status*/,
             gss_buffer_t /*buffer*/
            );
 
-OM_uint32 gss_release_oid_set
+OM_uint32 GSSAPI_LIB_FUNCTION gss_release_oid_set
            (OM_uint32 * /*minor_status*/,
             gss_OID_set * /*set*/
            );
 
-OM_uint32 gss_inquire_cred
+OM_uint32 GSSAPI_LIB_FUNCTION gss_inquire_cred
            (OM_uint32 * /*minor_status*/,
             const gss_cred_id_t /*cred_handle*/,
             gss_name_t * /*name*/,
@@ -551,7 +561,7 @@ OM_uint32 gss_inquire_cred
             gss_OID_set * /*mechanisms*/
            );
 
-OM_uint32 gss_inquire_context (
+OM_uint32 GSSAPI_LIB_FUNCTION gss_inquire_context (
             OM_uint32 * /*minor_status*/,
             const gss_ctx_id_t /*context_handle*/,
             gss_name_t * /*src_name*/,
@@ -563,7 +573,7 @@ OM_uint32 gss_inquire_context (
             int * /*open_context*/
            );
 
-OM_uint32 gss_wrap_size_limit (
+OM_uint32 GSSAPI_LIB_FUNCTION gss_wrap_size_limit (
             OM_uint32 * /*minor_status*/,
             const gss_ctx_id_t /*context_handle*/,
             int /*conf_req_flag*/,
@@ -572,7 +582,7 @@ OM_uint32 gss_wrap_size_limit (
             OM_uint32 * /*max_input_size*/
            );
 
-OM_uint32 gss_add_cred (
+OM_uint32 GSSAPI_LIB_FUNCTION gss_add_cred (
             OM_uint32 * /*minor_status*/,
             const gss_cred_id_t /*input_cred_handle*/,
             const gss_name_t /*desired_name*/,
@@ -586,7 +596,7 @@ OM_uint32 gss_add_cred (
             OM_uint32 * /*acceptor_time_rec*/
            );
 
-OM_uint32 gss_inquire_cred_by_mech (
+OM_uint32 GSSAPI_LIB_FUNCTION gss_inquire_cred_by_mech (
             OM_uint32 * /*minor_status*/,
             const gss_cred_id_t /*cred_handle*/,
             const gss_OID /*mech_type*/,
@@ -596,80 +606,81 @@ OM_uint32 gss_inquire_cred_by_mech (
             gss_cred_usage_t * /*cred_usage*/
            );
 
-OM_uint32 gss_export_sec_context (
+OM_uint32 GSSAPI_LIB_FUNCTION gss_export_sec_context (
             OM_uint32 * /*minor_status*/,
             gss_ctx_id_t * /*context_handle*/,
             gss_buffer_t /*interprocess_token*/
            );
 
-OM_uint32 gss_import_sec_context (
+OM_uint32 GSSAPI_LIB_FUNCTION gss_import_sec_context (
             OM_uint32 * /*minor_status*/,
             const gss_buffer_t /*interprocess_token*/,
             gss_ctx_id_t * /*context_handle*/
            );
 
-OM_uint32 gss_create_empty_oid_set (
+OM_uint32 GSSAPI_LIB_FUNCTION gss_create_empty_oid_set (
             OM_uint32 * /*minor_status*/,
             gss_OID_set * /*oid_set*/
            );
 
-OM_uint32 gss_add_oid_set_member (
+OM_uint32 GSSAPI_LIB_FUNCTION gss_add_oid_set_member (
             OM_uint32 * /*minor_status*/,
             const gss_OID /*member_oid*/,
             gss_OID_set * /*oid_set*/
            );
 
-OM_uint32 gss_test_oid_set_member (
+OM_uint32 GSSAPI_LIB_FUNCTION gss_test_oid_set_member (
             OM_uint32 * /*minor_status*/,
             const gss_OID /*member*/,
             const gss_OID_set /*set*/,
             int * /*present*/
            );
 
-OM_uint32 gss_inquire_names_for_mech (
+OM_uint32 GSSAPI_LIB_FUNCTION gss_inquire_names_for_mech (
             OM_uint32 * /*minor_status*/,
             const gss_OID /*mechanism*/,
             gss_OID_set * /*name_types*/
            );
 
-OM_uint32 gss_inquire_mechs_for_name (
+OM_uint32 GSSAPI_LIB_FUNCTION gss_inquire_mechs_for_name (
             OM_uint32 * /*minor_status*/,
             const gss_name_t /*input_name*/,
             gss_OID_set * /*mech_types*/
            );
 
-OM_uint32 gss_canonicalize_name (
+OM_uint32 GSSAPI_LIB_FUNCTION gss_canonicalize_name (
             OM_uint32 * /*minor_status*/,
             const gss_name_t /*input_name*/,
             const gss_OID /*mech_type*/,
             gss_name_t * /*output_name*/
            );
 
-OM_uint32 gss_duplicate_name (
+OM_uint32 GSSAPI_LIB_FUNCTION gss_duplicate_name (
             OM_uint32 * /*minor_status*/,
             const gss_name_t /*src_name*/,
             gss_name_t * /*dest_name*/
            );
 
-OM_uint32 gss_duplicate_oid (
+OM_uint32 GSSAPI_LIB_FUNCTION gss_duplicate_oid (
            OM_uint32 * /* minor_status */,
            gss_OID /* src_oid */,
            gss_OID * /* dest_oid */
            );
-OM_uint32
+
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_release_oid
        (OM_uint32 * /*minor_status*/,
         gss_OID * /* oid */
        );
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_oid_to_str(
            OM_uint32 * /*minor_status*/,
            gss_OID /* oid */,
            gss_buffer_t /* str */
            );
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_inquire_sec_context_by_oid(
            OM_uint32 * minor_status,
             const gss_ctx_id_t context_handle,
@@ -677,38 +688,38 @@ gss_inquire_sec_context_by_oid(
             gss_buffer_set_t *data_set
            );
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_set_sec_context_option (OM_uint32 *minor_status,
                            gss_ctx_id_t *context_handle,
                            const gss_OID desired_object,
                            const gss_buffer_t value);
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_set_cred_option (OM_uint32 *minor_status,
                     gss_cred_id_t *cred_handle,
                     const gss_OID object,
                     const gss_buffer_t value);
 
-int
+int GSSAPI_LIB_FUNCTION
 gss_oid_equal(const gss_OID a, const gss_OID b);
 
-OM_uint32 
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_create_empty_buffer_set
           (OM_uint32 * minor_status,
            gss_buffer_set_t *buffer_set);
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_add_buffer_set_member
           (OM_uint32 * minor_status,
            const gss_buffer_t member_buffer,
            gss_buffer_set_t *buffer_set);
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_release_buffer_set
           (OM_uint32 * minor_status,
            gss_buffer_set_t *buffer_set);
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_inquire_cred_by_oid(OM_uint32 *minor_status,
                        const gss_cred_id_t cred_handle,
                        const gss_OID desired_object,
@@ -721,7 +732,7 @@ gss_inquire_cred_by_oid(OM_uint32 *minor_status,
 #define GSS_C_PRF_KEY_FULL 0
 #define GSS_C_PRF_KEY_PARTIAL 1
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_pseudo_random
        (OM_uint32 *minor_status,
         gss_ctx_id_t context,
@@ -742,7 +753,7 @@ gss_pseudo_random
  * obsolete versions of these routines and their current forms.
  */
 
-OM_uint32 gss_sign
+OM_uint32 GSSAPI_LIB_FUNCTION gss_sign
            (OM_uint32 * /*minor_status*/,
             gss_ctx_id_t /*context_handle*/,
             int /*qop_req*/,
@@ -750,7 +761,7 @@ OM_uint32 gss_sign
             gss_buffer_t /*message_token*/
            );
 
-OM_uint32 gss_verify
+OM_uint32 GSSAPI_LIB_FUNCTION gss_verify
            (OM_uint32 * /*minor_status*/,
             gss_ctx_id_t /*context_handle*/,
             gss_buffer_t /*message_buffer*/,
@@ -758,7 +769,7 @@ OM_uint32 gss_verify
             int * /*qop_state*/
            );
 
-OM_uint32 gss_seal
+OM_uint32 GSSAPI_LIB_FUNCTION gss_seal
            (OM_uint32 * /*minor_status*/,
             gss_ctx_id_t /*context_handle*/,
             int /*conf_req_flag*/,
@@ -768,7 +779,7 @@ OM_uint32 gss_seal
             gss_buffer_t /*output_message_buffer*/
            );
 
-OM_uint32 gss_unseal
+OM_uint32 GSSAPI_LIB_FUNCTION gss_unseal
            (OM_uint32 * /*minor_status*/,
             gss_ctx_id_t /*context_handle*/,
             gss_buffer_t /*input_message_buffer*/,
@@ -781,18 +792,18 @@ OM_uint32 gss_unseal
  *
  */
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_inquire_sec_context_by_oid (OM_uint32 *minor_status,
                                const gss_ctx_id_t context_handle,
                                const gss_OID desired_object,
                                gss_buffer_set_t *data_set);
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_encapsulate_token(gss_buffer_t /* input_token */,
                      gss_OID /* oid */,
                      gss_buffer_t /* output_token */);
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_decapsulate_token(gss_buffer_t /* input_token */,
                      gss_OID /* oid */,
                      gss_buffer_t /* output_token */);
index 2223f4f22f778f916d6e36fb3c4ee4b761785c68..55f78866588c8c86be32929b9eee55de36a94801 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE. 
  */
 
-/* $Id: gssapi_krb5.h 22655 2008-02-26 12:40:35Z lha $ */
+/* $Id: gssapi_krb5.h 23420 2008-07-26 18:37:48Z lha $ */
 
 #ifndef GSSAPI_KRB5_H_
 #define GSSAPI_KRB5_H_
@@ -46,12 +46,12 @@ extern "C" {
  * This is for kerberos5 names.
  */
 
-extern gss_OID GSS_KRB5_NT_PRINCIPAL_NAME;
-extern gss_OID GSS_KRB5_NT_USER_NAME;
-extern gss_OID GSS_KRB5_NT_MACHINE_UID_NAME;
-extern gss_OID GSS_KRB5_NT_STRING_UID_NAME;
+extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_NT_PRINCIPAL_NAME;
+extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_NT_USER_NAME;
+extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_NT_MACHINE_UID_NAME;
+extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_NT_STRING_UID_NAME;
 
-extern gss_OID GSS_KRB5_MECHANISM;
+extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_MECHANISM;
 
 /* for compatibility with MIT api */
 
@@ -59,28 +59,30 @@ extern gss_OID GSS_KRB5_MECHANISM;
 #define gss_krb5_nt_general_name GSS_KRB5_NT_PRINCIPAL_NAME
 
 /* Extensions set contexts options */
-extern gss_OID GSS_KRB5_COPY_CCACHE_X;
-extern gss_OID GSS_KRB5_COMPAT_DES3_MIC_X;
-extern gss_OID GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_X;
-extern gss_OID GSS_KRB5_SET_DNS_CANONICALIZE_X;
-extern gss_OID GSS_KRB5_SEND_TO_KDC_X;
-extern gss_OID GSS_KRB5_SET_DEFAULT_REALM_X;
-extern gss_OID GSS_KRB5_CCACHE_NAME_X;
+extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_COPY_CCACHE_X;
+extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_COMPAT_DES3_MIC_X;
+extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_X;
+extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_SET_DNS_CANONICALIZE_X;
+extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_SEND_TO_KDC_X;
+extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_SET_DEFAULT_REALM_X;
+extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_CCACHE_NAME_X;
+extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_SET_TIME_OFFSET_X;
+extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_GET_TIME_OFFSET_X;
 /* Extensions inquire context */
-extern gss_OID GSS_KRB5_GET_TKT_FLAGS_X;
-extern gss_OID GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_X;
-extern gss_OID GSS_C_PEER_HAS_UPDATED_SPNEGO;
-extern gss_OID GSS_KRB5_EXPORT_LUCID_CONTEXT_X;
-extern gss_OID GSS_KRB5_EXPORT_LUCID_CONTEXT_V1_X;
-extern gss_OID GSS_KRB5_GET_SUBKEY_X;
-extern gss_OID GSS_KRB5_GET_INITIATOR_SUBKEY_X;
-extern gss_OID GSS_KRB5_GET_ACCEPTOR_SUBKEY_X;
-extern gss_OID GSS_KRB5_GET_AUTHTIME_X;
-extern gss_OID GSS_KRB5_GET_SERVICE_KEYBLOCK_X;
+extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_GET_TKT_FLAGS_X;
+extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_X;
+extern GSSAPI_LIB_VARIABLE gss_OID GSS_C_PEER_HAS_UPDATED_SPNEGO;
+extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_EXPORT_LUCID_CONTEXT_X;
+extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_EXPORT_LUCID_CONTEXT_V1_X;
+extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_GET_SUBKEY_X;
+extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_GET_INITIATOR_SUBKEY_X;
+extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_GET_ACCEPTOR_SUBKEY_X;
+extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_GET_AUTHTIME_X;
+extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_GET_SERVICE_KEYBLOCK_X;
 /* Extensions creds */
-extern gss_OID GSS_KRB5_IMPORT_CRED_X;
-extern gss_OID GSS_KRB5_SET_ALLOWABLE_ENCTYPES_X;
-extern gss_OID GSS_KRB5_CRED_NO_CI_FLAGS_X;
+extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_IMPORT_CRED_X;
+extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_SET_ALLOWABLE_ENCTYPES_X;
+extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_CRED_NO_CI_FLAGS_X;
 
 /*
  * kerberos mechanism specific functions
@@ -90,39 +92,42 @@ struct krb5_keytab_data;
 struct krb5_ccache_data;
 struct Principal;
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_krb5_ccache_name(OM_uint32 * /*minor_status*/, 
                     const char * /*name */,
                     const char ** /*out_name */);
 
-OM_uint32 gsskrb5_register_acceptor_identity
+OM_uint32 GSSAPI_LIB_FUNCTION gsskrb5_register_acceptor_identity
         (const char */*identity*/);
 
-OM_uint32 gss_krb5_copy_ccache
+OM_uint32 GSSAPI_LIB_FUNCTION krb5_gss_register_acceptor_identity
+       (const char */*identity*/);
+
+OM_uint32 GSSAPI_LIB_FUNCTION gss_krb5_copy_ccache
        (OM_uint32 */*minor*/,
         gss_cred_id_t /*cred*/,
         struct krb5_ccache_data */*out*/);
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_krb5_import_cred(OM_uint32 */*minor*/,
                     struct krb5_ccache_data * /*in*/,
                     struct Principal * /*keytab_principal*/,
                     struct krb5_keytab_data * /*keytab*/,
                     gss_cred_id_t */*out*/);
 
-OM_uint32 gss_krb5_get_tkt_flags
+OM_uint32 GSSAPI_LIB_FUNCTION gss_krb5_get_tkt_flags
        (OM_uint32 */*minor*/,
         gss_ctx_id_t /*context_handle*/,
         OM_uint32 */*tkt_flags*/);
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gsskrb5_extract_authz_data_from_sec_context
        (OM_uint32 * /*minor_status*/,
         gss_ctx_id_t /*context_handle*/,
         int /*ad_type*/,
         gss_buffer_t /*ad_data*/);
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gsskrb5_set_dns_canonicalize(int);
 
 struct gsskrb5_send_to_kdc {
@@ -130,30 +135,36 @@ struct gsskrb5_send_to_kdc {
     void *ptr;
 };
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gsskrb5_set_send_to_kdc(struct gsskrb5_send_to_kdc *);
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gsskrb5_set_default_realm(const char *);
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gsskrb5_extract_authtime_from_sec_context(OM_uint32 *, gss_ctx_id_t, time_t *);
 
 struct EncryptionKey;
 
-OM_uint32 
+OM_uint32 GSSAPI_LIB_FUNCTION
 gsskrb5_extract_service_keyblock(OM_uint32 *minor_status,
                                 gss_ctx_id_t context_handle,
                                 struct EncryptionKey **out);
-OM_uint32 
+OM_uint32 GSSAPI_LIB_FUNCTION
 gsskrb5_get_initiator_subkey(OM_uint32 *minor_status,
                                 gss_ctx_id_t context_handle,
                                 struct EncryptionKey **out);
-OM_uint32 
+OM_uint32 GSSAPI_LIB_FUNCTION
 gsskrb5_get_subkey(OM_uint32 *minor_status,
                   gss_ctx_id_t context_handle,
                   struct EncryptionKey **out);
 
+OM_uint32 GSSAPI_LIB_FUNCTION
+gsskrb5_set_time_offset(int);
+
+OM_uint32 GSSAPI_LIB_FUNCTION
+gsskrb5_get_time_offset(int *);
+
 /*
  * Lucid - NFSv4 interface to GSS-API KRB5 to expose key material to
  * do GSS content token handling in-kernel.
@@ -196,19 +207,19 @@ typedef struct gss_krb5_lucid_context_version {
  * Function declarations
  */
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_krb5_export_lucid_sec_context(OM_uint32 *minor_status,
                                  gss_ctx_id_t *context_handle,
                                  OM_uint32 version,
                                  void **kctx);
 
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_krb5_free_lucid_sec_context(OM_uint32 *minor_status,
                                void *kctx);
 
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_krb5_set_allowable_enctypes(OM_uint32 *minor_status, 
                                gss_cred_id_t cred,
                                OM_uint32 num_enctypes,
index fbb7906369be50221110eae6588a5d3cfac23f14..3358863a801613af9617b09b4e8fee509ae61cbc 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE. 
  */
 
-/* $Id: gssapi_spnego.h 18335 2006-10-07 22:26:21Z lha $ */
+/* $Id: gssapi_spnego.h 23025 2008-04-17 10:01:57Z lha $ */
 
 #ifndef GSSAPI_SPNEGO_H_
 #define GSSAPI_SPNEGO_H_
@@ -48,7 +48,7 @@ extern "C" {
  *  negotiation token is identified by the Object Identifier
  *  iso.org.dod.internet.security.mechanism.snego (1.3.6.1.5.5.2).
  */
-extern gss_OID GSS_SPNEGO_MECHANISM;
+extern GSSAPI_LIB_VARIABLE gss_OID GSS_SPNEGO_MECHANISM;
 #define gss_mech_spnego GSS_SPNEGO_MECHANISM
 
 #ifdef __cplusplus
index 73b93ceba4c6bb472c546afd52981bcf13051173..8dbd087da62669129a0c6896630c27544c78ffac 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5/gsskrb5_locl.h"
 
-RCSID("$Id: accept_sec_context.c 20199 2007-02-07 22:36:39Z lha $");
+RCSID("$Id: accept_sec_context.c 23433 2008-07-26 18:44:26Z lha $");
 
 HEIMDAL_MUTEX gssapi_keytab_mutex = HEIMDAL_MUTEX_INITIALIZER;
 krb5_keytab _gsskrb5_keytab;
@@ -250,6 +250,62 @@ gsskrb5_acceptor_ready(OM_uint32 * minor_status,
     return GSS_S_COMPLETE;
 }
 
+static OM_uint32
+send_error_token(OM_uint32 *minor_status,
+                krb5_context context,
+                krb5_error_code kret,
+                krb5_principal server,
+                krb5_data *indata,
+                gss_buffer_t output_token)
+{
+    krb5_principal ap_req_server = NULL;
+    krb5_error_code ret;
+    krb5_data outbuf;
+
+    /* build server from request if the acceptor had not selected one */
+    if (server == NULL) {
+       AP_REQ ap_req;
+
+       ret = krb5_decode_ap_req(context, indata, &ap_req);
+       if (ret) {
+           *minor_status = ret;
+           return GSS_S_FAILURE;
+       }
+       ret = _krb5_principalname2krb5_principal(context,
+                                                 &ap_req_server,
+                                                 ap_req.ticket.sname,
+                                                 ap_req.ticket.realm);
+       free_AP_REQ(&ap_req);
+       if (ret) {
+           *minor_status = ret;
+           return GSS_S_FAILURE;
+       }
+       server = ap_req_server;
+    }
+    
+    ret = krb5_mk_error(context, kret, NULL, NULL, NULL,
+                       server, NULL, NULL, &outbuf);
+    if (ap_req_server)
+       krb5_free_principal(context, ap_req_server);
+    if (ret) {
+       *minor_status = ret;
+       return GSS_S_FAILURE;
+    }
+    
+    ret = _gsskrb5_encapsulate(minor_status,
+                              &outbuf,
+                              output_token,
+                              "\x03\x00",
+                              GSS_KRB5_MECHANISM);
+    krb5_data_free (&outbuf);
+    if (ret)
+       return ret;
+
+    *minor_status = 0;
+    return GSS_S_CONTINUE_NEEDED;
+}
+
+
 static OM_uint32
 gsskrb5_acceptor_start(OM_uint32 * minor_status,
                       gsskrb5_ctx ctx,
@@ -304,6 +360,10 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status,
     {
        krb5_rd_req_in_ctx in = NULL;
        krb5_rd_req_out_ctx out = NULL;
+       krb5_principal server = NULL;
+
+       if (acceptor_cred)
+           server = acceptor_cred->principal;
 
        kret = krb5_rd_req_in_ctx_alloc(context, &in);
        if (kret == 0)
@@ -319,17 +379,20 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status,
        kret = krb5_rd_req_ctx(context,
                               &ctx->auth_context,
                               &indata,
-                              (acceptor_cred_handle == GSS_C_NO_CREDENTIAL) ? NULL : acceptor_cred->principal,
+                              server,
                               in, &out);
        krb5_rd_req_in_ctx_free(context, in);
        if (kret) {
-           ret = GSS_S_FAILURE;
-           *minor_status = kret;
-           return ret;
+           /* 
+            * No reply in non-MUTUAL mode, but we don't know that its
+            * non-MUTUAL mode yet, thats inside the 8003 checksum.
+            */
+           return send_error_token(minor_status, context, kret,
+                                   server, &indata, output_token);
        }
 
        /*
-        * We need to remember some data on the context_handle.
+        * we need to remember some data on the context_handle.
         */
        kret = krb5_rd_req_out_get_ap_req_options(context, out,
                                                  &ap_options);
index abad98655026a2199ce208ca286868d1009608d7..9c618ac6a621b6a1b54aea21279354b505e8f3f4 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5/gsskrb5_locl.h"
 
-RCSID("$Id: delete_sec_context.c 19031 2006-11-13 18:02:57Z lha $");
+RCSID("$Id: delete_sec_context.c 23420 2008-07-26 18:37:48Z lha $");
 
 OM_uint32
 _gsskrb5_delete_sec_context(OM_uint32 * minor_status,
@@ -61,6 +61,8 @@ _gsskrb5_delete_sec_context(OM_uint32 * minor_status,
     HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
 
     krb5_auth_con_free (context, ctx->auth_context);
+    if (ctx->kcred)
+       krb5_free_creds(context, ctx->kcred);
     if(ctx->source)
        krb5_free_principal (context, ctx->source);
     if(ctx->target)
index c0192522a72a42e3ae75ae0d104beec2db6b68dc..f932261ffa098b30b9c0088172993d6ce5b3d3a5 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5/gsskrb5_locl.h"
 
-RCSID("$Id: display_status.c 19031 2006-11-13 18:02:57Z lha $");
+RCSID("$Id: display_status.c 23316 2008-06-23 04:32:32Z lha $");
 
 static const char *
 calling_error(OM_uint32 v)
@@ -135,7 +135,7 @@ _gsskrb5_set_status (const char *fmt, ...)
     vasprintf(&str, fmt, args);
     va_end(args);
     if (str) {
-       krb5_set_error_string(context, str);
+       krb5_set_error_message(context, 0, str);
        free(str);
     }
 }
index 03fe61dc5744f772dfd98934d08d16b97aa92fa2..2ee018708a536f583b9f66167d6ab9f78f2ca192 100644 (file)
@@ -34,7 +34,7 @@
 #include "krb5/gsskrb5_locl.h"
 #include <gssapi_mech.h>
 
-RCSID("$Id: external.c 22128 2007-12-04 00:56:55Z lha $");
+RCSID("$Id: external.c 23420 2008-07-26 18:37:48Z lha $");
 
 /*
  * The implementation must reserve static storage for a
@@ -49,9 +49,10 @@ RCSID("$Id: external.c 22128 2007-12-04 00:56:55Z lha $");
  */
 
 static gss_OID_desc gss_c_nt_user_name_oid_desc =
-{10, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12" "\x01\x02\x01\x01")};
+    {10, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12" "\x01\x02\x01\x01")};
 
-gss_OID GSS_C_NT_USER_NAME = &gss_c_nt_user_name_oid_desc;
+gss_OID GSSAPI_LIB_VARIABLE GSS_C_NT_USER_NAME =
+    &gss_c_nt_user_name_oid_desc;
 
 /*
  * The implementation must reserve static storage for a
@@ -66,9 +67,10 @@ gss_OID GSS_C_NT_USER_NAME = &gss_c_nt_user_name_oid_desc;
  */
 
 static gss_OID_desc gss_c_nt_machine_uid_name_oid_desc =
-{10, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12" "\x01\x02\x01\x02")};
+    {10, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12" "\x01\x02\x01\x02")};
 
-gss_OID GSS_C_NT_MACHINE_UID_NAME = &gss_c_nt_machine_uid_name_oid_desc;
+gss_OID GSSAPI_LIB_VARIABLE GSS_C_NT_MACHINE_UID_NAME =
+    &gss_c_nt_machine_uid_name_oid_desc;
 
 /*
  * The implementation must reserve static storage for a
@@ -83,9 +85,10 @@ gss_OID GSS_C_NT_MACHINE_UID_NAME = &gss_c_nt_machine_uid_name_oid_desc;
  */
 
 static gss_OID_desc gss_c_nt_string_uid_name_oid_desc =
-{10, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12" "\x01\x02\x01\x03")};
+    {10, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12" "\x01\x02\x01\x03")};
 
-gss_OID GSS_C_NT_STRING_UID_NAME = &gss_c_nt_string_uid_name_oid_desc;
+gss_OID GSSAPI_LIB_VARIABLE GSS_C_NT_STRING_UID_NAME =
+    &gss_c_nt_string_uid_name_oid_desc;
 
 /*
  * The implementation must reserve static storage for a
@@ -106,9 +109,10 @@ gss_OID GSS_C_NT_STRING_UID_NAME = &gss_c_nt_string_uid_name_oid_desc;
  */
 
 static gss_OID_desc gss_c_nt_hostbased_service_x_oid_desc =
-{6, rk_UNCONST("\x2b\x06\x01\x05\x06\x02")};
+    {6, rk_UNCONST("\x2b\x06\x01\x05\x06\x02")};
 
-gss_OID GSS_C_NT_HOSTBASED_SERVICE_X = &gss_c_nt_hostbased_service_x_oid_desc;
+gss_OID GSSAPI_LIB_VARIABLE GSS_C_NT_HOSTBASED_SERVICE_X =
+    &gss_c_nt_hostbased_service_x_oid_desc;
 
 /*
  * The implementation must reserve static storage for a
@@ -122,9 +126,10 @@ gss_OID GSS_C_NT_HOSTBASED_SERVICE_X = &gss_c_nt_hostbased_service_x_oid_desc;
  * to point to that gss_OID_desc.
  */
 static gss_OID_desc gss_c_nt_hostbased_service_oid_desc =
-{10, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12" "\x01\x02\x01\x04")};
+    {10, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12" "\x01\x02\x01\x04")};
 
-gss_OID GSS_C_NT_HOSTBASED_SERVICE = &gss_c_nt_hostbased_service_oid_desc;
+gss_OID GSSAPI_LIB_VARIABLE GSS_C_NT_HOSTBASED_SERVICE =
+    &gss_c_nt_hostbased_service_oid_desc;
 
 /*
  * The implementation must reserve static storage for a
@@ -138,9 +143,10 @@ gss_OID GSS_C_NT_HOSTBASED_SERVICE = &gss_c_nt_hostbased_service_oid_desc;
  */
 
 static gss_OID_desc gss_c_nt_anonymous_oid_desc =
-{6, rk_UNCONST("\x2b\x06\01\x05\x06\x03")};
+    {6, rk_UNCONST("\x2b\x06\01\x05\x06\x03")};
 
-gss_OID GSS_C_NT_ANONYMOUS = &gss_c_nt_anonymous_oid_desc;
+gss_OID GSSAPI_LIB_VARIABLE GSS_C_NT_ANONYMOUS =
+    &gss_c_nt_anonymous_oid_desc;
 
 /*
  * The implementation must reserve static storage for a
@@ -154,9 +160,10 @@ gss_OID GSS_C_NT_ANONYMOUS = &gss_c_nt_anonymous_oid_desc;
  */
 
 static gss_OID_desc gss_c_nt_export_name_oid_desc =
-{6, rk_UNCONST("\x2b\x06\x01\x05\x06\x04") };
+    {6, rk_UNCONST("\x2b\x06\x01\x05\x06\x04") };
 
-gss_OID GSS_C_NT_EXPORT_NAME = &gss_c_nt_export_name_oid_desc;
+gss_OID GSSAPI_LIB_VARIABLE GSS_C_NT_EXPORT_NAME =
+    &gss_c_nt_export_name_oid_desc;
 
 /*
  *   This name form shall be represented by the Object Identifier {iso(1)
@@ -166,9 +173,10 @@ gss_OID GSS_C_NT_EXPORT_NAME = &gss_c_nt_export_name_oid_desc;
  */
 
 static gss_OID_desc gss_krb5_nt_principal_name_oid_desc =
-{10, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x01") };
+    {10, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x01") };
 
-gss_OID GSS_KRB5_NT_PRINCIPAL_NAME = &gss_krb5_nt_principal_name_oid_desc;
+gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_NT_PRINCIPAL_NAME =
+    &gss_krb5_nt_principal_name_oid_desc;
 
 /*
  *   This name form shall be represented by the Object Identifier {iso(1)
@@ -177,7 +185,8 @@ gss_OID GSS_KRB5_NT_PRINCIPAL_NAME = &gss_krb5_nt_principal_name_oid_desc;
  *   type is "GSS_KRB5_NT_USER_NAME".
  */
 
-gss_OID GSS_KRB5_NT_USER_NAME = &gss_c_nt_user_name_oid_desc;
+gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_NT_USER_NAME =
+    &gss_c_nt_user_name_oid_desc;
 
 /*
  *   This name form shall be represented by the Object Identifier {iso(1)
@@ -186,7 +195,8 @@ gss_OID GSS_KRB5_NT_USER_NAME = &gss_c_nt_user_name_oid_desc;
  *   this type is "GSS_KRB5_NT_MACHINE_UID_NAME".
  */
 
-gss_OID GSS_KRB5_NT_MACHINE_UID_NAME = &gss_c_nt_machine_uid_name_oid_desc;
+gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_NT_MACHINE_UID_NAME =
+    &gss_c_nt_machine_uid_name_oid_desc;
 
 /*
  *   This name form shall be represented by the Object Identifier {iso(1)
@@ -195,7 +205,8 @@ gss_OID GSS_KRB5_NT_MACHINE_UID_NAME = &gss_c_nt_machine_uid_name_oid_desc;
  *   this type is "GSS_KRB5_NT_STRING_UID_NAME".
  */
 
-gss_OID GSS_KRB5_NT_STRING_UID_NAME = &gss_c_nt_string_uid_name_oid_desc;
+gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_NT_STRING_UID_NAME =
+    &gss_c_nt_string_uid_name_oid_desc;
 
 /*
  *   To support ongoing experimentation, testing, and evolution of the
@@ -217,14 +228,15 @@ gss_OID GSS_KRB5_NT_STRING_UID_NAME = &gss_c_nt_string_uid_name_oid_desc;
 #if 0 /* This is the old OID */
 
 static gss_OID_desc gss_krb5_mechanism_oid_desc =
-{5, rk_UNCONST("\x2b\x05\x01\x05\x02")};
+    {5, rk_UNCONST("\x2b\x05\x01\x05\x02")};
 
 #endif
 
 static gss_OID_desc gss_krb5_mechanism_oid_desc =
-{9, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12\x01\x02\x02") };
+    {9, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12\x01\x02\x02") };
 
-gss_OID GSS_KRB5_MECHANISM = &gss_krb5_mechanism_oid_desc;
+gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_MECHANISM =
+    &gss_krb5_mechanism_oid_desc;
 
 /*
  * draft-ietf-cat-iakerb-09, IAKERB:
@@ -240,23 +252,26 @@ gss_OID GSS_KRB5_MECHANISM = &gss_krb5_mechanism_oid_desc;
  */
 
 static gss_OID_desc gss_iakerb_proxy_mechanism_oid_desc =
-{7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0a\x01")};
+    {7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0a\x01")};
 
-gss_OID GSS_IAKERB_PROXY_MECHANISM = &gss_iakerb_proxy_mechanism_oid_desc;
+gss_OID GSSAPI_LIB_VARIABLE GSS_IAKERB_PROXY_MECHANISM =
+    &gss_iakerb_proxy_mechanism_oid_desc;
 
 static gss_OID_desc gss_iakerb_min_msg_mechanism_oid_desc =
-{7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0a\x02") };
+    {7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0a\x02") };
 
-gss_OID GSS_IAKERB_MIN_MSG_MECHANISM = &gss_iakerb_min_msg_mechanism_oid_desc;
+gss_OID GSSAPI_LIB_VARIABLE GSS_IAKERB_MIN_MSG_MECHANISM =
+    &gss_iakerb_min_msg_mechanism_oid_desc;
 
 /*
  *
  */
 
 static gss_OID_desc gss_c_peer_has_updated_spnego_oid_desc =
-{9, (void *)"\x2b\x06\x01\x04\x01\xa9\x4a\x13\x05"};
+    {9, (void *)"\x2b\x06\x01\x04\x01\xa9\x4a\x13\x05"};
 
-gss_OID GSS_C_PEER_HAS_UPDATED_SPNEGO = &gss_c_peer_has_updated_spnego_oid_desc;
+gss_OID GSSAPI_LIB_VARIABLE GSS_C_PEER_HAS_UPDATED_SPNEGO =
+    &gss_c_peer_has_updated_spnego_oid_desc;
 
 /*
  * 1.2.752.43.13 Heimdal GSS-API Extentions
@@ -264,111 +279,143 @@ gss_OID GSS_C_PEER_HAS_UPDATED_SPNEGO = &gss_c_peer_has_updated_spnego_oid_desc;
 
 /* 1.2.752.43.13.1 */
 static gss_OID_desc gss_krb5_copy_ccache_x_oid_desc =
-{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x01")};
+    {6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x01")};
 
-gss_OID GSS_KRB5_COPY_CCACHE_X = &gss_krb5_copy_ccache_x_oid_desc;
+gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_COPY_CCACHE_X =
+    &gss_krb5_copy_ccache_x_oid_desc;
 
 /* 1.2.752.43.13.2 */
 static gss_OID_desc gss_krb5_get_tkt_flags_x_oid_desc =
-{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x02")};
+    {6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x02")};
 
-gss_OID GSS_KRB5_GET_TKT_FLAGS_X = &gss_krb5_get_tkt_flags_x_oid_desc;
+gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_GET_TKT_FLAGS_X =
+    &gss_krb5_get_tkt_flags_x_oid_desc;
 
 /* 1.2.752.43.13.3 */
 static gss_OID_desc gss_krb5_extract_authz_data_from_sec_context_x_oid_desc =
-{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x03")};
+    {6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x03")};
 
-gss_OID GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_X = &gss_krb5_extract_authz_data_from_sec_context_x_oid_desc;
+gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_X =
+    &gss_krb5_extract_authz_data_from_sec_context_x_oid_desc;
 
 /* 1.2.752.43.13.4 */
 static gss_OID_desc gss_krb5_compat_des3_mic_x_oid_desc =
-{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x04")};
+    {6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x04")};
 
-gss_OID GSS_KRB5_COMPAT_DES3_MIC_X = &gss_krb5_compat_des3_mic_x_oid_desc;
+gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_COMPAT_DES3_MIC_X =
+    &gss_krb5_compat_des3_mic_x_oid_desc;
 
 /* 1.2.752.43.13.5 */
 static gss_OID_desc gss_krb5_register_acceptor_identity_x_desc =
-{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x05")};
+    {6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x05")};
 
-gss_OID GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_X = &gss_krb5_register_acceptor_identity_x_desc;
+gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_X =
+    &gss_krb5_register_acceptor_identity_x_desc;
 
 /* 1.2.752.43.13.6 */
 static gss_OID_desc gss_krb5_export_lucid_context_x_desc =
-{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x06")};
+    {6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x06")};
 
-gss_OID GSS_KRB5_EXPORT_LUCID_CONTEXT_X = &gss_krb5_export_lucid_context_x_desc;
+gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_EXPORT_LUCID_CONTEXT_X =
+    &gss_krb5_export_lucid_context_x_desc;
 
 /* 1.2.752.43.13.6.1 */
 static gss_OID_desc gss_krb5_export_lucid_context_v1_x_desc =
-{7, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x06\x01")};
+    {7, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x06\x01")};
 
-gss_OID GSS_KRB5_EXPORT_LUCID_CONTEXT_V1_X = &gss_krb5_export_lucid_context_v1_x_desc;
+gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_EXPORT_LUCID_CONTEXT_V1_X =
+    &gss_krb5_export_lucid_context_v1_x_desc;
 
 /* 1.2.752.43.13.7 */
 static gss_OID_desc gss_krb5_set_dns_canonicalize_x_desc =
-{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x07")};
+    {6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x07")};
 
-gss_OID GSS_KRB5_SET_DNS_CANONICALIZE_X = &gss_krb5_set_dns_canonicalize_x_desc;
+gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_SET_DNS_CANONICALIZE_X =
+    &gss_krb5_set_dns_canonicalize_x_desc;
 
 /* 1.2.752.43.13.8 */
 static gss_OID_desc gss_krb5_get_subkey_x_desc =
-{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x08")};
+    {6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x08")};
 
-gss_OID GSS_KRB5_GET_SUBKEY_X = &gss_krb5_get_subkey_x_desc;
+gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_GET_SUBKEY_X =
+    &gss_krb5_get_subkey_x_desc;
 
 /* 1.2.752.43.13.9 */
 static gss_OID_desc gss_krb5_get_initiator_subkey_x_desc =
-{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x09")};
+    {6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x09")};
 
-gss_OID GSS_KRB5_GET_INITIATOR_SUBKEY_X = &gss_krb5_get_initiator_subkey_x_desc;
+gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_GET_INITIATOR_SUBKEY_X =
+    &gss_krb5_get_initiator_subkey_x_desc;
 
 /* 1.2.752.43.13.10 */
 static gss_OID_desc gss_krb5_get_acceptor_subkey_x_desc =
-{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0a")};
+    {6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0a")};
 
-gss_OID GSS_KRB5_GET_ACCEPTOR_SUBKEY_X = &gss_krb5_get_acceptor_subkey_x_desc;
+gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_GET_ACCEPTOR_SUBKEY_X =
+    &gss_krb5_get_acceptor_subkey_x_desc;
 
 /* 1.2.752.43.13.11 */
 static gss_OID_desc gss_krb5_send_to_kdc_x_desc =
-{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0b")};
+    {6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0b")};
 
-gss_OID GSS_KRB5_SEND_TO_KDC_X = &gss_krb5_send_to_kdc_x_desc;
+gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_SEND_TO_KDC_X =
+    &gss_krb5_send_to_kdc_x_desc;
 
 /* 1.2.752.43.13.12 */
 static gss_OID_desc gss_krb5_get_authtime_x_desc =
-{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0c")};
+    {6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0c")};
 
-gss_OID GSS_KRB5_GET_AUTHTIME_X = &gss_krb5_get_authtime_x_desc;
+gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_GET_AUTHTIME_X =
+    &gss_krb5_get_authtime_x_desc;
 
 /* 1.2.752.43.13.13 */
 static gss_OID_desc gss_krb5_get_service_keyblock_x_desc =
-{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0d")};
+    {6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0d")};
 
-gss_OID GSS_KRB5_GET_SERVICE_KEYBLOCK_X = &gss_krb5_get_service_keyblock_x_desc;
+gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_GET_SERVICE_KEYBLOCK_X =
+    &gss_krb5_get_service_keyblock_x_desc;
 
 /* 1.2.752.43.13.14 */
 static gss_OID_desc gss_krb5_set_allowable_enctypes_x_desc =
-{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0e")};
+    {6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0e")};
 
-gss_OID GSS_KRB5_SET_ALLOWABLE_ENCTYPES_X = &gss_krb5_set_allowable_enctypes_x_desc;
+gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_SET_ALLOWABLE_ENCTYPES_X =
+    &gss_krb5_set_allowable_enctypes_x_desc;
 
 /* 1.2.752.43.13.15 */
 static gss_OID_desc gss_krb5_set_default_realm_x_desc =
-{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0f")};
+    {6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0f")};
 
-gss_OID GSS_KRB5_SET_DEFAULT_REALM_X = &gss_krb5_set_default_realm_x_desc;
+gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_SET_DEFAULT_REALM_X =
+    &gss_krb5_set_default_realm_x_desc;
 
 /* 1.2.752.43.13.16 */
 static gss_OID_desc gss_krb5_ccache_name_x_desc =
-{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x10")};
+    {6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x10")};
 
-gss_OID GSS_KRB5_CCACHE_NAME_X = &gss_krb5_ccache_name_x_desc;
+gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_CCACHE_NAME_X =
+    &gss_krb5_ccache_name_x_desc;
+
+/* 1.2.752.43.13.17 */
+static gss_OID_desc gss_krb5_set_time_offset_x_desc =
+    {6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x11")};
+
+gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_SET_TIME_OFFSET_X =
+    &gss_krb5_set_time_offset_x_desc;
+
+/* 1.2.752.43.13.18 */
+static gss_OID_desc gss_krb5_get_time_offset_x_desc =
+    {6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x12")};
+
+gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_GET_TIME_OFFSET_X =
+    &gss_krb5_get_time_offset_x_desc;
 
 /* 1.2.752.43.14.1 */
 static gss_OID_desc gss_sasl_digest_md5_mechanism_desc =
-{6, rk_UNCONST("\x2a\x85\x70\x2b\x0e\x01") };
+    {6, rk_UNCONST("\x2a\x85\x70\x2b\x0e\x01") };
 
-gss_OID GSS_SASL_DIGEST_MD5_MECHANISM = &gss_sasl_digest_md5_mechanism_desc;
+gss_OID GSSAPI_LIB_VARIABLE GSS_SASL_DIGEST_MD5_MECHANISM = 
+    &gss_sasl_digest_md5_mechanism_desc;
 
 /*
  * Context for krb5 calls.
index 133481ffe17369834488ac8e651f54ca1a619700..f689e624a89b23ed0db6a0561cd87b4d9fef65cd 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5/gsskrb5_locl.h"
 
-RCSID("$Id: get_mic.c 19031 2006-11-13 18:02:57Z lha $");
+RCSID("$Id: get_mic.c 23112 2008-04-27 18:51:26Z lha $");
 
 static OM_uint32
 mic_des
@@ -88,7 +88,7 @@ mic_des
 
   memset (&zero, 0, sizeof(zero));
   memcpy (&deskey, key->keyvalue.data, sizeof(deskey));
-  DES_set_key (&deskey, &schedule);
+  DES_set_key_unchecked (&deskey, &schedule);
   DES_cbc_cksum ((void *)hash, (void *)hash, sizeof(hash),
                 &schedule, &zero);
   memcpy (p - 8, hash, 8);     /* SGN_CKSUM */
@@ -108,7 +108,7 @@ mic_des
          (ctx->more_flags & LOCAL) ? 0 : 0xFF,
          4);
 
-  DES_set_key (&deskey, &schedule);
+  DES_set_key_unchecked (&deskey, &schedule);
   DES_cbc_encrypt ((void *)p, (void *)p, 8,
                   &schedule, (DES_cblock *)(p + 8), DES_ENCRYPT);
 
index 3e8c1b8fa65de5d7952a343478b037f24b183c32..d9af44f960cd1d09105a2a2da361b9bb453210c4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997 - 2006 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
  * All rights reserved. 
  *
@@ -31,7 +31,7 @@
  * SUCH DAMAGE. 
  */
 
-/* $Id: gsskrb5_locl.h 22655 2008-02-26 12:40:35Z lha $ */
+/* $Id: gsskrb5_locl.h 23435 2008-07-26 20:49:35Z lha $ */
 
 #ifndef GSSKRB5_LOCL_H
 #define GSSKRB5_LOCL_H
@@ -62,11 +62,14 @@ typedef struct {
   enum { LOCAL = 1, OPEN = 2, 
         COMPAT_OLD_DES3 = 4,
          COMPAT_OLD_DES3_SELECTED = 8,
-        ACCEPTOR_SUBKEY = 16
+        ACCEPTOR_SUBKEY = 16,
+        RETRIED = 32,
+        CLOSE_CCACHE = 64
   } more_flags;
   enum gss_ctx_id_t_state {
       /* initiator states */
       INITIATOR_START,
+      INITIATOR_RESTART,
       INITIATOR_WAIT_FOR_MUTAL,
       INITIATOR_READY,
       /* acceptor states */
@@ -74,6 +77,8 @@ typedef struct {
       ACCEPTOR_WAIT_FOR_DCESTYLE,
       ACCEPTOR_READY
   } state;
+  krb5_creds *kcred;
+  krb5_ccache ccache;
   struct krb5_ticket *ticket;
   OM_uint32 lifetime;
   HEIMDAL_MUTEX ctx_id_mutex;
index 3300036a81b32dcbce5cb8cfa2b0c249f5318f70..5fd8c941042020fef32a10a6fbbe49e18309f25c 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5/gsskrb5_locl.h"
 
-RCSID("$Id: import_sec_context.c 19031 2006-11-13 18:02:57Z lha $");
+RCSID("$Id: import_sec_context.c 22997 2008-04-15 19:36:25Z lha $");
 
 OM_uint32
 _gsskrb5_import_sec_context (
@@ -52,8 +52,7 @@ _gsskrb5_import_sec_context (
     krb5_data data;
     gss_buffer_desc buffer;
     krb5_keyblock keyblock;
-    int32_t tmp;
-    int32_t flags;
+    int32_t flags, tmp;
     gsskrb5_ctx ctx;
     gss_name_t name;
 
@@ -96,8 +95,9 @@ _gsskrb5_import_sec_context (
     /* retrieve the auth context */
 
     ac = ctx->auth_context;
-    if (krb5_ret_uint32 (sp, &ac->flags) != 0)
+    if (krb5_ret_int32 (sp, &tmp) != 0)
        goto failure;
+    ac->flags = tmp;
     if (flags & SC_LOCAL_ADDRESS) {
        if (krb5_ret_address (sp, localp = &local) != 0)
            goto failure;
index c455a5dc8b7246c0c8e795206be5b9c3db114cb8..c9b9e155888f54384a35f37d32dc028bb93c5086 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5/gsskrb5_locl.h"
 
-RCSID("$Id: init_sec_context.c 22671 2008-03-09 23:57:54Z lha $");
+RCSID("$Id: init_sec_context.c 23422 2008-07-26 18:38:29Z lha $");
 
 /*
  * copy the addresses from `input_chan_bindings' (if any) to
@@ -121,6 +121,8 @@ _gsskrb5_create_ctx(
     ctx->auth_context          = NULL;
     ctx->source                        = NULL;
     ctx->target                        = NULL;
+    ctx->kcred                 = NULL;
+    ctx->ccache                        = NULL;
     ctx->state                 = state;
     ctx->flags                 = 0;
     ctx->more_flags            = 0;
@@ -134,9 +136,7 @@ _gsskrb5_create_ctx(
     kret = krb5_auth_con_init (context, &ctx->auth_context);
     if (kret) {
        *minor_status = kret;
-
        HEIMDAL_MUTEX_destroy(&ctx->ctx_id_mutex);
-               
        return GSS_S_FAILURE;
     }
 
@@ -232,27 +232,32 @@ gsskrb5_initiator_ready(
        gsskrb5_ctx ctx,
        krb5_context context)
 {
-       OM_uint32 ret;
-       int32_t seq_number;
-       int is_cfx = 0;
-       OM_uint32 flags = ctx->flags;
-
-       krb5_auth_getremoteseqnumber (context,
-                                     ctx->auth_context,
-                                     &seq_number);
-
-       _gsskrb5i_is_cfx(ctx, &is_cfx);
-
-       ret = _gssapi_msg_order_create(minor_status,
-                                      &ctx->order,
-                                      _gssapi_msg_order_f(flags),
-                                      seq_number, 0, is_cfx);
-       if (ret) return ret;
+    OM_uint32 ret;
+    int32_t seq_number;
+    int is_cfx = 0;
+    OM_uint32 flags = ctx->flags;
+    
+    krb5_free_creds(context, ctx->kcred);
+    ctx->kcred = NULL;
 
-       ctx->state      = INITIATOR_READY;
-       ctx->more_flags |= OPEN;
+    if (ctx->more_flags & CLOSE_CCACHE)
+       krb5_cc_close(context, ctx->ccache);
+    ctx->ccache = NULL;
 
-       return GSS_S_COMPLETE;
+    krb5_auth_getremoteseqnumber (context, ctx->auth_context, &seq_number);
+    
+    _gsskrb5i_is_cfx(ctx, &is_cfx);
+    
+    ret = _gssapi_msg_order_create(minor_status,
+                                  &ctx->order,
+                                  _gssapi_msg_order_f(flags),
+                                  seq_number, 0, is_cfx);
+    if (ret) return ret;
+    
+    ctx->state = INITIATOR_READY;
+    ctx->more_flags    |= OPEN;
+    
+    return GSS_S_COMPLETE;
 }
 
 /*
@@ -333,7 +338,6 @@ init_auth
  const gss_OID mech_type,
  OM_uint32 req_flags,
  OM_uint32 time_req,
- const gss_channel_bindings_t input_chan_bindings,
  const gss_buffer_t input_token,
  gss_OID * actual_mech_type,
  gss_buffer_t output_token,
@@ -343,14 +347,7 @@ init_auth
 {
     OM_uint32 ret = GSS_S_FAILURE;
     krb5_error_code kret;
-    krb5_flags ap_options;
-    krb5_creds *kcred = NULL;
     krb5_data outbuf;
-    krb5_ccache ccache = NULL;
-    uint32_t flags;
-    krb5_data authenticator;
-    Checksum cksum;
-    krb5_enctype enctype;
     krb5_data fwd_data;
     OM_uint32 lifetime_rec;
 
@@ -363,16 +360,17 @@ init_auth
        *actual_mech_type = GSS_KRB5_MECHANISM;
 
     if (cred == NULL) {
-       kret = krb5_cc_default (context, &ccache);
+       kret = krb5_cc_default (context, &ctx->ccache);
        if (kret) {
            *minor_status = kret;
            ret = GSS_S_FAILURE;
            goto failure;
        }
+       ctx->more_flags |= CLOSE_CCACHE;
     } else
-       ccache = cred->ccache;
+       ctx->ccache = cred->ccache;
 
-    kret = krb5_cc_get_principal (context, ccache, &ctx->source);
+    kret = krb5_cc_get_principal (context, ctx->ccache, &ctx->source);
     if (kret) {
        *minor_status = kret;
        ret = GSS_S_FAILURE;
@@ -407,16 +405,16 @@ init_auth
 
     ret = gsskrb5_get_creds(minor_status,
                            context,
-                           ccache,
+                           ctx->ccache,
                            ctx,
                            ctx->target,
                            time_req,
                            time_rec,
-                           &kcred);
+                           &ctx->kcred);
     if (ret)
        goto failure;
 
-    ctx->lifetime = kcred->times.endtime;
+    ctx->lifetime = ctx->kcred->times.endtime;
 
     ret = _gsskrb5_lifetime_left(minor_status,
                                 context,
@@ -434,17 +432,59 @@ init_auth
 
     krb5_auth_con_setkey(context, 
                         ctx->auth_context, 
-                        &kcred->session);
+                        &ctx->kcred->session);
 
     kret = krb5_auth_con_generatelocalsubkey(context, 
                                             ctx->auth_context,
-                                            &kcred->session);
+                                            &ctx->kcred->session);
     if(kret) {
        *minor_status = kret;
        ret = GSS_S_FAILURE;
        goto failure;
     }
-    
+
+    return GSS_S_COMPLETE;
+
+failure:
+    if (ctx->ccache && (ctx->more_flags & CLOSE_CCACHE))
+       krb5_cc_close(context, ctx->ccache);
+    ctx->ccache = NULL;
+
+    return ret;
+
+}
+
+static OM_uint32
+init_auth_restart
+(OM_uint32 * minor_status,
+ gsskrb5_cred cred,
+ gsskrb5_ctx ctx,
+ krb5_context context,
+ OM_uint32 req_flags,
+ const gss_channel_bindings_t input_chan_bindings,
+ const gss_buffer_t input_token,
+ gss_OID * actual_mech_type,
+ gss_buffer_t output_token,
+ OM_uint32 * ret_flags,
+ OM_uint32 * time_rec
+    )
+{
+    OM_uint32 ret = GSS_S_FAILURE;
+    krb5_error_code kret;
+    krb5_flags ap_options;
+    krb5_data outbuf;
+    uint32_t flags;
+    krb5_data authenticator;
+    Checksum cksum;
+    krb5_enctype enctype;
+    krb5_data fwd_data, timedata;
+    int32_t offset = 0, oldoffset;
+
+    krb5_data_zero(&outbuf);
+    krb5_data_zero(&fwd_data);
+
+    *minor_status = 0;
+
     /* 
      * If the credential doesn't have ok-as-delegate, check what local
      * policy say about ok-as-delegate, default is FALSE that makes
@@ -452,12 +492,24 @@ init_auth
      * requested. If it is TRUE, strip of the GSS_C_DELEG_FLAG if the
      * KDC doesn't set ok-as-delegate.
      */
-    if (!kcred->flags.b.ok_as_delegate) {
-       krb5_boolean delegate;
+    if (!ctx->kcred->flags.b.ok_as_delegate) {
+       krb5_boolean delegate, realm_setting;
+       krb5_data data;
     
-       krb5_appdefault_boolean(context,
-                               "gssapi", name->realm,
-                               "ok-as-delegate", FALSE, &delegate);
+       realm_setting = FALSE;
+
+       ret = krb5_cc_get_config(context, ctx->ccache, NULL,
+                                "realm-config", &data);
+       if (ret == 0) {
+           /* XXX 1 is use ok-as-delegate */
+           if (data.length > 0 && (((unsigned char *)data.data)[0]) & 1)
+               realm_setting = TRUE;
+           krb5_data_free(&data);
+       }
+
+       krb5_appdefault_boolean(context, "gssapi", ctx->target->realm,
+                               "ok-as-delegate", realm_setting,
+                               &delegate);
        if (delegate)
            req_flags &= ~GSS_C_DELEG_FLAG;
     }
@@ -467,7 +519,8 @@ init_auth
     if (req_flags & GSS_C_DELEG_FLAG)
        do_delegation (context,
                       ctx->auth_context,
-                      ccache, kcred, name, &fwd_data, &flags);
+                      ctx->ccache, ctx->kcred, ctx->target,
+                      &fwd_data, &flags);
     
     if (req_flags & GSS_C_MUTUAL_FLAG) {
        flags |= GSS_C_MUTUAL_FLAG;
@@ -518,16 +571,33 @@ init_auth
 
     enctype = ctx->auth_context->keyblock->keytype;
 
+    ret = krb5_cc_get_config(context, ctx->ccache, ctx->target,
+                            "time-offset", &timedata);
+    if (ret == 0) {
+       if (timedata.length == 4) {
+           const u_char *p = timedata.data;
+           offset = (p[0] <<24) | (p[1] << 16) | (p[2] << 8) | (p[3] << 0);
+       }
+       krb5_data_free(&timedata);
+    }
+
+    if (offset) {
+       krb5_get_kdc_sec_offset (context, &oldoffset, NULL);
+       krb5_set_kdc_sec_offset (context, offset, -1);
+    }
+
     kret = krb5_build_authenticator (context,
                                     ctx->auth_context,
                                     enctype,
-                                    kcred,
+                                    ctx->kcred,
                                     &cksum,
                                     NULL,
                                     &authenticator,
                                     KRB5_KU_AP_REQ_AUTH);
 
     if (kret) {
+       if (offset)
+           krb5_set_kdc_sec_offset (context, oldoffset, -1);
        *minor_status = kret;
        ret = GSS_S_FAILURE;
        goto failure;
@@ -535,11 +605,12 @@ init_auth
 
     kret = krb5_build_ap_req (context,
                              enctype,
-                             kcred,
+                             ctx->kcred,
                              ap_options,
                              authenticator,
                              &outbuf);
-
+    if (offset)
+       krb5_set_kdc_sec_offset (context, oldoffset, -1);
     if (kret) {
        *minor_status = kret;
        ret = GSS_S_FAILURE;
@@ -552,16 +623,12 @@ init_auth
     } else {
         ret = _gsskrb5_encapsulate (minor_status, &outbuf, output_token,
                                    (u_char *)"\x01\x00", GSS_KRB5_MECHANISM);
+       krb5_data_free (&outbuf);
        if (ret)
            goto failure;
-
-       krb5_data_free (&outbuf);
     }
 
-    krb5_free_creds(context, kcred);
     free_Checksum(&cksum);
-    if (cred == NULL)
-       krb5_cc_close(context, ccache);
 
     if (flags & GSS_C_MUTUAL_FLAG) {
        ctx->state = INITIATOR_WAIT_FOR_MUTAL;
@@ -570,15 +637,14 @@ init_auth
 
     return gsskrb5_initiator_ready(minor_status, ctx, context);
 failure:
-    if(kcred)
-       krb5_free_creds(context, kcred);
-    if (ccache && cred == NULL)
-       krb5_cc_close(context, ccache);
+    if (ctx->ccache && (ctx->more_flags & CLOSE_CCACHE))
+       krb5_cc_close(context, ctx->ccache);
+    ctx->ccache = NULL;
 
     return ret;
-
 }
 
+
 static OM_uint32
 repl_mutual
 (OM_uint32 * minor_status,
@@ -617,8 +683,46 @@ repl_mutual
                                    &indata,
                                    "\x02\x00",
                                    GSS_KRB5_MECHANISM);
-       if (ret) {
-           /* XXX - Handle AP_ERROR */
+       if (ret == GSS_S_DEFECTIVE_TOKEN) {
+           /* check if there is an error token sent instead */
+           ret = _gsskrb5_decapsulate (minor_status,
+                                       input_token,
+                                       &indata,
+                                       "\x03\x00",
+                                       GSS_KRB5_MECHANISM);
+           if (ret == GSS_S_COMPLETE) {
+               KRB_ERROR error;
+               
+               kret = krb5_rd_error(context, &indata, &error);
+               if (kret == 0) {
+                   kret = krb5_error_from_rd_error(context, &error, NULL);
+
+                   /* save the time skrew for this host */
+                   if (kret == KRB5KRB_AP_ERR_SKEW) {
+                       krb5_data timedata;
+                       unsigned char p[4];
+                       int32_t t = error.stime - time(NULL);
+
+                       p[0] = (t >> 24) & 0xFF;
+                       p[1] = (t >> 16) & 0xFF;
+                       p[2] = (t >> 8)  & 0xFF;
+                       p[3] = (t >> 0)  & 0xFF;
+
+                       timedata.data = p;
+                       timedata.length = sizeof(p);
+
+                       krb5_cc_set_config(context, ctx->ccache, ctx->target,
+                                          "time-offset", &timedata);
+
+                       if ((ctx->more_flags & RETRIED) == 0)
+                           ctx->state = INITIATOR_RESTART;
+                       ctx->more_flags |= RETRIED;
+                   }
+                   free_KRB_ERROR (&error);
+               }
+               *minor_status = kret;
+               return GSS_S_FAILURE;
+           }
            return ret;
        }
     }
@@ -661,30 +765,31 @@ repl_mutual
        *ret_flags = ctx->flags;
 
     if (req_flags & GSS_C_DCE_STYLE) {
-       int32_t con_flags;
+       int32_t local_seq, remote_seq;
        krb5_data outbuf;
 
-       /* Do don't do sequence number for the mk-rep */
-       krb5_auth_con_removeflags(context,
-                                 ctx->auth_context,
-                                 KRB5_AUTH_CONTEXT_DO_SEQUENCE,
-                                 &con_flags);
+       /*
+        * So DCE_STYLE is strange. The client echos the seq number
+        * that the server used in the server's mk_rep in its own
+        * mk_rep(). After when done, it resets to it's own seq number
+        * for the gss_wrap calls.
+        */
 
-       kret = krb5_mk_rep(context,
-                          ctx->auth_context,
-                          &outbuf);
+       krb5_auth_getremoteseqnumber(context, ctx->auth_context, &remote_seq);
+       krb5_auth_con_getlocalseqnumber(context, ctx->auth_context, &local_seq);
+       krb5_auth_con_setlocalseqnumber(context, ctx->auth_context, remote_seq);
+
+       kret = krb5_mk_rep(context, ctx->auth_context, &outbuf);
        if (kret) {
            *minor_status = kret;
            return GSS_S_FAILURE;
        }
        
+       /* reset local seq number */
+       krb5_auth_con_setlocalseqnumber(context, ctx->auth_context, local_seq); 
+
        output_token->length = outbuf.length;
        output_token->value  = outbuf.data;
-
-       krb5_auth_con_removeflags(context,
-                                 ctx->auth_context,
-                                 KRB5_AUTH_CONTEXT_DO_SEQUENCE,
-                                 NULL);
     }
 
     return gsskrb5_initiator_ready(minor_status, ctx, context);
@@ -768,6 +873,7 @@ OM_uint32 _gsskrb5_init_sec_context
 
     HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
 
+ again:
     switch (ctx->state) {
     case INITIATOR_START:
        ret = init_auth(minor_status,
@@ -778,12 +884,26 @@ OM_uint32 _gsskrb5_init_sec_context
                        mech_type,
                        req_flags,
                        time_req,
-                       input_chan_bindings,
                        input_token,
                        actual_mech_type,
                        output_token,
                        ret_flags,
                        time_rec);
+       if (ret != GSS_S_COMPLETE)
+           break;          
+       /* FALL THOUGH */
+    case INITIATOR_RESTART:
+       ret = init_auth_restart(minor_status,
+                               cred,
+                               ctx,
+                               context,
+                               req_flags,
+                               input_chan_bindings,
+                               input_token,
+                               actual_mech_type,
+                               output_token,
+                               ret_flags,
+                               time_rec);
        break;
     case INITIATOR_WAIT_FOR_MUTAL:
        ret = repl_mutual(minor_status,
@@ -798,6 +918,8 @@ OM_uint32 _gsskrb5_init_sec_context
                          output_token,
                          ret_flags,
                          time_rec);
+       if (ctx->state == INITIATOR_RESTART)
+           goto again;
        break;
     case INITIATOR_READY:
        /* 
index 85b50d032286fe12caec230283a0cf88b81cc1ae..8c554fb8e0f54a3b340c9e303bed6d468f1e6b80 100644 (file)
@@ -32,7 +32,7 @@
 
 #include "krb5/gsskrb5_locl.h"
 
-RCSID("$Id: set_cred_option.c 22655 2008-02-26 12:40:35Z lha $");
+RCSID("$Id: set_cred_option.c 23331 2008-06-27 12:01:48Z lha $");
 
 /* 1.2.752.43.13.17 */
 static gss_OID_desc gss_krb5_cred_no_ci_flags_x_oid_desc =
index 50441a11ad3cb88c5c4eecfc29c859c7639404c6..fd76838af514688bf8d61dcd8eb1e74f96501128 100644 (file)
@@ -36,7 +36,7 @@
 
 #include "krb5/gsskrb5_locl.h"
 
-RCSID("$Id: set_sec_context_option.c 20384 2007-04-18 08:51:06Z lha $");
+RCSID("$Id: set_sec_context_option.c 23420 2008-07-26 18:37:48Z lha $");
 
 static OM_uint32
 get_bool(OM_uint32 *minor_status,
@@ -70,6 +70,36 @@ get_string(OM_uint32 *minor_status,
     return GSS_S_COMPLETE;
 }
 
+static OM_uint32
+get_int32(OM_uint32 *minor_status,
+         const gss_buffer_t value,
+         OM_uint32 *ret)
+{
+    *minor_status = 0;
+    if (value == NULL || value->length == 0)
+       *ret = 0;
+    else if (value->length == sizeof(*ret))
+       memcpy(ret, value->value, sizeof(*ret));
+    else
+       return GSS_S_UNAVAILABLE;
+
+    return GSS_S_COMPLETE;
+}
+
+static OM_uint32
+set_int32(OM_uint32 *minor_status,
+         const gss_buffer_t value,
+         OM_uint32 set)
+{
+    *minor_status = 0;
+    if (value->length == sizeof(set))
+       memcpy(value->value, &set, sizeof(set));
+    else
+       return GSS_S_UNAVAILABLE;
+
+    return GSS_S_COMPLETE;
+}
+
 OM_uint32
 _gsskrb5_set_sec_context_option
            (OM_uint32 *minor_status,
@@ -185,6 +215,35 @@ _gsskrb5_set_sec_context_option
            return GSS_S_FAILURE;
 
        return GSS_S_COMPLETE;
+    } else if (gss_oid_equal(desired_object, GSS_KRB5_SET_TIME_OFFSET_X)) {
+       OM_uint32 offset;
+       time_t t;
+
+       maj_stat = get_int32(minor_status, value, &offset);
+       if (maj_stat != GSS_S_COMPLETE)
+           return maj_stat;
+
+       t = time(NULL) + offset;
+       
+       krb5_set_real_time(context, t, 0);
+
+       *minor_status = 0;
+       return GSS_S_COMPLETE;
+    } else if (gss_oid_equal(desired_object, GSS_KRB5_GET_TIME_OFFSET_X)) {
+       krb5_timestamp sec;
+       int32_t usec;
+       time_t t;
+
+       t = time(NULL);
+
+       krb5_us_timeofday (context, &sec, &usec);
+
+       maj_stat = set_int32(minor_status, value, sec - t);
+       if (maj_stat != GSS_S_COMPLETE)
+           return maj_stat;
+
+       *minor_status = 0;
+       return GSS_S_COMPLETE;
     }
 
     *minor_status = EINVAL;
index d0a33d86fbfcbde2b15b7f068b31286138f8fb74..eec4078a706017102c3a12e63a0072e84de13283 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5/gsskrb5_locl.h"
 
-RCSID("$Id: unwrap.c 19031 2006-11-13 18:02:57Z lha $");
+RCSID("$Id: unwrap.c 23112 2008-04-27 18:51:26Z lha $");
 
 static OM_uint32
 unwrap_des
@@ -93,7 +93,7 @@ unwrap_des
 
       for (i = 0; i < sizeof(deskey); ++i)
          deskey[i] ^= 0xf0;
-      DES_set_key (&deskey, &schedule);
+      DES_set_key_unchecked (&deskey, &schedule);
       memset (&zero, 0, sizeof(zero));
       DES_cbc_encrypt ((void *)p,
                       (void *)p,
@@ -119,7 +119,7 @@ unwrap_des
 
   memset (&zero, 0, sizeof(zero));
   memcpy (&deskey, key->keyvalue.data, sizeof(deskey));
-  DES_set_key (&deskey, &schedule);
+  DES_set_key_unchecked (&deskey, &schedule);
   DES_cbc_cksum ((void *)hash, (void *)hash, sizeof(hash),
                 &schedule, &zero);
   if (memcmp (p - 8, hash, 8) != 0)
@@ -130,7 +130,7 @@ unwrap_des
   HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
 
   p -= 16;
-  DES_set_key (&deskey, &schedule);
+  DES_set_key_unchecked (&deskey, &schedule);
   DES_cbc_encrypt ((void *)p, (void *)p, 8,
                   &schedule, (DES_cblock *)hash, DES_DECRYPT);
 
index 52381afcc28ae9fc11645ca1119df452c0667432..560c14bc89560d442c6c86fffc9983d98ea63214 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5/gsskrb5_locl.h"
 
-RCSID("$Id: verify_mic.c 19031 2006-11-13 18:02:57Z lha $");
+RCSID("$Id: verify_mic.c 23112 2008-04-27 18:51:26Z lha $");
 
 static OM_uint32
 verify_mic_des
@@ -83,7 +83,7 @@ verify_mic_des
   memset (&zero, 0, sizeof(zero));
   memcpy (&deskey, key->keyvalue.data, sizeof(deskey));
 
-  DES_set_key (&deskey, &schedule);
+  DES_set_key_unchecked (&deskey, &schedule);
   DES_cbc_cksum ((void *)hash, (void *)hash, sizeof(hash),
                 &schedule, &zero);
   if (memcmp (p - 8, hash, 8) != 0) {
@@ -97,7 +97,7 @@ verify_mic_des
   HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
 
   p -= 16;
-  DES_set_key (&deskey, &schedule);
+  DES_set_key_unchecked (&deskey, &schedule);
   DES_cbc_encrypt ((void *)p, (void *)p, 8,
                   &schedule, (DES_cblock *)hash, DES_DECRYPT);
 
index d41379870ae90976023c661c0a317ba91a4de65f..6d00f2adcfbadf708d1b43e397cdd4b371e0fd42 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5/gsskrb5_locl.h"
 
-RCSID("$Id: wrap.c 19035 2006-11-14 09:49:56Z lha $");
+RCSID("$Id: wrap.c 23316 2008-06-23 04:32:32Z lha $");
 
 /*
  * Return initiator subkey, or if that doesn't exists, the subkey.
@@ -61,7 +61,7 @@ _gsskrb5i_get_initiator_subkey(const gsskrb5_ctx ctx,
                                   ctx->auth_context, 
                                   key);
     if (ret == 0 && *key == NULL) {
-       krb5_set_error_string(context, "No initiator subkey available");
+       krb5_set_error_message(context, 0, "No initiator subkey available");
        return GSS_KRB5_S_KG_NO_SUBKEY;
     }
     return ret;
@@ -85,7 +85,7 @@ _gsskrb5i_get_acceptor_subkey(const gsskrb5_ctx ctx,
                                     key);
     }
     if (ret == 0 && *key == NULL) {
-       krb5_set_error_string(context, "No acceptor subkey available");
+       krb5_set_error_message(context, 0, "No acceptor subkey available");
        return GSS_KRB5_S_KG_NO_SUBKEY;
     }
     return ret;
@@ -106,7 +106,7 @@ _gsskrb5i_get_token_key(const gsskrb5_ctx ctx,
            _gsskrb5i_get_initiator_subkey(ctx, context, key);
     }
     if (*key == NULL) {
-       krb5_set_error_string(context, "No token key available");
+       krb5_set_error_message(context, 0, "No token key available");
        return GSS_KRB5_S_KG_NO_SUBKEY;
     }
     return 0;
@@ -259,7 +259,7 @@ wrap_des
 
   memset (&zero, 0, sizeof(zero));
   memcpy (&deskey, key->keyvalue.data, sizeof(deskey));
-  DES_set_key (&deskey, &schedule);
+  DES_set_key_unchecked (&deskey, &schedule);
   DES_cbc_cksum ((void *)hash, (void *)hash, sizeof(hash),
                 &schedule, &zero);
   memcpy (p - 8, hash, 8);
@@ -279,7 +279,7 @@ wrap_des
          (ctx->more_flags & LOCAL) ? 0 : 0xFF,
          4);
 
-  DES_set_key (&deskey, &schedule);
+  DES_set_key_unchecked (&deskey, &schedule);
   DES_cbc_encrypt ((void *)p, (void *)p, 8,
                   &schedule, (DES_cblock *)(p + 8), DES_ENCRYPT);
 
@@ -296,7 +296,7 @@ wrap_des
 
       for (i = 0; i < sizeof(deskey); ++i)
          deskey[i] ^= 0xf0;
-      DES_set_key (&deskey, &schedule);
+      DES_set_key_unchecked (&deskey, &schedule);
       memset (&zero, 0, sizeof(zero));
       DES_cbc_encrypt ((void *)p,
                       (void *)p,
index cb1b62308c0a0b28cb5110011eb5f243eb55e982..a2757140ae24db293fd34cbfff0fb6f692ecaa45 100644 (file)
@@ -27,9 +27,9 @@
  */
 
 #include "mech_locl.h"
-RCSID("$Id: gss_acquire_cred.c 21478 2007-07-10 16:32:01Z lha $");
+RCSID("$Id: gss_acquire_cred.c 23025 2008-04-17 10:01:57Z lha $");
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_acquire_cred(OM_uint32 *minor_status,
     const gss_name_t desired_name,
     OM_uint32 time_req,
index 09b592b5da7c4f4ead4316c185c231b02def9709..49efa20c8beba2e71282a2ea4c704fc227e06f30 100644 (file)
@@ -27,7 +27,7 @@
  */
 
 #include "mech_locl.h"
-RCSID("$Id: gss_add_cred.c 21474 2007-07-10 16:30:23Z lha $");
+RCSID("$Id: gss_add_cred.c 23025 2008-04-17 10:01:57Z lha $");
 
 static struct _gss_mechanism_cred *
 _gss_copy_cred(struct _gss_mechanism_cred *mc)
@@ -71,7 +71,7 @@ _gss_copy_cred(struct _gss_mechanism_cred *mc)
        return (new_mc);
 }
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_add_cred(OM_uint32 *minor_status,
     const gss_cred_id_t input_cred_handle,
     const gss_name_t desired_name,
index 87d1ab3725e48e46f3c96f8c7987250a13bff081..d89adbf63a3de5c0d6dc13a26ac0abdd01356b06 100644 (file)
@@ -32,9 +32,9 @@
  */
 
 #include "mech_locl.h"
-RCSID("$Id: gss_add_oid_set_member.c 18817 2006-10-22 09:36:13Z lha $");
+RCSID("$Id: gss_add_oid_set_member.c 23025 2008-04-17 10:01:57Z lha $");
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_add_oid_set_member (OM_uint32 * minor_status,
                        const gss_OID member_oid,
                        gss_OID_set * oid_set)
index 56e003937972f700cf487bcfccd850bd2284f1e5..091e219367981ce3ba3bf26ba236555ea5b9c6a0 100644 (file)
@@ -31,9 +31,9 @@
  */
 
 #include "mech_locl.h"
-RCSID("$Id: gss_buffer_set.c 18885 2006-10-24 21:53:02Z lha $");
+RCSID("$Id: gss_buffer_set.c 23025 2008-04-17 10:01:57Z lha $");
 
-OM_uint32 
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_create_empty_buffer_set
           (OM_uint32 * minor_status,
            gss_buffer_set_t *buffer_set)
@@ -55,7 +55,7 @@ gss_create_empty_buffer_set
     return GSS_S_COMPLETE;
 }
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_add_buffer_set_member
           (OM_uint32 * minor_status,
            const gss_buffer_t member_buffer,
@@ -97,7 +97,7 @@ gss_add_buffer_set_member
     return GSS_S_COMPLETE;
 }
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_release_buffer_set(OM_uint32 * minor_status,
                       gss_buffer_set_t *buffer_set)
 {
index c950c03166b1de24884dbbdcd5239141c6673239..d242c56a909b275bdaa168bb133b94c7cbfaeba0 100644 (file)
@@ -27,9 +27,9 @@
  */
 
 #include "mech_locl.h"
-RCSID("$Id: gss_canonicalize_name.c 21476 2007-07-10 16:31:27Z lha $");
+RCSID("$Id: gss_canonicalize_name.c 23025 2008-04-17 10:01:57Z lha $");
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_canonicalize_name(OM_uint32 *minor_status,
     const gss_name_t input_name,
     const gss_OID mech_type,
index 617ff13d984436f2dc7e55018c11ce49a19683e8..1eb7625ee2820258281df75e883541af6652bc7a 100644 (file)
@@ -27,9 +27,9 @@
  */
 
 #include "mech_locl.h"
-RCSID("$Id: gss_compare_name.c 21475 2007-07-10 16:31:03Z lha $");
+RCSID("$Id: gss_compare_name.c 23025 2008-04-17 10:01:57Z lha $");
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_compare_name(OM_uint32 *minor_status,
     const gss_name_t name1_arg,
     const gss_name_t name2_arg,
index 47999f35cfa556a848cdc2449913f8c03cd4fa65..8dce822a9fc9f09126f31d07578a08f0577271ff 100644 (file)
@@ -27,9 +27,9 @@
  */
 
 #include "mech_locl.h"
-RCSID("$Id: gss_context_time.c 17700 2006-06-28 09:00:26Z lha $");
+RCSID("$Id: gss_context_time.c 23025 2008-04-17 10:01:57Z lha $");
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_context_time(OM_uint32 *minor_status,
     const gss_ctx_id_t context_handle,
     OM_uint32 *time_rec)
index 841271b1fd98552fcfb37b13b2a08723e9e3ce4a..8dd35273492557e507a9f797a991ee7cfeee6916 100644 (file)
@@ -27,9 +27,9 @@
  */
 
 #include "mech_locl.h"
-RCSID("$Id: gss_create_empty_oid_set.c 19951 2007-01-17 10:14:58Z lha $");
+RCSID("$Id: gss_create_empty_oid_set.c 23025 2008-04-17 10:01:57Z lha $");
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_create_empty_oid_set(OM_uint32 *minor_status,
     gss_OID_set *oid_set)
 {
index e8b86e4d228fc8b660f866033b349abc19a4964f..8f939255850488b1ba5570411166f443227ccf46 100644 (file)
@@ -32,9 +32,9 @@
  */
 
 #include "mech_locl.h"
-RCSID("$Id: gss_decapsulate_token.c 19951 2007-01-17 10:14:58Z lha $");
+RCSID("$Id: gss_decapsulate_token.c 23025 2008-04-17 10:01:57Z lha $");
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_decapsulate_token(gss_buffer_t input_token,
                      gss_OID oid,
                      gss_buffer_t output_token)
index 8c4099473915808351bff7fa4112ea5e41f25204..91273bcf5687ae93cac2aca1510230a227328a81 100644 (file)
@@ -27,9 +27,9 @@
  */
 
 #include "mech_locl.h"
-RCSID("$Id: gss_delete_sec_context.c 19951 2007-01-17 10:14:58Z lha $");
+RCSID("$Id: gss_delete_sec_context.c 23025 2008-04-17 10:01:57Z lha $");
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_delete_sec_context(OM_uint32 *minor_status,
     gss_ctx_id_t *context_handle,
     gss_buffer_t output_token)
index fc10933692cb9f44272cb6290dabe7c4a16fd5af..0d8240024648a30e22bdf6a37426e213338d4eee 100644 (file)
@@ -27,9 +27,9 @@
  */
 
 #include "mech_locl.h"
-RCSID("$Id: gss_display_name.c 21246 2007-06-20 15:25:19Z lha $");
+RCSID("$Id: gss_display_name.c 23025 2008-04-17 10:01:57Z lha $");
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_display_name(OM_uint32 *minor_status,
     const gss_name_t input_name,
     gss_buffer_t output_name_buffer,
index 37ded26db690129b03dfd6f3218b3e16db67cb14..5bbc89b1ece37477353f3a41db31ed9c3a8d9ca2 100644 (file)
@@ -59,7 +59,7 @@
  */
 
 #include "mech_locl.h"
-RCSID("$Id: gss_display_status.c 21247 2007-06-21 00:37:27Z lha $");
+RCSID("$Id: gss_display_status.c 23025 2008-04-17 10:01:57Z lha $");
 
 static const char *
 calling_error(OM_uint32 v)
@@ -136,7 +136,7 @@ supplementary_error(OM_uint32 v)
 }
 
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_display_status(OM_uint32 *minor_status,
     OM_uint32 status_value,
     int status_type,
index 476d4513756cbb2ab4a459d3d26df0ac352ff6fd..32ecbbacb2d6512530c78551d98c8f9eeed245f1 100644 (file)
@@ -32,9 +32,9 @@
  */
 
 #include "mech_locl.h"
-RCSID("$Id: gss_encapsulate_token.c 19954 2007-01-17 11:50:23Z lha $");
+RCSID("$Id: gss_encapsulate_token.c 23025 2008-04-17 10:01:57Z lha $");
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_encapsulate_token(gss_buffer_t input_token,
                      gss_OID oid,
                      gss_buffer_t output_token)
index 11c9dd2db5fad7f69e8d3de08b1d671d90b833ef..22053202aa86048be00cfbea5ad192270837cc0b 100644 (file)
@@ -27,9 +27,9 @@
  */
 
 #include "mech_locl.h"
-RCSID("$Id: gss_export_name.c 19954 2007-01-17 11:50:23Z lha $");
+RCSID("$Id: gss_export_name.c 23025 2008-04-17 10:01:57Z lha $");
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_export_name(OM_uint32 *minor_status,
     const gss_name_t input_name,
     gss_buffer_t exported_name)
index cf13bc0cd3275516efc6528479fdf7b34fd9ba30..053d203ba16ecf14b62df8942d6209ac61c44ca4 100644 (file)
@@ -27,9 +27,9 @@
  */
 
 #include "mech_locl.h"
-RCSID("$Id: gss_export_sec_context.c 19954 2007-01-17 11:50:23Z lha $");
+RCSID("$Id: gss_export_sec_context.c 23025 2008-04-17 10:01:57Z lha $");
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_export_sec_context(OM_uint32 *minor_status,
     gss_ctx_id_t *context_handle,
     gss_buffer_t interprocess_token)
index 496dd2065c5a3ac4ee443840b194641c3320fb4b..7b33ac0ed9e325f26223b04da4aa5d353e070d7a 100644 (file)
@@ -27,9 +27,9 @@
  */
 
 #include "mech_locl.h"
-RCSID("$Id: gss_get_mic.c 19954 2007-01-17 11:50:23Z lha $");
+RCSID("$Id: gss_get_mic.c 23025 2008-04-17 10:01:57Z lha $");
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_get_mic(OM_uint32 *minor_status,
     const gss_ctx_id_t context_handle,
     gss_qop_t qop_req,
index 6f55a1d61cf24e6253ca54bdc046480f9a94c35b..104452f5b95e27d6e19602ecca0d802f44adcc36 100644 (file)
@@ -27,7 +27,7 @@
  */
 
 #include "mech_locl.h"
-RCSID("$Id: gss_import_name.c 19954 2007-01-17 11:50:23Z lha $");
+RCSID("$Id: gss_import_name.c 23025 2008-04-17 10:01:57Z lha $");
 
 static OM_uint32
 _gss_import_export_name(OM_uint32 *minor_status,
@@ -139,7 +139,7 @@ _gss_import_export_name(OM_uint32 *minor_status,
        return (GSS_S_COMPLETE);
 }
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_import_name(OM_uint32 *minor_status,
     const gss_buffer_t input_name_buffer,
     const gss_OID input_name_type,
index 44ca1b2677bad5964e7102ccb20de57ba2d17081..c68849ce008b245ac7cb0646e3dc5fc185d13602 100644 (file)
@@ -27,9 +27,9 @@
  */
 
 #include "mech_locl.h"
-RCSID("$Id: gss_import_sec_context.c 19956 2007-01-17 12:04:16Z lha $");
+RCSID("$Id: gss_import_sec_context.c 23025 2008-04-17 10:01:57Z lha $");
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_import_sec_context(OM_uint32 *minor_status,
     const gss_buffer_t interprocess_token,
     gss_ctx_id_t *context_handle)
index 00c6ed28ee6c1269afc5da3f57b1a418009b5626..cafb6609914cace3c6a7e504c4f3350922459be3 100644 (file)
@@ -27,9 +27,9 @@
  */
 
 #include "mech_locl.h"
-RCSID("$Id: gss_indicate_mechs.c 17803 2006-07-05 22:36:49Z lha $");
+RCSID("$Id: gss_indicate_mechs.c 23025 2008-04-17 10:01:57Z lha $");
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_indicate_mechs(OM_uint32 *minor_status,
     gss_OID_set *mech_set)
 {
index b9a1680dcb3ed3a00cb48c7ab52c5948ab627c02..d0e92f41cebc03e8ba4bdf90254cfa1b7693a94a 100644 (file)
@@ -27,7 +27,7 @@
  */
 
 #include "mech_locl.h"
-RCSID("$Id: gss_init_sec_context.c 21479 2007-07-10 16:32:19Z lha $");
+RCSID("$Id: gss_init_sec_context.c 23025 2008-04-17 10:01:57Z lha $");
 
 static gss_cred_id_t
 _gss_mech_cred_find(gss_cred_id_t cred_handle, gss_OID mech_type)
@@ -45,7 +45,7 @@ _gss_mech_cred_find(gss_cred_id_t cred_handle, gss_OID mech_type)
        return GSS_C_NO_CREDENTIAL;
 }
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_init_sec_context(OM_uint32 * minor_status,
     const gss_cred_id_t initiator_cred_handle,
     gss_ctx_id_t * context_handle,
index d45baac6027c3f54630ed0e3d6e404e1c3d94b86..26f4038071208d687c0be6dbe9d1f4f1c1039e77 100644 (file)
@@ -27,9 +27,9 @@
  */
 
 #include "mech_locl.h"
-RCSID("$Id: gss_inquire_context.c 21125 2007-06-18 20:11:07Z lha $");
+RCSID("$Id: gss_inquire_context.c 23025 2008-04-17 10:01:57Z lha $");
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_inquire_context(OM_uint32 *minor_status,
     const gss_ctx_id_t context_handle,
     gss_name_t *src_name,
index 97c3628225b3ff7de3b5620f019db58757b9ab00..1610be5538723277082283587694ace7336871f4 100644 (file)
@@ -27,7 +27,7 @@
  */
 
 #include "mech_locl.h"
-RCSID("$Id: gss_inquire_cred.c 20626 2007-05-08 13:56:49Z lha $");
+RCSID("$Id: gss_inquire_cred.c 23025 2008-04-17 10:01:57Z lha $");
 
 #define AUSAGE 1
 #define IUSAGE 2
@@ -43,7 +43,7 @@ updateusage(gss_cred_usage_t usage, int *usagemask)
        *usagemask |= IUSAGE;
 }
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_inquire_cred(OM_uint32 *minor_status,
     const gss_cred_id_t cred_handle,
     gss_name_t *name_ret,
index aa83efb0c285c3145965a2eb446d17e7aec7c573..fedd963ffa4cb647472a043b2451f41ec07ea5b0 100644 (file)
@@ -27,9 +27,9 @@
  */
 
 #include "mech_locl.h"
-RCSID("$Id: gss_inquire_cred_by_mech.c 21124 2007-06-18 20:08:24Z lha $");
+RCSID("$Id: gss_inquire_cred_by_mech.c 23025 2008-04-17 10:01:57Z lha $");
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_inquire_cred_by_mech(OM_uint32 *minor_status,
     const gss_cred_id_t cred_handle,
     const gss_OID mech_type,
index 7b53a2ff4a822f8c6545b2274dd64ec01faa7b19..c1bbf3a724f8ddc67ecb9e0c3bad1d8e39a9a35c 100644 (file)
@@ -31,9 +31,9 @@
  */
 
 #include "mech_locl.h"
-RCSID("$Id: gss_inquire_cred_by_oid.c 19960 2007-01-17 15:09:24Z lha $");
+RCSID("$Id: gss_inquire_cred_by_oid.c 23025 2008-04-17 10:01:57Z lha $");
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_inquire_cred_by_oid (OM_uint32 *minor_status,
                         const gss_cred_id_t cred_handle,
                         const gss_OID desired_object,
index 5330a747a6b27de5f9bc37e0cf5702ba4ca25b0c..6b06a33053da1b1ad9052fb3cb12fb1f0c56bbcf 100644 (file)
@@ -27,9 +27,9 @@
  */
 
 #include "mech_locl.h"
-RCSID("$Id: gss_inquire_mechs_for_name.c 17844 2006-07-20 02:04:00Z lha $");
+RCSID("$Id: gss_inquire_mechs_for_name.c 23025 2008-04-17 10:01:57Z lha $");
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_inquire_mechs_for_name(OM_uint32 *minor_status,
     const gss_name_t input_name,
     gss_OID_set *mech_types)
index 65b52cbbc301c4ed80a86ee4570ff38b68a75173..1ba1ee056336cd77efe97cfb39de1ef4f6d6c019 100644 (file)
@@ -27,9 +27,9 @@
  */
 
 #include "mech_locl.h"
-RCSID("$Id: gss_inquire_names_for_mech.c 19960 2007-01-17 15:09:24Z lha $");
+RCSID("$Id: gss_inquire_names_for_mech.c 23025 2008-04-17 10:01:57Z lha $");
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_inquire_names_for_mech(OM_uint32 *minor_status,
     const gss_OID mechanism,
     gss_OID_set *name_types)
index fd8219ce0280048910fce53e069506707495fbd3..b06a3e10f0902dda295bdf929f9c171fa65282e4 100644 (file)
@@ -31,9 +31,9 @@
  */
 
 #include "mech_locl.h"
-RCSID("$Id: gss_inquire_sec_context_by_oid.c 19961 2007-01-17 15:57:51Z lha $");
+RCSID("$Id: gss_inquire_sec_context_by_oid.c 23025 2008-04-17 10:01:57Z lha $");
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_inquire_sec_context_by_oid (OM_uint32 *minor_status,
                                const gss_ctx_id_t context_handle,
                                const gss_OID desired_object,
index 03081cb70ffe906262a4c2436b21456a1a221dc8..d6b89e3e236a994eeadd75eb8c91f8d7e28783e8 100644 (file)
  */
 
 #include "mech_locl.h"
-RCSID("$Id: gss_krb5.c 21889 2007-08-09 07:43:24Z lha $");
+RCSID("$Id: gss_krb5.c 23420 2008-07-26 18:37:48Z lha $");
 
 #include <krb5.h>
 #include <roken.h>
 
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_krb5_copy_ccache(OM_uint32 *minor_status,
                     gss_cred_id_t cred,
                     krb5_ccache out)
@@ -91,7 +91,7 @@ gss_krb5_copy_ccache(OM_uint32 *minor_status,
     return ret;
 }
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_krb5_import_cred(OM_uint32 *minor_status,
                     krb5_ccache id,
                     krb5_principal keytab_principal,
@@ -186,7 +186,7 @@ out:
     return major_status;
 }
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gsskrb5_register_acceptor_identity(const char *identity)
 {
         struct _gss_mech_switch        *m;
@@ -208,7 +208,14 @@ gsskrb5_register_acceptor_identity(const char *identity)
        return (GSS_S_COMPLETE);
 }
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
+krb5_gss_register_acceptor_identity(const char *identity)
+{
+    return gsskrb5_register_acceptor_identity(identity);
+}
+
+
+OM_uint32 GSSAPI_LIB_FUNCTION
 gsskrb5_set_dns_canonicalize(int flag)
 {
         struct _gss_mech_switch        *m;
@@ -253,7 +260,7 @@ free_key(gss_krb5_lucid_key_t *key)
     memset(key, 0, sizeof(*key));
 }
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_krb5_export_lucid_sec_context(OM_uint32 *minor_status,
                                  gss_ctx_id_t *context_handle,
                                  OM_uint32 version,
@@ -396,7 +403,7 @@ out:
     return GSS_S_COMPLETE;
 }
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_krb5_free_lucid_sec_context(OM_uint32 *minor_status, void *c)
 {
     gss_krb5_lucid_context_v1_t *ctx = c;
@@ -424,7 +431,7 @@ gss_krb5_free_lucid_sec_context(OM_uint32 *minor_status, void *c)
  *
  */
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_krb5_set_allowable_enctypes(OM_uint32 *minor_status, 
                                gss_cred_id_t cred,
                                OM_uint32 num_enctypes,
@@ -478,7 +485,7 @@ out:
  *
  */
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gsskrb5_set_send_to_kdc(struct gsskrb5_send_to_kdc *c)
 {
     struct _gss_mech_switch *m;
@@ -509,7 +516,7 @@ gsskrb5_set_send_to_kdc(struct gsskrb5_send_to_kdc *c)
  *
  */
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_krb5_ccache_name(OM_uint32 *minor_status, 
                     const char *name,
                     const char **out_name)
@@ -541,7 +548,7 @@ gss_krb5_ccache_name(OM_uint32 *minor_status,
  *
  */
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gsskrb5_extract_authtime_from_sec_context(OM_uint32 *minor_status,
                                          gss_ctx_id_t context_handle,
                                          time_t *authtime)
@@ -596,7 +603,7 @@ gsskrb5_extract_authtime_from_sec_context(OM_uint32 *minor_status,
  *
  */
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gsskrb5_extract_authz_data_from_sec_context(OM_uint32 *minor_status,
                                            gss_ctx_id_t context_handle,
                                            int ad_type,
@@ -769,7 +776,7 @@ out:
  *
  */
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gsskrb5_extract_service_keyblock(OM_uint32 *minor_status,
                                 gss_ctx_id_t context_handle,
                                 krb5_keyblock **keyblock)
@@ -780,7 +787,7 @@ gsskrb5_extract_service_keyblock(OM_uint32 *minor_status,
                               keyblock);
 }
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gsskrb5_get_initiator_subkey(OM_uint32 *minor_status,
                             gss_ctx_id_t context_handle,
                             krb5_keyblock **keyblock)
@@ -791,7 +798,7 @@ gsskrb5_get_initiator_subkey(OM_uint32 *minor_status,
                               keyblock);
 }
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gsskrb5_get_subkey(OM_uint32 *minor_status,
                   gss_ctx_id_t context_handle,
                   krb5_keyblock **keyblock)
@@ -802,7 +809,7 @@ gsskrb5_get_subkey(OM_uint32 *minor_status,
                               keyblock);
 }
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gsskrb5_set_default_realm(const char *realm)
 {
         struct _gss_mech_switch        *m;
@@ -824,7 +831,7 @@ gsskrb5_set_default_realm(const char *realm)
        return (GSS_S_COMPLETE);
 }
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_krb5_get_tkt_flags(OM_uint32 *minor_status,
                       gss_ctx_id_t context_handle,
                       OM_uint32 *tkt_flags)
@@ -863,3 +870,53 @@ gss_krb5_get_tkt_flags(OM_uint32 *minor_status,
     return GSS_S_COMPLETE;
 }
 
+OM_uint32 GSSAPI_LIB_FUNCTION
+gsskrb5_set_time_offset(int offset)
+{
+        struct _gss_mech_switch        *m;
+       gss_buffer_desc buffer;
+       OM_uint32 junk;
+       int32_t o = offset;
+
+       _gss_load_mech();
+
+       buffer.value = &o;
+       buffer.length = sizeof(o);
+
+       SLIST_FOREACH(m, &_gss_mechs, gm_link) {
+               if (m->gm_mech.gm_set_sec_context_option == NULL)
+                       continue;
+               m->gm_mech.gm_set_sec_context_option(&junk, NULL,
+                   GSS_KRB5_SET_TIME_OFFSET_X, &buffer);
+       }
+
+       return (GSS_S_COMPLETE);
+}
+
+OM_uint32 GSSAPI_LIB_FUNCTION
+gsskrb5_get_time_offset(int *offset)
+{
+        struct _gss_mech_switch        *m;
+       gss_buffer_desc buffer;
+       OM_uint32 maj_stat, junk;
+       int32_t o;
+
+       _gss_load_mech();
+
+       buffer.value = &o;
+       buffer.length = sizeof(o);
+
+       SLIST_FOREACH(m, &_gss_mechs, gm_link) {
+               if (m->gm_mech.gm_set_sec_context_option == NULL)
+                       continue;
+               maj_stat = m->gm_mech.gm_set_sec_context_option(&junk, NULL,
+                   GSS_KRB5_GET_TIME_OFFSET_X, &buffer);
+
+               if (maj_stat == GSS_S_COMPLETE) {
+                       *offset = o;
+                       return maj_stat;
+               }
+       }
+
+       return (GSS_S_UNAVAILABLE);
+}
index fe65ad1ae15561c0b309b3b10dd3eb55daa3bcd7..8abbb7d0cc1d35813b6c1d4cde26d32ef239a373 100644 (file)
@@ -28,7 +28,7 @@
 
 #include "mech_locl.h"
 #include <heim_threads.h>
-RCSID("$Id: gss_mech_switch.c 21698 2007-07-26 19:07:11Z lha $");
+RCSID("$Id: gss_mech_switch.c 23471 2008-07-27 12:17:49Z lha $");
 
 #ifndef _PATH_GSS_MECH
 #define _PATH_GSS_MECH "/etc/gss/mech"
@@ -46,7 +46,7 @@ static int
 _gss_string_to_oid(const char* s, gss_OID oid)
 {
        int                     number_count, i, j;
-       int                     byte_count;
+       size_t                  byte_count;
        const char              *p, *q;
        char                    *res;
 
@@ -118,7 +118,7 @@ _gss_string_to_oid(const char* s, gss_OID oid)
                                 * The number is encoded in seven bit chunks.
                                 */
                                unsigned int t;
-                               int bytes;
+                               unsigned int bytes;
 
                                bytes = 0;
                                for (t = number; t; t >>= 7)
@@ -229,6 +229,7 @@ _gss_load_mech(void)
                HEIMDAL_MUTEX_unlock(&_gss_mech_mutex);
                return;
        }
+       rk_cloexec_file(fp);
 
        while (fgets(buf, sizeof(buf), fp)) {
                if (*buf == '#')
index 8c75410cc124b012506bc7f9a38b970b62ce8555..b272316115a4fa1967a0a56459d7e9a3f3593371 100644 (file)
@@ -32,9 +32,9 @@
  */
 
 #include "mech_locl.h"
-RCSID("$Id: gss_oid_equal.c 17702 2006-06-28 09:07:08Z lha $");
+RCSID("$Id: gss_oid_equal.c 23025 2008-04-17 10:01:57Z lha $");
 
-int
+int GSSAPI_LIB_FUNCTION
 gss_oid_equal(const gss_OID a, const gss_OID b)
 {
     if (a == b)
index e2cecaf6b446e09b79eabb2cf21945b617519656..4678a3e7107771b9ad5e454ee58bb1cedd515728 100644 (file)
@@ -32,9 +32,9 @@
  */
 
 #include "mech_locl.h"
-RCSID("$Id: gss_oid_to_str.c 21409 2007-07-04 14:19:11Z lha $");
+RCSID("$Id: gss_oid_to_str.c 23025 2008-04-17 10:01:57Z lha $");
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_oid_to_str(OM_uint32 *minor_status, gss_OID oid, gss_buffer_t oid_str)
 {
     int ret;
index dff6b04f14e1941b6e62afbd66e2ba8019ddc063..db55bc24be29fe4414aff74c6016954cf471c656 100644 (file)
@@ -27,9 +27,9 @@
  */
 
 #include "mech_locl.h"
-RCSID("$Id: gss_process_context_token.c 17700 2006-06-28 09:00:26Z lha $");
+RCSID("$Id: gss_process_context_token.c 23025 2008-04-17 10:01:57Z lha $");
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_process_context_token(OM_uint32 *minor_status,
     const gss_ctx_id_t context_handle,
     const gss_buffer_t token_buffer)
index fc55cae0309ebb28462febe4e4aba7461727d1c8..eb1bf34985dca12faf784b5349379aa15356594d 100644 (file)
@@ -27,9 +27,9 @@
  */
 
 #include "mech_locl.h"
-RCSID("$Id: gss_release_buffer.c 19962 2007-01-17 15:59:04Z lha $");
+RCSID("$Id: gss_release_buffer.c 23025 2008-04-17 10:01:57Z lha $");
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_release_buffer(OM_uint32 *minor_status,
                   gss_buffer_t buffer)
 {
index b26dbd78651ef9285386462bf36714909eb25d35..9648929c91b7f9eb4b9eb3f042cf38eb46f94703 100644 (file)
@@ -27,9 +27,9 @@
  */
 
 #include "mech_locl.h"
-RCSID("$Id: gss_release_cred.c 19963 2007-01-17 16:01:22Z lha $");
+RCSID("$Id: gss_release_cred.c 23025 2008-04-17 10:01:57Z lha $");
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_release_cred(OM_uint32 *minor_status, gss_cred_id_t *cred_handle)
 {
        struct _gss_cred *cred = (struct _gss_cred *) *cred_handle;
index 313eab8245c1174c38d44ea24ea74dbbeb91ba7b..d8c36c10a71c02e185d1e59151560ac2ac3d6ce2 100644 (file)
@@ -27,9 +27,9 @@
  */
 
 #include "mech_locl.h"
-RCSID("$Id: gss_release_name.c 18812 2006-10-22 07:59:06Z lha $");
+RCSID("$Id: gss_release_name.c 23025 2008-04-17 10:01:57Z lha $");
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_release_name(OM_uint32 *minor_status,
     gss_name_t *input_name)
 {
index 7754787fa8dabf30977c4f8f930ecf311cf10940..ccc59638fb51c3ac20a8b27f917410fac34e94ef 100644 (file)
@@ -33,9 +33,9 @@
 
 #include "mech_locl.h"
 
-RCSID("$Id: gss_release_oid.c 17747 2006-06-30 09:34:54Z lha $");
+RCSID("$Id: gss_release_oid.c 23025 2008-04-17 10:01:57Z lha $");
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_release_oid(OM_uint32 *minor_status, gss_OID *oid)
 {
     gss_OID o = *oid;
index 388cfdbf4cfa0012b13085ee4348040255ac6675..00b1f4656ded0b4e59fb836dbe751f4d6821dbcf 100644 (file)
@@ -27,9 +27,9 @@
  */
 
 #include "mech_locl.h"
-RCSID("$Id: gss_release_oid_set.c 22144 2007-12-04 17:31:55Z lha $");
+RCSID("$Id: gss_release_oid_set.c 23025 2008-04-17 10:01:57Z lha $");
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_release_oid_set(OM_uint32 *minor_status,
     gss_OID_set *set)
 {
index 71c5e70dc751c931443ec6821e31ec580104d071..79794554305b54ed82822fd35209a7d8829a1555 100644 (file)
@@ -27,9 +27,9 @@
  */
 
 #include "mech_locl.h"
-RCSID("$Id: gss_seal.c 17700 2006-06-28 09:00:26Z lha $");
+RCSID("$Id: gss_seal.c 23025 2008-04-17 10:01:57Z lha $");
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_seal(OM_uint32 *minor_status,
     gss_ctx_id_t context_handle,
     int conf_req_flag,
index c32291396f175a7c7127a69a2ca2b4d35ae413aa..bbd75c9849cfed67bd4e4ea6a0d1ede0166d120f 100644 (file)
@@ -31,9 +31,9 @@
  */
 
 #include "mech_locl.h"
-RCSID("$Id: gss_set_cred_option.c 21126 2007-06-18 20:19:59Z lha $");
+RCSID("$Id: gss_set_cred_option.c 23025 2008-04-17 10:01:57Z lha $");
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_set_cred_option (OM_uint32 *minor_status,
                     gss_cred_id_t *cred_handle,
                     const gss_OID object,
index d312251f53305909fde80a1897b60f9ec523ea25..48377fd6bcbdab3bddf585b99de681679f51529b 100644 (file)
@@ -31,9 +31,9 @@
  */
 
 #include "mech_locl.h"
-RCSID("$Id: gss_set_sec_context_option.c 19928 2007-01-16 10:37:54Z lha $");
+RCSID("$Id: gss_set_sec_context_option.c 23025 2008-04-17 10:01:57Z lha $");
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_set_sec_context_option (OM_uint32 *minor_status,
                            gss_ctx_id_t *context_handle,
                            const gss_OID object,
index 5268197c6165b5df0a5ad555f7232e00879d0bf6..c91b6490d2ccb8229154503eab8d03f5ea98171c 100644 (file)
@@ -27,9 +27,9 @@
  */
 
 #include "mech_locl.h"
-RCSID("$Id: gss_sign.c 17700 2006-06-28 09:00:26Z lha $");
+RCSID("$Id: gss_sign.c 23025 2008-04-17 10:01:57Z lha $");
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_sign(OM_uint32 *minor_status,
     gss_ctx_id_t context_handle,
     int qop_req,
index fc3c5ddeeff1cc8e68207b7c8467dc72cddf98bf..ee42cc5d1a3ae787533d8dddc7e3e0f7da28e54e 100644 (file)
@@ -27,9 +27,9 @@
  */
 
 #include "mech_locl.h"
-RCSID("$Id: gss_test_oid_set_member.c 17700 2006-06-28 09:00:26Z lha $");
+RCSID("$Id: gss_test_oid_set_member.c 23025 2008-04-17 10:01:57Z lha $");
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_test_oid_set_member(OM_uint32 *minor_status,
     const gss_OID member,
     const gss_OID_set set,
index 205cc6e326c8c290584103a1a8553d56e990ef78..d6f73c55222abde69349d60c923cb8b8662291c8 100644 (file)
@@ -27,9 +27,9 @@
  */
 
 #include "mech_locl.h"
-RCSID("$Id: gss_unseal.c 17700 2006-06-28 09:00:26Z lha $");
+RCSID("$Id: gss_unseal.c 23025 2008-04-17 10:01:57Z lha $");
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_unseal(OM_uint32 *minor_status,
     gss_ctx_id_t context_handle,
     gss_buffer_t input_message_buffer,
index 69c125356beaeb7afa14b351e5235ebb173001b8..4866bacbe52e3d93ec88715581ee5099bc11ac58 100644 (file)
@@ -27,9 +27,9 @@
  */
 
 #include "mech_locl.h"
-RCSID("$Id: gss_unwrap.c 17700 2006-06-28 09:00:26Z lha $");
+RCSID("$Id: gss_unwrap.c 23025 2008-04-17 10:01:57Z lha $");
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_unwrap(OM_uint32 *minor_status,
     const gss_ctx_id_t context_handle,
     const gss_buffer_t input_message_buffer,
index f11cac7d2e3423974091290d510aa53d5c675b27..d82ceee9847b8e2394704690cfd03b6676027700 100644 (file)
@@ -27,9 +27,9 @@
  */
 
 #include "mech_locl.h"
-RCSID("$Id: gss_verify.c 17700 2006-06-28 09:00:26Z lha $");
+RCSID("$Id: gss_verify.c 23025 2008-04-17 10:01:57Z lha $");
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_verify(OM_uint32 *minor_status,
     gss_ctx_id_t context_handle,
     gss_buffer_t message_buffer,
index 118f50735ff9c371e418e85fc650204f3a39d4be..c58c63ac0fb2476635abe74fad43429f88358078 100644 (file)
@@ -27,9 +27,9 @@
  */
 
 #include "mech_locl.h"
-RCSID("$Id: gss_verify_mic.c 19965 2007-01-17 16:23:47Z lha $");
+RCSID("$Id: gss_verify_mic.c 23025 2008-04-17 10:01:57Z lha $");
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_verify_mic(OM_uint32 *minor_status,
     const gss_ctx_id_t context_handle,
     const gss_buffer_t message_buffer,
index 0eb9dfbc6db689b0ac3e14fc52cc0658d932655b..f6b5077d0e02a27c4d147c3ef903d99c13b7e9f9 100644 (file)
@@ -27,9 +27,9 @@
  */
 
 #include "mech_locl.h"
-RCSID("$Id: gss_wrap.c 19965 2007-01-17 16:23:47Z lha $");
+RCSID("$Id: gss_wrap.c 23025 2008-04-17 10:01:57Z lha $");
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_wrap(OM_uint32 *minor_status,
     const gss_ctx_id_t context_handle,
     int conf_req_flag,
index 35b3ad723d7df53a35148bd2868beb5c1eefcdeb..14f373dada4004e8cc0fc522e83ddefdbf8e56e5 100644 (file)
@@ -27,9 +27,9 @@
  */
 
 #include "mech_locl.h"
-RCSID("$Id: gss_wrap_size_limit.c 19965 2007-01-17 16:23:47Z lha $");
+RCSID("$Id: gss_wrap_size_limit.c 23025 2008-04-17 10:01:57Z lha $");
 
-OM_uint32
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_wrap_size_limit(OM_uint32 *minor_status,
     const gss_ctx_id_t context_handle,
     int conf_req_flag,
index df25b0f4bf61c76570c2de575f03ad118661cc2b..6b618092fe1696311cbcf69500ffa05e93436fea 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "spnego/spnego_locl.h"
 
-RCSID("$Id: accept_sec_context.c 22600 2008-02-21 12:46:24Z lha $");
+RCSID("$Id: accept_sec_context.c 23158 2008-05-02 09:45:28Z lha $");
 
 static OM_uint32
 send_reject (OM_uint32 *minor_status,
@@ -376,6 +376,9 @@ select_mech(OM_uint32 *minor_status, MechType *mechType, int verify_p,
     char mechbuf[64];
     size_t mech_len;
     gss_OID_desc oid;
+    gss_OID oidp;
+    gss_OID_set mechs;
+    int i;
     OM_uint32 ret, junk;
 
     ret = der_put_oid ((unsigned char *)mechbuf + sizeof(mechbuf) - 1,
@@ -396,27 +399,29 @@ select_mech(OM_uint32 *minor_status, MechType *mechType, int verify_p,
     *minor_status = 0;
 
     /* Translate broken MS Kebreros OID */
-    if (gss_oid_equal(&oid, &_gss_spnego_mskrb_mechanism_oid_desc)) {
-       gssapi_mech_interface mech;
+    if (gss_oid_equal(&oid, &_gss_spnego_mskrb_mechanism_oid_desc))
+           oidp = &_gss_spnego_krb5_mechanism_oid_desc;
+    else
+           oidp = &oid;
 
-       mech = __gss_get_mechanism(&_gss_spnego_krb5_mechanism_oid_desc);
-       if (mech == NULL)
-           return GSS_S_BAD_MECH;
 
-       ret = gss_duplicate_oid(minor_status,
-                               &_gss_spnego_mskrb_mechanism_oid_desc,
-                               mech_p);
-    } else {
-       gssapi_mech_interface mech;
+    ret = gss_indicate_mechs(&junk, &mechs);
+    if (ret)
+           return (ret);
 
-       mech = __gss_get_mechanism(&oid);
-       if (mech == NULL)
-           return GSS_S_BAD_MECH;
+    for (i = 0; i < mechs->count; i++)
+           if (gss_oid_equal(&mechs->elements[i], oidp))
+                   break;
 
-       ret = gss_duplicate_oid(minor_status,
-                               &mech->gm_mech_oid,
-                               mech_p);
+    if (i == mechs->count) {
+           gss_release_oid_set(&junk, &mechs);
+           return GSS_S_BAD_MECH;
     }
+    gss_release_oid_set(&junk, &mechs);
+
+    ret = gss_duplicate_oid(minor_status,
+                           &oid, /* possibly this should be oidp */
+                           mech_p);
 
     if (verify_p) {
        gss_name_t name = GSS_C_NO_NAME;
@@ -635,9 +640,6 @@ acceptor_start
        if (ctx->mech_src_name != GSS_C_NO_NAME)
            gss_release_name(&junk, &ctx->mech_src_name);
        
-       if (ctx->delegated_cred_id != GSS_C_NO_CREDENTIAL)
-           _gss_spnego_release_cred(&junk, &ctx->delegated_cred_id);
-       
        ret = gss_accept_sec_context(minor_status,
                                     &ctx->negotiated_ctx_id,
                                     mech_cred,
@@ -649,19 +651,20 @@ acceptor_start
                                     &ctx->mech_flags,
                                     &ctx->mech_time_rec,
                                     &mech_delegated_cred);
+
+       if (mech_delegated_cred && delegated_cred_handle) {
+           _gss_spnego_alloc_cred(&junk,
+                                  mech_delegated_cred,
+                                  delegated_cred_handle);
+       } else if (mech_delegated_cred != GSS_C_NO_CREDENTIAL)
+           gss_release_cred(&junk, &mech_delegated_cred);
+
        if (ret == GSS_S_COMPLETE || ret == GSS_S_CONTINUE_NEEDED) {
            ctx->preferred_mech_type = preferred_mech_type;
            ctx->negotiated_mech_type = preferred_mech_type;
            if (ret == GSS_S_COMPLETE)
                ctx->open = 1;
 
-           if (mech_delegated_cred && delegated_cred_handle)
-               ret = _gss_spnego_alloc_cred(&junk,
-                                            mech_delegated_cred,
-                                            delegated_cred_handle);
-           else
-               gss_release_cred(&junk, &mech_delegated_cred);
-
            ret = acceptor_complete(minor_status,
                                    ctx,
                                    &get_mic,
@@ -740,10 +743,6 @@ out:
                *src_name = (gss_name_t)name;
            }
        }
-        if (delegated_cred_handle != NULL) {
-           *delegated_cred_handle = ctx->delegated_cred_id;
-           ctx->delegated_cred_id = GSS_C_NO_CREDENTIAL;
-       }
     }
     
     if (mech_type != NULL)
@@ -780,7 +779,7 @@ acceptor_continue
            gss_cred_id_t *delegated_cred_handle
           )
 {
-    OM_uint32 ret, ret2, minor;
+    OM_uint32 ret, ret2, minor, junk;
     NegotiationToken nt;
     size_t nt_len;
     NegTokenResp *na;
@@ -836,27 +835,16 @@ acceptor_continue
 
        if (mech_input_token != GSS_C_NO_BUFFER) {
            gss_cred_id_t mech_cred;
-           gss_cred_id_t mech_delegated_cred;
-           gss_cred_id_t *mech_delegated_cred_p;
+           gss_cred_id_t mech_delegated_cred = GSS_C_NO_CREDENTIAL;
 
            if (acceptor_cred != NULL)
                mech_cred = acceptor_cred->negotiated_cred_id;
            else
                mech_cred = GSS_C_NO_CREDENTIAL;
 
-           if (delegated_cred_handle != NULL) {
-               mech_delegated_cred = GSS_C_NO_CREDENTIAL;
-               mech_delegated_cred_p = &mech_delegated_cred;
-           } else {
-               mech_delegated_cred_p = NULL;
-           }
-
            if (ctx->mech_src_name != GSS_C_NO_NAME)
                gss_release_name(&minor, &ctx->mech_src_name);
 
-           if (ctx->delegated_cred_id != GSS_C_NO_CREDENTIAL)
-               _gss_spnego_release_cred(&minor, &ctx->delegated_cred_id);
-
            ret = gss_accept_sec_context(&minor,
                                         &ctx->negotiated_ctx_id,
                                         mech_cred,
@@ -867,16 +855,16 @@ acceptor_continue
                                         &obuf,
                                         &ctx->mech_flags,
                                         &ctx->mech_time_rec,
-                                        mech_delegated_cred_p);
+                                        &mech_delegated_cred);
+
+           if (mech_delegated_cred && delegated_cred_handle) {
+               _gss_spnego_alloc_cred(&junk,
+                                      mech_delegated_cred,
+                                      delegated_cred_handle);
+           } else if (mech_delegated_cred != GSS_C_NO_CREDENTIAL)
+               gss_release_cred(&junk, &mech_delegated_cred);
+
            if (ret == GSS_S_COMPLETE || ret == GSS_S_CONTINUE_NEEDED) {
-               if (mech_delegated_cred_p != NULL &&
-                   mech_delegated_cred != GSS_C_NO_CREDENTIAL) {
-                   ret2 = _gss_spnego_alloc_cred(minor_status,
-                                                 mech_delegated_cred,
-                                                 &ctx->delegated_cred_id);
-                   if (ret2 != GSS_S_COMPLETE)
-                       ret = ret2;
-               }
                mech_output_token = &obuf;
            }
            if (ret != GSS_S_COMPLETE && ret != GSS_S_CONTINUE_NEEDED) {
@@ -958,10 +946,6 @@ acceptor_continue
                *src_name = (gss_name_t)name;
            }
        }
-        if (delegated_cred_handle != NULL) {
-           *delegated_cred_handle = ctx->delegated_cred_id;
-           ctx->delegated_cred_id = GSS_C_NO_CREDENTIAL;
-       }
     }
 
     if (mech_type != NULL)
index 287f4f760ed76871241cf41d1dd5404f4dca07c0..36de854784c3f0c77f9eb7572038627ae46ce3ee 100644 (file)
@@ -32,7 +32,7 @@
 
 #include "spnego/spnego_locl.h"
 
-RCSID("$Id: compat.c 21866 2007-08-08 11:31:29Z lha $");
+RCSID("$Id: compat.c 22688 2008-03-16 11:33:58Z lha $");
 
 /*
  * Apparently Microsoft got the OID wrong, and used
@@ -76,7 +76,6 @@ OM_uint32 _gss_spnego_alloc_sec_context (OM_uint32 * minor_status,
     ctx->mech_flags = 0;
     ctx->mech_time_rec = 0;
     ctx->mech_src_name = GSS_C_NO_NAME;
-    ctx->delegated_cred_id = GSS_C_NO_CREDENTIAL;
 
     ctx->open = 0;
     ctx->local = 0;
@@ -124,8 +123,6 @@ OM_uint32 _gss_spnego_internal_delete_sec_context
     if (ctx->initiator_mech_types.val != NULL)
        free_MechTypeList(&ctx->initiator_mech_types);
 
-    _gss_spnego_release_cred(&minor, &ctx->delegated_cred_id);
-
     gss_release_oid(&minor, &ctx->preferred_mech_type);
     ctx->negotiated_mech_type = GSS_C_NO_OID;
 
index 0169017ee5af9de3bff86d5b3db2fad233ee76ac..6f1c3eb4b6f493e4050c46e0ff5b3b007a5f82a6 100644 (file)
@@ -32,7 +32,7 @@
 
 #include "spnego/spnego_locl.h"
 
-RCSID("$Id: context_stubs.c 22604 2008-02-21 21:12:48Z lha $");
+RCSID("$Id: context_stubs.c 22688 2008-03-16 11:33:58Z lha $");
 
 static OM_uint32
 spnego_supported_mechs(OM_uint32 *minor_status, gss_OID_set *mechs)
@@ -907,7 +907,7 @@ OM_uint32 _gss_spnego_set_sec_context_option
        return GSS_S_NO_CONTEXT;
     }
 
-    ctx = (gssspnego_ctx)context_handle;
+    ctx = (gssspnego_ctx)*context_handle;
 
     if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
        return GSS_S_NO_CONTEXT;
@@ -919,3 +919,31 @@ OM_uint32 _gss_spnego_set_sec_context_option
                                      value);
 }
 
+
+OM_uint32
+_gss_spnego_pseudo_random(OM_uint32 *minor_status,
+                         gss_ctx_id_t context_handle,
+                         int prf_key,
+                         const gss_buffer_t prf_in,
+                         ssize_t desired_output_len,
+                         gss_buffer_t prf_out)
+{
+    gssspnego_ctx ctx;
+
+    *minor_status = 0;
+
+    if (context_handle == GSS_C_NO_CONTEXT)
+       return GSS_S_NO_CONTEXT;
+
+    ctx = (gssspnego_ctx)context_handle;
+
+    if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT)
+       return GSS_S_NO_CONTEXT;
+
+    return gss_pseudo_random(minor_status,
+                            ctx->negotiated_ctx_id,
+                            prf_key,
+                            prf_in,
+                            desired_output_len,
+                            prf_out);
+}
index 2362e99019633ed88cddc1c608ad1907a09ec59c..d87d7d618e77684e35e2bcd84ef4e57933e09e9d 100644 (file)
@@ -32,7 +32,7 @@
 
 #include "spnego/spnego_locl.h"
 
-RCSID("$Id: cred_stubs.c 20619 2007-05-08 13:43:45Z lha $");
+RCSID("$Id: cred_stubs.c 22688 2008-03-16 11:33:58Z lha $");
 
 OM_uint32
 _gss_spnego_release_cred(OM_uint32 *minor_status, gss_cred_id_t *cred_handle)
@@ -334,3 +334,23 @@ OM_uint32 _gss_spnego_inquire_cred_by_oid
     return ret;
 }
 
+OM_uint32
+_gss_spnego_set_cred_option (OM_uint32 *minor_status,
+                            gss_cred_id_t *cred_handle,
+                            const gss_OID object,
+                            const gss_buffer_t value)
+{
+    gssspnego_cred cred;
+
+    if (cred_handle == NULL || *cred_handle == GSS_C_NO_CREDENTIAL) {
+       *minor_status = 0;
+       return GSS_S_NO_CRED;
+    }
+
+    cred = (gssspnego_cred)*cred_handle;
+    return gss_set_cred_option(minor_status,
+                             &cred->negotiated_cred_id,
+                             object,
+                             value);
+}
+
index 6c9a03a3b0042c66f7c81115310ebfc353da5089..317d358707269c92a67f625c5061dbae29401c38 100644 (file)
@@ -33,7 +33,7 @@
 #include "spnego/spnego_locl.h"
 #include <gssapi_mech.h>
 
-RCSID("$Id: external.c 22600 2008-02-21 12:46:24Z lha $");
+RCSID("$Id: external.c 22688 2008-03-16 11:33:58Z lha $");
 
 /*
  * RFC2478, SPNEGO:
@@ -57,8 +57,8 @@ static gssapi_mech_interface_desc spnego_mech = {
     _gss_spnego_verify_mic,
     _gss_spnego_wrap,
     _gss_spnego_unwrap,
-    NULL,
-    NULL,
+    NULL, /* gm_display_status */
+    NULL, /* gm_indicate_mechs */
     _gss_spnego_compare_name,
     _gss_spnego_display_name,
     _gss_spnego_import_name,
@@ -74,7 +74,12 @@ static gssapi_mech_interface_desc spnego_mech = {
     _gss_spnego_inquire_names_for_mech,
     _gss_spnego_inquire_mechs_for_name,
     _gss_spnego_canonicalize_name,
-    _gss_spnego_duplicate_name
+    _gss_spnego_duplicate_name,
+    _gss_spnego_inquire_sec_context_by_oid,
+    _gss_spnego_inquire_cred_by_oid,
+    _gss_spnego_set_sec_context_option,
+    _gss_spnego_set_cred_option,
+    _gss_spnego_pseudo_random
 };
 
 gssapi_mech_interface
index 69f4d8423d24e63aa911b0689b5b1e73ecc3f275..3b20d737b72adf8bc87aaaa5096e02f56f6e2bb9 100644 (file)
@@ -224,6 +224,15 @@ _gss_spnego_process_context_token (
        const gss_ctx_id_t /*context_handle*/,
        const gss_buffer_t token_buffer );
 
+OM_uint32
+_gss_spnego_pseudo_random (
+       OM_uint32 */*minor_status*/,
+       gss_ctx_id_t /*context_handle*/,
+       int /*prf_key*/,
+       const gss_buffer_t /*prf_in*/,
+       ssize_t /*desired_output_len*/,
+       gss_buffer_t /*prf_out*/);
+
 OM_uint32
 _gss_spnego_release_cred (
        OM_uint32 */*minor_status*/,
@@ -250,6 +259,13 @@ _gss_spnego_seal (
        int * /*conf_state*/,
        gss_buffer_t output_message_buffer );
 
+OM_uint32
+_gss_spnego_set_cred_option (
+       OM_uint32 */*minor_status*/,
+       gss_cred_id_t */*cred_handle*/,
+       const gss_OID /*object*/,
+       const gss_buffer_t /*value*/);
+
 OM_uint32
 _gss_spnego_set_sec_context_option (
        OM_uint32 * /*minor_status*/,
index 44b24688e18ff639119fba1c259b3ebb3dbe9bb5..6eb808efbc277dcdcbe1afe62c6351d2bed4bba0 100644 (file)
@@ -30,7 +30,7 @@
  * SUCH DAMAGE.
  */
 
-/* $Id: spnego_locl.h 19411 2006-12-18 15:42:03Z lha $ */
+/* $Id: spnego_locl.h 23161 2008-05-05 09:56:20Z lha $ */
 
 #ifndef SPNEGO_LOCL_H
 #define SPNEGO_LOCL_H
@@ -86,7 +86,6 @@ typedef struct {
        OM_uint32               mech_flags;
        OM_uint32               mech_time_rec;
        gss_name_t              mech_src_name;
-       gss_cred_id_t           delegated_cred_id;
        unsigned int            open : 1;
        unsigned int            local : 1;
        unsigned int            require_mic : 1;
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
index e91d8e7..eeba5c9
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
-/* $Id: aes.h 17450 2006-05-05 11:11:43Z lha $ */
+/* $Id: aes.h 22958 2008-04-11 11:33:22Z lha $ */
 
 #ifndef HEIM_AES_H
 #define HEIM_AES_H 1
@@ -58,6 +58,10 @@ typedef struct aes_key {
     int rounds;
 } AES_KEY;
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 int AES_set_encrypt_key(const unsigned char *, const int, AES_KEY *);
 int AES_set_decrypt_key(const unsigned char *, const int, AES_KEY *);
 
@@ -68,4 +72,8 @@ void AES_cbc_encrypt(const unsigned char *, unsigned char *,
                     const unsigned long, const AES_KEY *,
                     unsigned char *, int);
 
+#ifdef  __cplusplus
+}
+#endif
+
 #endif /* HEIM_AES_H */
index 6076478bbb04bdddc9ef612e4bdd0d521924c4a1..1f8c1d5471f63ff979cee4cf47197b4ef7a8a3ce 100644 (file)
@@ -35,7 +35,7 @@
 #include <config.h>
 #endif
 
-RCSID("$Id: bn.c 22261 2007-12-09 06:24:18Z lha $");
+RCSID("$Id: bn.c 22850 2008-04-07 18:49:01Z lha $");
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -297,13 +297,13 @@ BN_set_word(BIGNUM *bn, unsigned long num)
     for (num2 = num, i = 0; num2 > 0; i++)
        num2 = num2 >> 8;
 
-    len = i - 1;
+    len = i;
     for (; i > 0; i--) {
        p[i - 1] = (num & 0xff);
        num = num >> 8;
     }
 
-    bn = BN_bin2bn(p, len + 1, bn);
+    bn = BN_bin2bn(p, len, bn);
     return bn != NULL;
 }
 
index c32c406baaa96b238e2f2ee2cfff25e124e7305d..80fc49aef9c572052db2958273c9a6120560cf89 100644 (file)
  *  http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html
  */
 
+
 #include <string.h>
 #include <stdlib.h>
 
-#include "camellia.h"
-
-/* u32 must be 32bit word */
-typedef unsigned int u32;
-typedef unsigned char u8;
+#include <krb5-types.h>
+#include "camellia-ntt.h"
 
 /* key constants */
 
@@ -444,7 +442,7 @@ static const u32 camellia_sp4404[256] = {
 #define subl(x) subL[(x)]
 #define subr(x) subR[(x)]
 
-void camellia_setup128(const unsigned char *key, u32 *subkey)
+static void camellia_setup128(const unsigned char *key, u32 *subkey)
 {
     u32 kll, klr, krl, krr;
     u32 il, ir, t0, t1, w0, w1;
@@ -655,7 +653,7 @@ void camellia_setup128(const unsigned char *key, u32 *subkey)
     return;
 }
 
-void camellia_setup256(const unsigned char *key, u32 *subkey)
+static void camellia_setup256(const unsigned char *key, u32 *subkey)
 {
     u32 kll,klr,krl,krr;           /* left half of key */
     u32 krll,krlr,krrl,krrr;       /* right half of key */
@@ -941,7 +939,7 @@ void camellia_setup256(const unsigned char *key, u32 *subkey)
     return;
 }
 
-void camellia_setup192(const unsigned char *key, u32 *subkey)
+static void camellia_setup192(const unsigned char *key, u32 *subkey)
 {
     unsigned char kk[32];
     u32 krll, krlr, krrl,krrr;
@@ -963,7 +961,7 @@ void camellia_setup192(const unsigned char *key, u32 *subkey)
  *
  * "io" must be 4byte aligned and big-endian data.
  */
-void camellia_encrypt128(const u32 *subkey, u32 *io)
+static void camellia_encrypt128(const u32 *subkey, u32 *io)
 {
     u32 il, ir, t0, t1;
 
@@ -1053,7 +1051,7 @@ void camellia_encrypt128(const u32 *subkey, u32 *io)
     return;
 }
 
-void camellia_decrypt128(const u32 *subkey, u32 *io)
+static void camellia_decrypt128(const u32 *subkey, u32 *io)
 {
     u32 il,ir,t0,t1;               /* temporary valiables */
     
@@ -1146,7 +1144,7 @@ void camellia_decrypt128(const u32 *subkey, u32 *io)
 /**
  * stuff for 192 and 256bit encryption/decryption
  */
-void camellia_encrypt256(const u32 *subkey, u32 *io)
+static void camellia_encrypt256(const u32 *subkey, u32 *io)
 {
     u32 il,ir,t0,t1;           /* temporary valiables */
 
@@ -1260,7 +1258,7 @@ void camellia_encrypt256(const u32 *subkey, u32 *io)
     return;
 }
 
-void camellia_decrypt256(const u32 *subkey, u32 *io)
+static void camellia_decrypt256(const u32 *subkey, u32 *io)
 {
     u32 il,ir,t0,t1;           /* temporary valiables */
 
index 740ed8bfd9f4a0451b7a15ebfb6b4065e4bcdaf7..8356e3b31e873740099872bd561b388d341781ad 100644 (file)
@@ -29,7 +29,11 @@ extern "C" {
 #define CAMELLIA_TABLE_BYTE_LEN 272
 #define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / 4)
 
-typedef unsigned int KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN];
+/* u32 must be 32bit word */
+typedef uint32_t u32;
+typedef unsigned char u8;
+
+typedef u32 KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN];
 
 
 void Camellia_Ekeygen(const int keyBitLength,
index 3b21934b660d082d9cce9581d4d9e57bfa3ff937..f736f88b1e44f414956302ed5e264ed3ff40c81a 100644 (file)
@@ -36,9 +36,6 @@
 #ifndef HEIM_CAMELLIA_H
 #define HEIM_CAMELLIA_H 1
 
-#include <krb5-types.h>
-#include "camellia-ntt.h"
-
 /* symbol renaming */
 #define CAMELLIA_set_key hc_CAMELLIA_set_encrypt_key
 #define CAMELLIA_encrypt hc_CAMELLIA_encrypt
  */
 
 #define CAMELLIA_BLOCK_SIZE 16
-#define CAMELLIA_MAXNR 14
+#define CAMELLIA_TABLE_BYTE_LEN 272
+#define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / 4)
 
 #define CAMELLIA_ENCRYPT 1
 #define CAMELLIA_DECRYPT 0
 
 typedef struct camellia_key {
     unsigned int bits;
-    KEY_TABLE_TYPE key;
+    uint32_t key[CAMELLIA_TABLE_WORD_LEN];
 } CAMELLIA_KEY;
 
 int CAMELLIA_set_key(const unsigned char *, const int, CAMELLIA_KEY *);
index a4444a8a7c544e19adeb370c9b723a87efa65731..9e533dd708e6e8b3070cca18bd2dc10f1ed6a753 100644 (file)
  * SUCH DAMAGE.
  */
 
-/*
+/**
+ * @page page_des DES - Data Encryption Standard crypto interface
+ *
+ * See the library functions here: @ref hcrypto_des
+ *
+ * DES was created by IBM, modififed by NSA and then adopted by NBS
+ * (now NIST) and published ad FIPS PUB 46 (updated by FIPS 46-1).
+ *
+ * Since the 19th May 2005 DES was withdrawn by NIST and should no
+ * longer be used. See @ref page_evp for replacement encryption
+ * algorithms and interfaces.
+ *
+ * Read more the iteresting history of DES on Wikipedia
+ * http://www.wikipedia.org/wiki/Data_Encryption_Standard .
+ *
+ * @section des_keygen DES key generation
+ *
+ * To generate a DES key safely you have to use the code-snippet
+ * below. This is because the DES_random_key() can fail with an
+ * abort() in case of and failure to start the random generator.
+ *
+ * There is a replacement function DES_new_random_key(), however that
+ * function does not exists in OpenSSL.
+ *
+ * @code
+ * DES_cblock key;
+ * do {
+ *     if (RAND_rand(&key, sizeof(key)) != 1)
+ *          goto failure;
+ *     DES_set_odd_parity(key);
+ * } while (DES_is_weak_key(&key));
+ * @endcode
+ *
+ * @section des_impl DES implementation history
+ *
+ * There was no complete BSD licensed, fast, GPL compatible
+ * implementation of DES, so Love wrote the part that was missing,
+ * fast key schedule setup and adapted the interface to the orignal
+ * libdes.
+ *
  * The document that got me started for real was "Efficient
  * Implementation of the Data Encryption Standard" by Dag Arne Osvik.
  * I never got to the PC1 transformation was working, instead I used
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
-RCSID("$Id: des.c 17211 2006-04-24 14:26:19Z lha $");
+RCSID("$Id: des.c 23117 2008-04-28 10:29:36Z lha $");
 #endif
 
+#define HC_DEPRECATED
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -70,17 +111,39 @@ static void FP(uint32_t [2]);
        x = ( ((x)<<(2)) & 0xffffffc) | ((x) >> 26);    \
     }
 
-/*
+/**
+ * Set the parity of the key block, used to generate a des key from a
+ * random key. See @ref des_keygen.
  *
+ * @param key key to fixup the parity for.
+ * @ingroup hcrypto_des
  */
 
-int
+void
 DES_set_odd_parity(DES_cblock *key)
 {
-    int i;
+    unsigned int i;
     for (i = 0; i < DES_CBLOCK_LEN; i++)
        (*key)[i] = odd_parity[(*key)[i]];
-    return 0;
+}
+
+/**
+ * Check if the key have correct parity.
+ *
+ * @param key key to check the parity.
+ * @return 1 on success, 0 on failure.
+ * @ingroup hcrypto_des
+ */
+
+int HC_DEPRECATED
+DES_check_key_parity(DES_cblock *key)
+{
+    unsigned int i;
+
+    for (i = 0; i <  DES_CBLOCK_LEN; i++)
+       if ((*key)[i] != odd_parity[(*key)[i]])
+           return 0;
+    return 1;
 }
 
 /*
@@ -107,6 +170,16 @@ static DES_cblock weak_keys[] = {
     {0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1}
 };
 
+/**
+ * Checks if the key is any of the weaks keys that makes DES attacks
+ * trival.
+ *
+ * @param key key to check.
+ *
+ * @return 1 if the key is weak, 0 otherwise.
+ * @ingroup hcrypto_des
+ */
+
 int
 DES_is_weak_key(DES_cblock *key)
 {
@@ -119,13 +192,38 @@ DES_is_weak_key(DES_cblock *key)
     return 0;
 }
 
+/**
+ * Setup a des key schedule from a key. Deprecated function, use
+ * DES_set_key_unchecked() or DES_set_key_checked() instead.
+ *
+ * @param key a key to initialize the key schedule with.
+ * @param ks a key schedule to initialize.
+ *
+ * @return 0 on success
+ * @ingroup hcrypto_des
+ */
 
-/*
+int HC_DEPRECATED
+DES_set_key(DES_cblock *key, DES_key_schedule *ks)
+{
+    return DES_set_key_checked(key, ks);
+}
+
+/**
+ * Setup a des key schedule from a key. The key is no longer needed
+ * after this transaction and can cleared.
  *
+ * Does NOT check that the key is weak for or have wrong parity.
+ *
+ * @param key a key to initialize the key schedule with.
+ * @param ks a key schedule to initialize.
+ *
+ * @return 0 on success
+ * @ingroup hcrypto_des
  */
 
 int
-DES_set_key(DES_cblock *key, DES_key_schedule *ks)
+DES_set_key_unchecked(DES_cblock *key, DES_key_schedule *ks)
 {
     uint32_t t1, t2;
     uint32_t c, d;
@@ -184,28 +282,46 @@ DES_set_key(DES_cblock *key, DES_key_schedule *ks)
     return 0;
 }
 
-/*
+/**
+ * Just like DES_set_key_unchecked() except checking that the key is
+ * not weak for or have correct parity.
+ *
+ * @param key a key to initialize the key schedule with.
+ * @param ks a key schedule to initialize.
  *
+ * @return 0 on success, -1 on invalid parity, -2 on weak key.
+ * @ingroup hcrypto_des
  */
 
 int
 DES_set_key_checked(DES_cblock *key, DES_key_schedule *ks)
 {
+    if (!DES_check_key_parity(key)) {
+       memset(ks, 0, sizeof(*ks));
+       return -1;
+    }
     if (DES_is_weak_key(key)) {
        memset(ks, 0, sizeof(*ks));
-       return 1;
+       return -2;
     }
-    return DES_set_key(key, ks);
+    return DES_set_key_unchecked(key, ks);
 }
 
-/*
- * Compatibility function for eay libdes
+/**
+ * Compatibility function for eay libdes, works just like
+ * DES_set_key_checked().
+ *
+ * @param key a key to initialize the key schedule with.
+ * @param ks a key schedule to initialize.
+ *
+ * @return 0 on success, -1 on invalid parity, -2 on weak key.
+ * @ingroup hcrypto_des
  */
 
 int
 DES_key_sched(DES_cblock *key, DES_key_schedule *ks)
 {
-    return DES_set_key(key, ks);
+    return DES_set_key_checked(key, ks);
 }
 
 /*
@@ -238,39 +354,63 @@ store(const uint32_t v[2], unsigned char *b)
     b[7] = (v[1] >>  0) & 0xff;
 }
 
-/*
+/**
+ * Encrypt/decrypt a block using DES. Also called ECB mode
+ *
+ * @param u data to encrypt
+ * @param ks key schedule to use
+ * @param encp if non zero, encrypt. if zero, decrypt.
  *
+ * @ingroup hcrypto_des
  */
 
 void
-DES_encrypt(uint32_t u[2], DES_key_schedule *ks, int forward_encrypt)
+DES_encrypt(uint32_t u[2], DES_key_schedule *ks, int encp)
 {
     IP(u);
-    desx(u, ks, forward_encrypt);
+    desx(u, ks, encp);
     FP(u);
 }
 
-/*
+/**
+ * Encrypt/decrypt a block using DES.
  *
+ * @param input data to encrypt
+ * @param output data to encrypt
+ * @param ks key schedule to use
+ * @param encp if non zero, encrypt. if zero, decrypt.
+ *
+ * @ingroup hcrypto_des
  */
 
 void
 DES_ecb_encrypt(DES_cblock *input, DES_cblock *output,
-               DES_key_schedule *ks, int forward_encrypt)
+               DES_key_schedule *ks, int encp)
 {
     uint32_t u[2];
     load(*input, u);
-    DES_encrypt(u, ks, forward_encrypt);
+    DES_encrypt(u, ks, encp);
     store(u, *output);
 }
 
-/*
+/**
+ * Encrypt/decrypt a block using DES in Chain Block Cipher mode (cbc).
  *
+ * The IV must always be diffrent for diffrent input data blocks.
+ *
+ * @param in data to encrypt
+ * @param out data to encrypt
+ * @param length length of data
+ * @param ks key schedule to use
+ * @param iv initial vector to use
+ * @param encp if non zero, encrypt. if zero, decrypt.
+ *
+ * @ingroup hcrypto_des
  */
 
 void
 DES_cbc_encrypt(const void *in, void *out, long length,
-               DES_key_schedule *ks, DES_cblock *iv, int forward_encrypt)
+               DES_key_schedule *ks, DES_cblock *iv, int encp)
 {
     const unsigned char *input = in;
     unsigned char *output = out;
@@ -279,7 +419,7 @@ DES_cbc_encrypt(const void *in, void *out, long length,
 
     load(*iv, uiv);
 
-    if (forward_encrypt) {
+    if (encp) {
        while (length >= DES_CBLOCK_LEN) {
            load(input, u);
            u[0] ^= uiv[0]; u[1] ^= uiv[1];
@@ -327,13 +467,26 @@ DES_cbc_encrypt(const void *in, void *out, long length,
     uiv[0] = 0; u[0] = 0; uiv[1] = 0; u[1] = 0;
 }
 
-/*
+/**
+ * Encrypt/decrypt a block using DES in Propagating Cipher Block
+ * Chaining mode. This mode is only used for Kerberos 4, and it should
+ * stay that way.
+ *
+ * The IV must always be diffrent for diffrent input data blocks.
  *
+ * @param in data to encrypt
+ * @param out data to encrypt
+ * @param length length of data
+ * @param ks key schedule to use
+ * @param iv initial vector to use
+ * @param encp if non zero, encrypt. if zero, decrypt.
+ *
+ * @ingroup hcrypto_des
  */
 
 void
 DES_pcbc_encrypt(const void *in, void *out, long length,
-                DES_key_schedule *ks, DES_cblock *iv, int forward_encrypt)
+                DES_key_schedule *ks, DES_cblock *iv, int encp)
 {
     const unsigned char *input = in;
     unsigned char *output = out;
@@ -342,7 +495,7 @@ DES_pcbc_encrypt(const void *in, void *out, long length,
 
     load(*iv, uiv);
 
-    if (forward_encrypt) {
+    if (encp) {
        uint32_t t[2];
        while (length >= DES_CBLOCK_LEN) {
            load(input, u);
@@ -397,10 +550,10 @@ DES_pcbc_encrypt(const void *in, void *out, long length,
 
 static void
 _des3_encrypt(uint32_t u[2], DES_key_schedule *ks1, DES_key_schedule *ks2, 
-             DES_key_schedule *ks3, int forward_encrypt)
+             DES_key_schedule *ks3, int encp)
 {
     IP(u);
-    if (forward_encrypt) {
+    if (encp) {
        desx(u, ks1, 1); /* IP + FP cancel out each other */
        desx(u, ks2, 0);
        desx(u, ks3, 1);
@@ -412,8 +565,18 @@ _des3_encrypt(uint32_t u[2], DES_key_schedule *ks1, DES_key_schedule *ks2,
     FP(u);
 }
 
-/*
+/**
+ * Encrypt/decrypt a block using triple DES using EDE mode,
+ * encrypt/decrypt/encrypt.
+ *
+ * @param input data to encrypt
+ * @param output data to encrypt
+ * @param ks1 key schedule to use
+ * @param ks2 key schedule to use
+ * @param ks3 key schedule to use
+ * @param encp if non zero, encrypt. if zero, decrypt.
  *
+ * @ingroup hcrypto_des
  */
 
 void
@@ -422,24 +585,37 @@ DES_ecb3_encrypt(DES_cblock *input,
                 DES_key_schedule *ks1,
                 DES_key_schedule *ks2,
                 DES_key_schedule *ks3,
-                int forward_encrypt)
+                int encp)
 {
     uint32_t u[2];
     load(*input, u);
-    _des3_encrypt(u, ks1, ks2, ks3, forward_encrypt);
+    _des3_encrypt(u, ks1, ks2, ks3, encp);
     store(u, *output);
     return;
 }
 
-/*
+/**
+ * Encrypt/decrypt using Triple DES in Chain Block Cipher mode (cbc).
+ *
+ * The IV must always be diffrent for diffrent input data blocks.
  *
+ * @param in data to encrypt
+ * @param out data to encrypt
+ * @param length length of data
+ * @param ks1 key schedule to use
+ * @param ks2 key schedule to use
+ * @param ks3 key schedule to use
+ * @param iv initial vector to use
+ * @param encp if non zero, encrypt. if zero, decrypt.
+ *
+ * @ingroup hcrypto_des
  */
 
 void
 DES_ede3_cbc_encrypt(const void *in, void *out,
                     long length, DES_key_schedule *ks1, 
                     DES_key_schedule *ks2, DES_key_schedule *ks3,
-                    DES_cblock *iv, int forward_encrypt)
+                    DES_cblock *iv, int encp)
 {
     const unsigned char *input = in;
     unsigned char *output = out;
@@ -448,7 +624,7 @@ DES_ede3_cbc_encrypt(const void *in, void *out,
 
     load(*iv, uiv);
 
-    if (forward_encrypt) {
+    if (encp) {
        while (length >= DES_CBLOCK_LEN) {
            load(input, u);
            u[0] ^= uiv[0]; u[1] ^= uiv[1];
@@ -497,14 +673,27 @@ DES_ede3_cbc_encrypt(const void *in, void *out,
     uiv[0] = 0; u[0] = 0; uiv[1] = 0; u[1] = 0;
 }
 
-/*
+/**
+ * Encrypt/decrypt using DES in cipher feedback mode with 64 bit
+ * feedback.
+ *
+ * The IV must always be diffrent for diffrent input data blocks.
+ *
+ * @param in data to encrypt
+ * @param out data to encrypt
+ * @param length length of data
+ * @param ks key schedule to use
+ * @param iv initial vector to use
+ * @param num offset into in cipher block encryption/decryption stop last time.
+ * @param encp if non zero, encrypt. if zero, decrypt.
  *
+ * @ingroup hcrypto_des
  */
 
 void
 DES_cfb64_encrypt(const void *in, void *out, 
                  long length, DES_key_schedule *ks, DES_cblock *iv,
-                 int *num, int forward_encrypt)
+                 int *num, int encp)
 {
     const unsigned char *input = in;
     unsigned char *output = out;
@@ -515,7 +704,7 @@ DES_cfb64_encrypt(const void *in, void *out,
 
     assert(*num >= 0 && *num < DES_CBLOCK_LEN);
 
-    if (forward_encrypt) {
+    if (encp) {
        int i = *num;
 
        while (length > 0) {
@@ -562,8 +751,19 @@ DES_cfb64_encrypt(const void *in, void *out,
     }
 }
 
-/*
+/**
+ * Crete a checksum using DES in CBC encryption mode. This mode is
+ * only used for Kerberos 4, and it should stay that way.
+ *
+ * The IV must always be diffrent for diffrent input data blocks.
+ *
+ * @param in data to checksum
+ * @param output the checksum
+ * @param length length of data
+ * @param ks key schedule to use
+ * @param iv initial vector to use
  *
+ * @ingroup hcrypto_des
  */
 
 uint32_t
@@ -616,6 +816,16 @@ bitswap8(unsigned char b)
     return r;
 }
 
+/**
+ * Convert a string to a DES key. Use something like
+ * PKCS5_PBKDF2_HMAC_SHA1() to create key from passwords.
+ *
+ * @param str The string to convert to a key
+ * @param key the resulting key
+ *
+ * @ingroup hcrypto_des
+ */
+
 void
 DES_string_to_key(const char *str, DES_cblock *key)
 {
@@ -646,8 +856,16 @@ DES_string_to_key(const char *str, DES_cblock *key)
        k[7] ^= 0xF0;
 }
 
-/*
+/**
+ * Read password from prompt and create a DES key. Internal uses
+ * DES_string_to_key(). Really, go use a really string2key function
+ * like PKCS5_PBKDF2_HMAC_SHA1().
+ *
+ * @param key key to convert to
+ * @param prompt prompt to display user
+ * @param verify prompt twice.
  *
+ * @return 1 on success, non 1 on failure.
  */
 
 int
@@ -657,7 +875,7 @@ DES_read_password(DES_cblock *key, char *prompt, int verify)
     int ret;
 
     ret = UI_UTIL_read_pw_string(buf, sizeof(buf) - 1, prompt, verify);
-    if (ret == 0)
+    if (ret == 1)
        DES_string_to_key(buf, key);
     return ret;
 }
@@ -892,7 +1110,7 @@ FP(uint32_t v[2])
 }
 
 static void
-desx(uint32_t block[2], DES_key_schedule *ks, int forward_encrypt)
+desx(uint32_t block[2], DES_key_schedule *ks, int encp)
 {
     uint32_t *keys;
     uint32_t fval, work, right, left;
@@ -901,7 +1119,7 @@ desx(uint32_t block[2], DES_key_schedule *ks, int forward_encrypt)
     left = block[0];
     right = block[1];
 
-    if (forward_encrypt) {
+    if (encp) {
        keys = &ks->ks[0];
 
        for( round = 0; round < 8; round++ ) {
index ac8deb8ab8449538cb65cab67d10e56b6c98647f..3c52f59e289d28887e4f969d7a2907dca93cb1b7 100644 (file)
  * SUCH DAMAGE.
  */
 
-/* $Id: des.h 16480 2006-01-08 21:47:29Z lha $ */
+/* $Id: des.h 23148 2008-04-29 05:53:27Z biorn $ */
 
 #ifndef _DESperate_H
 #define _DESperate_H 1
 
 /* symbol renaming */
-#define DES_set_odd_parity hc_DES_set_odd_parity
+#define        _DES_ipfp_test _hc_DES_ipfp_test
+#define DES_cbc_cksum hc_DES_cbc_cksum
+#define DES_cbc_encrypt hc_DES_cbc_encrypt
+#define DES_cfb64_encrypt hc_DES_cfb64_encrypt
+#define DES_check_key_parity hc_DES_check_key_parity
+#define DES_ecb3_encrypt hc_DES_ecb3_encrypt
+#define DES_ecb_encrypt hc_DES_ecb_encrypt
+#define DES_ede3_cbc_encrypt hc_DES_ede3_cbc_encrypt
+#define DES_encrypt hc_DES_encrypt
+#define DES_generate_random_block hc_DES_generate_random_block
+#define DES_init_random_number_generator hc_DES_init_random_number_generator
 #define DES_is_weak_key hc_DES_is_weak_key
 #define DES_key_sched hc_DES_key_sched
+#define DES_new_random_key hc_DES_new_random_key
+#define DES_pcbc_encrypt hc_DES_pcbc_encrypt
+#define DES_rand_data hc_DES_rand_data
+#define DES_random_key hc_DES_random_key
+#define DES_read_password hc_DES_read_password
 #define DES_set_key hc_DES_set_key
 #define DES_set_key_checked hc_DES_set_key_checked
+#define DES_set_key_unchecked hc_DES_set_key_unchecked
 #define DES_set_key_sched hc_DES_set_key_sched
-#define DES_new_random_key hc_DES_new_random_key
-#define DES_string_to_key hc_DES_string_to_key
-#define DES_read_password hc_DES_read_password
-#define DES_rand_data hc_DES_rand_data
+#define DES_set_odd_parity hc_DES_set_odd_parity
 #define DES_set_random_generator_seed hc_DES_set_random_generator_seed
-#define DES_generate_random_block hc_DES_generate_random_block
 #define DES_set_sequence_number hc_DES_set_sequence_number
-#define DES_init_random_number_generator hc_DES_init_random_number_generator
-#define DES_random_key hc_DES_random_key
-#define DES_encrypt hc_DES_encrypt
-#define DES_ecb_encrypt hc_DES_ecb_encrypt
-#define DES_ecb3_encrypt hc_DES_ecb3_encrypt
-#define DES_pcbc_encrypt hc_DES_pcbc_encrypt
-#define DES_cbc_encrypt hc_DES_cbc_encrypt
-#define DES_cbc_cksum hc_DES_cbc_cksum
-#define DES_ede3_cbc_encrypt hc_DES_ede3_cbc_encrypt
-#define DES_cfb64_encrypt hc_DES_cfb64_encrypt
-#define        _DES_ipfp_test _hc_DES_ipfp_test
+#define DES_string_to_key hc_DES_string_to_key
 
 /*
  *
@@ -82,21 +84,35 @@ typedef struct DES_key_schedule
  *
  */
 
-int    DES_set_odd_parity(DES_cblock *);
+#if !defined(__GNUC__) && !defined(__attribute__)
+#define __attribute__(x)
+#endif
+
+#ifndef HC_DEPRECATED
+#define HC_DEPRECATED __attribute__((deprecated))
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void   DES_set_odd_parity(DES_cblock *);
+int    DES_check_key_parity(DES_cblock *);
 int    DES_is_weak_key(DES_cblock *);
-int    DES_set_key(DES_cblock *, DES_key_schedule *);
+int    HC_DEPRECATED DES_set_key(DES_cblock *, DES_key_schedule *);
 int    DES_set_key_checked(DES_cblock *, DES_key_schedule *);
+int    DES_set_key_unchecked(DES_cblock *, DES_key_schedule *);
 int    DES_key_sched(DES_cblock *, DES_key_schedule *);
-int    DES_new_random_key(DES_cblock *);
 void   DES_string_to_key(const char *, DES_cblock *);
 int    DES_read_password(DES_cblock *, char *, int);
 
-void   DES_rand_data(void *, int);
-void   DES_set_random_generator_seed(DES_cblock *);
-void   DES_generate_random_block(DES_cblock *);
-void   DES_set_sequence_number(void *);
-void   DES_init_random_number_generator(DES_cblock *);
-void   DES_random_key(DES_cblock *);
+void   HC_DEPRECATED DES_rand_data(void *, int);
+void   HC_DEPRECATED DES_set_random_generator_seed(DES_cblock *);
+void   HC_DEPRECATED DES_generate_random_block(DES_cblock *);
+void   HC_DEPRECATED DES_set_sequence_number(void *);
+void   HC_DEPRECATED DES_init_random_number_generator(DES_cblock *);
+void   HC_DEPRECATED DES_random_key(DES_cblock *);
+int    HC_DEPRECATED DES_new_random_key(DES_cblock *);
 
 
 void   DES_encrypt(uint32_t [2], DES_key_schedule *, int);
@@ -110,8 +126,8 @@ void        DES_cbc_encrypt(const void *, void *, long,
 void   DES_ede3_cbc_encrypt(const void *, void *, long, 
                             DES_key_schedule *, DES_key_schedule *, 
                             DES_key_schedule *, DES_cblock *, int);
-void DES_cfb64_encrypt(const void *, void *, long,
-                      DES_key_schedule *, DES_cblock *, int *, int);
+void   DES_cfb64_encrypt(const void *, void *, long,
+                         DES_key_schedule *, DES_cblock *, int *, int);
 
 
 uint32_t DES_cbc_cksum(const void *, DES_cblock *,
@@ -120,5 +136,9 @@ uint32_t DES_cbc_cksum(const void *, DES_cblock *,
 
 void   _DES_ipfp_test(void);
 
+#ifdef  __cplusplus
+}
+#endif
+
 
 #endif /* _DESperate_H */
index 788000b05489e2fecc7b82ce03acb914103c3963..b4fb8a7f2302bc580f96a50452d01461c4ee18a0 100644 (file)
@@ -35,7 +35,9 @@
 #include <config.h>
 #endif
 
-RCSID("$Id: evp.c 22379 2007-12-29 11:13:26Z lha $");
+RCSID("$Id: evp.c 23144 2008-04-29 05:47:16Z lha $");
+
+#define HC_DEPRECATED
 
 #include <sys/types.h>
 #include <stdio.h>
@@ -79,6 +81,13 @@ struct hc_evp_md {
     evp_md_cleanup cleanup;
 };
 
+struct hc_EVP_MD_CTX {
+    const EVP_MD *md;
+    ENGINE *engine;
+    void *ptr;
+};
+
+
 /**
  * Return the output size of the message digest function.
  *
@@ -135,7 +144,7 @@ EVP_MD_CTX_create(void)
  * @ingroup hcrypto_evp
  */
 
-void
+void HC_DEPRECATED
 EVP_MD_CTX_init(EVP_MD_CTX *ctx)
 {
     memset(ctx, 0, sizeof(*ctx));
@@ -166,7 +175,7 @@ EVP_MD_CTX_destroy(EVP_MD_CTX *ctx)
  * @ingroup hcrypto_evp
  */
 
-int
+int HC_DEPRECATED
 EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
 {
     if (ctx->md && ctx->md->cleanup)
@@ -508,7 +517,6 @@ EVP_md_null(void)
 }
 
 #if 0
-void   EVP_MD_CTX_init(EVP_MD_CTX *ctx);
 int    EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type);
 int    EVP_DigestFinal(EVP_MD_CTX *ctx,unsigned char *md,unsigned int *s);
 int    EVP_SignFinal(EVP_MD_CTX *, void *, size_t *, EVP_PKEY *);
@@ -1050,10 +1058,19 @@ des_ede3_cbc_init(EVP_CIPHER_CTX *ctx,
                  int encp)
 {
     struct des_ede3_cbc *k = ctx->cipher_data;
+    DES_cblock deskey;
+
+    memcpy(&deskey, key, sizeof(deskey));
+    DES_set_odd_parity(&deskey);
+    DES_set_key_unchecked(&deskey, &k->ks[0]);
+
+    memcpy(&deskey, key + 8, sizeof(deskey));
+    DES_set_odd_parity(&deskey);
+    DES_set_key_unchecked(&deskey, &k->ks[1]);
 
-    DES_key_sched((DES_cblock *)(key), &k->ks[0]);
-    DES_key_sched((DES_cblock *)(key + 8), &k->ks[1]);
-    DES_key_sched((DES_cblock *)(key + 16), &k->ks[2]);
+    memcpy(&deskey, key + 16, sizeof(deskey));
+    DES_set_odd_parity(&deskey);
+    DES_set_key_unchecked(&deskey, &k->ks[2]);
 
     return 1;
 }
index 4910ca01b8df87736e53e3fa079e6b6617e6f3cd..c8f8f80f800f9b22d9d59cbacb6859a995b0f920 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
-/* $Id: evp.h 21687 2007-07-24 16:29:05Z lha $ */
+/* $Id: evp.h 23141 2008-04-29 05:47:04Z lha $ */
 
 #ifndef HEIM_EVP_H
 #define HEIM_EVP_H 1
@@ -155,11 +155,17 @@ struct hc_CIPHER_CTX {
     unsigned char final[EVP_MAX_BLOCK_LENGTH];
 };
 
-struct hc_EVP_MD_CTX {
-    const EVP_MD *md;
-    ENGINE *engine;
-    void *ptr;
-};
+#if !defined(__GNUC__) && !defined(__attribute__)
+#define __attribute__(x)
+#endif
+
+#ifndef HC_DEPRECATED
+#define HC_DEPRECATED __attribute__((deprecated))
+#endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
 
 /*
  * Avaible crypto algs
@@ -201,9 +207,9 @@ size_t      EVP_MD_CTX_block_size(EVP_MD_CTX *);
 
 EVP_MD_CTX *
        EVP_MD_CTX_create(void);
-void   EVP_MD_CTX_init(EVP_MD_CTX *);
+void   HC_DEPRECATED EVP_MD_CTX_init(EVP_MD_CTX *);
 void   EVP_MD_CTX_destroy(EVP_MD_CTX *);
-int    EVP_MD_CTX_cleanup(EVP_MD_CTX *);
+int    HC_DEPRECATED EVP_MD_CTX_cleanup(EVP_MD_CTX *);
 
 int    EVP_DigestInit_ex(EVP_MD_CTX *, const EVP_MD *, ENGINE *);
 int    EVP_DigestUpdate(EVP_MD_CTX *,const void *, size_t);
@@ -258,4 +264,8 @@ void        OpenSSL_add_all_algorithms(void);
 void   OpenSSL_add_all_algorithms_conf(void);
 void   OpenSSL_add_all_algorithms_noconf(void);
 
+#ifdef  __cplusplus
+}
+#endif
+
 #endif /* HEIM_EVP_H */
index cecfb114040d738b929cc493b6b8994a8ca5016c..53dd364c2b06369edff3dbaca82358a0f3a8d573 100644 (file)
@@ -1,4 +1,4 @@
-IMath is Copyright 2002-2006 Michael J. Fromberger
+IMath is Copyright 2002-2007 Michael J. Fromberger
 You may use it subject to the following Licensing Terms:
 
 Permission is hereby granted, free of charge, to any person obtaining
index b43fe571d6c8ea8b606f6fc88f78905d64cbabc6..fcf04a73c169720ea3c17aac9cc6f99d4ea45913 100644 (file)
@@ -35,7 +35,7 @@
 #include <config.h>
 #endif
 
-RCSID("$Id: pkcs12.c 21155 2007-06-18 21:59:44Z lha $");
+RCSID("$Id: pkcs12.c 23137 2008-04-29 05:46:48Z lha $");
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -55,19 +55,24 @@ PKCS12_key_gen(const void *key, size_t keylen,
     unsigned char *v, *I, hash[EVP_MAX_MD_SIZE];
     unsigned int size, size_I = 0;
     unsigned char idc = id;
-    EVP_MD_CTX ctx;
+    EVP_MD_CTX *ctx;
     unsigned char *outp = out;
     int i, vlen;
 
-    EVP_MD_CTX_init(&ctx);
+    ctx = EVP_MD_CTX_create();
+    if (ctx == NULL)
+       return 0;
 
     vlen = EVP_MD_block_size(md);
     v = malloc(vlen + 1);
-    if (v == NULL)
+    if (v == NULL) {
+       EVP_MD_CTX_destroy(ctx);
        return 0;
+    }
 
     I = calloc(1, vlen * 2);
     if (I == NULL) {
+       EVP_MD_CTX_destroy(ctx);
        free(v);
        return 0;
     }
@@ -93,15 +98,16 @@ PKCS12_key_gen(const void *key, size_t keylen,
     while (1) {
        BIGNUM *bnB, *bnOne;
 
-       if (!EVP_DigestInit_ex(&ctx, md, NULL)) {
+       if (!EVP_DigestInit_ex(ctx, md, NULL)) {
+           EVP_MD_CTX_destroy(ctx);
            free(I);
            free(v);
            return 0;
        }
        for (i = 0; i < vlen; i++)
-           EVP_DigestUpdate(&ctx, &idc, 1);
-       EVP_DigestUpdate(&ctx, I, size_I);
-       EVP_DigestFinal_ex(&ctx, hash, &size);
+           EVP_DigestUpdate(ctx, &idc, 1);
+       EVP_DigestUpdate(ctx, I, size_I);
+       EVP_DigestFinal_ex(ctx, hash, &size);
 
        for (i = 1; i < iteration; i++)
            EVP_Digest(hash, size, hash, &size, md, NULL);
@@ -145,7 +151,7 @@ PKCS12_key_gen(const void *key, size_t keylen,
        size_I = vlen * 2;
     }
 
-    EVP_MD_CTX_cleanup(&ctx);
+    EVP_MD_CTX_destroy(ctx);
     free(I);
     free(v);
 
index 85b8713cba190fafad33d9b7bf55cf7d5b802bfd..8a8f948abb5abafb504810348d6ca5c716ce12d2 100644 (file)
@@ -35,7 +35,7 @@
 #include <config.h>
 #endif
 
-RCSID("$Id: pkcs5.c 17445 2006-05-05 10:37:46Z lha $");
+RCSID("$Id: pkcs5.c 23059 2008-04-18 13:04:08Z lha $");
 
 #ifdef KRB5
 #include <krb5-types.h>
@@ -49,6 +49,22 @@ RCSID("$Id: pkcs5.c 17445 2006-05-05 10:37:46Z lha $");
 
 #include <roken.h>
 
+/**
+ * As descriped in PKCS5, convert a password, salt, and iteration counter into a crypto key.
+ *
+ * @param password Password.
+ * @param password_len Length of password.
+ * @param salt Salt
+ * @param salt_len Length of salt.
+ * @param iter iteration counter.
+ * @param keylen the output key length.
+ * @param key the output key.
+ *
+ * @return 1 on success, non 1 on failure.
+ *
+ * @ingroup hcrypto_misc
+ */
+
 int
 PKCS5_PBKDF2_HMAC_SHA1(const void * password, size_t password_len,
                       const void * salt, size_t salt_len,
index 497a3ab5f805bc338b4d311e705276eccc8f16d7..c1f306bcc3dbdf1f818135ac7e125ac1f50c1e43 100644 (file)
@@ -35,7 +35,7 @@
 #include <config.h>
 #endif
 
-RCSID("$Id: rand-egd.c 21156 2007-06-18 22:00:59Z lha $");
+RCSID("$Id: rand-egd.c 23461 2008-07-27 12:14:20Z lha $");
 
 #include <sys/types.h>
 #ifdef HAVE_SYS_UN_H
@@ -76,6 +76,8 @@ connect_egd(const char *path)
     if (fd < 0)
        return -1;
 
+    rk_cloexec(fd);
+
     if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) != 0) {
        close(fd);
        return -1;
index 1d47ed49cc3521649cfef5c7c789a45659e2405b..da59a433b17f70c74bfd7769131c5daf4e5c8b27 100644 (file)
@@ -33,7 +33,7 @@
 #include <config.h>
 #endif
 
-RCSID("$Id: rand-fortuna.c 21196 2007-06-20 05:08:58Z lha $");
+RCSID("$Id: rand-fortuna.c 23463 2008-07-27 12:15:06Z lha $");
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -118,6 +118,7 @@ struct fortuna_state
     unsigned           pool0_bytes;
     unsigned           rnd_pos;
     int                        tricks_done;
+    pid_t              pid;
 };
 typedef struct fortuna_state FState;
 
@@ -175,6 +176,7 @@ init_state(FState * st)
     memset(st, 0, sizeof(*st));
     for (i = 0; i < NUM_POOLS; i++)
        md_init(&st->pool[i]);
+    st->pid = getpid();
 }
 
 /*
@@ -276,6 +278,9 @@ reseed(FState * st)
     /* add old key into mix too */
     md_update(&key_md, st->key, BLOCK);
 
+    /* add pid to make output diverse after fork() */
+    md_update(&key_md, (const unsigned char *)&st->pid, sizeof(st->pid));
+
     /* now we have new key */
     md_result(&key_md, st->key);
 
@@ -384,6 +389,7 @@ extract_data(FState * st, unsigned count, unsigned char *dst)
 {
     unsigned   n;
     unsigned   block_nr = 0;
+    pid_t      pid = getpid();
 
     /* Should we reseed? */
     if (st->pool0_bytes >= POOL0_FILL || st->reseed_count == 0)
@@ -394,6 +400,12 @@ extract_data(FState * st, unsigned count, unsigned char *dst)
     if (!st->tricks_done)
        startup_tricks(st);
 
+    /* If we forked, force a reseed again */
+    if (pid != st->pid) {
+       st->pid = pid;
+       reseed(st);
+    }
+
     while (count > 0)
     {
        /* produce bytes */
@@ -493,6 +505,7 @@ fortuna_reseed(void)
        fd = open("/etc/shadow", O_RDONLY, 0);
        if (fd >= 0) {
            ssize_t n;
+           rk_cloexec(fd);
            /* add_entropy will hash the buf */
            while ((n = read(fd, (char *)u.shad, sizeof(u.shad))) > 0)
                add_entropy(&main_state, u.shad, sizeof(u.shad));
index 354492fb3db5d431ab82e6e1bbcfa0d9393180ee..5fb099d724604be175b4ba43583d6bd6b804e798 100644 (file)
@@ -35,7 +35,7 @@
 #include <config.h>
 #endif
 
-RCSID("$Id: rand-unix.c 20028 2007-01-21 09:54:56Z lha $");
+RCSID("$Id: rand-unix.c 23462 2008-07-27 12:14:42Z lha $");
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -63,8 +63,10 @@ get_device_fd(int flags)
 
     for(p = rnd_devices; *p; p++) {
        int fd = open(*p, flags | O_NDELAY);
-       if(fd >= 0)
+       if(fd >= 0) {
+           rk_cloexec(fd);
            return fd;
+       }
     }
     return -1;
 }
index 79dd39eb76609b197a5e50654ccad8f1e7d1eecb..1561f2ad3936b9bdcf27c1ed6762361d29ca5494 100644 (file)
@@ -35,7 +35,7 @@
 #include <config.h>
 #endif
 
-RCSID("$Id: rand.c 22199 2007-12-07 13:43:25Z lha $");
+RCSID("$Id: rand.c 23464 2008-07-27 12:15:21Z lha $");
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -48,8 +48,14 @@ RCSID("$Id: rand.c 22199 2007-12-07 13:43:25Z lha $");
 #define O_BINARY 0
 #endif
 
+/**
+ * @page page_rand RAND - random number
+ *
+ * See the library functions here: @ref hcrypto_rand
+ */
 
 const static RAND_METHOD *selected_meth = NULL;
+static ENGINE *selected_engine = NULL;
 
 static void
 init_method(void)
@@ -59,6 +65,16 @@ init_method(void)
     selected_meth = &hc_rand_fortuna_method;
 }
 
+/**
+ * Seed that random number generator. Secret material can securely be
+ * feed into the function, they will never be returned.
+ *
+ * @param indata seed data
+ * @param size length seed data
+ *
+ * @ingroup hcrypto_rand
+ */
+
 void
 RAND_seed(const void *indata, size_t size)
 {
@@ -66,6 +82,16 @@ RAND_seed(const void *indata, size_t size)
     (*selected_meth->seed)(indata, size);
 }
 
+/**
+ * Get a random block from the random generator, can be used for key material.
+ *
+ * @param outdata random data
+ * @param size length random data
+ *
+ * @return 1 on success, 0 on failure.
+ *
+ * @ingroup hcrypto_rand
+ */
 int
 RAND_bytes(void *outdata, size_t size)
 {
@@ -73,13 +99,39 @@ RAND_bytes(void *outdata, size_t size)
     return (*selected_meth->bytes)(outdata, size);
 }
 
+/**
+ * Reset and free memory used by the random generator.
+ *
+ * @ingroup hcrypto_rand
+ */
+
 void
 RAND_cleanup(void)
 {
-    init_method();
-    (*selected_meth->cleanup)();
+    const RAND_METHOD *meth = selected_meth;
+    ENGINE *engine = selected_engine;
+
+    selected_meth = NULL;
+    selected_engine = NULL;
+
+    if (meth)
+       (*meth->cleanup)();
+    if (engine)
+       ENGINE_finish(engine);
 }
 
+/**
+ * Seed that random number generator. Secret material can securely be
+ * feed into the function, they will never be returned.
+ *
+ * @param indata the input data.
+ * @param size size of in data.
+ * @param entropi entropi in data.
+ * 
+ *
+ * @ingroup hcrypto_rand
+ */
+
 void
 RAND_add(const void *indata, size_t size, double entropi)
 {
@@ -87,6 +139,17 @@ RAND_add(const void *indata, size_t size, double entropi)
     (*selected_meth->add)(indata, size, entropi);
 }
 
+/**
+ * Get a random block from the random generator, should NOT be used for key material.
+ *
+ * @param outdata random data
+ * @param size length random data
+ *
+ * @return 1 on success, 0 on failure.
+ *
+ * @ingroup hcrypto_rand
+ */
+
 int
 RAND_pseudo_bytes(void *outdata, size_t size)
 {
@@ -94,6 +157,14 @@ RAND_pseudo_bytes(void *outdata, size_t size)
     return (*selected_meth->pseudorand)(outdata, size);
 }
 
+/**
+ * Return status of the random generator
+ *
+ * @return 1 if the random generator can deliver random data.
+ *
+ * @ingroup hcrypto_rand
+ */
+
 int
 RAND_status(void)
 {
@@ -101,27 +172,92 @@ RAND_status(void)
     return (*selected_meth->status)();
 }
 
+/**
+ * Set the default random method.
+ *
+ * @param meth set the new default method.
+ *
+ * @return 1 on success.
+ *
+ * @ingroup hcrypto_rand
+ */
+
 int
 RAND_set_rand_method(const RAND_METHOD *meth)
 {
+    const RAND_METHOD *old = selected_meth;
     selected_meth = meth;
+    if (old)
+       (*old->cleanup)();
+    if (selected_engine) {
+       ENGINE_finish(selected_engine);
+       selected_engine = NULL;
+    }
     return 1;
 }
 
+/**
+ * Get the default random method.
+ *
+ * @ingroup hcrypto_rand
+ */
+
 const RAND_METHOD *
 RAND_get_rand_method(void)
 {
+    init_method();
     return selected_meth;
 }
 
+/**
+ * Set the default random method from engine.
+ *
+ * @param engine use engine, if NULL is passed it, old method and engine is cleared.
+ *
+ * @return 1 on success, 0 on failure.
+ *
+ * @ingroup hcrypto_rand
+ */
+
 int
 RAND_set_rand_engine(ENGINE *engine)
 {
+    const RAND_METHOD *meth, *old = selected_meth;
+
+    if (engine) {
+       ENGINE_up_ref(engine);
+       meth = ENGINE_get_RAND(engine);
+       if (meth == NULL) {
+           ENGINE_finish(engine);
+           return 0;
+       }
+    } else {
+       meth = NULL;
+    }
+
+    if (old)
+       (*old->cleanup)();
+
+    if (selected_engine)
+       ENGINE_finish(selected_engine);
+
+    selected_engine = engine;
+    selected_meth = meth;
+
     return 1;
 }
 
 #define RAND_FILE_SIZE 1024
 
+/**
+ * Load a a file and feed it into RAND_seed().
+ *
+ * @param filename name of file to read.
+ * @param size minimum size to read.
+ *
+ * @ingroup hcrypto_rand
+ */
+
 int
 RAND_load_file(const char *filename, size_t size)
 {
@@ -133,7 +269,7 @@ RAND_load_file(const char *filename, size_t size)
     fd = open(filename, O_RDONLY | O_BINARY, 0600);
     if (fd < 0)
        return 0;
-
+    rk_cloexec(fd);
     len = 0;
     while(len < size) {
        slen = read(fd, buf, sizeof(buf));
@@ -147,6 +283,15 @@ RAND_load_file(const char *filename, size_t size)
     return len ? 1 : 0;
 }
 
+/**
+ * Write of random numbers to a file to store for later initiation with RAND_load_file().
+ *
+ * @param filename name of file to write.
+ *
+ * @return 1 on success and non-one on failure.
+ * @ingroup hcrypto_rand
+ */
+
 int
 RAND_write_file(const char *filename)
 {
@@ -157,6 +302,7 @@ RAND_write_file(const char *filename)
     fd = open(filename, O_WRONLY | O_CREAT | O_BINARY, 0600);
     if (fd < 0)
        return 0;
+    rk_cloexec(fd);
 
     len = 0;
     while(len < RAND_FILE_SIZE) {
@@ -175,6 +321,18 @@ RAND_write_file(const char *filename)
     return res;
 }
 
+/**
+ * Return the default random state filename for a user to use for
+ * RAND_load_file(), and RAND_write_file().
+ *
+ * @param filename buffer to hold file name.
+ * @param size size of buffer filename.
+ *
+ * @return the buffer filename or NULL on failure.
+ *
+ * @ingroup hcrypto_rand
+ */
+
 const char *
 RAND_file_name(char *filename, size_t size)
 {
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
index a035b890b887385249e7e88bcf80f294146678a4..0fd64af3b5de48b08874e705f2373af96d90de39 100644 (file)
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 
-RCSID("$Id: rnd_keys.c 17445 2006-05-05 10:37:46Z lha $");
+RCSID("$Id: rnd_keys.c 23093 2008-04-27 18:49:51Z lha $");
 #endif
 
+#define HC_DEPRECATED
+
 #ifdef KRB5
 #include <krb5-types.h>
 #endif
 #include <des.h>
+#include <rand.h>
 
 #include <stdlib.h>
-#include <string.h>
-
-#ifdef TIME_WITH_SYS_TIME
-#include <sys/time.h>
-#include <time.h>
-#elif defined(HAVE_SYS_TIME_H)
-#include <sys/time.h>
-#else
-#include <time.h>
-#endif
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_IO_H
-#include <io.h>
-#endif
-
-#ifdef HAVE_SIGNAL_H
-#include <signal.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-
-/*
- * Generate "random" data by checksumming a file.
- *
- * Returns -1 if there were any problems with permissions or I/O
- * errors.
- */
-static
-int
-sumFile (const char *name, int len, void *res)
-{
-  uint32_t sum[2] = { 0, 0 };
-  uint32_t buf[1024*2];
-  int fd, i;
-
-  fd = open (name, 0);
-  if (fd < 0)
-    return -1;
-
-  while (len > 0)
-    {
-      int n = read(fd, buf, sizeof(buf));
-      if (n < 0)
-       {
-         close(fd);
-         return n;
-       }
-      for (i = 0; i < (n/sizeof(buf[0])); i++)
-       {
-         sum[0] += buf[i];
-         i++;
-         sum[1] += buf[i];
-       }
-      len -= n;
-    }
-  close (fd);
-  memcpy (res, &sum, sizeof(sum));
-  return 0;
-}
-
-#if 0
-static
-int
-md5sumFile (const char *name, int len, int32_t sum[4])
-{
-  int32_t buf[1024*2];
-  int fd, cnt;
-  struct md5 md5;
-
-  fd = open (name, 0);
-  if (fd < 0)
-    return -1;
-
-  md5_init(&md5);
-  while (len > 0)
-    {
-      int n = read(fd, buf, sizeof(buf));
-      if (n < 0)
-       {
-         close(fd);
-         return n;
-       }
-      md5_update(&md5, buf, n);
-      len -= n;
-    }
-  md5_finito(&md5, (unsigned char *)sum);
-  close (fd);
-  return 0;
-}
-#endif
-
-/*
- * Create a sequence of random 64 bit blocks.
- * The sequence is indexed with a long long and 
- * based on an initial des key used as a seed.
- */
-static DES_key_schedule sequence_seed;
-static uint32_t sequence_index[2];
-
-/* 
- * Random number generator based on ideas from truerand in cryptolib
- * as described on page 424 in Applied Cryptography 2 ed. by Bruce
- * Schneier.
- */
-
-static volatile int counter;
-static volatile unsigned char *gdata; /* Global data */
-static volatile int igdata;    /* Index into global data */
-static int gsize;
 
-#if !defined(WIN32) && !defined(__EMX__) && !defined(__OS2__) && !defined(__CYGWIN32__)
-/* Visual C++ 4.0 (Windows95/NT) */
+#undef __attribute__
+#define __attribute__(X)
 
-static
-RETSIGTYPE
-sigALRM(int sig)
-{
-    if (igdata < gsize)
-       gdata[igdata++] ^= counter & 0xff;
-
-#ifndef HAVE_SIGACTION
-    signal(SIGALRM, sigALRM); /* Reinstall SysV signal handler */
-#endif
-    SIGRETURN(0);
-}
-
-#endif
-
-#if !defined(HAVE_RANDOM) && defined(HAVE_RAND)
-#ifndef srandom
-#define srandom srand
-#endif
-#ifndef random
-#define random rand
-#endif
-#endif
-
-#if !defined(HAVE_SETITIMER) || defined(WIN32) || defined(__EMX__) || defined(__OS2__) || defined(__CYGWIN32__)
-static void
-des_not_rand_data(unsigned char *data, int size)
-{
-  int i;
-
-  srandom (time (NULL));
-
-  for(i = 0; i < size; ++i)
-    data[i] ^= random() % 0x100;
-}
-#endif
-
-#if !defined(WIN32) && !defined(__EMX__) && !defined(__OS2__) && !defined(__CYGWIN32__)
-
-#ifndef HAVE_SETITIMER
-static void
-pacemaker(struct timeval *tv)
-{
-    fd_set fds;
-    pid_t pid;
-    pid = getppid();
-    while(1){
-       FD_ZERO(&fds);
-       FD_SET(0, &fds);
-       select(1, &fds, NULL, NULL, tv);
-       kill(pid, SIGALRM);
-    }
-}
-#endif
-
-#ifdef HAVE_SIGACTION
-/* XXX ugly hack, should perhaps use function from roken */
-static RETSIGTYPE 
-(*fake_signal(int sig, RETSIGTYPE (*f)(int)))(int)
-{
-    struct sigaction sa, osa;
-    sa.sa_handler = f;
-    sa.sa_flags = 0;
-    sigemptyset(&sa.sa_mask);
-    sigaction(sig, &sa, &osa);
-    return osa.sa_handler;
-}
-#define signal(S, F) fake_signal((S), (F))
-#endif
-
-/*
- * Generate size bytes of "random" data using timed interrupts.
- * It takes about 40ms/byte random data.
- * It's not neccessary to be root to run it.
- */
-void
+void HC_DEPRECATED
 DES_rand_data(void *outdata, int size)
 {
-    unsigned char *data = outdata;
-    struct itimerval tv, otv;
-    RETSIGTYPE (*osa)(int);
-    int i, j;
-#ifndef HAVE_SETITIMER 
-    RETSIGTYPE (*ochld)(int);
-    pid_t pid;
-#endif
-    const char *rnd_devices[] = {"/dev/random",
-                          "/dev/srandom",
-                          "/dev/urandom",
-                          "/dev/arandom",
-                          NULL};
-    const char **p;
-
-    for(p = rnd_devices; *p; p++) {
-      int fd = open(*p, O_RDONLY | O_NDELAY);
-      
-      if(fd >= 0 && read(fd, data, size) == size) {
-       close(fd);
-       return;
-      }
-      close(fd);
-    }
-
-    /* Paranoia? Initialize data from /dev/mem if we can read it. */
-    if (size >= 8)
-      sumFile("/dev/mem", (1024*1024*2), data);
-
-    gdata = data;
-    gsize = size;
-    igdata = 0;
-
-    osa = signal(SIGALRM, sigALRM);
-  
-    /* Start timer */
-    tv.it_value.tv_sec = 0;
-    tv.it_value.tv_usec = 10 * 1000; /* 10 ms */
-    tv.it_interval = tv.it_value;
-#ifdef HAVE_SETITIMER
-    setitimer(ITIMER_REAL, &tv, &otv);
-#else
-    ochld = signal(SIGCHLD, SIG_IGN);
-    pid = fork();
-    if(pid == -1){
-       signal(SIGCHLD, ochld != SIG_ERR ? ochld : SIG_DFL);
-       des_not_rand_data(data, size);
-       return;
-    }
-    if(pid == 0)
-       pacemaker(&tv.it_interval);
-#endif
-
-    for(i = 0; i < 4; i++) {
-       for (igdata = 0; igdata < size;) /* igdata++ in sigALRM */
-           counter++;
-       for (j = 0; j < size; j++) /* Only use 2 bits each lap */
-           gdata[j] = (gdata[j]>>2) | (gdata[j]<<6);
-    }
-#ifdef HAVE_SETITIMER
-    setitimer(ITIMER_REAL, &otv, 0);
-#else
-    kill(pid, SIGKILL);
-    while(waitpid(pid, NULL, 0) != pid);
-    signal(SIGCHLD, ochld != SIG_ERR ? ochld : SIG_DFL);
-#endif
-    signal(SIGALRM, osa != SIG_ERR ? osa : SIG_DFL);
-}
-#else
-void
-DES_rand_data(unsigned char *p, int s)
-{
-  des_not_rand_data (p, s);
+    RAND_bytes(outdata, size);
 }
-#endif
 
-void
+void HC_DEPRECATED
 DES_generate_random_block(DES_cblock *block)
 {
-  DES_rand_data((unsigned char *)block, sizeof(*block));
+    RAND_bytes(block, sizeof(*block));
 }
 
 #define DES_rand_data_key hc_DES_rand_data_key
 
-void
+void HC_DEPRECATED
 DES_rand_data_key(DES_cblock *key);
 
 /*
- * Generate a "random" DES key.
+ * Generate a random DES key.
  */
-void
-DES_rand_data_key(DES_cblock *key)
-{
-    unsigned char data[8];
-    DES_key_schedule sched;
-    do {
-       DES_rand_data(data, sizeof(data));
-       DES_rand_data((unsigned char*)key, sizeof(DES_cblock));
-       DES_set_odd_parity(key);
-       DES_set_key(key, &sched);
-       DES_ecb_encrypt(&data, key, &sched, DES_ENCRYPT);
-       memset(&data, 0, sizeof(data));
-       memset(&sched, 0, sizeof(sched));
-       DES_set_odd_parity(key);
-    } while(DES_is_weak_key(key));
-}
 
-/*
- * Generate "random" data by checksumming /dev/mem
- *
- * It's neccessary to be root to run it. Returns -1 if there were any
- * problems with permissions.
- */
-
-#define DES_mem_rand8 hc_DES_mem_rand8
-
-int
-DES_mem_rand8(unsigned char *data);
-
-int
-DES_mem_rand8(unsigned char *data)
-{
-  return 1;
-}
-
-/*
- * In case the generator does not get initialized use this as fallback.
- */
-static int initialized;
-
-static void
-do_initialize(void)
+void HC_DEPRECATED
+DES_rand_data_key(DES_cblock *key)
 {
-    DES_cblock default_seed;
-    do {
-       DES_generate_random_block(&default_seed);
-       DES_set_odd_parity(&default_seed);
-    } while (DES_is_weak_key(&default_seed));
-    DES_init_random_number_generator(&default_seed);
+    DES_new_random_key(key);
 }
 
-#define zero_long_long(ll) do { ll[0] = ll[1] = 0; } while (0)
-
-#define incr_long_long(ll) do { if (++ll[0] == 0) ++ll[1]; } while (0)
-
-#define set_sequence_number(ll) \
-memcpy((char *)sequence_index, (ll), sizeof(sequence_index));
-
-/*
- * Set the sequnce number to this value (a long long).
- */
-void
+void HC_DEPRECATED
 DES_set_sequence_number(void *ll)
 {
-    set_sequence_number(ll);
 }
 
-/*
- * Set the generator seed and reset the sequence number to 0.
- */
-void
+void HC_DEPRECATED
 DES_set_random_generator_seed(DES_cblock *seed)
 {
-    DES_set_key(seed, &sequence_seed);
-    zero_long_long(sequence_index);
-    initialized = 1;
+    RAND_seed(seed, sizeof(*seed));
 }
 
-/*
- * Generate a sequence of random des keys
- * using the random block sequence, fixup
- * parity and skip weak keys.
+/**
+ * Generate a random des key using a random block, fixup parity and
+ * skip weak keys.
+ *
+ * @param key is set to a random key.
+ *
+ * @return 0 on success, non zero on random number generator failure.
+ *
+ * @ingroup hcrypto_des
  */
-int
+
+int HC_DEPRECATED
 DES_new_random_key(DES_cblock *key)
 {
-    if (!initialized)
-       do_initialize();
-
     do {
-       DES_ecb_encrypt((DES_cblock *) sequence_index,
-                       key,
-                       &sequence_seed,
-                       DES_ENCRYPT);
-       incr_long_long(sequence_index);
-       /* random key must have odd parity and not be weak */
+       if (RAND_bytes(key, sizeof(*key)) != 1)
+           return 1;
        DES_set_odd_parity(key);
-    } while (DES_is_weak_key(key));
+    } while(DES_is_weak_key(key));
+
     return(0);
 }
 
-/*
- * des_init_random_number_generator:
+/**
+ * Seed the random number generator. Deprecated, use @ref page_rand
  *
- * Initialize the sequence of random 64 bit blocks.  The input seed
- * can be a secret key since it should be well hidden and is also not
- * kept.
+ * @param seed a seed to seed that random number generate with.
  *
+ * @ingroup hcrypto_des
  */
-void 
-DES_init_random_number_generator(DES_cblock *seed)
-{
-    struct timeval now;
-    DES_cblock uniq;
-    DES_cblock new_key;
 
-    gettimeofday(&now, (struct timezone *)0);
-    DES_generate_random_block(&uniq);
-
-    /* Pick a unique random key from the shared sequence. */
-    DES_set_random_generator_seed(seed);
-    set_sequence_number((unsigned char *)&uniq);
-    DES_new_random_key(&new_key);
-
-    /* Select a new nonshared sequence, */
-    DES_set_random_generator_seed(&new_key);
-
-    /* and use the current time to pick a key for the new sequence. */
-    set_sequence_number((unsigned char *)&now);
-    DES_new_random_key(&new_key);
-    DES_set_random_generator_seed(&new_key);
-}
-
-/* This is for backwards compatibility. */
-void
-DES_random_key(DES_cblock *ret)
+void HC_DEPRECATED
+DES_init_random_number_generator(DES_cblock *seed)
 {
-    DES_new_random_key(ret);
+    RAND_seed(seed, sizeof(*seed));
 }
 
-#ifdef TESTRUN
-int
-main()
-{
-    unsigned char data[8];
-    int i;
-
-    while (1)
-        {
-           if (sumFile("/dev/mem", (1024*1024*8), data) != 0)
-             { perror("sumFile"); exit(1); }
-            for (i = 0; i < 8; i++)
-                printf("%02x", data[i]);
-            printf("\n");
-        }
-}
-#endif
+/**
+ * Generate a random key, deprecated since it doesn't return an error
+ * code, use DES_new_random_key().
+ *
+ * @param key is set to a random key.
+ *
+ * @ingroup hcrypto_des
+ */
 
-#ifdef TESTRUN2
-int
-main()
+void HC_DEPRECATED
+DES_random_key(DES_cblock *key)
 {
-    DES_cblock data;
-    int i;
-
-    while (1)
-        {
-           do_initialize();
-            DES_random_key(data);
-            for (i = 0; i < 8; i++)
-                printf("%02x", data[i]);
-            printf("\n");
-        }
+    if (DES_new_random_key(key))
+       abort();
 }
-#endif
index 3e651998b535659fda01038cf53905729215e78c..8c3ea1fa156198e6804ba4ca778a52411e53f4ed 100644 (file)
@@ -33,7 +33,7 @@
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
-RCSID("$Id: ui.c 18158 2006-09-22 15:45:57Z lha $");
+RCSID("$Id: ui.c 23466 2008-07-27 12:16:15Z lha $");
 #endif
 
 #include <stdio.h>
@@ -84,7 +84,9 @@ read_string(const char *preprompt, const char *prompt,
            if (sigaction(i, &sa, &sigs[i]) == 0)
                oksigs[i] = 1;
 
-    if((tty = fopen("/dev/tty", "r")) == NULL)
+    if((tty = fopen("/dev/tty", "r")) != NULL)
+       rk_cloexec_file(tty);
+    else
        tty = stdin;
        
     fprintf(stderr, "%s%s", preprompt, prompt);
@@ -116,7 +118,7 @@ read_string(const char *preprompt, const char *prompt,
     *p = 0;
     
     if(echo == 0){
-       printf("\n");
+       fprintf(stderr, "\n");
        tcsetattr(fileno(tty), TCSANOW, &t_old);
     }
     
index 870f0431cf3a8d379177d72df039c6d465f98b92..cb282264310731129d4413aaa43e29c017443b11 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "hdb_locl.h"
 
-RCSID("$Id: db.c 20215 2007-02-09 21:59:53Z lha $");
+RCSID("$Id: db.c 23316 2008-06-23 04:32:32Z lha $");
 
 #if HAVE_DB1
 
@@ -68,8 +68,8 @@ DB_lock(krb5_context context, HDB *db, int operation)
     DB *d = (DB*)db->hdb_db;
     int fd = (*d->fd)(d);
     if(fd < 0) {
-       krb5_set_error_string(context,
-                             "Can't lock database: %s", db->hdb_name);
+       krb5_set_error_message(context, HDB_ERR_CANT_LOCK_DB,
+                              "Can't lock database: %s", db->hdb_name);
        return HDB_ERR_CANT_LOCK_DB;
     }
     return hdb_lock(fd, operation);
@@ -81,8 +81,8 @@ DB_unlock(krb5_context context, HDB *db)
     DB *d = (DB*)db->hdb_db;
     int fd = (*d->fd)(d);
     if(fd < 0) {
-       krb5_set_error_string(context, 
-                             "Can't unlock database: %s", db->hdb_name);
+       krb5_set_error_message(context, HDB_ERR_CANT_LOCK_DB,
+                              "Can't unlock database: %s", db->hdb_name);
        return HDB_ERR_CANT_LOCK_DB;
     }
     return hdb_unlock(fd);
@@ -100,15 +100,15 @@ DB_seq(krb5_context context, HDB *db,
 
     code = db->hdb_lock(context, db, HDB_RLOCK);
     if(code == -1) {
-       krb5_set_error_string(context, "Database %s in use", db->hdb_name);
+       krb5_set_error_message(context, HDB_ERR_DB_INUSE, "Database %s in use", db->hdb_name);
        return HDB_ERR_DB_INUSE;
     }
     code = (*d->seq)(d, &key, &value, flag);
     db->hdb_unlock(context, db); /* XXX check value */
     if(code == -1) {
        code = errno;
-       krb5_set_error_string(context, "Database %s seq error: %s", 
-                             db->hdb_name, strerror(code));
+       krb5_set_error_message(context, code, "Database %s seq error: %s", 
+                              db->hdb_name, strerror(code));
        return code;
     }
     if(code == 1) {
@@ -131,8 +131,8 @@ DB_seq(krb5_context context, HDB *db,
     if (code == 0 && entry->entry.principal == NULL) {
        entry->entry.principal = malloc(sizeof(*entry->entry.principal));
        if (entry->entry.principal == NULL) {
-           krb5_set_error_string(context, "malloc: out of memory");
            code = ENOMEM;
+           krb5_set_error_message(context, code, "malloc: out of memory");
            hdb_free_entry (context, entry);
        } else {
            hdb_key2principal(context, &key_data, entry->entry.principal);
@@ -190,8 +190,8 @@ DB__get(krb5_context context, HDB *db, krb5_data key, krb5_data *reply)
     db->hdb_unlock(context, db);
     if(code < 0) {
        code = errno;
-       krb5_set_error_string(context, "Database %s get error: %s", 
-                             db->hdb_name, strerror(code));
+       krb5_set_error_message(context, code, "Database %s get error: %s", 
+                              db->hdb_name, strerror(code));
        return code;
     }
     if(code == 1) {
@@ -222,8 +222,8 @@ DB__put(krb5_context context, HDB *db, int replace,
     db->hdb_unlock(context, db);
     if(code < 0) {
        code = errno;
-       krb5_set_error_string(context, "Database %s put error: %s", 
-                             db->hdb_name, strerror(code));
+       krb5_set_error_message(context, code, "Database %s put error: %s", 
+                              db->hdb_name, strerror(code));
        return code;
     }
     if(code == 1) {
@@ -248,8 +248,8 @@ DB__del(krb5_context context, HDB *db, krb5_data key)
     db->hdb_unlock(context, db);
     if(code == 1) {
        code = errno;
-       krb5_set_error_string(context, "Database %s put error: %s", 
-                             db->hdb_name, strerror(code));
+       krb5_set_error_message(context, code, "Database %s put error: %s", 
+                              db->hdb_name, strerror(code));
        return code;
     }
     if(code < 0)
@@ -265,7 +265,7 @@ DB_open(krb5_context context, HDB *db, int flags, mode_t mode)
 
     asprintf(&fn, "%s.db", db->hdb_name);
     if (fn == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     db->hdb_db = dbopen(fn, flags, mode, DB_BTREE, NULL);
@@ -275,7 +275,7 @@ DB_open(krb5_context context, HDB *db, int flags, mode_t mode)
        db->hdb_db = dbopen(db->hdb_name, flags, mode, DB_BTREE, NULL);
     if(db->hdb_db == NULL) {
        ret = errno;
-       krb5_set_error_string(context, "dbopen (%s): %s",
+       krb5_set_error_message(context, ret, "dbopen (%s): %s",
                              db->hdb_name, strerror(ret));
        return ret;
     }
@@ -289,7 +289,7 @@ DB_open(krb5_context context, HDB *db, int flags, mode_t mode)
     }
     if (ret) {
        DB_close(context, db);
-       krb5_set_error_string(context, "hdb_open: failed %s database %s",
+       krb5_set_error_message(context, ret, "hdb_open: failed %s database %s",
                              (flags & O_ACCMODE) == O_RDONLY ? 
                              "checking format of" : "initialize", 
                              db->hdb_name);
@@ -303,16 +303,16 @@ hdb_db_create(krb5_context context, HDB **db,
 {
     *db = calloc(1, sizeof(**db));
     if (*db == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
 
     (*db)->hdb_db = NULL;
     (*db)->hdb_name = strdup(filename);
     if ((*db)->hdb_name == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
        free(*db);
        *db = NULL;
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     (*db)->hdb_master_key_set = 0;
index d43e31b39ad3dc2ffe79664851bcaeea6a2a4aab..e99f72050dfbef56615d3147e818cb280b7f995f 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "hdb_locl.h"
 
-RCSID("$Id: dbinfo.c 22306 2007-12-14 12:22:38Z lha $");
+RCSID("$Id: dbinfo.c 23316 2008-06-23 04:32:32Z lha $");
 
 struct hdb_dbinfo {
     char *label;
@@ -63,7 +63,7 @@ get_dbinfo(krb5_context context,
 
     di = calloc(1, sizeof(*di));
     if (di == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     di->label = strdup(label);
index 5f60999946b819b99e78f9cd0c2fdc5fc8e68d62..30e15efb27509e07939751fd8eb50790b263401f 100644 (file)
@@ -34,7 +34,7 @@
 #include "hdb_locl.h"
 #include <der.h>
 
-RCSID("$Id: ext.c 21113 2007-06-18 12:59:32Z lha $");
+RCSID("$Id: ext.c 23316 2008-06-23 04:32:32Z lha $");
 
 krb5_error_code
 hdb_entry_check_mandatory(krb5_context context, const hdb_entry *ent)
@@ -53,8 +53,9 @@ hdb_entry_check_mandatory(krb5_context context, const hdb_entry *ent)
            choice_HDB_extension_data_asn1_ellipsis)
            continue;
        if (ent->extensions->val[i].mandatory) {
-           krb5_set_error_string(context,  "Principal have unknown "
-                                 "mandatory extension");
+           krb5_set_error_message(context, HDB_ERR_MANDATORY_OPTION,
+                                  "Principal have unknown "
+                                  "mandatory extension");
            return HDB_ERR_MANDATORY_OPTION;
        }
     }
@@ -95,7 +96,7 @@ hdb_replace_extension(krb5_context context,
     if (entry->extensions == NULL) {
        entry->extensions = calloc(1, sizeof(*entry->extensions));
        if (entry->extensions == NULL) {
-           krb5_set_error_string(context, "malloc: out of memory");
+           krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
            return ENOMEM;
        }
     } else if (ext->data.element != choice_HDB_extension_data_asn1_ellipsis) {
@@ -120,8 +121,8 @@ hdb_replace_extension(krb5_context context,
                          &replace_class, &replace_type, &replace_tag,
                          &size);
        if (ret) {
-           krb5_set_error_string(context, "hdb: failed to decode "
-                                 "replacement hdb extention");
+           krb5_set_error_message(context, ret, "hdb: failed to decode "
+                                  "replacement hdb extention");
            return ret;
        }
 
@@ -136,8 +137,8 @@ hdb_replace_extension(krb5_context context,
                              &list_class, &list_type, &list_tag,
                              &size);
            if (ret) {
-               krb5_set_error_string(context, "hdb: failed to decode "
-                                     "present hdb extention");
+               krb5_set_error_message(context, ret, "hdb: failed to decode "
+                                      "present hdb extention");
                return ret;
            }
 
@@ -153,15 +154,15 @@ hdb_replace_extension(krb5_context context,
        free_HDB_extension(ext2);
        ret = copy_HDB_extension(ext, ext2);
        if (ret)
-           krb5_set_error_string(context, "hdb: failed to copy replacement "
-                                 "hdb extention");
+           krb5_set_error_message(context, ret, "hdb: failed to copy replacement "
+                                  "hdb extention");
        return ret;
     }
 
     es = realloc(entry->extensions->val, 
                 (entry->extensions->len+1)*sizeof(entry->extensions->val[0]));
     if (es == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     entry->extensions->val = es;
@@ -171,7 +172,7 @@ hdb_replace_extension(krb5_context context,
     if (ret == 0)
        entry->extensions->len++;
     else
-       krb5_set_error_string(context, "hdb: failed to copy new extension");
+       krb5_set_error_message(context, ret, "hdb: failed to copy new extension");
 
     return ret;
 }
@@ -283,8 +284,9 @@ hdb_entry_get_password(krb5_context context, HDB *db,
                                       db->hdb_master_key);
 
            if (key == NULL) {
-               krb5_set_error_string(context, "master key %d missing",
-                                     *ext->data.u.password.mkvno);
+               krb5_set_error_message(context, HDB_ERR_NO_MKEY,
+                                      "master key %d missing",
+                                      *ext->data.u.password.mkvno);
                return HDB_ERR_NO_MKEY;
            }
 
@@ -302,7 +304,7 @@ hdb_entry_get_password(krb5_context context, HDB *db,
 
        str = pw.data;
        if (str[pw.length - 1] != '\0') {
-           krb5_set_error_string(context, "password malformated");
+           krb5_set_error_message(context, EINVAL, "password malformated");
            return EINVAL;
        }
 
@@ -310,7 +312,7 @@ hdb_entry_get_password(krb5_context context, HDB *db,
 
        der_free_octet_string(&pw);
        if (*p == NULL) {
-           krb5_set_error_string(context, "malloc: out of memory");
+           krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
            return ENOMEM;
        }
        return 0;
@@ -318,7 +320,7 @@ hdb_entry_get_password(krb5_context context, HDB *db,
 
     ret = krb5_unparse_name(context, entry->principal, &str);
     if (ret == 0) {
-       krb5_set_error_string(context, "no password attributefor %s", str);
+       krb5_set_error_message(context, ENOENT, "no password attributefor %s", str);
        free(str);
     } else 
        krb5_clear_error_string(context);
@@ -341,8 +343,9 @@ hdb_entry_set_password(krb5_context context, HDB *db,
 
        key = _hdb_find_master_key(NULL, db->hdb_master_key);
        if (key == NULL) {
-           krb5_set_error_string(context, "hdb_entry_set_password: "
-                                 "failed to find masterkey");
+           krb5_set_error_message(context, HDB_ERR_NO_MKEY,
+                                  "hdb_entry_set_password: "
+                                  "failed to find masterkey");
            return HDB_ERR_NO_MKEY;
        }
 
@@ -356,7 +359,7 @@ hdb_entry_set_password(krb5_context context, HDB *db,
            malloc(sizeof(*ext.data.u.password.mkvno));
        if (ext.data.u.password.mkvno == NULL) {
            free_HDB_extension(&ext);
-           krb5_set_error_string(context, "malloc: out of memory");
+           krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
            return ENOMEM;
        }
        *ext.data.u.password.mkvno = _hdb_mkey_version(key);
@@ -367,7 +370,7 @@ hdb_entry_set_password(krb5_context context, HDB *db,
        ret = krb5_data_copy(&ext.data.u.password.password, 
                             p, strlen(p) + 1);
        if (ret) {
-           krb5_set_error_string(context, "malloc: out of memory");
+           krb5_set_error_message(context, ret, "malloc: out of memory");
            free_HDB_extension(&ext);
            return ret;
        }
index f0731ed98eb8f8d2d01a7503d722f495d1b22aae..3da980a81f7ba47bbc514cb32b922c5c4c885f36 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "hdb_locl.h"
 
-RCSID("$Id: hdb.c 20214 2007-02-09 21:51:10Z lha $");
+RCSID("$Id: hdb.c 23316 2008-06-23 04:32:32Z lha $");
 
 #ifdef HAVE_DLFCN_H
 #include <dlfcn.h>
@@ -88,7 +88,8 @@ hdb_next_enctype2key(krb5_context context,
            return 0;
        }
     }
-    krb5_set_error_string(context, "No next enctype %d for hdb-entry", 
+    krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP,
+                          "No next enctype %d for hdb-entry", 
                          (int)enctype);
     return KRB5_PROG_ETYPE_NOSUPP; /* XXX */
 }
@@ -381,7 +382,7 @@ hdb_list_builtin(krb5_context context, char **list)
     len += 1;
     buf = malloc(len);
     if (buf == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     buf[0] = '\0';
index 60a58677fef99888d8e8c385619cbd438550a20d..e689ae102034e57bea5f7e0d179dc4144fffa35e 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "hdb_locl.h"
 
-RCSID("$Id: keys.c 22071 2007-11-14 20:04:50Z lha $");
+RCSID("$Id: keys.c 23316 2008-06-23 04:32:32Z lha $");
 
 /*
  * free all the memory used by (len, keys)
@@ -153,7 +153,7 @@ parse_key_set(krb5_context context, const char *key,
               v4 compat, and a cell name for afs compat */
            salt->saltvalue.data = strdup(buf[i]);
            if (salt->saltvalue.data == NULL) {
-               krb5_set_error_string(context, "out of memory");
+               krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
                return ENOMEM;
            }
            salt->saltvalue.length = strlen(buf[i]);
@@ -161,7 +161,7 @@ parse_key_set(krb5_context context, const char *key,
     }
     
     if(enctypes == NULL || salt->salttype == 0) {
-       krb5_set_error_string(context, "bad value for default_keys `%s'", key);
+       krb5_set_error_message(context, EINVAL, "bad value for default_keys `%s'", key);
        return EINVAL;
     }
     
@@ -173,8 +173,9 @@ parse_key_set(krb5_context context, const char *key,
            krb5_realm *realm = krb5_princ_realm(context, principal);
            salt->saltvalue.data = strdup(*realm);
            if(salt->saltvalue.data == NULL) {
-               krb5_set_error_string(context, "out of memory while "
-                                     "parsing salt specifiers");
+               krb5_set_error_message(context, ENOMEM,
+                                      "out of memory while "
+                                      "parsing salt specifiers");
                return ENOMEM;
            }
            strlwr(salt->saltvalue.data);
@@ -185,7 +186,7 @@ parse_key_set(krb5_context context, const char *key,
     *ret_enctypes = malloc(sizeof(enctypes[0]) * num_enctypes);
     if (*ret_enctypes == NULL) {
        krb5_free_salt(context, *salt);
-       krb5_set_error_string(context, "out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     memcpy(*ret_enctypes, enctypes, sizeof(enctypes[0]) * num_enctypes);
index 5c867daf20915d473d17732cfe6978264ae473e2..dc4ccf7678f50dd1ecb1cf3be580fc750d8c5f62 100644 (file)
@@ -35,7 +35,7 @@
 
 /* keytab backend for HDB databases */
 
-RCSID("$Id: keytab.c 18380 2006-10-09 12:36:40Z lha $");
+RCSID("$Id: keytab.c 23316 2008-06-23 04:32:32Z lha $");
 
 struct hdb_data {
     char *dbname;
@@ -55,7 +55,7 @@ hdb_resolve(krb5_context context, const char *name, krb5_keytab id)
 
     d = malloc(sizeof(*d));
     if(d == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     db = name;
@@ -67,7 +67,7 @@ hdb_resolve(krb5_context context, const char *name, krb5_keytab id)
            d->dbname = strdup(name);
            if(d->dbname == NULL) {
                free(d);
-               krb5_set_error_string(context, "malloc: out of memory");
+               krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
                return ENOMEM;
            }
        }
@@ -79,7 +79,7 @@ hdb_resolve(krb5_context context, const char *name, krb5_keytab id)
            d->dbname = malloc(mkey - db + 1);
            if(d->dbname == NULL) {
                free(d);
-               krb5_set_error_string(context, "malloc: out of memory");
+               krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
                return ENOMEM;
            }
            memmove(d->dbname, db, mkey - db);
@@ -89,7 +89,7 @@ hdb_resolve(krb5_context context, const char *name, krb5_keytab id)
        if(d->mkey == NULL) {
            free(d->dbname);
            free(d);
-           krb5_set_error_string(context, "malloc: out of memory");
+           krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
            return ENOMEM;
        }
     }
index 05cf71c59311c125d7bd09d1ed01f6d3667b69b5..04cb42388982b74e9cdd74e4d1347d3121ad90a7 100644 (file)
@@ -36,7 +36,7 @@
 #define O_BINARY 0
 #endif
 
-RCSID("$Id: mkey.c 21745 2007-07-31 16:11:25Z lha $");
+RCSID("$Id: mkey.c 23316 2008-06-23 04:32:32Z lha $");
 
 struct hdb_master_key_data {
     krb5_keytab_entry keytab;
@@ -67,7 +67,7 @@ hdb_process_master_key(krb5_context context,
 
     *mkey = calloc(1, sizeof(**mkey));
     if(*mkey == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     (*mkey)->keytab.vno = kvno;
@@ -159,8 +159,8 @@ read_master_mit(krb5_context context, const char *filename,
     fd = open(filename, O_RDONLY | O_BINARY);
     if(fd < 0) {
        int save_errno = errno;
-       krb5_set_error_string(context, "failed to open %s: %s", filename,
-                             strerror(save_errno));
+       krb5_set_error_message(context, save_errno, "failed to open %s: %s",
+                              filename, strerror(save_errno));
        return save_errno;
     }
     sp = krb5_storage_from_fd(fd);
@@ -176,9 +176,9 @@ read_master_mit(krb5_context context, const char *filename,
 #else
     ret = krb5_ret_int16(sp, &enctype);
     if((htons(enctype) & 0xff00) == 0x3000) {
-       krb5_set_error_string(context, "unknown keytype in %s: %#x, expected %#x", 
-                             filename, htons(enctype), 0x3000);
        ret = HEIM_ERR_BAD_MKEY;
+       krb5_set_error_message(context, ret, "unknown keytype in %s: %#x, expected %#x", 
+                              filename, htons(enctype), 0x3000);
        goto out;
     }
     key.keytype = enctype;
@@ -209,7 +209,7 @@ read_master_encryptionkey(krb5_context context, const char *filename,
     fd = open(filename, O_RDONLY | O_BINARY);
     if(fd < 0) {
        int save_errno = errno;
-       krb5_set_error_string(context, "failed to open %s: %s", 
+       krb5_set_error_message(context, save_errno, "failed to open %s: %s", 
                              filename, strerror(save_errno));
        return save_errno;
     }
@@ -218,7 +218,7 @@ read_master_encryptionkey(krb5_context context, const char *filename,
     close(fd);
     if(len < 0) {
        int save_errno = errno;
-       krb5_set_error_string(context, "error reading %s: %s", 
+       krb5_set_error_message(context, save_errno, "error reading %s: %s", 
                              filename, strerror(save_errno));
        return save_errno;
     }
@@ -255,8 +255,8 @@ read_master_krb4(krb5_context context, const char *filename,
     fd = open(filename, O_RDONLY | O_BINARY);
     if(fd < 0) {
        int save_errno = errno;
-       krb5_set_error_string(context, "failed to open %s: %s", 
-                             filename, strerror(save_errno));
+       krb5_set_error_message(context, save_errno, "failed to open %s: %s", 
+                              filename, strerror(save_errno));
        return save_errno;
     }
     
@@ -264,12 +264,13 @@ read_master_krb4(krb5_context context, const char *filename,
     close(fd);
     if(len < 0) {
        int save_errno = errno;
-       krb5_set_error_string(context, "error reading %s: %s", 
-                             filename, strerror(save_errno));
+       krb5_set_error_message(context, save_errno, "error reading %s: %s", 
+                              filename, strerror(save_errno));
        return save_errno;
     }
     if(len != 8) {
-       krb5_set_error_string(context, "bad contents of %s", filename);
+       krb5_set_error_message(context, HEIM_ERR_EOF, 
+                              "bad contents of %s", filename);
        return HEIM_ERR_EOF; /* XXX file might be too large */
     }
 
@@ -303,14 +304,14 @@ hdb_read_master_key(krb5_context context, const char *filename,
     f = fopen(filename, "r");
     if(f == NULL) {
        int save_errno = errno;
-       krb5_set_error_string(context, "failed to open %s: %s", 
-                             filename, strerror(save_errno));
+       krb5_set_error_message(context, save_errno, "failed to open %s: %s", 
+                              filename, strerror(save_errno));
        return save_errno;
     }
     
     if(fread(buf, 1, 2, f) != 2) {
-       krb5_set_error_string(context, "end of file reading %s", filename);
        fclose(f);
+       krb5_set_error_message(context, HEIM_ERR_EOF, "end of file reading %s", filename);
        return HEIM_ERR_EOF;
     }
     
index 6575b8a4171c75ee2ba06d005f06ae6e35119491..e1e8aacf87f9073b2e7cb5f9d4e182465be9b2f6 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "hdb_locl.h"
 
-RCSID("$Id: ndbm.c 16395 2005-12-13 11:54:10Z lha $");
+RCSID("$Id: ndbm.c 23316 2008-06-23 04:32:32Z lha $");
 
 #if HAVE_NDBM
 
@@ -110,9 +110,9 @@ NDBM_seq(krb5_context context, HDB *db,
     if (ret == 0 && entry->entry.principal == NULL) {
        entry->entry.principal = malloc (sizeof(*entry->entry.principal));
        if (entry->entry.principal == NULL) {
-           ret = ENOMEM;
            hdb_free_entry (context, entry);
-           krb5_set_error_string(context, "malloc: out of memory");
+           ret = ENOMEM;
+           krb5_set_error_message(context, ret, "malloc: out of memory");
        } else {
            hdb_key2principal (context, &key_data, entry->entry.principal);
        }
@@ -152,15 +152,15 @@ NDBM_rename(krb5_context context, HDB *db, const char *new_name)
     asprintf(&new_lock, "%s.lock", new_name);
     if(new_lock == NULL) {
        db->hdb_unlock(context, db);
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     lock_fd = open(new_lock, O_RDWR | O_CREAT, 0600);
     if(lock_fd < 0) {
        ret = errno;
        db->hdb_unlock(context, db);
-       krb5_set_error_string(context, "open(%s): %s", new_lock,
-                             strerror(ret));
+       krb5_set_error_message(context, ret, "open(%s): %s", new_lock,
+                              strerror(ret));
        free(new_lock);
        return ret;
     }
@@ -188,7 +188,7 @@ NDBM_rename(krb5_context context, HDB *db, const char *new_name)
     if(ret) {
        ret = errno;
        close(lock_fd);
-       krb5_set_error_string(context, "rename: %s", strerror(ret));
+       krb5_set_error_message(context, ret, "rename: %s", strerror(ret));
        return ret;
     }
 
@@ -284,13 +284,13 @@ NDBM_open(krb5_context context, HDB *db, int flags, mode_t mode)
     char *lock_file;
 
     if(d == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     asprintf(&lock_file, "%s.lock", (char*)db->hdb_name);
     if(lock_file == NULL) {
        free(d);
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     d->db = dbm_open((char*)db->hdb_name, flags, mode);
@@ -298,8 +298,8 @@ NDBM_open(krb5_context context, HDB *db, int flags, mode_t mode)
        ret = errno;
        free(d);
        free(lock_file);
-       krb5_set_error_string(context, "dbm_open(%s): %s", db->hdb_name,
-                             strerror(ret));
+       krb5_set_error_message(context, ret, "dbm_open(%s): %s", db->hdb_name,
+                              strerror(ret));
        return ret;
     }
     d->lock_fd = open(lock_file, O_RDWR | O_CREAT, 0600);
@@ -307,8 +307,8 @@ NDBM_open(krb5_context context, HDB *db, int flags, mode_t mode)
        ret = errno;
        dbm_close(d->db);
        free(d);
-       krb5_set_error_string(context, "open(%s): %s", lock_file,
-                             strerror(ret));
+       krb5_set_error_message(context, ret, "open(%s): %s", lock_file,
+                              strerror(ret));
        free(lock_file);
        return ret;
     }
@@ -322,10 +322,10 @@ NDBM_open(krb5_context context, HDB *db, int flags, mode_t mode)
        return 0;
     if (ret) {
        NDBM_close(context, db);
-       krb5_set_error_string(context, "hdb_open: failed %s database %s",
-                             (flags & O_ACCMODE) == O_RDONLY ? 
-                             "checking format of" : "initialize", 
-                             db->hdb_name);
+       krb5_set_error_message(context, ret, "hdb_open: failed %s database %s",
+                              (flags & O_ACCMODE) == O_RDONLY ? 
+                              "checking format of" : "initialize", 
+                              db->hdb_name);
     }
     return ret;
 }
@@ -336,16 +336,16 @@ hdb_ndbm_create(krb5_context context, HDB **db,
 {
     *db = calloc(1, sizeof(**db));
     if (*db == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
 
     (*db)->hdb_db = NULL;
     (*db)->hdb_name = strdup(filename);
     if ((*db)->hdb_name == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
        free(*db);
        *db = NULL;
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     (*db)->hdb_master_key_set = 0;
index 40260700b3fa2f7f734e7be948dda673bb776362..55374321ea500f9a51966b8a182ded0bee3afee1 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "hx_locl.h"
 #include <pkinit_asn1.h>
-RCSID("$Id: ca.c 22456 2008-01-15 20:22:53Z lha $");
+RCSID("$Id: ca.c 22995 2008-04-15 19:31:29Z lha $");
 
 /**
  * @page page_ca Hx509 CA functions
@@ -1225,7 +1225,7 @@ ca_sign(hx509_context context,
     {
        BasicConstraints bc;
        int aCA = 1;
-       uint32_t path;
+       unsigned int path;
 
        memset(&bc, 0, sizeof(bc));
 
index 09c85bc08413818cc4c9cd3cdf1937b940b326f1..3194526e3456ef36094a57ff2b0b6c9c400d1268 100644 (file)
@@ -32,7 +32,7 @@
  */
 
 #include "hx_locl.h"
-RCSID("$Id: cert.c 22583 2008-02-11 20:46:21Z lha $");
+RCSID("$Id: cert.c 23457 2008-07-27 12:12:56Z lha $");
 #include "crypto-headers.h"
 #include <rtbl.h>
 
@@ -138,7 +138,7 @@ hx509_context_init(hx509_context *context)
 
 /**
  * Selects if the hx509_revoke_verify() function is going to require
- * the existans of a revokation method (OSCP, CRL) or not. Note that
+ * the existans of a revokation method (OCSP, CRL) or not. Note that
  * hx509_verify_path(), hx509_cms_verify_signed(), and other function
  * call hx509_revoke_verify().
  * 
@@ -485,6 +485,12 @@ hx509_verify_set_time(hx509_verify_ctx ctx, time_t t)
     ctx->time_now = t;
 }
 
+time_t
+_hx509_verify_get_time(hx509_verify_ctx ctx)
+{
+    return ctx->time_now;
+}
+
 /**
  * Set the maximum depth of the certificate chain that the path
  * builder is going to try.
@@ -2355,7 +2361,7 @@ hx509_verify_hostname(hx509_context context,
     } while (1);
 
     {
-       Name *name = &cert->data->tbsCertificate.subject;
+       const Name *name = &cert->data->tbsCertificate.subject;
 
        /* match if first component is a CN= */
        if (name->u.rdnSequence.len > 0
@@ -2491,8 +2497,16 @@ hx509_cert_get_friendly_name(hx509_cert cert)
 
     a = hx509_cert_get_attribute(cert, oid_id_pkcs_9_at_friendlyName());
     if (a == NULL) {
-       /* XXX use subject name ? */
-       return NULL; 
+       hx509_name name;
+
+       ret = hx509_cert_get_subject(cert, &name);
+       if (ret)
+           return NULL;
+       ret = hx509_name_to_string(name, &cert->friendlyname);
+       hx509_name_free(&name);
+       if (ret)
+           return NULL;
+       return cert->friendlyname;
     }
 
     ret = decode_PKCS9_friendlyName(a->data.data, a->data.length, &n, &sz);
@@ -2548,6 +2562,7 @@ hx509_query_alloc(hx509_context context, hx509_query **q)
     return 0;
 }
 
+
 /**
  * Set match options for the hx509 query controller.
  *
@@ -2697,6 +2712,25 @@ hx509_query_match_eku(hx509_query *q, const heim_oid *eku)
     return 0;
 }
 
+int
+hx509_query_match_expr(hx509_context context, hx509_query *q, const char *expr)
+{
+    if (q->expr) {
+       _hx509_expr_free(q->expr);
+       q->expr = NULL;
+    }
+
+    if (expr == NULL) {
+       q->match &= ~HX509_QUERY_MATCH_EXPR;
+    } else {
+       q->expr = _hx509_expr_parse(expr);
+       if (q->expr)
+           q->match |= HX509_QUERY_MATCH_EXPR;
+    }
+
+    return 0;
+}
+
 /**
  * Set the query controller to match using a specific match function.
  *
@@ -2753,6 +2787,9 @@ hx509_query_free(hx509_context context, hx509_query *q)
     }
     if (q->friendlyname)
        free(q->friendlyname);
+    if (q->expr)
+       _hx509_expr_free(q->expr);
+
     memset(q, 0, sizeof(*q));
     free(q);
 }
@@ -2890,6 +2927,19 @@ _hx509_query_match_cert(hx509_context context, const hx509_query *q, hx509_cert
        hx509_cert_check_eku(context, cert, q->eku, 0))
        return 0;
 
+    if ((q->match & HX509_QUERY_MATCH_EXPR)) {
+       hx509_env env = NULL;
+
+       ret = _hx509_cert_to_env(context, cert, &env);
+       if (ret)
+           return 0;
+
+       ret = _hx509_expr_eval(context, env, q->expr);
+       hx509_env_free(&env);
+       if (ret == 0)
+           return 0;
+    }
+
     if (q->match & ~HX509_QUERY_MASK)
        return 0;
 
@@ -2922,6 +2972,7 @@ _hx509_query_statistic(hx509_context context, int type, const hx509_query *q)
     f = fopen(context->querystat, "a");
     if (f == NULL)
        return;
+    rk_cloexec_file(f);
     fprintf(f, "%d %d\n", type, q->match);
     fclose(f);
 }
@@ -2992,6 +3043,7 @@ hx509_query_unparse_stats(hx509_context context, int printtype, FILE *out)
                context->querystat, strerror(errno));
        return;
     }
+    rk_cloexec_file(f);
     
     for (i = 0; i < sizeof(stats)/sizeof(stats[0]); i++) {
        stats[i].index = i;
@@ -3206,3 +3258,103 @@ hx509_xfree(void *ptr)
 {
     free(ptr);
 }
+
+/**
+ *
+ */
+
+int
+_hx509_cert_to_env(hx509_context context, hx509_cert cert, hx509_env *env)
+{
+    ExtKeyUsage eku;
+    hx509_name name;
+    char *buf;
+    int ret;
+    hx509_env envcert = NULL;
+
+    *env = NULL;
+
+    /* version */
+    asprintf(&buf, "%d", _hx509_cert_get_version(_hx509_get_cert(cert)));
+    ret = hx509_env_add(context, &envcert, "version", buf);
+    free(buf);
+    if (ret)
+       goto out;
+
+    /* subject */
+    ret = hx509_cert_get_subject(cert, &name);
+    if (ret)
+       goto out;
+
+    ret = hx509_name_to_string(name, &buf);
+    if (ret) {
+       hx509_name_free(&name);
+       goto out;
+    }
+
+    ret = hx509_env_add(context, &envcert, "subject", buf);
+    hx509_name_free(&name);
+    if (ret)
+       goto out;
+
+    /* issuer */
+    ret = hx509_cert_get_issuer(cert, &name);
+    if (ret)
+       goto out;
+
+    ret = hx509_name_to_string(name, &buf);
+    hx509_name_free(&name);
+    if (ret)
+       goto out;
+
+    ret = hx509_env_add(context, &envcert, "issuer", buf);
+    hx509_xfree(buf);
+    if (ret)
+       goto out;
+
+    /* eku */
+
+    ret = _hx509_cert_get_eku(context, cert, &eku);
+    if (ret == HX509_EXTENSION_NOT_FOUND)
+       ;
+    else if (ret != 0)
+       goto out;
+    else {
+       int i;
+       hx509_env enveku = NULL;
+
+       for (i = 0; i < eku.len; i++) {
+
+           ret = der_print_heim_oid(&eku.val[i], '.', &buf);
+           if (ret) {
+               free_ExtKeyUsage(&eku);
+               hx509_env_free(&enveku);
+               goto out;
+           }
+           ret = hx509_env_add(context, &enveku, buf, "oid-name-here");
+           free(buf);
+           if (ret) {
+               free_ExtKeyUsage(&eku);
+               hx509_env_free(&enveku);
+               goto out;
+           }
+       }
+       free_ExtKeyUsage(&eku);
+
+       ret = hx509_env_add_binding(context, &envcert, "eku", enveku);
+       if (ret) {
+           hx509_env_free(&enveku);
+           goto out;
+       }
+    }
+
+    ret = hx509_env_add_binding(context, env, "certificate", envcert);
+    if (ret)
+       goto out;
+
+    return 0;
+
+out:
+    hx509_env_free(&envcert);
+    return ret;
+}
index 80bcaac6c9832b54e46d9e7db6418adfd60ebd1e..69e7730f3c851103b2301a28835ee8fe535475d0 100644 (file)
@@ -32,7 +32,7 @@
  */
 
 #include "hx_locl.h"
-RCSID("$Id: cms.c 22327 2007-12-15 04:49:37Z lha $");
+RCSID("$Id: cms.c 23268 2008-06-23 03:23:47Z lha $");
 
 /**
  * @page page_cms CMS/PKCS7 message functions.
@@ -260,6 +260,7 @@ static int
 find_CMSIdentifier(hx509_context context,
                   CMSIdentifier *client,
                   hx509_certs certs,
+                  time_t time_now,
                   hx509_cert *signer_cert,
                   int match)
 {
@@ -292,7 +293,10 @@ find_CMSIdentifier(hx509_context context,
     q.match |= match;
 
     q.match |= HX509_QUERY_MATCH_TIME;
-    q.timenow = time(NULL);
+    if (time_now)
+       q.timenow = time_now;
+    else
+       q.timenow = time(NULL);
 
     ret = hx509_certs_find(context, certs, &q, &cert);
     if (ret == HX509_CERT_NOT_FOUND) {
@@ -333,6 +337,7 @@ find_CMSIdentifier(hx509_context context,
  * @param length length of the data that data point to.
  * @param encryptedContent in case of detached signature, this
  * contains the actual encrypted data, othersize its should be NULL.
+ * @param time_now set the current time, if zero the library uses now as the date.
  * @param contentType output type oid, should be freed with der_free_oid().
  * @param content the data, free with der_free_octet_string().
  *
@@ -346,6 +351,7 @@ hx509_cms_unenvelope(hx509_context context,
                     const void *data,
                     size_t length,
                     const heim_octet_string *encryptedContent,
+                    time_t time_now,
                     heim_oid *contentType,
                     heim_octet_string *content)
 {
@@ -407,7 +413,8 @@ hx509_cms_unenvelope(hx509_context context,
 
        ri = &ed.recipientInfos.val[i];
 
-       ret = find_CMSIdentifier(context, &ri->rid, certs, &cert,
+       ret = find_CMSIdentifier(context, &ri->rid, certs,
+                                time_now, &cert,
                                 HX509_QUERY_PRIVATE_KEY|findflags);
        if (ret)
            continue;
@@ -831,7 +838,8 @@ hx509_cms_verify_signed(hx509_context context,
            continue;
        }
 
-       ret = find_CMSIdentifier(context, &signer_info->sid, certs, &cert,
+       ret = find_CMSIdentifier(context, &signer_info->sid, certs, 
+                                _hx509_verify_get_time(ctx), &cert,
                                 HX509_QUERY_KU_DIGITALSIGNATURE);
        if (ret)
            continue;
index e0f00ad7b45bd74dc66cc0728e31f633218093d7..9334a4a8474ba73b8807077e61a04ba16bbefbfd 100644 (file)
@@ -32,7 +32,7 @@
  */
 
 #include "hx_locl.h"
-RCSID("$Id: crypto.c 22435 2008-01-14 20:53:56Z lha $");
+RCSID("$Id: crypto.c 22855 2008-04-07 18:49:24Z lha $");
 
 struct hx509_crypto;
 
@@ -1592,11 +1592,11 @@ _hx509_private_key_init(hx509_private_key *key,
 hx509_private_key
 _hx509_private_key_ref(hx509_private_key key)
 {
-    if (key->ref <= 0)
-       _hx509_abort("refcount <= 0");
-    key->ref++;
     if (key->ref == 0)
-       _hx509_abort("refcount == 0");
+       _hx509_abort("key refcount <= 0 on ref");
+    key->ref++;
+    if (key->ref == UINT_MAX)
+       _hx509_abort("key refcount == UINT_MAX on ref");
     return key;
 }
 
@@ -1612,8 +1612,8 @@ _hx509_private_key_free(hx509_private_key *key)
     if (key == NULL || *key == NULL)
        return 0;
 
-    if ((*key)->ref <= 0)
-       _hx509_abort("refcount <= 0");
+    if ((*key)->ref == 0)
+       _hx509_abort("key refcount == 0 on free");
     if (--(*key)->ref > 0)
        return 0;
 
index f868c22488cb4d333909d45b0a302bb90af7c1db..a124e6ea1c35d4753b82c987c7676ea8d33e674e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007 Kungliga Tekniska Högskolan
+ * Copyright (c) 2007 - 2008 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
  * All rights reserved. 
  *
@@ -32,7 +32,7 @@
  */
 
 #include "hx_locl.h"
-RCSID("$Id: env.c 22349 2007-12-26 19:32:49Z lha $");
+RCSID("$Id: env.c 22677 2008-03-13 17:35:49Z lha $");
 
 /**
  * @page page_env Hx509 enviroment functions
@@ -40,19 +40,13 @@ RCSID("$Id: env.c 22349 2007-12-26 19:32:49Z lha $");
  * See the library functions here: @ref hx509_env
  */
 
-struct hx509_env {
-    struct {
-       char *key;
-       char *value;
-    } *val;
-    size_t len;
-};
-
 /**
- * Allocate a new hx509_env container object.
+ * Add a new key/value pair to the hx509_env.
  *
  * @param context A hx509 context.
- * @param env return a hx509_env structure, free with hx509_env_free().
+ * @param env enviroment to add the enviroment variable too.
+ * @param key key to add
+ * @param value value to add
  *
  * @return An hx509 error code, see hx509_get_error_string().
  *
@@ -60,23 +54,50 @@ struct hx509_env {
  */
 
 int
-hx509_env_init(hx509_context context, hx509_env *env)
+hx509_env_add(hx509_context context, hx509_env *env, 
+             const char *key, const char *value)
 {
-    *env = calloc(1, sizeof(**env));
-    if (*env == NULL) {
+    hx509_env n;
+
+    n = malloc(sizeof(*n));
+    if (n == NULL) {
        hx509_set_error_string(context, 0, ENOMEM, "out of memory");
        return ENOMEM;
     }
+
+    n->type = env_string;
+    n->next = NULL;
+    n->name = strdup(key);
+    if (n->name == NULL) {
+       free(n);
+       return ENOMEM;
+    }
+    n->u.string = strdup(value);
+    if (n->u.string == NULL) {
+       free(n->name);
+       free(n);
+       return ENOMEM;
+    }
+
+    /* add to tail */
+    if (*env) {
+       hx509_env e = *env;
+       while (e->next)
+           e = e->next;
+       e->next = n;
+    } else
+       *env = n;
+
     return 0;
 }
 
 /**
- * Add a new key/value pair to the hx509_env.
+ * Add a new key/binding pair to the hx509_env.
  *
  * @param context A hx509 context.
  * @param env enviroment to add the enviroment variable too.
  * @param key key to add
- * @param value value to add
+ * @param list binding list to add
  *
  * @return An hx509 error code, see hx509_get_error_string().
  *
@@ -84,34 +105,41 @@ hx509_env_init(hx509_context context, hx509_env *env)
  */
 
 int
-hx509_env_add(hx509_context context, hx509_env env, 
-             const char *key, const char *value)
+hx509_env_add_binding(hx509_context context, hx509_env *env, 
+                     const char *key, hx509_env list)
 {
-    void *ptr;
+    hx509_env n;
 
-    ptr = realloc(env->val, sizeof(env->val[0]) * (env->len + 1));
-    if (ptr == NULL) {
+    n = malloc(sizeof(*n));
+    if (n == NULL) {
        hx509_set_error_string(context, 0, ENOMEM, "out of memory");
        return ENOMEM;
     }
-    env->val = ptr;
-    env->val[env->len].key = strdup(key);
-    if (env->val[env->len].key == NULL) {
-       hx509_set_error_string(context, 0, ENOMEM, "out of memory");
-       return ENOMEM;
-    }
-    env->val[env->len].value = strdup(value);
-    if (env->val[env->len].value == NULL) {
-       free(env->val[env->len].key);
-       hx509_set_error_string(context, 0, ENOMEM, "out of memory");
+
+    n->type = env_list;
+    n->next = NULL;
+    n->name = strdup(key);
+    if (n->name == NULL) {
+       free(n);
        return ENOMEM;
     }
-    env->len++;
+    n->u.list = list;
+
+    /* add to tail */
+    if (*env) {
+       hx509_env e = *env;
+       while (e->next)
+           e = e->next;
+       e->next = n;
+    } else
+       *env = n;
+
     return 0;
 }
 
+
 /**
- * Search the hx509_env for a key.
+ * Search the hx509_env for a length based key.
  *
  * @param context A hx509 context.
  * @param env enviroment to add the enviroment variable too.
@@ -127,16 +155,80 @@ const char *
 hx509_env_lfind(hx509_context context, hx509_env env,
                const char *key, size_t len)
 {
-    size_t i;
+    while(env) {
+       if (strncmp(key, env->name ,len) == 0
+           && env->name[len] == '\0' && env->type == env_string) 
+           return env->u.string;
+       env = env->next;
+    }
+    return NULL;
+}
 
-    for (i = 0; i < env->len; i++) {
-       char *s = env->val[i].key;
-       if (strncmp(key, s, len) == 0 && s[len] == '\0')
-           return env->val[i].value;
+/**
+ * Search the hx509_env for a key.
+ *
+ * @param context A hx509 context.
+ * @param env enviroment to add the enviroment variable too.
+ * @param key key to search for.
+ *
+ * @return the value if the key is found, NULL otherwise.
+ *
+ * @ingroup hx509_env
+ */
+
+const char *
+hx509_env_find(hx509_context context, hx509_env env, const char *key)
+{
+    while(env) {
+       if (strcmp(key, env->name) == 0 && env->type == env_string) 
+           return env->u.string;
+       env = env->next;
     }
     return NULL;
 }
 
+/**
+ * Search the hx509_env for a binding.
+ *
+ * @param context A hx509 context.
+ * @param env enviroment to add the enviroment variable too.
+ * @param key key to search for.
+ *
+ * @return the binding if the key is found, NULL if not found.
+ *
+ * @ingroup hx509_env
+ */
+
+hx509_env
+hx509_env_find_binding(hx509_context context,
+                      hx509_env env,
+                      const char *key)
+{
+    while(env) {
+       if (strcmp(key, env->name) == 0 && env->type == env_list)
+           return env->u.list;
+       env = env->next;
+    }
+    return NULL;
+}
+
+static void
+env_free(hx509_env b)
+{
+    while(b) {
+       hx509_env next = b->next;
+
+       if (b->type == env_string)
+           free(b->u.string);
+       else if (b->type == env_list)
+           env_free(b->u.list);
+
+       free(b->name);
+       free(b);
+       b = next;
+    }
+}
+
 /**
  * Free an hx509_env enviroment context.
  *
@@ -148,14 +240,7 @@ hx509_env_lfind(hx509_context context, hx509_env env,
 void
 hx509_env_free(hx509_env *env)
 {
-    size_t i;
-
-    for (i = 0; i < (*env)->len; i++) {
-       free((*env)->val[i].key);
-       free((*env)->val[i].value);
-    }
-    free((*env)->val);
-    free(*env);
+    if (*env)
+       env_free(*env);
     *env = NULL;
 }
-
index b076b74f44df661485ba84c065e572b54f357729..c8f0e9a64230adba23f34f868ce1978aa42af107 100644 (file)
 RCSID("$ID$");
 
 int
-_hx509_map_file_os(const char *fn, heim_octet_string *os, struct stat *rsb)
+_hx509_map_file_os(const char *fn, heim_octet_string *os)
 {
     size_t length;
     void *data;
     int ret;
 
-    ret = _hx509_map_file(fn, &data, &length, rsb);
+    ret = rk_undumpdata(fn, &data, &length);
 
     os->data = data;
     os->length = length;
@@ -52,86 +52,13 @@ _hx509_map_file_os(const char *fn, heim_octet_string *os, struct stat *rsb)
 void
 _hx509_unmap_file_os(heim_octet_string *os)
 {
-    _hx509_unmap_file(os->data, os->length);
-}
-
-int
-_hx509_map_file(const char *fn, void **data, size_t *length, struct stat *rsb)
-{
-    struct stat sb;
-    size_t len;
-    ssize_t l;
-    int ret;
-    void *d;
-    int fd;
-
-    *data = NULL;
-    *length = 0;
-
-    fd = open(fn, O_RDONLY);
-    if (fd < 0)
-       return errno;
-    
-    if (fstat(fd, &sb) < 0) {
-       ret = errno;
-       close(fd);
-       return ret;
-    }
-
-    len = sb.st_size;
-
-    d = malloc(len);
-    if (d == NULL) {
-       close(fd);
-       return ENOMEM;
-    }
-    
-    l = read(fd, d, len);
-    close(fd);
-    if (l < 0 || l != len) {
-       free(d);
-       return EINVAL;
-    }
-
-    if (rsb)
-       *rsb = sb;
-    *data = d;
-    *length = len;
-    return 0;
-}
-
-void
-_hx509_unmap_file(void *data, size_t len)
-{
-    free(data);
+    rk_xfree(os->data);
 }
 
 int
 _hx509_write_file(const char *fn, const void *data, size_t length)
 {
-    ssize_t sz;
-    const unsigned char *p = data;
-    int fd;
-
-    fd = open(fn, O_WRONLY|O_TRUNC|O_CREAT, 0644);
-    if (fd < 0)
-       return errno;
-
-    do {
-       sz = write(fd, p, length);
-       if (sz < 0) {
-           int saved_errno = errno;
-           close(fd);
-           return saved_errno;
-       }
-       if (sz == 0)
-           break;
-       length -= sz;
-    } while (length > 0);
-               
-    if (close(fd) == -1)
-       return errno;
-
+    rk_dumpdata(fn, data, length);
     return 0;
 }
 
index be36c07421e7092506ba0bdb8766ddbe75f69f2b..de1fcfa7e65246a9a3221e9dfa86f83b7bdaebea 100644 (file)
@@ -97,6 +97,12 @@ _hx509_cert_set_release (
        _hx509_cert_release_func /*release*/,
        void */*ctx*/);
 
+int
+_hx509_cert_to_env (
+       hx509_context /*context*/,
+       hx509_cert /*cert*/,
+       hx509_env */*env*/);
+
 int
 _hx509_certs_keys_add (
        hx509_context /*context*/,
@@ -181,6 +187,18 @@ _hx509_create_signature_bitstring (
        AlgorithmIdentifier */*signatureAlgorithm*/,
        heim_bit_string */*sig*/);
 
+int
+_hx509_expr_eval (
+       hx509_context /*context*/,
+       hx509_env /*env*/,
+       struct hx_expr */*expr*/);
+
+void
+_hx509_expr_free (struct hx_expr */*expr*/);
+
+struct hx_expr *
+_hx509_expr_parse (const char */*buf*/);
+
 int
 _hx509_find_extension_subject_key_id (
        const Certificate */*issuer*/,
@@ -253,18 +271,16 @@ _hx509_lock_get_passwords (hx509_lock /*lock*/);
 hx509_certs
 _hx509_lock_unlock_certs (hx509_lock /*lock*/);
 
-int
-_hx509_map_file (
-       const char */*fn*/,
-       void **/*data*/,
-       size_t */*length*/,
-       struct stat */*rsb*/);
+struct hx_expr *
+_hx509_make_expr (
+       enum hx_expr_op /*op*/,
+       void */*arg1*/,
+       void */*arg2*/);
 
 int
 _hx509_map_file_os (
        const char */*fn*/,
-       heim_octet_string */*os*/,
-       struct stat */*rsb*/);
+       heim_octet_string */*os*/);
 
 int
 _hx509_match_keys (
@@ -486,6 +502,9 @@ _hx509_request_to_pkcs10 (
 hx509_revoke_ctx
 _hx509_revoke_ref (hx509_revoke_ctx /*ctx*/);
 
+void
+_hx509_sel_yyerror (char */*s*/);
+
 int
 _hx509_set_cert_attribute (
        hx509_context /*context*/,
@@ -493,11 +512,6 @@ _hx509_set_cert_attribute (
        const heim_oid */*oid*/,
        const heim_octet_string */*attr*/);
 
-void
-_hx509_unmap_file (
-       void */*data*/,
-       size_t /*len*/);
-
 void
 _hx509_unmap_file_os (heim_octet_string */*os*/);
 
@@ -506,6 +520,9 @@ _hx509_unparse_Name (
        const Name */*aname*/,
        char **/*str*/);
 
+time_t
+_hx509_verify_get_time (hx509_verify_ctx /*ctx*/);
+
 int
 _hx509_verify_signature (
        hx509_context /*context*/,
index 3e297424cc9ce0b56c8d2628b20fdaa649dddb8d..f8e6bc19a4f14c9ba5978f4ebbb989d50074c1fd 100644 (file)
@@ -8,11 +8,13 @@
 extern "C" {
 #endif
 
-#ifndef HX509_LIB_FUNCTION
+#ifndef HX509_LIB
 #if defined(_WIN32)
-#define HX509_LIB_FUNCTION _stdcall
+#define HX509_LIB_FUNCTION _stdcall __declspec(dllimport)
+#define HX509_LIB_VARIABLE __declspec(dllimport)
 #else
 #define HX509_LIB_FUNCTION
+#define HX509_LIB_VARIABLE
 #endif
 #endif
 
@@ -396,6 +398,7 @@ hx509_cms_unenvelope (
        const void */*data*/,
        size_t /*length*/,
        const heim_octet_string */*encryptedContent*/,
+       time_t /*time_now*/,
        heim_oid */*contentType*/,
        heim_octet_string */*content*/);
 
@@ -564,17 +567,31 @@ hx509_crypto_set_random_key (
 int
 hx509_env_add (
        hx509_context /*context*/,
-       hx509_env /*env*/,
+       hx509_env */*env*/,
        const char */*key*/,
        const char */*value*/);
 
-void
-hx509_env_free (hx509_env */*env*/);
-
 int
-hx509_env_init (
+hx509_env_add_binding (
        hx509_context /*context*/,
-       hx509_env */*env*/);
+       hx509_env */*env*/,
+       const char */*key*/,
+       hx509_env /*list*/);
+
+const char *
+hx509_env_find (
+       hx509_context /*context*/,
+       hx509_env /*env*/,
+       const char */*key*/);
+
+hx509_env
+hx509_env_find_binding (
+       hx509_context /*context*/,
+       hx509_env /*env*/,
+       const char */*key*/);
+
+void
+hx509_env_free (hx509_env */*env*/);
 
 const char *
 hx509_env_lfind (
@@ -825,6 +842,12 @@ hx509_query_match_eku (
        hx509_query */*q*/,
        const heim_oid */*eku*/);
 
+int
+hx509_query_match_expr (
+       hx509_context /*context*/,
+       hx509_query */*q*/,
+       const char */*expr*/);
+
 int
 hx509_query_match_friendly_name (
        hx509_query */*q*/,
@@ -1047,6 +1070,9 @@ hx509_verify_signature (
 void
 hx509_xfree (void */*ptr*/);
 
+int
+yywrap (void);
+
 #ifdef __cplusplus
 }
 #endif
index be02f6347490392294625102ccdca61959f1c81e..d2a6b06e0c63a3c305b0ded06434afe38746253f 100644 (file)
  * SUCH DAMAGE. 
  */
 
-/* $Id: hx509.h 22464 2008-01-16 14:24:50Z lha $ */
+/* $Id: hx509.h 22908 2008-04-08 08:16:32Z lha $ */
+
+#ifndef HEIMDAL_HX509_H
+#define HEIMDAL_HX509_H 1
+
+#include <heim_asn1.h>
+#include <rfc2459_asn1.h>
 
 typedef struct hx509_cert_attribute_data *hx509_cert_attribute;
 typedef struct hx509_cert_data *hx509_cert;
@@ -50,7 +56,7 @@ typedef struct hx509_request_data *hx509_request;
 typedef struct hx509_error_data *hx509_error;
 typedef struct hx509_peer_info *hx509_peer_info;
 typedef struct hx509_ca_tbs *hx509_ca_tbs;
-typedef struct hx509_env *hx509_env;
+typedef struct hx509_env_data *hx509_env;
 typedef struct hx509_crl *hx509_crl;
 
 typedef void (*hx509_vprint_func)(void *, const char *, va_list);
@@ -146,3 +152,6 @@ typedef enum  {
 } hx509_hostname_type;
 
 #include <hx509-protos.h>
+#include <hx509_err.h>
+
+#endif /* HEIMDAL_HX509_H */
index 6d89167bfcb53bd33773ec30b3192f3a399238bd..d2db3354c7f408c2344595a785fd63ac5d378393 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE. 
  */
 
-/* $Id: hx_locl.h 22538 2008-01-27 13:05:47Z lha $ */
+/* $Id: hx_locl.h 23189 2008-05-23 15:04:27Z lha $ */
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
@@ -45,6 +45,8 @@
 #include <assert.h>
 #include <stdarg.h>
 #include <err.h>
+#include <limits.h>
+
 #include <getarg.h>
 #include <base64.h>
 #include <hex.h>
@@ -80,6 +82,8 @@ typedef void (*_hx509_cert_release_func)(struct hx509_cert_data *, void *);
 
 typedef struct hx509_private_key_ops hx509_private_key_ops;
 
+#include "sel.h"
+
 #include <hx509-private.h>
 #include <hx509_err.h>
 
@@ -129,7 +133,8 @@ struct hx509_query_data {
 #define HX509_QUERY_MATCH_KEY_HASH_SHA1                0x100000
 #define HX509_QUERY_MATCH_TIME                 0x200000
 #define HX509_QUERY_MATCH_EKU                  0x400000
-#define HX509_QUERY_MASK                       0x7fffff
+#define HX509_QUERY_MATCH_EXPR                 0x800000
+#define HX509_QUERY_MASK                       0xffffff
     Certificate *subject;
     Certificate *certificate;
     heim_integer *serial;
@@ -144,6 +149,7 @@ struct hx509_query_data {
     heim_octet_string *keyhash_sha1;
     time_t timenow;
     heim_oid *eku;
+    struct hx_expr *expr;
 };
 
 struct hx509_keyset_ops {
@@ -188,6 +194,18 @@ struct hx509_context_data {
 /* _hx509_calculate_path flag field */
 #define HX509_CALCULATE_PATH_NO_ANCHOR 1
 
+/* environment */
+struct hx509_env_data {
+    enum { env_string, env_list } type;
+    char *name;
+    struct hx509_env_data *next;
+    union {
+       char *string;
+       struct hx509_env_data *list;
+    } u;
+};
+
+
 extern const AlgorithmIdentifier * _hx509_crypto_default_sig_alg;
 extern const AlgorithmIdentifier * _hx509_crypto_default_digest_alg;
 extern const AlgorithmIdentifier * _hx509_crypto_default_secret_alg;
index 2fcff7b03b352f527c6c1059a106a56add5520d8..1fceb849ec854426568f629f0d945edae61af65a 100644 (file)
@@ -32,7 +32,7 @@
  */
 
 #include "hx_locl.h"
-RCSID("$Id: keyset.c 22466 2008-01-16 14:26:35Z lha $");
+RCSID("$Id: keyset.c 22851 2008-04-07 18:49:07Z lha $");
 
 /**
  * @page page_keyset Certificate store operations
@@ -59,7 +59,7 @@ RCSID("$Id: keyset.c 22466 2008-01-16 14:26:35Z lha $");
  */
 
 struct hx509_certs_data {
-    int ref;
+    unsigned int ref;
     struct hx509_keyset_ops *ops;
     void *ops_data;
 };
@@ -203,11 +203,11 @@ _hx509_certs_ref(hx509_certs certs)
 {
     if (certs == NULL)
        return NULL;
-    if (certs->ref <= 0)
-       _hx509_abort("certs refcount <= 0");
-    certs->ref++;
     if (certs->ref == 0)
-       _hx509_abort("certs refcount == 0");
+       _hx509_abort("certs refcount == 0 on ref");
+    if (certs->ref == UINT_MAX)
+       _hx509_abort("certs refcount == UINT_MAX on ref");
+    certs->ref++;
     return certs;
 }
 
@@ -223,8 +223,8 @@ void
 hx509_certs_free(hx509_certs *certs)
 {
     if (*certs) {
-       if ((*certs)->ref <= 0)
-           _hx509_abort("refcount <= 0");
+       if ((*certs)->ref == 0)
+           _hx509_abort("cert refcount == 0 on free");
        if (--(*certs)->ref > 0)
            return;
 
index a0bc875e5b8c356539b8640974cad62395671801..0dabc78c52f9af29933bbc45ecf068af1e2bcd45 100644 (file)
@@ -32,7 +32,7 @@
  */
 
 #include "hx_locl.h"
-RCSID("$Id: ks_dir.c 19778 2007-01-09 10:52:13Z lha $");
+RCSID("$Id: ks_dir.c 23460 2008-07-27 12:14:03Z lha $");
 #include <dirent.h>
 
 /*
@@ -116,6 +116,7 @@ dir_iter_start(hx509_context context,
        free(d);
        return errno;
     }
+    rk_cloexec(dirfd(d->dir));
     d->certs = NULL;
     d->iter = NULL;
 
index 87b97af401c5097c5188c6a6539ce0dcc0e1f08d..25ceb1c64f9144e9c016aea5f332bdd5b568ff6c 100644 (file)
@@ -32,7 +32,7 @@
  */
 
 #include "hx_locl.h"
-RCSID("$Id: ks_file.c 22465 2008-01-16 14:25:24Z lha $");
+RCSID("$Id: ks_file.c 23459 2008-07-27 12:13:31Z lha $");
 
 typedef enum { USE_PEM, USE_DER } outformat;
 
@@ -391,6 +391,7 @@ file_init_common(hx509_context context,
                                   p, strerror(errno));
            goto out;
        }
+       rk_cloexec_file(f);
 
        ret = hx509_pem_read(context, f, pem_func, &pem_ctx);
        fclose(f);                   
@@ -401,7 +402,7 @@ file_init_common(hx509_context context,
            void *ptr;
            int i;
 
-           ret = _hx509_map_file(p, &ptr, &length, NULL);
+           ret = rk_undumpdata(p, &ptr, &length);
            if (ret) {
                hx509_clear_error_string(context);
                goto out;
@@ -412,7 +413,7 @@ file_init_common(hx509_context context,
                if (ret == 0)
                    break;
            }
-           _hx509_unmap_file(ptr, length);
+           rk_xfree(ptr);
            if (ret)
                goto out;
        }
@@ -525,6 +526,7 @@ file_store(hx509_context context,
                               "Failed to open file %s for writing");
        return ENOENT;
     }
+    rk_cloexec_file(sc.f);
     sc.format = f->format;
 
     ret = hx509_certs_iter(context, f->certs, store_func, &sc);
index 0d7c312c72413dfa2f462b699e0dc5bdba6145ec..bf46e6604e501a118f8ac89e8043ec1953d88657 100644 (file)
@@ -32,7 +32,7 @@
  */
 
 #include "hx_locl.h"
-RCSID("$Id: ks_p11.c 22071 2007-11-14 20:04:50Z lha $");
+RCSID("$Id: ks_p11.c 22899 2008-04-07 18:52:36Z lha $");
 #ifdef HAVE_DLFCN_H
 #include <dlfcn.h>
 #endif
@@ -65,7 +65,7 @@ struct p11_module {
     void *dl_handle;
     CK_FUNCTION_LIST_PTR funcs;
     CK_ULONG num_slots;
-    unsigned int refcount;
+    unsigned int ref;
     struct p11_slot *slot;
 };
 
@@ -309,7 +309,8 @@ p11_init_slot(hx509_context context,
     CK_SESSION_HANDLE session;
     CK_SLOT_INFO slot_info;
     CK_TOKEN_INFO token_info;
-    int ret, i;
+    size_t i;
+    int ret;
 
     slot->certs = NULL;
     slot->id = id;
@@ -640,9 +641,11 @@ collect_private_key(hx509_context context,
     p11rsa->slot = slot;
     p11rsa->private_key = object;
     
-    p->refcount++;
-    if (p->refcount == 0)
-       _hx509_abort("pkcs11 refcount to high");
+    if (p->ref == 0)
+       _hx509_abort("pkcs11 ref == 0 on alloc");
+    p->ref++;
+    if (p->ref == UINT_MAX)
+       _hx509_abort("pkcs11 ref == UINT_MAX on alloc");
 
     RSA_set_method(rsa, &p11_rsa_pkcs1_method);
     ret = RSA_set_app_data(rsa, p11rsa);
@@ -695,9 +698,11 @@ collect_cert(hx509_context context,
     if (ret)
        return ret;
 
-    p->refcount++;
-    if (p->refcount == 0)
-       _hx509_abort("pkcs11 refcount to high");
+    if (p->ref == 0)
+       _hx509_abort("pkcs11 ref == 0 on alloc");
+    p->ref++;
+    if (p->ref == UINT_MAX)
+       _hx509_abort("pkcs11 ref to high");
 
     _hx509_cert_set_release(cert, p11_cert_release, p);
 
@@ -808,7 +813,7 @@ p11_init(hx509_context context,
        return ENOMEM;
     }
 
-    p->refcount = 1;
+    p->ref = 1;
 
     str = strchr(list, ',');
     if (str)
@@ -934,9 +939,9 @@ p11_release_module(struct p11_module *p)
 {
     int i;
 
-    if (p->refcount == 0)
-       _hx509_abort("pkcs11 refcount to low");
-    if (--p->refcount > 0)
+    if (p->ref == 0)
+       _hx509_abort("pkcs11 ref to low");
+    if (--p->ref > 0)
        return;
 
     for (i = 0; i < p->num_slots; i++) {
index 12756e6c071dbfd10479e59f1d2aa1537e36314c..3ab824a330ea215f510652b2630a99cc5d5c1768 100644 (file)
@@ -32,7 +32,7 @@
  */
 
 #include "hx_locl.h"
-RCSID("$Id: ks_p12.c 21146 2007-06-18 21:37:25Z lha $");
+RCSID("$Id: ks_p12.c 23413 2008-07-26 18:34:53Z lha $");
 
 struct ks_pkcs12 {
     hx509_certs certs;
@@ -276,6 +276,7 @@ envelopedData_parser(hx509_context context,
                               0,
                               data, length,
                               NULL,
+                              0,
                               &contentType,
                               &content);
     if (ret) {
@@ -361,14 +362,14 @@ p12_init(hx509_context context,
        goto out;
     }
 
-    ret = _hx509_map_file(residue, &buf, &len, NULL);
+    ret = rk_undumpdata(residue, &buf, &len);
     if (ret) {
        hx509_clear_error_string(context);
        goto out;
     }
 
     ret = decode_PKCS12_PFX(buf, len, &pfx, NULL);
-    _hx509_unmap_file(buf, len);
+    rk_xfree(buf);
     if (ret) {
        hx509_set_error_string(context, 0, ret,
                               "Failed to decode the PFX in %s", residue);
index 3f0806ddc01ecd553d6abad287b2ea90095861e9..ccc33a3e55338c984f3468340ce13748adaef023 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "hx_locl.h"
 #include <wind.h>
-RCSID("$Id: name.c 22583 2008-02-11 20:46:21Z lha $");
+RCSID("$Id: name.c 22677 2008-03-13 17:35:49Z lha $");
 
 /**
  * @page page_name PKIX/X.509 Names
@@ -897,7 +897,7 @@ hx509_name_is_null_p(const hx509_name name)
  * @param name the name to print
  * @param str an allocated string returns the name in string form
  *
- * @return An hx509 error code, see krb5_get_error_string().
+ * @return An hx509 error code, see hx509_get_error_string().
  *
  * @ingroup hx509_name
  */
index d7a85e1cecd20291136bd9df6542a13c5c535233..f374044ca67041c21dbd59b7d8b31f7f22ee7496 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "hx_locl.h"
 #include <pkcs10_asn1.h>
-RCSID("$Id: req.c 21344 2007-06-26 14:22:34Z lha $");
+RCSID("$Id: req.c 23413 2008-07-26 18:34:53Z lha $");
 
 struct hx509_request_data {
     hx509_name name;
@@ -257,14 +257,14 @@ _hx509_request_parse(hx509_context context,
 
     /* XXX PEM request */
 
-    ret = _hx509_map_file(path, &p, &len, NULL);
+    ret = rk_undumpdata(path, &p, &len);
     if (ret) {
        hx509_set_error_string(context, 0, ret, "Failed to map file %s", path);
        return ret;
     }
 
     ret = decode_CertificationRequest(p, len, &r, &size);
-    _hx509_unmap_file(p, len);
+    rk_xfree(p);
     if (ret) {
        hx509_set_error_string(context, 0, ret, "Failed to decode %s", path);
        return ret;
index 2010f945f0eff6366493c1473cd7f1ea12258230..8325c4723d7e26d307bd6b4ac539f1cfdad455f5 100644 (file)
@@ -50,7 +50,7 @@
  */
 
 #include "hx_locl.h"
-RCSID("$Id: revoke.c 22583 2008-02-11 20:46:21Z lha $");
+RCSID("$Id: revoke.c 23413 2008-07-26 18:34:53Z lha $");
 
 struct revoke_crl {
     char *path;
@@ -70,7 +70,7 @@ struct revoke_ocsp {
 
 
 struct hx509_revoke_ctx_data {
-    unsigned ref;
+    unsigned int ref;
     struct {
        struct revoke_crl *val;
        size_t len;
@@ -113,11 +113,11 @@ _hx509_revoke_ref(hx509_revoke_ctx ctx)
 {
     if (ctx == NULL)
        return NULL;
-    if (ctx->ref <= 0)
-       _hx509_abort("revoke ctx refcount <= 0");
-    ctx->ref++;
     if (ctx->ref == 0)
-       _hx509_abort("revoke ctx refcount == 0");
+       _hx509_abort("revoke ctx refcount == 0 on ref");
+    ctx->ref++;
+    if (ctx->ref == UINT_MAX)
+       _hx509_abort("revoke ctx refcount == UINT_MAX on ref");
     return ctx;
 }
 
@@ -146,8 +146,8 @@ hx509_revoke_free(hx509_revoke_ctx *ctx)
     if (ctx == NULL || *ctx == NULL)
        return;
 
-    if ((*ctx)->ref <= 0)
-       _hx509_abort("revoke ctx refcount <= 0 on free");
+    if ((*ctx)->ref == 0)
+       _hx509_abort("revoke ctx refcount == 0 on free");
     if (--(*ctx)->ref > 0)
        return;
 
@@ -218,7 +218,7 @@ verify_ocsp(hx509_context context,
        ret = _hx509_cert_is_parent_cmp(s, p, 0);
        if (ret != 0) {
            ret = HX509_PARENT_NOT_CA;
-           hx509_set_error_string(context, 0, ret, "Revoke OSCP signer is "
+           hx509_set_error_string(context, 0, ret, "Revoke OCSP signer is "
                                   "doesn't have CA as signer certificate");
            goto out;
        }
@@ -230,7 +230,7 @@ verify_ocsp(hx509_context context,
                                                &s->signatureValue);
        if (ret) {
            hx509_set_error_string(context, HX509_ERROR_APPEND, ret,
-                                  "OSCP signer signature invalid");
+                                  "OCSP signer signature invalid");
            goto out;
        }
 
@@ -247,7 +247,7 @@ verify_ocsp(hx509_context context,
                                            &ocsp->ocsp.signature);
     if (ret) {
        hx509_set_error_string(context, HX509_ERROR_APPEND, ret, 
-                              "OSCP signature invalid");
+                              "OCSP signature invalid");
        goto out;
     }
 
@@ -333,12 +333,16 @@ load_ocsp(hx509_context context, struct revoke_ocsp *ocsp)
     void *data;
     int ret;
 
-    ret = _hx509_map_file(ocsp->path, &data, &length, &sb);
+    ret = rk_undumpdata(ocsp->path, &data, &length);
     if (ret)
        return ret;
 
+    ret = stat(ocsp->path, &sb);
+    if (ret)
+       return errno;
+
     ret = parse_ocsp_basic(data, length, &basic);
-    _hx509_unmap_file(data, length);
+    rk_xfree(data);
     if (ret) {
        hx509_set_error_string(context, 0, ret,
                               "Failed to parse OCSP response");
@@ -567,14 +571,18 @@ load_crl(const char *path, time_t *t, CRLCertificateList *crl)
 
     memset(crl, 0, sizeof(*crl));
 
-    ret = _hx509_map_file(path, &data, &length, &sb);
+    ret = rk_undumpdata(path, &data, &length);
     if (ret)
        return ret;
 
+    ret = stat(path, &sb);
+    if (ret)
+       return errno;
+
     *t = sb.st_mtime;
 
     ret = decode_CRLCertificateList(data, length, crl, &size);
-    _hx509_unmap_file(data, length);
+    rk_xfree(data);
     if (ret)
        return ret;
 
diff --git a/source4/heimdal/lib/hx509/sel-gram.c b/source4/heimdal/lib/hx509/sel-gram.c
new file mode 100644 (file)
index 0000000..905384d
--- /dev/null
@@ -0,0 +1,1714 @@
+/* A Bison parser, made by GNU Bison 2.3.  */
+
+/* Skeleton implementation for Bison's Yacc-like parsers in C
+
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+/* As a special exception, you may create a larger work that contains
+   part or all of the Bison parser skeleton and distribute that work
+   under terms of your choice, so long as that work isn't itself a
+   parser generator using the skeleton or a modified version thereof
+   as a parser skeleton.  Alternatively, if you modify or redistribute
+   the parser skeleton itself, you may (at your option) remove this
+   special exception, which will cause the skeleton and the resulting
+   Bison output files to be licensed under the GNU General Public
+   License without this special exception.
+
+   This special exception was added by the Free Software Foundation in
+   version 2.2 of Bison.  */
+
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+   simplifying the original so-called "semantic" parser.  */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+   infringing on user name space.  This should be done even for local
+   variables, as they might otherwise be expanded by user macros.
+   There are some unavoidable exceptions within include files to
+   define necessary library symbols; they are noted "INFRINGES ON
+   USER NAME SPACE" below.  */
+
+/* Identify Bison output.  */
+#define YYBISON 1
+
+/* Bison version.  */
+#define YYBISON_VERSION "2.3"
+
+/* Skeleton name.  */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers.  */
+#define YYPURE 0
+
+/* Using locations.  */
+#define YYLSP_NEEDED 0
+
+
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     kw_TRUE = 258,
+     kw_FALSE = 259,
+     kw_AND = 260,
+     kw_OR = 261,
+     kw_IN = 262,
+     kw_TAILMATCH = 263,
+     NUMBER = 264,
+     STRING = 265,
+     IDENTIFIER = 266
+   };
+#endif
+/* Tokens.  */
+#define kw_TRUE 258
+#define kw_FALSE 259
+#define kw_AND 260
+#define kw_OR 261
+#define kw_IN 262
+#define kw_TAILMATCH 263
+#define NUMBER 264
+#define STRING 265
+#define IDENTIFIER 266
+
+
+
+
+/* Copy the first part of user declarations.  */
+#line 34 "heimdal/lib/hx509/sel-gram.y"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <hx_locl.h>
+
+RCSID("$Id$");
+
+
+
+/* Enabling traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages.  */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+/* Enabling the token table.  */
+#ifndef YYTOKEN_TABLE
+# define YYTOKEN_TABLE 0
+#endif
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+#line 46 "heimdal/lib/hx509/sel-gram.y"
+{
+    char *string;
+    struct hx_expr *expr;
+}
+/* Line 187 of yacc.c.  */
+#line 135 "heimdal/lib/hx509/sel-gram.y"
+       YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+
+
+/* Copy the second part of user declarations.  */
+
+
+/* Line 216 of yacc.c.  */
+#line 148 "heimdal/lib/hx509/sel-gram.y"
+
+#ifdef short
+# undef short
+#endif
+
+#ifdef YYTYPE_UINT8
+typedef YYTYPE_UINT8 yytype_uint8;
+#else
+typedef unsigned char yytype_uint8;
+#endif
+
+#ifdef YYTYPE_INT8
+typedef YYTYPE_INT8 yytype_int8;
+#elif (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+typedef signed char yytype_int8;
+#else
+typedef short int yytype_int8;
+#endif
+
+#ifdef YYTYPE_UINT16
+typedef YYTYPE_UINT16 yytype_uint16;
+#else
+typedef unsigned short int yytype_uint16;
+#endif
+
+#ifdef YYTYPE_INT16
+typedef YYTYPE_INT16 yytype_int16;
+#else
+typedef short int yytype_int16;
+#endif
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+#  define YYSIZE_T __SIZE_TYPE__
+# elif defined size_t
+#  define YYSIZE_T size_t
+# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYSIZE_T size_t
+# else
+#  define YYSIZE_T unsigned int
+# endif
+#endif
+
+#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
+
+#ifndef YY_
+# if YYENABLE_NLS
+#  if ENABLE_NLS
+#   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+#   define YY_(msgid) dgettext ("bison-runtime", msgid)
+#  endif
+# endif
+# ifndef YY_
+#  define YY_(msgid) msgid
+# endif
+#endif
+
+/* Suppress unused-variable warnings by "using" E.  */
+#if ! defined lint || defined __GNUC__
+# define YYUSE(e) ((void) (e))
+#else
+# define YYUSE(e) /* empty */
+#endif
+
+/* Identity function, used to suppress warnings about constant conditions.  */
+#ifndef lint
+# define YYID(n) (n)
+#else
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static int
+YYID (int i)
+#else
+static int
+YYID (i)
+    int i;
+#endif
+{
+  return i;
+}
+#endif
+
+#if ! defined yyoverflow || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols.  */
+
+# ifdef YYSTACK_USE_ALLOCA
+#  if YYSTACK_USE_ALLOCA
+#   ifdef __GNUC__
+#    define YYSTACK_ALLOC __builtin_alloca
+#   elif defined __BUILTIN_VA_ARG_INCR
+#    include <alloca.h> /* INFRINGES ON USER NAME SPACE */
+#   elif defined _AIX
+#    define YYSTACK_ALLOC __alloca
+#   elif defined _MSC_VER
+#    include <malloc.h> /* INFRINGES ON USER NAME SPACE */
+#    define alloca _alloca
+#   else
+#    define YYSTACK_ALLOC alloca
+#    if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+#     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+#     ifndef _STDLIB_H
+#      define _STDLIB_H 1
+#     endif
+#    endif
+#   endif
+#  endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+   /* Pacify GCC's `empty if-body' warning.  */
+#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
+#  ifndef YYSTACK_ALLOC_MAXIMUM
+    /* The OS might guarantee only one guard page at the bottom of the stack,
+       and a page size can be as small as 4096 bytes.  So we cannot safely
+       invoke alloca (N) if N exceeds 4096.  Use a slightly smaller number
+       to allow for a few compiler-allocated temporary stack slots.  */
+#   define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
+#  endif
+# else
+#  define YYSTACK_ALLOC YYMALLOC
+#  define YYSTACK_FREE YYFREE
+#  ifndef YYSTACK_ALLOC_MAXIMUM
+#   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
+#  endif
+#  if (defined __cplusplus && ! defined _STDLIB_H \
+       && ! ((defined YYMALLOC || defined malloc) \
+            && (defined YYFREE || defined free)))
+#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+#   ifndef _STDLIB_H
+#    define _STDLIB_H 1
+#   endif
+#  endif
+#  ifndef YYMALLOC
+#   define YYMALLOC malloc
+#   if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+#   endif
+#  endif
+#  ifndef YYFREE
+#   define YYFREE free
+#   if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+#   endif
+#  endif
+# endif
+#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
+
+
+#if (! defined yyoverflow \
+     && (! defined __cplusplus \
+        || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member.  */
+union yyalloc
+{
+  yytype_int16 yyss;
+  YYSTYPE yyvs;
+  };
+
+/* The size of the maximum gap between one aligned stack and the next.  */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+   N elements.  */
+# define YYSTACK_BYTES(N) \
+     ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
+      + YYSTACK_GAP_MAXIMUM)
+
+/* Copy COUNT objects from FROM to TO.  The source and destination do
+   not overlap.  */
+# ifndef YYCOPY
+#  if defined __GNUC__ && 1 < __GNUC__
+#   define YYCOPY(To, From, Count) \
+      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+#  else
+#   define YYCOPY(To, From, Count)             \
+      do                                       \
+       {                                       \
+         YYSIZE_T yyi;                         \
+         for (yyi = 0; yyi < (Count); yyi++)   \
+           (To)[yyi] = (From)[yyi];            \
+       }                                       \
+      while (YYID (0))
+#  endif
+# endif
+
+/* Relocate STACK from its old location to the new one.  The
+   local variables YYSIZE and YYSTACKSIZE give the old and new number of
+   elements in the stack, and YYPTR gives the new location of the
+   stack.  Advance YYPTR to a properly aligned location for the next
+   stack.  */
+# define YYSTACK_RELOCATE(Stack)                                       \
+    do                                                                 \
+      {                                                                        \
+       YYSIZE_T yynewbytes;                                            \
+       YYCOPY (&yyptr->Stack, Stack, yysize);                          \
+       Stack = &yyptr->Stack;                                          \
+       yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+       yyptr += yynewbytes / sizeof (*yyptr);                          \
+      }                                                                        \
+    while (YYID (0))
+
+#endif
+
+/* YYFINAL -- State number of the termination state.  */
+#define YYFINAL  21
+/* YYLAST -- Last index in YYTABLE.  */
+#define YYLAST   50
+
+/* YYNTOKENS -- Number of terminals.  */
+#define YYNTOKENS  21
+/* YYNNTS -- Number of nonterminals.  */
+#define YYNNTS  11
+/* YYNRULES -- Number of rules.  */
+#define YYNRULES  26
+/* YYNRULES -- Number of states.  */
+#define YYNSTATES  50
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
+#define YYUNDEFTOK  2
+#define YYMAXUTOK   266
+
+#define YYTRANSLATE(YYX)                                               \
+  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
+static const yytype_uint8 yytranslate[] =
+{
+       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,    12,     2,     2,     2,    17,     2,     2,
+      13,    14,     2,     2,    15,     2,    20,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,    16,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,    18,     2,    19,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
+       5,     6,     7,     8,     9,    10,    11
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+   YYRHS.  */
+static const yytype_uint8 yyprhs[] =
+{
+       0,     0,     3,     5,     7,     9,    12,    16,    20,    24,
+      26,    28,    32,    37,    42,    46,    52,    56,    58,    60,
+      62,    64,    66,    68,    73,    78,    82
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS.  */
+static const yytype_int8 yyrhs[] =
+{
+      22,     0,    -1,    23,    -1,     3,    -1,     4,    -1,    12,
+      23,    -1,    23,     5,    23,    -1,    23,     6,    23,    -1,
+      13,    23,    14,    -1,    25,    -1,    26,    -1,    26,    15,
+      24,    -1,    26,    16,    16,    26,    -1,    26,    12,    16,
+      26,    -1,    26,     8,    26,    -1,    26,     7,    13,    24,
+      14,    -1,    26,     7,    30,    -1,    27,    -1,    28,    -1,
+      29,    -1,    30,    -1,     9,    -1,    10,    -1,    11,    13,
+      24,    14,    -1,    17,    18,    31,    19,    -1,    11,    20,
+      31,    -1,    11,    -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
+static const yytype_uint8 yyrline[] =
+{
+       0,    74,    74,    76,    77,    78,    79,    80,    81,    82,
+      85,    86,    89,    90,    91,    92,    93,    96,    97,    98,
+      99,   102,   103,   105,   108,   111,   113
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+   First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
+static const char *const yytname[] =
+{
+  "$end", "error", "$undefined", "kw_TRUE", "kw_FALSE", "kw_AND", "kw_OR",
+  "kw_IN", "kw_TAILMATCH", "NUMBER", "STRING", "IDENTIFIER", "'!'", "'('",
+  "')'", "','", "'='", "'%'", "'{'", "'}'", "'.'", "$accept", "start",
+  "expr", "words", "comp", "word", "number", "string", "function",
+  "variable", "variables", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+   token YYLEX-NUM.  */
+static const yytype_uint16 yytoknum[] =
+{
+       0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
+     265,   266,    33,    40,    41,    44,    61,    37,   123,   125,
+      46
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
+static const yytype_uint8 yyr1[] =
+{
+       0,    21,    22,    23,    23,    23,    23,    23,    23,    23,
+      24,    24,    25,    25,    25,    25,    25,    26,    26,    26,
+      26,    27,    28,    29,    30,    31,    31
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
+static const yytype_uint8 yyr2[] =
+{
+       0,     2,     1,     1,     1,     2,     3,     3,     3,     1,
+       1,     3,     4,     4,     3,     5,     3,     1,     1,     1,
+       1,     1,     1,     4,     4,     3,     1
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+   STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
+   means the default is an error.  */
+static const yytype_uint8 yydefact[] =
+{
+       0,     3,     4,    21,    22,     0,     0,     0,     0,     0,
+       2,     9,     0,    17,    18,    19,    20,     0,     5,     0,
+       0,     1,     0,     0,     0,     0,     0,     0,     0,    10,
+       8,    26,     0,     6,     7,     0,    16,    14,     0,     0,
+      23,     0,     0,    24,     0,    13,    12,    11,    25,    15
+};
+
+/* YYDEFGOTO[NTERM-NUM].  */
+static const yytype_int8 yydefgoto[] =
+{
+      -1,     9,    10,    28,    11,    12,    13,    14,    15,    16,
+      32
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+   STATE-NUM.  */
+#define YYPACT_NINF -31
+static const yytype_int8 yypact[] =
+{
+      22,   -31,   -31,   -31,   -31,    -1,    22,    22,   -11,    27,
+      11,   -31,    -6,   -31,   -31,   -31,   -31,    19,    11,     9,
+      26,   -31,    22,    22,    -4,    19,    24,    25,    28,    23,
+     -31,    29,    31,    11,    11,    19,   -31,   -31,    19,    19,
+     -31,    19,    26,   -31,    30,   -31,   -31,   -31,   -31,   -31
+};
+
+/* YYPGOTO[NTERM-NUM].  */
+static const yytype_int8 yypgoto[] =
+{
+     -31,   -31,    -3,   -30,   -31,   -17,   -31,   -31,   -31,    21,
+       1
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
+   positive, shift that token.  If negative, reduce the rule which
+   number is the opposite.  If zero, do what YYDEFACT says.
+   If YYTABLE_NINF, syntax error.  */
+#define YYTABLE_NINF -1
+static const yytype_uint8 yytable[] =
+{
+      29,    24,    25,    18,    19,    44,    26,    20,    37,    35,
+      27,    47,    17,     8,    22,    23,    22,    23,    29,    33,
+      34,    45,    46,    30,    29,     1,     2,    21,     3,     4,
+       5,     3,     4,     5,     6,     7,     8,    31,    41,     8,
+      38,    39,    40,    48,    49,    36,     0,     0,     0,    42,
+      43
+};
+
+static const yytype_int8 yycheck[] =
+{
+      17,     7,     8,     6,     7,    35,    12,    18,    25,    13,
+      16,    41,    13,    17,     5,     6,     5,     6,    35,    22,
+      23,    38,    39,    14,    41,     3,     4,     0,     9,    10,
+      11,     9,    10,    11,    12,    13,    17,    11,    15,    17,
+      16,    16,    14,    42,    14,    24,    -1,    -1,    -1,    20,
+      19
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+   symbol of state STATE-NUM.  */
+static const yytype_uint8 yystos[] =
+{
+       0,     3,     4,     9,    10,    11,    12,    13,    17,    22,
+      23,    25,    26,    27,    28,    29,    30,    13,    23,    23,
+      18,     0,     5,     6,     7,     8,    12,    16,    24,    26,
+      14,    11,    31,    23,    23,    13,    30,    26,    16,    16,
+      14,    15,    20,    19,    24,    26,    26,    24,    31,    14
+};
+
+#define yyerrok                (yyerrstatus = 0)
+#define yyclearin      (yychar = YYEMPTY)
+#define YYEMPTY                (-2)
+#define YYEOF          0
+
+#define YYACCEPT       goto yyacceptlab
+#define YYABORT                goto yyabortlab
+#define YYERROR                goto yyerrorlab
+
+
+/* Like YYERROR except do call yyerror.  This remains here temporarily
+   to ease the transition to the new meaning of YYERROR, for GCC.
+   Once GCC version 2 has supplanted version 1, this can go.  */
+
+#define YYFAIL         goto yyerrlab
+
+#define YYRECOVERING()  (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value)                                 \
+do                                                             \
+  if (yychar == YYEMPTY && yylen == 1)                         \
+    {                                                          \
+      yychar = (Token);                                                \
+      yylval = (Value);                                                \
+      yytoken = YYTRANSLATE (yychar);                          \
+      YYPOPSTACK (1);                                          \
+      goto yybackup;                                           \
+    }                                                          \
+  else                                                         \
+    {                                                          \
+      yyerror (YY_("syntax error: cannot back up")); \
+      YYERROR;                                                 \
+    }                                                          \
+while (YYID (0))
+
+
+#define YYTERROR       1
+#define YYERRCODE      256
+
+
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+   If N is 0, then set CURRENT to the empty location which ends
+   the previous symbol: RHS[0] (always defined).  */
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N)                               \
+    do                                                                 \
+      if (YYID (N))                                                    \
+       {                                                               \
+         (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;        \
+         (Current).first_column = YYRHSLOC (Rhs, 1).first_column;      \
+         (Current).last_line    = YYRHSLOC (Rhs, N).last_line;         \
+         (Current).last_column  = YYRHSLOC (Rhs, N).last_column;       \
+       }                                                               \
+      else                                                             \
+       {                                                               \
+         (Current).first_line   = (Current).last_line   =              \
+           YYRHSLOC (Rhs, 0).last_line;                                \
+         (Current).first_column = (Current).last_column =              \
+           YYRHSLOC (Rhs, 0).last_column;                              \
+       }                                                               \
+    while (YYID (0))
+#endif
+
+
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+   This macro was not mandated originally: define only if we know
+   we won't break user code: when these are the locations we know.  */
+
+#ifndef YY_LOCATION_PRINT
+# if YYLTYPE_IS_TRIVIAL
+#  define YY_LOCATION_PRINT(File, Loc)                 \
+     fprintf (File, "%d.%d-%d.%d",                     \
+             (Loc).first_line, (Loc).first_column,     \
+             (Loc).last_line,  (Loc).last_column)
+# else
+#  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
+#endif
+
+
+/* YYLEX -- calling `yylex' with the right arguments.  */
+
+#ifdef YYLEX_PARAM
+# define YYLEX yylex (YYLEX_PARAM)
+#else
+# define YYLEX yylex ()
+#endif
+
+/* Enable debugging if requested.  */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args)                       \
+do {                                           \
+  if (yydebug)                                 \
+    YYFPRINTF Args;                            \
+} while (YYID (0))
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)                   \
+do {                                                                     \
+  if (yydebug)                                                           \
+    {                                                                    \
+      YYFPRINTF (stderr, "%s ", Title);                                          \
+      yy_symbol_print (stderr,                                           \
+                 Type, Value); \
+      YYFPRINTF (stderr, "\n");                                                  \
+    }                                                                    \
+} while (YYID (0))
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT.  |
+`--------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+#else
+static void
+yy_symbol_value_print (yyoutput, yytype, yyvaluep)
+    FILE *yyoutput;
+    int yytype;
+    YYSTYPE const * const yyvaluep;
+#endif
+{
+  if (!yyvaluep)
+    return;
+# ifdef YYPRINT
+  if (yytype < YYNTOKENS)
+    YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# else
+  YYUSE (yyoutput);
+# endif
+  switch (yytype)
+    {
+      default:
+       break;
+    }
+}
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT.  |
+`--------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+#else
+static void
+yy_symbol_print (yyoutput, yytype, yyvaluep)
+    FILE *yyoutput;
+    int yytype;
+    YYSTYPE const * const yyvaluep;
+#endif
+{
+  if (yytype < YYNTOKENS)
+    YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+  else
+    YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+  yy_symbol_value_print (yyoutput, yytype, yyvaluep);
+  YYFPRINTF (yyoutput, ")");
+}
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included).                                                   |
+`------------------------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_stack_print (yytype_int16 *bottom, yytype_int16 *top)
+#else
+static void
+yy_stack_print (bottom, top)
+    yytype_int16 *bottom;
+    yytype_int16 *top;
+#endif
+{
+  YYFPRINTF (stderr, "Stack now");
+  for (; bottom <= top; ++bottom)
+    YYFPRINTF (stderr, " %d", *bottom);
+  YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top)                           \
+do {                                                           \
+  if (yydebug)                                                 \
+    yy_stack_print ((Bottom), (Top));                          \
+} while (YYID (0))
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced.  |
+`------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_reduce_print (YYSTYPE *yyvsp, int yyrule)
+#else
+static void
+yy_reduce_print (yyvsp, yyrule)
+    YYSTYPE *yyvsp;
+    int yyrule;
+#endif
+{
+  int yynrhs = yyr2[yyrule];
+  int yyi;
+  unsigned long int yylno = yyrline[yyrule];
+  YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
+            yyrule - 1, yylno);
+  /* The symbols being reduced.  */
+  for (yyi = 0; yyi < yynrhs; yyi++)
+    {
+      fprintf (stderr, "   $%d = ", yyi + 1);
+      yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
+                      &(yyvsp[(yyi + 1) - (yynrhs)])
+                                      );
+      fprintf (stderr, "\n");
+    }
+}
+
+# define YY_REDUCE_PRINT(Rule)         \
+do {                                   \
+  if (yydebug)                         \
+    yy_reduce_print (yyvsp, Rule); \
+} while (YYID (0))
+
+/* Nonzero means print parse trace.  It is left uninitialized so that
+   multiple parsers can coexist.  */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks.  */
+#ifndef        YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+   if the built-in stack extension method is used).
+
+   Do not make this value too large; the results are undefined if
+   YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+   evaluated with infinite-precision integer arithmetic.  */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+\f
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+#  if defined __GLIBC__ && defined _STRING_H
+#   define yystrlen strlen
+#  else
+/* Return the length of YYSTR.  */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static YYSIZE_T
+yystrlen (const char *yystr)
+#else
+static YYSIZE_T
+yystrlen (yystr)
+    const char *yystr;
+#endif
+{
+  YYSIZE_T yylen;
+  for (yylen = 0; yystr[yylen]; yylen++)
+    continue;
+  return yylen;
+}
+#  endif
+# endif
+
+# ifndef yystpcpy
+#  if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
+#   define yystpcpy stpcpy
+#  else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+   YYDEST.  */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static char *
+yystpcpy (char *yydest, const char *yysrc)
+#else
+static char *
+yystpcpy (yydest, yysrc)
+    char *yydest;
+    const char *yysrc;
+#endif
+{
+  char *yyd = yydest;
+  const char *yys = yysrc;
+
+  while ((*yyd++ = *yys++) != '\0')
+    continue;
+
+  return yyd - 1;
+}
+#  endif
+# endif
+
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+   quotes and backslashes, so that it's suitable for yyerror.  The
+   heuristic is that double-quoting is unnecessary unless the string
+   contains an apostrophe, a comma, or backslash (other than
+   backslash-backslash).  YYSTR is taken from yytname.  If YYRES is
+   null, do not copy; instead, return the length of what the result
+   would have been.  */
+static YYSIZE_T
+yytnamerr (char *yyres, const char *yystr)
+{
+  if (*yystr == '"')
+    {
+      YYSIZE_T yyn = 0;
+      char const *yyp = yystr;
+
+      for (;;)
+       switch (*++yyp)
+         {
+         case '\'':
+         case ',':
+           goto do_not_strip_quotes;
+
+         case '\\':
+           if (*++yyp != '\\')
+             goto do_not_strip_quotes;
+           /* Fall through.  */
+         default:
+           if (yyres)
+             yyres[yyn] = *yyp;
+           yyn++;
+           break;
+
+         case '"':
+           if (yyres)
+             yyres[yyn] = '\0';
+           return yyn;
+         }
+    do_not_strip_quotes: ;
+    }
+
+  if (! yyres)
+    return yystrlen (yystr);
+
+  return yystpcpy (yyres, yystr) - yyres;
+}
+# endif
+
+/* Copy into YYRESULT an error message about the unexpected token
+   YYCHAR while in state YYSTATE.  Return the number of bytes copied,
+   including the terminating null byte.  If YYRESULT is null, do not
+   copy anything; just return the number of bytes that would be
+   copied.  As a special case, return 0 if an ordinary "syntax error"
+   message will do.  Return YYSIZE_MAXIMUM if overflow occurs during
+   size calculation.  */
+static YYSIZE_T
+yysyntax_error (char *yyresult, int yystate, int yychar)
+{
+  int yyn = yypact[yystate];
+
+  if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
+    return 0;
+  else
+    {
+      int yytype = YYTRANSLATE (yychar);
+      YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
+      YYSIZE_T yysize = yysize0;
+      YYSIZE_T yysize1;
+      int yysize_overflow = 0;
+      enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+      char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+      int yyx;
+
+# if 0
+      /* This is so xgettext sees the translatable formats that are
+        constructed on the fly.  */
+      YY_("syntax error, unexpected %s");
+      YY_("syntax error, unexpected %s, expecting %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s or %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+# endif
+      char *yyfmt;
+      char const *yyf;
+      static char const yyunexpected[] = "syntax error, unexpected %s";
+      static char const yyexpecting[] = ", expecting %s";
+      static char const yyor[] = " or %s";
+      char yyformat[sizeof yyunexpected
+                   + sizeof yyexpecting - 1
+                   + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
+                      * (sizeof yyor - 1))];
+      char const *yyprefix = yyexpecting;
+
+      /* Start YYX at -YYN if negative to avoid negative indexes in
+        YYCHECK.  */
+      int yyxbegin = yyn < 0 ? -yyn : 0;
+
+      /* Stay within bounds of both yycheck and yytname.  */
+      int yychecklim = YYLAST - yyn + 1;
+      int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+      int yycount = 1;
+
+      yyarg[0] = yytname[yytype];
+      yyfmt = yystpcpy (yyformat, yyunexpected);
+
+      for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+       if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+         {
+           if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+             {
+               yycount = 1;
+               yysize = yysize0;
+               yyformat[sizeof yyunexpected - 1] = '\0';
+               break;
+             }
+           yyarg[yycount++] = yytname[yyx];
+           yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+           yysize_overflow |= (yysize1 < yysize);
+           yysize = yysize1;
+           yyfmt = yystpcpy (yyfmt, yyprefix);
+           yyprefix = yyor;
+         }
+
+      yyf = YY_(yyformat);
+      yysize1 = yysize + yystrlen (yyf);
+      yysize_overflow |= (yysize1 < yysize);
+      yysize = yysize1;
+
+      if (yysize_overflow)
+       return YYSIZE_MAXIMUM;
+
+      if (yyresult)
+       {
+         /* Avoid sprintf, as that infringes on the user's name space.
+            Don't have undefined behavior even if the translation
+            produced a string with the wrong number of "%s"s.  */
+         char *yyp = yyresult;
+         int yyi = 0;
+         while ((*yyp = *yyf) != '\0')
+           {
+             if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
+               {
+                 yyp += yytnamerr (yyp, yyarg[yyi++]);
+                 yyf += 2;
+               }
+             else
+               {
+                 yyp++;
+                 yyf++;
+               }
+           }
+       }
+      return yysize;
+    }
+}
+#endif /* YYERROR_VERBOSE */
+\f
+
+/*-----------------------------------------------.
+| Release the memory associated to this symbol.  |
+`-----------------------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yydestruct (yymsg, yytype, yyvaluep)
+    const char *yymsg;
+    int yytype;
+    YYSTYPE *yyvaluep;
+#endif
+{
+  YYUSE (yyvaluep);
+
+  if (!yymsg)
+    yymsg = "Deleting";
+  YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+  switch (yytype)
+    {
+
+      default:
+       break;
+    }
+}
+\f
+
+/* Prevent warnings from -Wmissing-prototypes.  */
+
+#ifdef YYPARSE_PARAM
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void *YYPARSE_PARAM);
+#else
+int yyparse ();
+#endif
+#else /* ! YYPARSE_PARAM */
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+
+
+/* The look-ahead symbol.  */
+int yychar;
+
+/* The semantic value of the look-ahead symbol.  */
+YYSTYPE yylval;
+
+/* Number of syntax errors so far.  */
+int yynerrs;
+
+
+
+/*----------.
+| yyparse.  |
+`----------*/
+
+#ifdef YYPARSE_PARAM
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (void *YYPARSE_PARAM)
+#else
+int
+yyparse (YYPARSE_PARAM)
+    void *YYPARSE_PARAM;
+#endif
+#else /* ! YYPARSE_PARAM */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (void)
+#else
+int
+yyparse ()
+
+#endif
+#endif
+{
+  
+  int yystate;
+  int yyn;
+  int yyresult;
+  /* Number of tokens to shift before error messages enabled.  */
+  int yyerrstatus;
+  /* Look-ahead token as an internal (translated) token number.  */
+  int yytoken = 0;
+#if YYERROR_VERBOSE
+  /* Buffer for error messages, and its allocated size.  */
+  char yymsgbuf[128];
+  char *yymsg = yymsgbuf;
+  YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
+#endif
+
+  /* Three stacks and their tools:
+     `yyss': related to states,
+     `yyvs': related to semantic values,
+     `yyls': related to locations.
+
+     Refer to the stacks thru separate pointers, to allow yyoverflow
+     to reallocate them elsewhere.  */
+
+  /* The state stack.  */
+  yytype_int16 yyssa[YYINITDEPTH];
+  yytype_int16 *yyss = yyssa;
+  yytype_int16 *yyssp;
+
+  /* The semantic value stack.  */
+  YYSTYPE yyvsa[YYINITDEPTH];
+  YYSTYPE *yyvs = yyvsa;
+  YYSTYPE *yyvsp;
+
+
+
+#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N))
+
+  YYSIZE_T yystacksize = YYINITDEPTH;
+
+  /* The variables used to return semantic value and location from the
+     action routines.  */
+  YYSTYPE yyval;
+
+
+  /* The number of symbols on the RHS of the reduced rule.
+     Keep to zero when no symbol should be popped.  */
+  int yylen = 0;
+
+  YYDPRINTF ((stderr, "Starting parse\n"));
+
+  yystate = 0;
+  yyerrstatus = 0;
+  yynerrs = 0;
+  yychar = YYEMPTY;            /* Cause a token to be read.  */
+
+  /* Initialize stack pointers.
+     Waste one element of value and location stack
+     so that they stay on the same level as the state stack.
+     The wasted elements are never initialized.  */
+
+  yyssp = yyss;
+  yyvsp = yyvs;
+
+  goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate.  |
+`------------------------------------------------------------*/
+ yynewstate:
+  /* In all cases, when you get here, the value and location stacks
+     have just been pushed.  So pushing a state here evens the stacks.  */
+  yyssp++;
+
+ yysetstate:
+  *yyssp = yystate;
+
+  if (yyss + yystacksize - 1 <= yyssp)
+    {
+      /* Get the current used size of the three stacks, in elements.  */
+      YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+      {
+       /* Give user a chance to reallocate the stack.  Use copies of
+          these so that the &'s don't force the real ones into
+          memory.  */
+       YYSTYPE *yyvs1 = yyvs;
+       yytype_int16 *yyss1 = yyss;
+
+
+       /* Each stack pointer address is followed by the size of the
+          data in use in that stack, in bytes.  This used to be a
+          conditional around just the two extra args, but that might
+          be undefined if yyoverflow is a macro.  */
+       yyoverflow (YY_("memory exhausted"),
+                   &yyss1, yysize * sizeof (*yyssp),
+                   &yyvs1, yysize * sizeof (*yyvsp),
+
+                   &yystacksize);
+
+       yyss = yyss1;
+       yyvs = yyvs1;
+      }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+      goto yyexhaustedlab;
+# else
+      /* Extend the stack our own way.  */
+      if (YYMAXDEPTH <= yystacksize)
+       goto yyexhaustedlab;
+      yystacksize *= 2;
+      if (YYMAXDEPTH < yystacksize)
+       yystacksize = YYMAXDEPTH;
+
+      {
+       yytype_int16 *yyss1 = yyss;
+       union yyalloc *yyptr =
+         (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+       if (! yyptr)
+         goto yyexhaustedlab;
+       YYSTACK_RELOCATE (yyss);
+       YYSTACK_RELOCATE (yyvs);
+
+#  undef YYSTACK_RELOCATE
+       if (yyss1 != yyssa)
+         YYSTACK_FREE (yyss1);
+      }
+# endif
+#endif /* no yyoverflow */
+
+      yyssp = yyss + yysize - 1;
+      yyvsp = yyvs + yysize - 1;
+
+
+      YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+                 (unsigned long int) yystacksize));
+
+      if (yyss + yystacksize - 1 <= yyssp)
+       YYABORT;
+    }
+
+  YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+  goto yybackup;
+
+/*-----------.
+| yybackup.  |
+`-----------*/
+yybackup:
+
+  /* Do appropriate processing given the current state.  Read a
+     look-ahead token if we need one and don't already have one.  */
+
+  /* First try to decide what to do without reference to look-ahead token.  */
+  yyn = yypact[yystate];
+  if (yyn == YYPACT_NINF)
+    goto yydefault;
+
+  /* Not known => get a look-ahead token if don't already have one.  */
+
+  /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol.  */
+  if (yychar == YYEMPTY)
+    {
+      YYDPRINTF ((stderr, "Reading a token: "));
+      yychar = YYLEX;
+    }
+
+  if (yychar <= YYEOF)
+    {
+      yychar = yytoken = YYEOF;
+      YYDPRINTF ((stderr, "Now at end of input.\n"));
+    }
+  else
+    {
+      yytoken = YYTRANSLATE (yychar);
+      YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+    }
+
+  /* If the proper action on seeing token YYTOKEN is to reduce or to
+     detect an error, take that action.  */
+  yyn += yytoken;
+  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+    goto yydefault;
+  yyn = yytable[yyn];
+  if (yyn <= 0)
+    {
+      if (yyn == 0 || yyn == YYTABLE_NINF)
+       goto yyerrlab;
+      yyn = -yyn;
+      goto yyreduce;
+    }
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+  /* Count tokens shifted since error; after three, turn off error
+     status.  */
+  if (yyerrstatus)
+    yyerrstatus--;
+
+  /* Shift the look-ahead token.  */
+  YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+
+  /* Discard the shifted token unless it is eof.  */
+  if (yychar != YYEOF)
+    yychar = YYEMPTY;
+
+  yystate = yyn;
+  *++yyvsp = yylval;
+
+  goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state.  |
+`-----------------------------------------------------------*/
+yydefault:
+  yyn = yydefact[yystate];
+  if (yyn == 0)
+    goto yyerrlab;
+  goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction.  |
+`-----------------------------*/
+yyreduce:
+  /* yyn is the number of a rule to reduce with.  */
+  yylen = yyr2[yyn];
+
+  /* If YYLEN is nonzero, implement the default value of the action:
+     `$$ = $1'.
+
+     Otherwise, the following line sets YYVAL to garbage.
+     This behavior is undocumented and Bison
+     users should not rely upon it.  Assigning to YYVAL
+     unconditionally makes the parser a bit smaller, and it avoids a
+     GCC warning that YYVAL may be used uninitialized.  */
+  yyval = yyvsp[1-yylen];
+
+
+  YY_REDUCE_PRINT (yyn);
+  switch (yyn)
+    {
+        case 2:
+#line 74 "heimdal/lib/hx509/sel-gram.y"
+    { _hx509_expr_input.expr = (yyvsp[(1) - (1)].expr); }
+    break;
+
+  case 3:
+#line 76 "heimdal/lib/hx509/sel-gram.y"
+    { (yyval.expr) = _hx509_make_expr(op_TRUE, NULL, NULL); }
+    break;
+
+  case 4:
+#line 77 "heimdal/lib/hx509/sel-gram.y"
+    { (yyval.expr) = _hx509_make_expr(op_FALSE, NULL, NULL); }
+    break;
+
+  case 5:
+#line 78 "heimdal/lib/hx509/sel-gram.y"
+    { (yyval.expr) = _hx509_make_expr(op_NOT, (yyvsp[(2) - (2)].expr), NULL); }
+    break;
+
+  case 6:
+#line 79 "heimdal/lib/hx509/sel-gram.y"
+    { (yyval.expr) = _hx509_make_expr(op_AND, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); }
+    break;
+
+  case 7:
+#line 80 "heimdal/lib/hx509/sel-gram.y"
+    { (yyval.expr) = _hx509_make_expr(op_OR, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); }
+    break;
+
+  case 8:
+#line 81 "heimdal/lib/hx509/sel-gram.y"
+    { (yyval.expr) = (yyvsp[(2) - (3)].expr); }
+    break;
+
+  case 9:
+#line 82 "heimdal/lib/hx509/sel-gram.y"
+    { (yyval.expr) = _hx509_make_expr(op_COMP, (yyvsp[(1) - (1)].expr), NULL); }
+    break;
+
+  case 10:
+#line 85 "heimdal/lib/hx509/sel-gram.y"
+    { (yyval.expr) = _hx509_make_expr(expr_WORDS, (yyvsp[(1) - (1)].expr), NULL); }
+    break;
+
+  case 11:
+#line 86 "heimdal/lib/hx509/sel-gram.y"
+    { (yyval.expr) = _hx509_make_expr(expr_WORDS, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); }
+    break;
+
+  case 12:
+#line 89 "heimdal/lib/hx509/sel-gram.y"
+    { (yyval.expr) = _hx509_make_expr(comp_EQ, (yyvsp[(1) - (4)].expr), (yyvsp[(4) - (4)].expr)); }
+    break;
+
+  case 13:
+#line 90 "heimdal/lib/hx509/sel-gram.y"
+    { (yyval.expr) = _hx509_make_expr(comp_NE, (yyvsp[(1) - (4)].expr), (yyvsp[(4) - (4)].expr)); }
+    break;
+
+  case 14:
+#line 91 "heimdal/lib/hx509/sel-gram.y"
+    { (yyval.expr) = _hx509_make_expr(comp_TAILEQ, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); }
+    break;
+
+  case 15:
+#line 92 "heimdal/lib/hx509/sel-gram.y"
+    { (yyval.expr) = _hx509_make_expr(comp_IN, (yyvsp[(1) - (5)].expr), (yyvsp[(4) - (5)].expr)); }
+    break;
+
+  case 16:
+#line 93 "heimdal/lib/hx509/sel-gram.y"
+    { (yyval.expr) = _hx509_make_expr(comp_IN, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); }
+    break;
+
+  case 17:
+#line 96 "heimdal/lib/hx509/sel-gram.y"
+    { (yyval.expr) = (yyvsp[(1) - (1)].expr); }
+    break;
+
+  case 18:
+#line 97 "heimdal/lib/hx509/sel-gram.y"
+    { (yyval.expr) = (yyvsp[(1) - (1)].expr); }
+    break;
+
+  case 19:
+#line 98 "heimdal/lib/hx509/sel-gram.y"
+    { (yyval.expr) = (yyvsp[(1) - (1)].expr); }
+    break;
+
+  case 20:
+#line 99 "heimdal/lib/hx509/sel-gram.y"
+    { (yyval.expr) = (yyvsp[(1) - (1)].expr); }
+    break;
+
+  case 21:
+#line 102 "heimdal/lib/hx509/sel-gram.y"
+    { (yyval.expr) = _hx509_make_expr(expr_NUMBER, (yyvsp[(1) - (1)].string), NULL); }
+    break;
+
+  case 22:
+#line 103 "heimdal/lib/hx509/sel-gram.y"
+    { (yyval.expr) = _hx509_make_expr(expr_STRING, (yyvsp[(1) - (1)].string), NULL); }
+    break;
+
+  case 23:
+#line 105 "heimdal/lib/hx509/sel-gram.y"
+    { 
+                       (yyval.expr) = _hx509_make_expr(expr_FUNCTION, (yyvsp[(1) - (4)].string), (yyvsp[(3) - (4)].expr)); }
+    break;
+
+  case 24:
+#line 108 "heimdal/lib/hx509/sel-gram.y"
+    { (yyval.expr) = (yyvsp[(3) - (4)].expr); }
+    break;
+
+  case 25:
+#line 111 "heimdal/lib/hx509/sel-gram.y"
+    { 
+                       (yyval.expr) = _hx509_make_expr(expr_VAR, (yyvsp[(1) - (3)].string), (yyvsp[(3) - (3)].expr)); }
+    break;
+
+  case 26:
+#line 113 "heimdal/lib/hx509/sel-gram.y"
+    { 
+                       (yyval.expr) = _hx509_make_expr(expr_VAR, (yyvsp[(1) - (1)].string), NULL); }
+    break;
+
+
+/* Line 1267 of yacc.c.  */
+#line 1501 "heimdal/lib/hx509/sel-gram.y"
+      default: break;
+    }
+  YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
+
+  YYPOPSTACK (yylen);
+  yylen = 0;
+  YY_STACK_PRINT (yyss, yyssp);
+
+  *++yyvsp = yyval;
+
+
+  /* Now `shift' the result of the reduction.  Determine what state
+     that goes to, based on the state we popped back to and the rule
+     number reduced by.  */
+
+  yyn = yyr1[yyn];
+
+  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+    yystate = yytable[yystate];
+  else
+    yystate = yydefgoto[yyn - YYNTOKENS];
+
+  goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+  /* If not already recovering from an error, report this error.  */
+  if (!yyerrstatus)
+    {
+      ++yynerrs;
+#if ! YYERROR_VERBOSE
+      yyerror (YY_("syntax error"));
+#else
+      {
+       YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
+       if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
+         {
+           YYSIZE_T yyalloc = 2 * yysize;
+           if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
+             yyalloc = YYSTACK_ALLOC_MAXIMUM;
+           if (yymsg != yymsgbuf)
+             YYSTACK_FREE (yymsg);
+           yymsg = (char *) YYSTACK_ALLOC (yyalloc);
+           if (yymsg)
+             yymsg_alloc = yyalloc;
+           else
+             {
+               yymsg = yymsgbuf;
+               yymsg_alloc = sizeof yymsgbuf;
+             }
+         }
+
+       if (0 < yysize && yysize <= yymsg_alloc)
+         {
+           (void) yysyntax_error (yymsg, yystate, yychar);
+           yyerror (yymsg);
+         }
+       else
+         {
+           yyerror (YY_("syntax error"));
+           if (yysize != 0)
+             goto yyexhaustedlab;
+         }
+      }
+#endif
+    }
+
+
+
+  if (yyerrstatus == 3)
+    {
+      /* If just tried and failed to reuse look-ahead token after an
+        error, discard it.  */
+
+      if (yychar <= YYEOF)
+       {
+         /* Return failure if at end of input.  */
+         if (yychar == YYEOF)
+           YYABORT;
+       }
+      else
+       {
+         yydestruct ("Error: discarding",
+                     yytoken, &yylval);
+         yychar = YYEMPTY;
+       }
+    }
+
+  /* Else will try to reuse look-ahead token after shifting the error
+     token.  */
+  goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR.  |
+`---------------------------------------------------*/
+yyerrorlab:
+
+  /* Pacify compilers like GCC when the user code never invokes
+     YYERROR and the label yyerrorlab therefore never appears in user
+     code.  */
+  if (/*CONSTCOND*/ 0)
+     goto yyerrorlab;
+
+  /* Do not reclaim the symbols of the rule which action triggered
+     this YYERROR.  */
+  YYPOPSTACK (yylen);
+  yylen = 0;
+  YY_STACK_PRINT (yyss, yyssp);
+  yystate = *yyssp;
+  goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR.  |
+`-------------------------------------------------------------*/
+yyerrlab1:
+  yyerrstatus = 3;     /* Each real token shifted decrements this.  */
+
+  for (;;)
+    {
+      yyn = yypact[yystate];
+      if (yyn != YYPACT_NINF)
+       {
+         yyn += YYTERROR;
+         if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+           {
+             yyn = yytable[yyn];
+             if (0 < yyn)
+               break;
+           }
+       }
+
+      /* Pop the current state because it cannot handle the error token.  */
+      if (yyssp == yyss)
+       YYABORT;
+
+
+      yydestruct ("Error: popping",
+                 yystos[yystate], yyvsp);
+      YYPOPSTACK (1);
+      yystate = *yyssp;
+      YY_STACK_PRINT (yyss, yyssp);
+    }
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+  *++yyvsp = yylval;
+
+
+  /* Shift the error token.  */
+  YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
+  yystate = yyn;
+  goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here.  |
+`-------------------------------------*/
+yyacceptlab:
+  yyresult = 0;
+  goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here.  |
+`-----------------------------------*/
+yyabortlab:
+  yyresult = 1;
+  goto yyreturn;
+
+#ifndef yyoverflow
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here.  |
+`-------------------------------------------------*/
+yyexhaustedlab:
+  yyerror (YY_("memory exhausted"));
+  yyresult = 2;
+  /* Fall through.  */
+#endif
+
+yyreturn:
+  if (yychar != YYEOF && yychar != YYEMPTY)
+     yydestruct ("Cleanup: discarding lookahead",
+                yytoken, &yylval);
+  /* Do not reclaim the symbols of the rule which action triggered
+     this YYABORT or YYACCEPT.  */
+  YYPOPSTACK (yylen);
+  YY_STACK_PRINT (yyss, yyssp);
+  while (yyssp != yyss)
+    {
+      yydestruct ("Cleanup: popping",
+                 yystos[*yyssp], yyvsp);
+      YYPOPSTACK (1);
+    }
+#ifndef yyoverflow
+  if (yyss != yyssa)
+    YYSTACK_FREE (yyss);
+#endif
+#if YYERROR_VERBOSE
+  if (yymsg != yymsgbuf)
+    YYSTACK_FREE (yymsg);
+#endif
+  /* Make sure YYID is used.  */
+  return YYID (yyresult);
+}
+
+
+
diff --git a/source4/heimdal/lib/hx509/sel-gram.h b/source4/heimdal/lib/hx509/sel-gram.h
new file mode 100644 (file)
index 0000000..bb4a64d
--- /dev/null
@@ -0,0 +1,83 @@
+/* A Bison parser, made by GNU Bison 2.3.  */
+
+/* Skeleton interface for Bison's Yacc-like parsers in C
+
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+/* As a special exception, you may create a larger work that contains
+   part or all of the Bison parser skeleton and distribute that work
+   under terms of your choice, so long as that work isn't itself a
+   parser generator using the skeleton or a modified version thereof
+   as a parser skeleton.  Alternatively, if you modify or redistribute
+   the parser skeleton itself, you may (at your option) remove this
+   special exception, which will cause the skeleton and the resulting
+   Bison output files to be licensed under the GNU General Public
+   License without this special exception.
+
+   This special exception was added by the Free Software Foundation in
+   version 2.2 of Bison.  */
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     kw_TRUE = 258,
+     kw_FALSE = 259,
+     kw_AND = 260,
+     kw_OR = 261,
+     kw_IN = 262,
+     kw_TAILMATCH = 263,
+     NUMBER = 264,
+     STRING = 265,
+     IDENTIFIER = 266
+   };
+#endif
+/* Tokens.  */
+#define kw_TRUE 258
+#define kw_FALSE 259
+#define kw_AND 260
+#define kw_OR 261
+#define kw_IN 262
+#define kw_TAILMATCH 263
+#define NUMBER 264
+#define STRING 265
+#define IDENTIFIER 266
+
+
+
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+#line 46 "heimdal/lib/hx509/sel-gram.y"
+{
+    char *string;
+    struct hx_expr *expr;
+}
+/* Line 1489 of yacc.c.  */
+#line 76 "heimdal/lib/hx509/sel-gram.y"
+       YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+extern YYSTYPE yylval;
+
diff --git a/source4/heimdal/lib/hx509/sel-gram.y b/source4/heimdal/lib/hx509/sel-gram.y
new file mode 100644 (file)
index 0000000..ca34a19
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2008 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden). 
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ *
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ */
+
+%{
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <hx_locl.h>
+
+RCSID("$Id$");
+
+%}
+
+%union {
+    char *string;
+    struct hx_expr *expr;
+}
+
+%token kw_TRUE
+%token kw_FALSE
+%token kw_AND
+%token kw_OR
+%token kw_IN
+%token kw_TAILMATCH
+
+%type <expr> expr
+%type <expr> comp
+%type <expr> word words
+%type <expr> number
+%type <expr> string
+%type <expr> function
+%type <expr> variable variables
+
+%token <string> NUMBER
+%token <string> STRING
+%token <string> IDENTIFIER
+
+%start start
+
+%%
+
+start: expr                    { _hx509_expr_input.expr = $1; }
+
+expr   : kw_TRUE               { $$ = _hx509_make_expr(op_TRUE, NULL, NULL); }
+       | kw_FALSE              { $$ = _hx509_make_expr(op_FALSE, NULL, NULL); }
+       | '!' expr              { $$ = _hx509_make_expr(op_NOT, $2, NULL); }
+       | expr kw_AND expr      { $$ = _hx509_make_expr(op_AND, $1, $3); }
+       | expr kw_OR expr       { $$ = _hx509_make_expr(op_OR, $1, $3); }
+       | '(' expr ')'          { $$ = $2; }
+       | comp                  { $$ = _hx509_make_expr(op_COMP, $1, NULL); }
+       ;
+
+words  : word                  { $$ = _hx509_make_expr(expr_WORDS, $1, NULL); }
+       | word ',' words        { $$ = _hx509_make_expr(expr_WORDS, $1, $3); }
+       ;
+
+comp   : word '=' '=' word     { $$ = _hx509_make_expr(comp_EQ, $1, $4); }
+       | word '!' '=' word     { $$ = _hx509_make_expr(comp_NE, $1, $4); } 
+       | word kw_TAILMATCH word { $$ = _hx509_make_expr(comp_TAILEQ, $1, $3); } 
+       | word kw_IN '(' words ')' { $$ = _hx509_make_expr(comp_IN, $1, $4); }
+       | word kw_IN variable   { $$ = _hx509_make_expr(comp_IN, $1, $3); }
+       ;
+
+word   : number                { $$ = $1; }
+       | string                { $$ = $1; }
+       | function              { $$ = $1; }
+       | variable              { $$ = $1; }
+       ;
+
+number : NUMBER        { $$ = _hx509_make_expr(expr_NUMBER, $1, NULL); };
+string : STRING        { $$ = _hx509_make_expr(expr_STRING, $1, NULL); };
+
+function: IDENTIFIER '(' words ')' { 
+                       $$ = _hx509_make_expr(expr_FUNCTION, $1, $3); }
+       ;
+variable: '%' '{' variables '}'        { $$ = $3; }
+       ;
+
+variables: IDENTIFIER '.' variables    { 
+                       $$ = _hx509_make_expr(expr_VAR, $1, $3); }
+       | IDENTIFIER                    { 
+                       $$ = _hx509_make_expr(expr_VAR, $1, NULL); }
+       ;
diff --git a/source4/heimdal/lib/hx509/sel-lex.c b/source4/heimdal/lib/hx509/sel-lex.c
new file mode 100644 (file)
index 0000000..8dcb374
--- /dev/null
@@ -0,0 +1,1899 @@
+#include "config.h"
+
+#line 3 "heimdal/lib/hx509/sel-lex.c"
+
+#define  YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+#define YY_FLEX_SUBMINOR_VERSION 34
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* First, we deal with  platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types. 
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t; 
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+#endif /* ! C99 */
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN               (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN              (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN              (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX               (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX              (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX              (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX              (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX             (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX             (4294967295U)
+#endif
+
+#endif /* ! FLEXINT_H */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else  /* ! __cplusplus */
+
+/* C99 requires __STDC__ to be defined as 1. */
+#if defined (__STDC__)
+
+#define YY_USE_CONST
+
+#endif /* defined (__STDC__) */
+#endif /* ! __cplusplus */
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index.  If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition.  This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN (yy_start) = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state.  The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START (((yy_start) - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart(yyin  )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#define YY_BUF_SIZE 16384
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE   ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+extern int yyleng;
+
+extern FILE *yyin, *yyout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+    #define YY_LESS_LINENO(n)
+    
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+       do \
+               { \
+               /* Undo effects of setting up yytext. */ \
+        int yyless_macro_arg = (n); \
+        YY_LESS_LINENO(yyless_macro_arg);\
+               *yy_cp = (yy_hold_char); \
+               YY_RESTORE_YY_MORE_OFFSET \
+               (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+               YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+               } \
+       while ( 0 )
+
+#define unput(c) yyunput( c, (yytext_ptr)  )
+
+/* The following is because we cannot portably get our hands on size_t
+ * (without autoconf's help, which isn't available because we want
+ * flex-generated scanners to compile on their own).
+ * Given that the standard has decreed that size_t exists since 1989,
+ * I guess we can afford to depend on it. Manoj.
+ */
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+       {
+       FILE *yy_input_file;
+
+       char *yy_ch_buf;                /* input buffer */
+       char *yy_buf_pos;               /* current position in input buffer */
+
+       /* Size of input buffer in bytes, not including room for EOB
+        * characters.
+        */
+       yy_size_t yy_buf_size;
+
+       /* Number of characters read into yy_ch_buf, not including EOB
+        * characters.
+        */
+       int yy_n_chars;
+
+       /* Whether we "own" the buffer - i.e., we know we created it,
+        * and can realloc() it to grow it, and should free() it to
+        * delete it.
+        */
+       int yy_is_our_buffer;
+
+       /* Whether this is an "interactive" input source; if so, and
+        * if we're using stdio for input, then we want to use getc()
+        * instead of fread(), to make sure we stop fetching input after
+        * each newline.
+        */
+       int yy_is_interactive;
+
+       /* Whether we're considered to be at the beginning of a line.
+        * If so, '^' rules will be active on the next match, otherwise
+        * not.
+        */
+       int yy_at_bol;
+
+    int yy_bs_lineno; /**< The line count. */
+    int yy_bs_column; /**< The column count. */
+    
+       /* Whether to try to fill the input buffer when we reach the
+        * end of it.
+        */
+       int yy_fill_buffer;
+
+       int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+       /* When an EOF's been seen but there's still some text to process
+        * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+        * shouldn't try reading from the input source any more.  We might
+        * still have a bunch of tokens to match, though, because of
+        * possible backing-up.
+        *
+        * When we actually see the EOF, we change the status to "new"
+        * (via yyrestart()), so that the user can continue scanning by
+        * just pointing yyin at a new input file.
+        */
+#define YY_BUFFER_EOF_PENDING 2
+
+       };
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* Stack of input buffers. */
+static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
+static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
+static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
+                          ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
+                          : NULL)
+
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
+
+/* yy_hold_char holds the character lost when yytext is formed. */
+static char yy_hold_char;
+static int yy_n_chars;         /* number of characters read into yy_ch_buf */
+int yyleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 0;                /* whether we need to initialize */
+static int yy_start = 0;       /* start state number */
+
+/* Flag which is used to allow yywrap()'s to do buffer switches
+ * instead of setting up a fresh yyin.  A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void yyrestart (FILE *input_file  );
+void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer  );
+YY_BUFFER_STATE yy_create_buffer (FILE *file,int size  );
+void yy_delete_buffer (YY_BUFFER_STATE b  );
+void yy_flush_buffer (YY_BUFFER_STATE b  );
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer  );
+void yypop_buffer_state (void );
+
+static void yyensure_buffer_stack (void );
+static void yy_load_buffer_state (void );
+static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file  );
+
+#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER )
+
+YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size  );
+YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str  );
+YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len  );
+
+void *yyalloc (yy_size_t  );
+void *yyrealloc (void *,yy_size_t  );
+void yyfree (void *  );
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+       { \
+       if ( ! YY_CURRENT_BUFFER ){ \
+        yyensure_buffer_stack (); \
+               YY_CURRENT_BUFFER_LVALUE =    \
+            yy_create_buffer(yyin,YY_BUF_SIZE ); \
+       } \
+       YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+       }
+
+#define yy_set_bol(at_bol) \
+       { \
+       if ( ! YY_CURRENT_BUFFER ){\
+        yyensure_buffer_stack (); \
+               YY_CURRENT_BUFFER_LVALUE =    \
+            yy_create_buffer(yyin,YY_BUF_SIZE ); \
+       } \
+       YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+       }
+
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+/* Begin user sect3 */
+
+typedef unsigned char YY_CHAR;
+
+FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+
+typedef int yy_state_type;
+
+extern int yylineno;
+
+int yylineno = 1;
+
+extern char *yytext;
+#define yytext_ptr yytext
+
+static yy_state_type yy_get_previous_state (void );
+static yy_state_type yy_try_NUL_trans (yy_state_type current_state  );
+static int yy_get_next_buffer (void );
+static void yy_fatal_error (yyconst char msg[]  );
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+       (yytext_ptr) = yy_bp; \
+       yyleng = (size_t) (yy_cp - yy_bp); \
+       (yy_hold_char) = *yy_cp; \
+       *yy_cp = '\0'; \
+       (yy_c_buf_p) = yy_cp;
+
+#define YY_NUM_RULES 12
+#define YY_END_OF_BUFFER 13
+/* This struct is not used in this scanner,
+   but its presence is necessary. */
+struct yy_trans_info
+       {
+       flex_int32_t yy_verify;
+       flex_int32_t yy_nxt;
+       };
+static yyconst flex_int16_t yy_accept[36] =
+    {   0,
+        0,    0,   13,   12,   11,    9,   10,    8,    7,    7,
+        7,    7,    7,    7,    7,    7,    7,    5,    4,    7,
+        7,    3,    7,    7,    7,    7,    7,    1,    2,    7,
+        7,    7,    7,    6,    0
+    } ;
+
+static yyconst flex_int32_t yy_ec[256] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    2,    4,    5,    1,    1,    4,    1,    1,    4,
+        4,    1,    1,    4,    6,    4,    1,    6,    6,    6,
+        6,    6,    6,    6,    6,    6,    6,    1,    1,    1,
+        4,    1,    1,    1,    7,    8,    9,   10,   11,   12,
+        8,   13,   14,    8,    8,   15,   16,   17,   18,    8,
+        8,   19,   20,   21,   22,    8,    8,    8,    8,    8,
+        1,    1,    1,    1,    6,    1,    8,    8,    8,    8,
+
+        8,    8,    8,    8,    8,    8,    8,    8,    8,    8,
+        8,    8,    8,    8,    8,    8,    8,    8,    8,    8,
+        8,    8,    4,    1,    4,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1
+    } ;
+
+static yyconst flex_int32_t yy_meta[23] =
+    {   0,
+        1,    1,    1,    1,    1,    2,    2,    2,    2,    2,
+        2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
+        2,    2
+    } ;
+
+static yyconst flex_int16_t yy_base[37] =
+    {   0,
+        0,    0,   43,   44,   44,   44,   44,   44,   25,    0,
+       34,   23,   20,   16,    0,   28,   22,    0,    0,   22,
+       12,    0,   13,   17,   20,   19,   13,    0,    0,   21,
+        6,   17,   12,    0,   44,   22
+    } ;
+
+static yyconst flex_int16_t yy_def[37] =
+    {   0,
+       35,    1,   35,   35,   35,   35,   35,   35,   36,   36,
+       36,   36,   36,   36,   36,   36,   36,   36,   36,   36,
+       36,   36,   36,   36,   36,   36,   36,   36,   36,   36,
+       36,   36,   36,   36,    0,   35
+    } ;
+
+static yyconst flex_int16_t yy_nxt[67] =
+    {   0,
+        4,    5,    6,    7,    8,    4,    9,   10,   10,   10,
+       10,   11,   10,   12,   10,   10,   10,   13,   10,   10,
+       14,   10,   20,   15,   34,   33,   32,   31,   30,   29,
+       28,   27,   26,   25,   21,   24,   23,   22,   19,   18,
+       17,   16,   35,    3,   35,   35,   35,   35,   35,   35,
+       35,   35,   35,   35,   35,   35,   35,   35,   35,   35,
+       35,   35,   35,   35,   35,   35
+    } ;
+
+static yyconst flex_int16_t yy_chk[67] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,   14,   36,   33,   32,   31,   30,   27,   26,
+       25,   24,   23,   21,   14,   20,   17,   16,   13,   12,
+       11,    9,    3,   35,   35,   35,   35,   35,   35,   35,
+       35,   35,   35,   35,   35,   35,   35,   35,   35,   35,
+       35,   35,   35,   35,   35,   35
+    } ;
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+extern int yy_flex_debug;
+int yy_flex_debug = 0;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *yytext;
+#line 1 "sel-lex.l"
+#line 2 "sel-lex.l"
+/*
+ * Copyright (c) 2004, 2008 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden). 
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ *
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ */
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#undef ECHO
+
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include "sel.h"
+#include "sel-gram.h"
+unsigned lineno = 1;
+
+static char * handle_string(void);
+static int lex_input(char *, int);
+
+struct hx_expr_input _hx509_expr_input;
+
+#define YY_NO_UNPUT 1
+
+#undef YY_INPUT
+#define YY_INPUT(buf,res,maxsize) (res = lex_input(buf, maxsize))
+
+#undef ECHO
+
+#line 541 "heimdal/lib/hx509/sel-lex.c"
+
+#define INITIAL 0
+
+#ifndef YY_NO_UNISTD_H
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+#include <unistd.h>
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+static int yy_init_globals (void );
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap (void );
+#else
+extern int yywrap (void );
+#endif
+#endif
+
+    static void yyunput (int c,char *buf_ptr  );
+    
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char *,yyconst char *,int );
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * );
+#endif
+
+#ifndef YY_NO_INPUT
+
+#ifdef __cplusplus
+static int yyinput (void );
+#else
+static int input (void );
+#endif
+
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO fwrite( yytext, yyleng, 1, yyout )
+#endif
+
+/* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+       if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+               { \
+               int c = '*'; \
+               int n; \
+               for ( n = 0; n < max_size && \
+                            (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+                       buf[n] = (char) c; \
+               if ( c == '\n' ) \
+                       buf[n++] = (char) c; \
+               if ( c == EOF && ferror( yyin ) ) \
+                       YY_FATAL_ERROR( "input in flex scanner failed" ); \
+               result = n; \
+               } \
+       else \
+               { \
+               errno=0; \
+               while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
+                       { \
+                       if( errno != EINTR) \
+                               { \
+                               YY_FATAL_ERROR( "input in flex scanner failed" ); \
+                               break; \
+                               } \
+                       errno=0; \
+                       clearerr(yyin); \
+                       } \
+               }\
+\
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int yylex (void);
+
+#define YY_DECL int yylex (void)
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+       YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+       register yy_state_type yy_current_state;
+       register char *yy_cp, *yy_bp;
+       register int yy_act;
+    
+#line 64 "sel-lex.l"
+
+
+#line 697 "heimdal/lib/hx509/sel-lex.c"
+
+       if ( !(yy_init) )
+               {
+               (yy_init) = 1;
+
+#ifdef YY_USER_INIT
+               YY_USER_INIT;
+#endif
+
+               if ( ! (yy_start) )
+                       (yy_start) = 1; /* first start state */
+
+               if ( ! yyin )
+                       yyin = stdin;
+
+               if ( ! yyout )
+                       yyout = stdout;
+
+               if ( ! YY_CURRENT_BUFFER ) {
+                       yyensure_buffer_stack ();
+                       YY_CURRENT_BUFFER_LVALUE =
+                               yy_create_buffer(yyin,YY_BUF_SIZE );
+               }
+
+               yy_load_buffer_state( );
+               }
+
+       while ( 1 )             /* loops until end-of-file is reached */
+               {
+               yy_cp = (yy_c_buf_p);
+
+               /* Support of yytext. */
+               *yy_cp = (yy_hold_char);
+
+               /* yy_bp points to the position in yy_ch_buf of the start of
+                * the current run.
+                */
+               yy_bp = yy_cp;
+
+               yy_current_state = (yy_start);
+yy_match:
+               do
+                       {
+                       register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+                       if ( yy_accept[yy_current_state] )
+                               {
+                               (yy_last_accepting_state) = yy_current_state;
+                               (yy_last_accepting_cpos) = yy_cp;
+                               }
+                       while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+                               {
+                               yy_current_state = (int) yy_def[yy_current_state];
+                               if ( yy_current_state >= 36 )
+                                       yy_c = yy_meta[(unsigned int) yy_c];
+                               }
+                       yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+                       ++yy_cp;
+                       }
+               while ( yy_base[yy_current_state] != 44 );
+
+yy_find_action:
+               yy_act = yy_accept[yy_current_state];
+               if ( yy_act == 0 )
+                       { /* have to back up */
+                       yy_cp = (yy_last_accepting_cpos);
+                       yy_current_state = (yy_last_accepting_state);
+                       yy_act = yy_accept[yy_current_state];
+                       }
+
+               YY_DO_BEFORE_ACTION;
+
+do_action:     /* This label is used only to access EOF actions. */
+
+               switch ( yy_act )
+       { /* beginning of action switch */
+                       case 0: /* must back up */
+                       /* undo the effects of YY_DO_BEFORE_ACTION */
+                       *yy_cp = (yy_hold_char);
+                       yy_cp = (yy_last_accepting_cpos);
+                       yy_current_state = (yy_last_accepting_state);
+                       goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 66 "sel-lex.l"
+{ return kw_TRUE; }
+       YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 67 "sel-lex.l"
+{ return kw_FALSE; }
+       YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 68 "sel-lex.l"
+{ return kw_AND; }
+       YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 69 "sel-lex.l"
+{ return kw_OR; }
+       YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 70 "sel-lex.l"
+{ return kw_IN; }
+       YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 71 "sel-lex.l"
+{ return kw_TAILMATCH; }
+       YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 73 "sel-lex.l"
+{
+                         yylval.string = strdup ((const char *)yytext);
+                         return IDENTIFIER;
+                       }
+       YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 77 "sel-lex.l"
+{ yylval.string = handle_string(); return STRING; }
+       YY_BREAK
+case 9:
+/* rule 9 can match eol */
+YY_RULE_SETUP
+#line 78 "sel-lex.l"
+{ ++lineno; }
+       YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 79 "sel-lex.l"
+{ return *yytext; }
+       YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 80 "sel-lex.l"
+;
+       YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 81 "sel-lex.l"
+ECHO;
+       YY_BREAK
+#line 844 "heimdal/lib/hx509/sel-lex.c"
+case YY_STATE_EOF(INITIAL):
+       yyterminate();
+
+       case YY_END_OF_BUFFER:
+               {
+               /* Amount of text matched not including the EOB char. */
+               int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
+
+               /* Undo the effects of YY_DO_BEFORE_ACTION. */
+               *yy_cp = (yy_hold_char);
+               YY_RESTORE_YY_MORE_OFFSET
+
+               if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+                       {
+                       /* We're scanning a new file or input source.  It's
+                        * possible that this happened because the user
+                        * just pointed yyin at a new source and called
+                        * yylex().  If so, then we have to assure
+                        * consistency between YY_CURRENT_BUFFER and our
+                        * globals.  Here is the right place to do so, because
+                        * this is the first action (other than possibly a
+                        * back-up) that will match for the new input source.
+                        */
+                       (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+                       YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
+                       YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+                       }
+
+               /* Note that here we test for yy_c_buf_p "<=" to the position
+                * of the first EOB in the buffer, since yy_c_buf_p will
+                * already have been incremented past the NUL character
+                * (since all states make transitions on EOB to the
+                * end-of-buffer state).  Contrast this with the test
+                * in input().
+                */
+               if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+                       { /* This was really a NUL. */
+                       yy_state_type yy_next_state;
+
+                       (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
+
+                       yy_current_state = yy_get_previous_state(  );
+
+                       /* Okay, we're now positioned to make the NUL
+                        * transition.  We couldn't have
+                        * yy_get_previous_state() go ahead and do it
+                        * for us because it doesn't know how to deal
+                        * with the possibility of jamming (and we don't
+                        * want to build jamming into it because then it
+                        * will run more slowly).
+                        */
+
+                       yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+                       yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+
+                       if ( yy_next_state )
+                               {
+                               /* Consume the NUL. */
+                               yy_cp = ++(yy_c_buf_p);
+                               yy_current_state = yy_next_state;
+                               goto yy_match;
+                               }
+
+                       else
+                               {
+                               yy_cp = (yy_c_buf_p);
+                               goto yy_find_action;
+                               }
+                       }
+
+               else switch ( yy_get_next_buffer(  ) )
+                       {
+                       case EOB_ACT_END_OF_FILE:
+                               {
+                               (yy_did_buffer_switch_on_eof) = 0;
+
+                               if ( yywrap( ) )
+                                       {
+                                       /* Note: because we've taken care in
+                                        * yy_get_next_buffer() to have set up
+                                        * yytext, we can now set up
+                                        * yy_c_buf_p so that if some total
+                                        * hoser (like flex itself) wants to
+                                        * call the scanner after we return the
+                                        * YY_NULL, it'll still work - another
+                                        * YY_NULL will get returned.
+                                        */
+                                       (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
+
+                                       yy_act = YY_STATE_EOF(YY_START);
+                                       goto do_action;
+                                       }
+
+                               else
+                                       {
+                                       if ( ! (yy_did_buffer_switch_on_eof) )
+                                               YY_NEW_FILE;
+                                       }
+                               break;
+                               }
+
+                       case EOB_ACT_CONTINUE_SCAN:
+                               (yy_c_buf_p) =
+                                       (yytext_ptr) + yy_amount_of_matched_text;
+
+                               yy_current_state = yy_get_previous_state(  );
+
+                               yy_cp = (yy_c_buf_p);
+                               yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+                               goto yy_match;
+
+                       case EOB_ACT_LAST_MATCH:
+                               (yy_c_buf_p) =
+                               &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
+
+                               yy_current_state = yy_get_previous_state(  );
+
+                               yy_cp = (yy_c_buf_p);
+                               yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+                               goto yy_find_action;
+                       }
+               break;
+               }
+
+       default:
+               YY_FATAL_ERROR(
+                       "fatal flex scanner internal error--no action found" );
+       } /* end of action switch */
+               } /* end of scanning one token */
+} /* end of yylex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ *     EOB_ACT_LAST_MATCH -
+ *     EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ *     EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer (void)
+{
+       register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+       register char *source = (yytext_ptr);
+       register int number_to_move, i;
+       int ret_val;
+
+       if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
+               YY_FATAL_ERROR(
+               "fatal flex scanner internal error--end of buffer missed" );
+
+       if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+               { /* Don't try to fill the buffer, so this is an EOF. */
+               if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
+                       {
+                       /* We matched a single character, the EOB, so
+                        * treat this as a final EOF.
+                        */
+                       return EOB_ACT_END_OF_FILE;
+                       }
+
+               else
+                       {
+                       /* We matched some text prior to the EOB, first
+                        * process it.
+                        */
+                       return EOB_ACT_LAST_MATCH;
+                       }
+               }
+
+       /* Try to read more data. */
+
+       /* First move last chars to start of buffer. */
+       number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
+
+       for ( i = 0; i < number_to_move; ++i )
+               *(dest++) = *(source++);
+
+       if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+               /* don't do the read, it's not guaranteed to return an EOF,
+                * just force an EOF
+                */
+               YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
+
+       else
+               {
+                       int num_to_read =
+                       YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+               while ( num_to_read <= 0 )
+                       { /* Not enough room in the buffer - grow it. */
+
+                       /* just a shorter name for the current buffer */
+                       YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
+
+                       int yy_c_buf_p_offset =
+                               (int) ((yy_c_buf_p) - b->yy_ch_buf);
+
+                       if ( b->yy_is_our_buffer )
+                               {
+                               int new_size = b->yy_buf_size * 2;
+
+                               if ( new_size <= 0 )
+                                       b->yy_buf_size += b->yy_buf_size / 8;
+                               else
+                                       b->yy_buf_size *= 2;
+
+                               b->yy_ch_buf = (char *)
+                                       /* Include room in for 2 EOB chars. */
+                                       yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2  );
+                               }
+                       else
+                               /* Can't grow it, we don't own it. */
+                               b->yy_ch_buf = 0;
+
+                       if ( ! b->yy_ch_buf )
+                               YY_FATAL_ERROR(
+                               "fatal error - scanner input buffer overflow" );
+
+                       (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+                       num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+                                               number_to_move - 1;
+
+                       }
+
+               if ( num_to_read > YY_READ_BUF_SIZE )
+                       num_to_read = YY_READ_BUF_SIZE;
+
+               /* Read in more data. */
+               YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+                       (yy_n_chars), (size_t) num_to_read );
+
+               YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+               }
+
+       if ( (yy_n_chars) == 0 )
+               {
+               if ( number_to_move == YY_MORE_ADJ )
+                       {
+                       ret_val = EOB_ACT_END_OF_FILE;
+                       yyrestart(yyin  );
+                       }
+
+               else
+                       {
+                       ret_val = EOB_ACT_LAST_MATCH;
+                       YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+                               YY_BUFFER_EOF_PENDING;
+                       }
+               }
+
+       else
+               ret_val = EOB_ACT_CONTINUE_SCAN;
+
+       if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+               /* Extend the array by 50%, plus the number we really need. */
+               yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
+               YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size  );
+               if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+                       YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+       }
+
+       (yy_n_chars) += number_to_move;
+       YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
+       YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
+
+       (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+       return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+    static yy_state_type yy_get_previous_state (void)
+{
+       register yy_state_type yy_current_state;
+       register char *yy_cp;
+    
+       yy_current_state = (yy_start);
+
+       for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
+               {
+               register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+               if ( yy_accept[yy_current_state] )
+                       {
+                       (yy_last_accepting_state) = yy_current_state;
+                       (yy_last_accepting_cpos) = yy_cp;
+                       }
+               while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+                       {
+                       yy_current_state = (int) yy_def[yy_current_state];
+                       if ( yy_current_state >= 36 )
+                               yy_c = yy_meta[(unsigned int) yy_c];
+                       }
+               yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+               }
+
+       return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ *     next_state = yy_try_NUL_trans( current_state );
+ */
+    static yy_state_type yy_try_NUL_trans  (yy_state_type yy_current_state )
+{
+       register int yy_is_jam;
+       register char *yy_cp = (yy_c_buf_p);
+
+       register YY_CHAR yy_c = 1;
+       if ( yy_accept[yy_current_state] )
+               {
+               (yy_last_accepting_state) = yy_current_state;
+               (yy_last_accepting_cpos) = yy_cp;
+               }
+       while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+               {
+               yy_current_state = (int) yy_def[yy_current_state];
+               if ( yy_current_state >= 36 )
+                       yy_c = yy_meta[(unsigned int) yy_c];
+               }
+       yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+       yy_is_jam = (yy_current_state == 35);
+
+       return yy_is_jam ? 0 : yy_current_state;
+}
+
+    static void yyunput (int c, register char * yy_bp )
+{
+       register char *yy_cp;
+    
+    yy_cp = (yy_c_buf_p);
+
+       /* undo effects of setting up yytext */
+       *yy_cp = (yy_hold_char);
+
+       if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+               { /* need to shift things up to make room */
+               /* +2 for EOB chars. */
+               register int number_to_move = (yy_n_chars) + 2;
+               register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
+                                       YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
+               register char *source =
+                               &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
+
+               while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+                       *--dest = *--source;
+
+               yy_cp += (int) (dest - source);
+               yy_bp += (int) (dest - source);
+               YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
+                       (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
+
+               if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+                       YY_FATAL_ERROR( "flex scanner push-back overflow" );
+               }
+
+       *--yy_cp = (char) c;
+
+       (yytext_ptr) = yy_bp;
+       (yy_hold_char) = *yy_cp;
+       (yy_c_buf_p) = yy_cp;
+}
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+    static int yyinput (void)
+#else
+    static int input  (void)
+#endif
+
+{
+       int c;
+    
+       *(yy_c_buf_p) = (yy_hold_char);
+
+       if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
+               {
+               /* yy_c_buf_p now points to the character we want to return.
+                * If this occurs *before* the EOB characters, then it's a
+                * valid NUL; if not, then we've hit the end of the buffer.
+                */
+               if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+                       /* This was really a NUL. */
+                       *(yy_c_buf_p) = '\0';
+
+               else
+                       { /* need more input */
+                       int offset = (yy_c_buf_p) - (yytext_ptr);
+                       ++(yy_c_buf_p);
+
+                       switch ( yy_get_next_buffer(  ) )
+                               {
+                               case EOB_ACT_LAST_MATCH:
+                                       /* This happens because yy_g_n_b()
+                                        * sees that we've accumulated a
+                                        * token and flags that we need to
+                                        * try matching the token before
+                                        * proceeding.  But for input(),
+                                        * there's no matching to consider.
+                                        * So convert the EOB_ACT_LAST_MATCH
+                                        * to EOB_ACT_END_OF_FILE.
+                                        */
+
+                                       /* Reset buffer status. */
+                                       yyrestart(yyin );
+
+                                       /*FALLTHROUGH*/
+
+                               case EOB_ACT_END_OF_FILE:
+                                       {
+                                       if ( yywrap( ) )
+                                               return EOF;
+
+                                       if ( ! (yy_did_buffer_switch_on_eof) )
+                                               YY_NEW_FILE;
+#ifdef __cplusplus
+                                       return yyinput();
+#else
+                                       return input();
+#endif
+                                       }
+
+                               case EOB_ACT_CONTINUE_SCAN:
+                                       (yy_c_buf_p) = (yytext_ptr) + offset;
+                                       break;
+                               }
+                       }
+               }
+
+       c = *(unsigned char *) (yy_c_buf_p);    /* cast for 8-bit char's */
+       *(yy_c_buf_p) = '\0';   /* preserve yytext */
+       (yy_hold_char) = *++(yy_c_buf_p);
+
+       return c;
+}
+#endif /* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ * 
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+    void yyrestart  (FILE * input_file )
+{
+    
+       if ( ! YY_CURRENT_BUFFER ){
+        yyensure_buffer_stack ();
+               YY_CURRENT_BUFFER_LVALUE =
+            yy_create_buffer(yyin,YY_BUF_SIZE );
+       }
+
+       yy_init_buffer(YY_CURRENT_BUFFER,input_file );
+       yy_load_buffer_state( );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ * 
+ */
+    void yy_switch_to_buffer  (YY_BUFFER_STATE  new_buffer )
+{
+    
+       /* TODO. We should be able to replace this entire function body
+        * with
+        *              yypop_buffer_state();
+        *              yypush_buffer_state(new_buffer);
+     */
+       yyensure_buffer_stack ();
+       if ( YY_CURRENT_BUFFER == new_buffer )
+               return;
+
+       if ( YY_CURRENT_BUFFER )
+               {
+               /* Flush out information for old buffer. */
+               *(yy_c_buf_p) = (yy_hold_char);
+               YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+               YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+               }
+
+       YY_CURRENT_BUFFER_LVALUE = new_buffer;
+       yy_load_buffer_state( );
+
+       /* We don't actually know whether we did this switch during
+        * EOF (yywrap()) processing, but the only time this flag
+        * is looked at is after yywrap() is called, so it's safe
+        * to go ahead and always set it.
+        */
+       (yy_did_buffer_switch_on_eof) = 1;
+}
+
+static void yy_load_buffer_state  (void)
+{
+       (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+       (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+       yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+       (yy_hold_char) = *(yy_c_buf_p);
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ * 
+ * @return the allocated buffer state.
+ */
+    YY_BUFFER_STATE yy_create_buffer  (FILE * file, int  size )
+{
+       YY_BUFFER_STATE b;
+    
+       b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state )  );
+       if ( ! b )
+               YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+       b->yy_buf_size = size;
+
+       /* yy_ch_buf has to be 2 characters longer than the size given because
+        * we need to put in 2 end-of-buffer characters.
+        */
+       b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2  );
+       if ( ! b->yy_ch_buf )
+               YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+       b->yy_is_our_buffer = 1;
+
+       yy_init_buffer(b,file );
+
+       return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with yy_create_buffer()
+ * 
+ */
+    void yy_delete_buffer (YY_BUFFER_STATE  b )
+{
+    
+       if ( ! b )
+               return;
+
+       if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+               YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+       if ( b->yy_is_our_buffer )
+               yyfree((void *) b->yy_ch_buf  );
+
+       yyfree((void *) b  );
+}
+
+#ifndef __cplusplus
+extern int isatty (int );
+#endif /* __cplusplus */
+    
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a yyrestart() or at EOF.
+ */
+    static void yy_init_buffer  (YY_BUFFER_STATE  b, FILE * file )
+
+{
+       int oerrno = errno;
+    
+       yy_flush_buffer(b );
+
+       b->yy_input_file = file;
+       b->yy_fill_buffer = 1;
+
+    /* If b is the current buffer, then yy_init_buffer was _probably_
+     * called from yyrestart() or through yy_get_next_buffer.
+     * In that case, we don't want to reset the lineno or column.
+     */
+    if (b != YY_CURRENT_BUFFER){
+        b->yy_bs_lineno = 1;
+        b->yy_bs_column = 0;
+    }
+
+        b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+    
+       errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ * 
+ */
+    void yy_flush_buffer (YY_BUFFER_STATE  b )
+{
+       if ( ! b )
+               return;
+
+       b->yy_n_chars = 0;
+
+       /* We always need two end-of-buffer characters.  The first causes
+        * a transition to the end-of-buffer state.  The second causes
+        * a jam in that state.
+        */
+       b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+       b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+       b->yy_buf_pos = &b->yy_ch_buf[0];
+
+       b->yy_at_bol = 1;
+       b->yy_buffer_status = YY_BUFFER_NEW;
+
+       if ( b == YY_CURRENT_BUFFER )
+               yy_load_buffer_state( );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ *  the current state. This function will allocate the stack
+ *  if necessary.
+ *  @param new_buffer The new state.
+ *  
+ */
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer )
+{
+       if (new_buffer == NULL)
+               return;
+
+       yyensure_buffer_stack();
+
+       /* This block is copied from yy_switch_to_buffer. */
+       if ( YY_CURRENT_BUFFER )
+               {
+               /* Flush out information for old buffer. */
+               *(yy_c_buf_p) = (yy_hold_char);
+               YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+               YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+               }
+
+       /* Only push if top exists. Otherwise, replace top. */
+       if (YY_CURRENT_BUFFER)
+               (yy_buffer_stack_top)++;
+       YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+       /* copied from yy_switch_to_buffer. */
+       yy_load_buffer_state( );
+       (yy_did_buffer_switch_on_eof) = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ *  The next element becomes the new top.
+ *  
+ */
+void yypop_buffer_state (void)
+{
+       if (!YY_CURRENT_BUFFER)
+               return;
+
+       yy_delete_buffer(YY_CURRENT_BUFFER );
+       YY_CURRENT_BUFFER_LVALUE = NULL;
+       if ((yy_buffer_stack_top) > 0)
+               --(yy_buffer_stack_top);
+
+       if (YY_CURRENT_BUFFER) {
+               yy_load_buffer_state( );
+               (yy_did_buffer_switch_on_eof) = 1;
+       }
+}
+
+/* Allocates the stack if it does not exist.
+ *  Guarantees space for at least one push.
+ */
+static void yyensure_buffer_stack (void)
+{
+       int num_to_alloc;
+    
+       if (!(yy_buffer_stack)) {
+
+               /* First allocation is just for 2 elements, since we don't know if this
+                * scanner will even need a stack. We use 2 instead of 1 to avoid an
+                * immediate realloc on the next call.
+         */
+               num_to_alloc = 1;
+               (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
+                                                               (num_to_alloc * sizeof(struct yy_buffer_state*)
+                                                               );
+               if ( ! (yy_buffer_stack) )
+                       YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+                                                                 
+               memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+                               
+               (yy_buffer_stack_max) = num_to_alloc;
+               (yy_buffer_stack_top) = 0;
+               return;
+       }
+
+       if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
+
+               /* Increase the buffer to prepare for a possible push. */
+               int grow_size = 8 /* arbitrary grow size */;
+
+               num_to_alloc = (yy_buffer_stack_max) + grow_size;
+               (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc
+                                                               ((yy_buffer_stack),
+                                                               num_to_alloc * sizeof(struct yy_buffer_state*)
+                                                               );
+               if ( ! (yy_buffer_stack) )
+                       YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
+               /* zero only the new slots.*/
+               memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
+               (yy_buffer_stack_max) = num_to_alloc;
+       }
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ * 
+ * @return the newly allocated buffer state object. 
+ */
+YY_BUFFER_STATE yy_scan_buffer  (char * base, yy_size_t  size )
+{
+       YY_BUFFER_STATE b;
+    
+       if ( size < 2 ||
+            base[size-2] != YY_END_OF_BUFFER_CHAR ||
+            base[size-1] != YY_END_OF_BUFFER_CHAR )
+               /* They forgot to leave room for the EOB's. */
+               return 0;
+
+       b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state )  );
+       if ( ! b )
+               YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+       b->yy_buf_size = size - 2;      /* "- 2" to take care of EOB's */
+       b->yy_buf_pos = b->yy_ch_buf = base;
+       b->yy_is_our_buffer = 0;
+       b->yy_input_file = 0;
+       b->yy_n_chars = b->yy_buf_size;
+       b->yy_is_interactive = 0;
+       b->yy_at_bol = 1;
+       b->yy_fill_buffer = 0;
+       b->yy_buffer_status = YY_BUFFER_NEW;
+
+       yy_switch_to_buffer(b  );
+
+       return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to yylex() will
+ * scan from a @e copy of @a str.
+ * @param yystr a NUL-terminated string to scan
+ * 
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ *       yy_scan_bytes() instead.
+ */
+YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
+{
+    
+       return yy_scan_bytes(yystr,strlen(yystr) );
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
+ * scan from a @e copy of @a bytes.
+ * @param bytes the byte buffer to scan
+ * @param len the number of bytes in the buffer pointed to by @a bytes.
+ * 
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_bytes  (yyconst char * yybytes, int  _yybytes_len )
+{
+       YY_BUFFER_STATE b;
+       char *buf;
+       yy_size_t n;
+       int i;
+    
+       /* Get memory for full buffer, including space for trailing EOB's. */
+       n = _yybytes_len + 2;
+       buf = (char *) yyalloc(n  );
+       if ( ! buf )
+               YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+       for ( i = 0; i < _yybytes_len; ++i )
+               buf[i] = yybytes[i];
+
+       buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+
+       b = yy_scan_buffer(buf,n );
+       if ( ! b )
+               YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+       /* It's okay to grow etc. this buffer, and we should throw it
+        * away when we're done.
+        */
+       b->yy_is_our_buffer = 1;
+
+       return b;
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+static void yy_fatal_error (yyconst char* msg )
+{
+       (void) fprintf( stderr, "%s\n", msg );
+       exit( YY_EXIT_FAILURE );
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+       do \
+               { \
+               /* Undo effects of setting up yytext. */ \
+        int yyless_macro_arg = (n); \
+        YY_LESS_LINENO(yyless_macro_arg);\
+               yytext[yyleng] = (yy_hold_char); \
+               (yy_c_buf_p) = yytext + yyless_macro_arg; \
+               (yy_hold_char) = *(yy_c_buf_p); \
+               *(yy_c_buf_p) = '\0'; \
+               yyleng = yyless_macro_arg; \
+               } \
+       while ( 0 )
+
+/* Accessor  methods (get/set functions) to struct members. */
+
+/** Get the current line number.
+ * 
+ */
+int yyget_lineno  (void)
+{
+        
+    return yylineno;
+}
+
+/** Get the input stream.
+ * 
+ */
+FILE *yyget_in  (void)
+{
+        return yyin;
+}
+
+/** Get the output stream.
+ * 
+ */
+FILE *yyget_out  (void)
+{
+        return yyout;
+}
+
+/** Get the length of the current token.
+ * 
+ */
+int yyget_leng  (void)
+{
+        return yyleng;
+}
+
+/** Get the current token.
+ * 
+ */
+
+char *yyget_text  (void)
+{
+        return yytext;
+}
+
+/** Set the current line number.
+ * @param line_number
+ * 
+ */
+void yyset_lineno (int  line_number )
+{
+    
+    yylineno = line_number;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param in_str A readable stream.
+ * 
+ * @see yy_switch_to_buffer
+ */
+void yyset_in (FILE *  in_str )
+{
+        yyin = in_str ;
+}
+
+void yyset_out (FILE *  out_str )
+{
+        yyout = out_str ;
+}
+
+int yyget_debug  (void)
+{
+        return yy_flex_debug;
+}
+
+void yyset_debug (int  bdebug )
+{
+        yy_flex_debug = bdebug ;
+}
+
+static int yy_init_globals (void)
+{
+        /* Initialization is the same as for the non-reentrant scanner.
+     * This function is called from yylex_destroy(), so don't allocate here.
+     */
+
+    (yy_buffer_stack) = 0;
+    (yy_buffer_stack_top) = 0;
+    (yy_buffer_stack_max) = 0;
+    (yy_c_buf_p) = (char *) 0;
+    (yy_init) = 0;
+    (yy_start) = 0;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+    yyin = stdin;
+    yyout = stdout;
+#else
+    yyin = (FILE *) 0;
+    yyout = (FILE *) 0;
+#endif
+
+    /* For future reference: Set errno on error, since we are called by
+     * yylex_init()
+     */
+    return 0;
+}
+
+/* yylex_destroy is for both reentrant and non-reentrant scanners. */
+int yylex_destroy  (void)
+{
+    
+    /* Pop the buffer stack, destroying each element. */
+       while(YY_CURRENT_BUFFER){
+               yy_delete_buffer(YY_CURRENT_BUFFER  );
+               YY_CURRENT_BUFFER_LVALUE = NULL;
+               yypop_buffer_state();
+       }
+
+       /* Destroy the stack itself. */
+       yyfree((yy_buffer_stack) );
+       (yy_buffer_stack) = NULL;
+
+    /* Reset the globals. This is important in a non-reentrant scanner so the next time
+     * yylex() is called, initialization will occur. */
+    yy_init_globals( );
+
+    return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
+{
+       register int i;
+       for ( i = 0; i < n; ++i )
+               s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * s )
+{
+       register int n;
+       for ( n = 0; s[n]; ++n )
+               ;
+
+       return n;
+}
+#endif
+
+void *yyalloc (yy_size_t  size )
+{
+       return (void *) malloc( size );
+}
+
+void *yyrealloc  (void * ptr, yy_size_t  size )
+{
+       /* The cast to (char *) in the following accommodates both
+        * implementations that use char* generic pointers, and those
+        * that use void* generic pointers.  It works with the latter
+        * because both ANSI C and C++ allow castless assignment from
+        * any pointer type to void*, and deal with argument conversions
+        * as though doing an assignment.
+        */
+       return (void *) realloc( (char *) ptr, size );
+}
+
+void yyfree (void * ptr )
+{
+       free( (char *) ptr );   /* see yyrealloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+#line 81 "sel-lex.l"
+
+
+
+static char *
+handle_string(void)
+{
+    char x[1024];
+    int i = 0;
+    int c;
+    int quote = 0;
+    while((c = input()) != EOF){
+       if(quote) {
+           x[i++] = '\\';
+           x[i++] = c;
+           quote = 0;
+           continue;
+       }
+       if(c == '\n'){
+           _hx509_sel_yyerror("unterminated string");
+           lineno++;
+           break;
+       }
+       if(c == '\\'){
+           quote++;
+           continue;
+       }
+       if(c == '\"')
+           break;
+       x[i++] = c;
+    }
+    x[i] = '\0';
+    return strdup(x);
+}
+
+int
+yywrap () 
+{
+     return 1;
+}
+
+static int
+lex_input(char *buf, int max_size)
+{
+    int n;
+
+    n = _hx509_expr_input.length - _hx509_expr_input.offset;
+    if (max_size < n)
+        n = max_size;
+    if (n <= 0)
+       return YY_NULL;
+    
+    memcpy(buf, _hx509_expr_input.buf + _hx509_expr_input.offset, n);
+    _hx509_expr_input.offset += n;
+
+    return n;
+}
+
diff --git a/source4/heimdal/lib/hx509/sel-lex.l b/source4/heimdal/lib/hx509/sel-lex.l
new file mode 100644 (file)
index 0000000..5394489
--- /dev/null
@@ -0,0 +1,135 @@
+%{
+/*
+ * Copyright (c) 2004, 2008 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden). 
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ *
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ */
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#undef ECHO
+
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include "sel.h"
+#include "sel-gram.h"
+unsigned lineno = 1;
+
+static char * handle_string(void);
+static int lex_input(char *, int);
+
+struct hx_expr_input _hx509_expr_input;
+
+#define YY_NO_UNPUT 1
+
+#undef YY_INPUT
+#define YY_INPUT(buf,res,maxsize) (res = lex_input(buf, maxsize))
+
+#undef ECHO
+
+%}
+%%
+
+TRUE                   { return kw_TRUE; }
+FALSE                  { return kw_FALSE; }
+AND                    { return kw_AND; }
+OR                     { return kw_OR; }
+IN                     { return kw_IN; }
+TAILMATCH              { return kw_TAILMATCH; }
+
+[A-Za-z][-A-Za-z0-9_]* {
+                         yylval.string = strdup ((const char *)yytext);
+                         return IDENTIFIER;
+                       }
+"\""                   { yylval.string = handle_string(); return STRING; }
+\n                     { ++lineno; }
+[,.!={}()%]            { return *yytext; }
+[ \t]                  ;
+%%
+
+static char *
+handle_string(void)
+{
+    char x[1024];
+    int i = 0;
+    int c;
+    int quote = 0;
+    while((c = input()) != EOF){
+       if(quote) {
+           x[i++] = '\\';
+           x[i++] = c;
+           quote = 0;
+           continue;
+       }
+       if(c == '\n'){
+           _hx509_sel_yyerror("unterminated string");
+           lineno++;
+           break;
+       }
+       if(c == '\\'){
+           quote++;
+           continue;
+       }
+       if(c == '\"')
+           break;
+       x[i++] = c;
+    }
+    x[i] = '\0';
+    return strdup(x);
+}
+
+int
+yywrap () 
+{
+     return 1;
+}
+
+static int
+lex_input(char *buf, int max_size)
+{
+    int n;
+
+    n = _hx509_expr_input.length - _hx509_expr_input.offset;
+    if (max_size < n)
+        n = max_size;
+    if (n <= 0)
+       return YY_NULL;
+    
+    memcpy(buf, _hx509_expr_input.buf + _hx509_expr_input.offset, n);
+    _hx509_expr_input.offset += n;
+
+    return n;
+}
diff --git a/source4/heimdal/lib/hx509/sel.c b/source4/heimdal/lib/hx509/sel.c
new file mode 100644 (file)
index 0000000..0e68f8b
--- /dev/null
@@ -0,0 +1,232 @@
+/*
+ * Copyright (c) 2008 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden). 
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ *
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ */
+
+#include "hx_locl.h"
+
+struct hx_expr *
+_hx509_make_expr(enum hx_expr_op op, void *arg1, void *arg2)
+{
+    struct hx_expr *expr;
+
+    expr = malloc(sizeof(*expr));
+    if (expr == NULL)
+       return NULL;
+    expr->op = op;
+    expr->arg1 = arg1;
+    expr->arg2 = arg2;
+
+    return expr;
+}
+
+static const char *
+eval_word(hx509_context context, hx509_env env, struct hx_expr *word)
+{
+    switch (word->op) {
+    case expr_STRING:
+       return word->arg1;
+    case expr_VAR:
+       if (word->arg2 == NULL)
+           return hx509_env_find(context, env, word->arg1);
+
+       env = hx509_env_find_binding(context, env, word->arg1);
+       if (env == NULL)
+           return NULL;
+
+       return eval_word(context, env, word->arg2);
+    default:
+       return NULL;
+    }
+}
+
+static hx509_env
+find_variable(hx509_context context, hx509_env env, struct hx_expr *word)
+{
+    assert(word->op == expr_VAR);
+
+    if (word->arg2 == NULL)
+       return hx509_env_find_binding(context, env, word->arg1);
+    
+    env = hx509_env_find_binding(context, env, word->arg1);
+    if (env == NULL)
+       return NULL;
+    return find_variable(context, env, word->arg2);
+}
+
+static int
+eval_comp(hx509_context context, hx509_env env, struct hx_expr *expr)
+{
+    switch (expr->op) {
+    case comp_NE:
+    case comp_EQ:
+    case comp_TAILEQ: {
+       const char *s1, *s2;
+       int ret;
+
+       s1 = eval_word(context, env, expr->arg1);
+       s2 = eval_word(context, env, expr->arg2);
+
+       if (s1 == NULL || s2 == NULL)
+           return FALSE;
+
+       if (expr->op == comp_TAILEQ) {
+           size_t len1 = strlen(s1);
+           size_t len2 = strlen(s2);
+           
+           if (len1 < len2)
+               return 0;
+           ret = strcmp(s1 + (len1 - len2), s2) == 0;
+       } else {
+           ret = strcmp(s1, s2) == 0;
+           if (expr->op == comp_NE)
+               ret = !ret;
+       }
+       return ret;
+    }
+    case comp_IN: {
+       struct hx_expr *subexpr;
+       const char *w, *s1;
+
+       w = eval_word(context, env, expr->arg1);
+
+       subexpr = expr->arg2;
+
+       if (subexpr->op == expr_WORDS) {
+           while (subexpr) {
+               s1 = eval_word(context, env, subexpr->arg1);
+               if (strcmp(w, s1) == 0)
+                   return TRUE;
+               subexpr = subexpr->arg2;
+           }
+       } else if (subexpr->op == expr_VAR) {
+           hx509_env subenv;
+
+           subenv = find_variable(context, env, subexpr);
+           if (subenv == NULL)
+               return FALSE;
+           
+           while (subenv) {
+               if (subenv->type != env_string)
+                   continue;
+               if (strcmp(w, subenv->name) == 0)
+                   return TRUE;
+               if (strcmp(w, subenv->u.string) == 0)
+                   return TRUE;
+               subenv = subenv->next;
+           }
+
+       } else
+           _hx509_abort("hx509 eval IN unknown op: %d", (int)subexpr->op);
+
+       return FALSE;
+    }
+    default:
+       _hx509_abort("hx509 eval expr with unknown op: %d", (int)expr->op);
+    }
+    return FALSE;
+}
+
+int
+_hx509_expr_eval(hx509_context context, hx509_env env, struct hx_expr *expr)
+{
+    switch (expr->op) {
+    case op_TRUE:
+       return 1;
+    case op_FALSE:
+       return 0;
+    case op_NOT:
+       return ! _hx509_expr_eval(context, env, expr->arg1);
+    case op_AND:
+       return _hx509_expr_eval(context, env, expr->arg1) && 
+           _hx509_expr_eval(context, env, expr->arg2);
+    case op_OR:
+       return _hx509_expr_eval(context, env, expr->arg1) ||
+           _hx509_expr_eval(context, env, expr->arg2);
+    case op_COMP:
+       return eval_comp(context, env, expr->arg1);
+    default:
+       _hx509_abort("hx509 eval expr with unknown op: %d", (int)expr->op);
+    }
+}
+
+void
+_hx509_expr_free(struct hx_expr *expr)
+{
+    switch (expr->op) {
+    case expr_STRING:
+    case expr_NUMBER:
+       free(expr->arg1);
+       break;
+    case expr_WORDS:
+    case expr_FUNCTION:
+    case expr_VAR:
+       free(expr->arg1);
+       if (expr->arg2)
+           _hx509_expr_free(expr->arg2);
+       break;
+    default:
+       if (expr->arg1)
+           _hx509_expr_free(expr->arg1);
+       if (expr->arg2)
+           _hx509_expr_free(expr->arg2);
+       break;
+    }
+    free(expr);
+}
+
+struct hx_expr *
+_hx509_expr_parse(const char *buf)
+{
+    _hx509_expr_input.buf = buf;
+    _hx509_expr_input.length = strlen(buf);
+    _hx509_expr_input.offset = 0;
+    _hx509_expr_input.expr = NULL;
+
+    if (_hx509_expr_input.error) {
+       free(_hx509_expr_input.error);
+       _hx509_expr_input.error = NULL;
+    }
+
+    yyparse();
+
+    return _hx509_expr_input.expr;
+}
+
+void
+_hx509_sel_yyerror (char *s)
+{
+     if (_hx509_expr_input.error)
+         free(_hx509_expr_input.error);
+     
+     _hx509_expr_input.error = strdup(s);
+}
+
diff --git a/source4/heimdal/lib/hx509/sel.h b/source4/heimdal/lib/hx509/sel.h
new file mode 100644 (file)
index 0000000..ce6c363
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2008 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden). 
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ *
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ */
+
+enum hx_expr_op {
+    op_TRUE, 
+    op_FALSE,
+    op_NOT,
+    op_AND,
+    op_OR,
+    op_COMP,
+
+    comp_EQ,
+    comp_NE,
+    comp_IN,
+    comp_TAILEQ,
+
+    expr_NUMBER,
+    expr_STRING,
+    expr_FUNCTION,
+    expr_VAR,
+    expr_WORDS
+};
+
+struct hx_expr {
+    enum hx_expr_op    op;
+    void               *arg1;
+    void               *arg2;
+};
+
+struct hx_expr_input {
+    const char *buf;
+    size_t length;
+    size_t offset;
+    struct hx_expr *expr;
+    char *error;
+};
+
+extern struct hx_expr_input _hx509_expr_input;
+
+#define yyparse _hx509_sel_yyparse
+#define yylex   _hx509_sel_yylex
+#define yyerror _hx509_sel_yyerror
+#define yylval  _hx509_sel_yylval
+#define yychar  _hx509_sel_yychar
+#define yydebug _hx509_sel_yydebug
+#define yynerrs _hx509_sel_yynerrs
+#define yywrap  _hx509_sel_yywrap
+
+int  _hx509_sel_yyparse(void);
+int  _hx509_sel_yylex(void);
+void _hx509_sel_yyerror(char *);
+
index 2c6dd516cb8001c49307bb411d92b6211c3ad40e..6dcf542d01861bf7ac1bdeae51f49fb4d62ea609 100644 (file)
@@ -32,7 +32,7 @@
  */
 
 #include "hx_locl.h"
-RCSID("$Id: test_name.c 19882 2007-01-13 01:02:57Z lha $");
+RCSID("$Id: test_name.c 22677 2008-03-13 17:35:49Z lha $");
 
 static int
 test_name(hx509_context context, const char *name)
@@ -72,13 +72,12 @@ test_name_fail(hx509_context context, const char *name)
 static int
 test_expand(hx509_context context, const char *name, const char *expected)
 {
-    hx509_env env;
+    hx509_env env = NULL;
     hx509_name n;
     char *s;
     int ret;
 
-    hx509_env_init(context, &env);
-    hx509_env_add(context, env, "uid", "lha");
+    hx509_env_add(context, &env, "uid", "lha");
 
     ret = hx509_parse_name(context, name, &n);
     if (ret)
index 775239cf6dfb2dc035be1bfea1f57e73180d3799..8dd86870053266328598a96a4775f89a408dc620 100644 (file)
@@ -37,7 +37,7 @@
 #include <dlfcn.h>
 #endif
 
-RCSID("$Id: acache.c 22669 2008-03-09 23:39:25Z lha $");
+RCSID("$Id: acache.c 23316 2008-06-23 04:32:32Z lha $");
 
 /* XXX should we fetch these for each open ? */
 static HEIMDAL_MUTEX acc_mutex = HEIMDAL_MUTEX_INITIALIZER;
@@ -68,6 +68,7 @@ static const struct {
     { ccIteratorEnd,           KRB5_CC_END },
     { ccErrNoMem,              KRB5_CC_NOMEM },
     { ccErrServerUnavailable,  KRB5_CC_NOSUPP },
+    { ccErrInvalidCCache,      KRB5_CC_BADNAME },
     { ccNoError,               0 }
 };
 
@@ -114,15 +115,17 @@ init_ccapi(krb5_context context)
     cc_handle = dlopen(lib, RTLD_LAZY);
     if (cc_handle == NULL) {
        HEIMDAL_MUTEX_unlock(&acc_mutex);
-       krb5_set_error_string(context, "Failed to load %s", lib);
+       krb5_set_error_message(context, KRB5_CC_NOSUPP, 
+                              "Failed to load %s", lib);
        return KRB5_CC_NOSUPP;
     }
 
     init_func = (cc_initialize_func)dlsym(cc_handle, "cc_initialize");
     HEIMDAL_MUTEX_unlock(&acc_mutex);
     if (init_func == NULL) {
-       krb5_set_error_string(context, "Failed to find cc_initialize"
-                             "in %s: %s", lib, dlerror());
+       krb5_set_error_message(context, KRB5_CC_NOSUPP,
+                              "Failed to find cc_initialize"
+                              "in %s: %s", lib, dlerror());
        dlclose(cc_handle);
        return KRB5_CC_NOSUPP;
     }
@@ -130,7 +133,7 @@ init_ccapi(krb5_context context)
     return 0;
 #else
     HEIMDAL_MUTEX_unlock(&acc_mutex);
-    krb5_set_error_string(context, "no support for shared object");
+    krb5_set_error_message(context, KRB5_CC_NOSUPP, "no support for shared object");
     return KRB5_CC_NOSUPP;
 #endif
 }    
@@ -141,7 +144,7 @@ make_cred_from_ccred(krb5_context context,
                     krb5_creds *cred)
 {
     krb5_error_code ret;
-    int i;
+    unsigned int i;
 
     memset(cred, 0, sizeof(*cred));
 
@@ -255,7 +258,7 @@ make_cred_from_ccred(krb5_context context,
     
 nomem:
     ret = ENOMEM;
-    krb5_set_error_string(context, "malloc - out of memory");
+    krb5_set_error_message(context, ret, "malloc: out of memory");
     
 fail:
     krb5_free_cred_contents(context, cred);
@@ -584,8 +587,10 @@ acc_close(krb5_context context,
        free(a->cache_name);
        a->cache_name = NULL;
     }
-    (*a->context->func->release)(a->context);
-    a->context = NULL;
+    if (a->context) {
+       (*a->context->func->release)(a->context);
+       a->context = NULL;
+    }
     krb5_data_free(&id->data);
     return 0;
 }
@@ -620,7 +625,8 @@ acc_store_cred(krb5_context context,
     cc_int32 error;
     
     if (a->ccache == NULL) {
-       krb5_set_error_string(context, "No API credential found");
+       krb5_set_error_message(context, KRB5_CC_NOTFOUND,
+                              "No API credential found");
        return KRB5_CC_NOTFOUND;
     }
 
@@ -653,7 +659,8 @@ acc_get_principal(krb5_context context,
     cc_string_t name;
 
     if (a->ccache == NULL) {
-       krb5_set_error_string(context, "No API credential found");
+       krb5_set_error_message(context, KRB5_CC_NOTFOUND,
+                              "No API credential found");
        return KRB5_CC_NOTFOUND;
     }
 
@@ -679,7 +686,8 @@ acc_get_first (krb5_context context,
     int32_t error;
     
     if (a->ccache == NULL) {
-       krb5_set_error_string(context, "No API credential found");
+       krb5_set_error_message(context, KRB5_CC_NOTFOUND,
+                              "No API credential found");
        return KRB5_CC_NOTFOUND;
     }
 
@@ -744,7 +752,8 @@ acc_remove_cred(krb5_context context,
     char *client, *server;
     
     if (a->ccache == NULL) {
-       krb5_set_error_string(context, "No API credential found");
+       krb5_set_error_message(context, KRB5_CC_NOTFOUND,
+                              "No API credential found");
        return KRB5_CC_NOTFOUND;
     }
 
@@ -796,8 +805,8 @@ acc_remove_cred(krb5_context context,
     (*iter->func->release)(iter);
 
     if (ret)
-       krb5_set_error_string(context, "Can't find credential %s in cache", 
-                             server);
+       krb5_set_error_message(context, ret,
+                              "Can't find credential %s in cache", server);
     free(server);
     free(client);
 
@@ -812,7 +821,7 @@ acc_set_flags(krb5_context context,
     return 0;
 }
 
-static krb5_error_code
+static int
 acc_get_version(krb5_context context,
                krb5_ccache id)
 {
@@ -837,7 +846,7 @@ acc_get_cache_first(krb5_context context, krb5_cc_cursor *cursor)
 
     iter = calloc(1, sizeof(*iter));
     if (iter == NULL) {
-       krb5_set_error_string(context, "malloc - out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
 
@@ -940,7 +949,7 @@ acc_move(krb5_context context, krb5_ccache from, krb5_ccache to)
 }
 
 static krb5_error_code
-acc_default_name(krb5_context context, char **str)
+acc_get_default_name(krb5_context context, char **str)
 {
     krb5_error_code ret;
     cc_context_t cc;
@@ -966,12 +975,30 @@ acc_default_name(krb5_context context, char **str)
     (*cc->func->release)(cc);
 
     if (*str == NULL) {
-       krb5_set_error_string(context, "out of memory");
+       krb5_set_error_message(context, ENOMEM, "out of memory");
        return ENOMEM;
     }
     return 0;
 }
 
+static krb5_error_code
+acc_set_default(krb5_context context, krb5_ccache id)
+{
+    krb5_acc *a = ACACHE(id);
+    cc_int32 error;
+    
+    if (a->ccache == NULL) {
+       krb5_set_error_message(context, KRB5_CC_NOTFOUND,
+                              "No API credential found");
+       return KRB5_CC_NOTFOUND;
+    }
+
+    error = (*a->ccache->func->set_default)(a->ccache);
+    if (error)
+       return translate_cc_error(context, error);
+
+    return 0;
+}
 
 /**
  * Variable containing the API based credential cache implemention.
@@ -979,7 +1006,8 @@ acc_default_name(krb5_context context, char **str)
  * @ingroup krb5_ccache
  */
 
-const krb5_cc_ops krb5_acc_ops = {
+KRB5_LIB_VARIABLE const krb5_cc_ops krb5_acc_ops = {
+    KRB5_CC_OPS_VERSION,
     "API",
     acc_get_name,
     acc_resolve,
@@ -1000,5 +1028,6 @@ const krb5_cc_ops krb5_acc_ops = {
     acc_get_cache_next,
     acc_end_cache_get,
     acc_move,
-    acc_default_name
+    acc_get_default_name,
+    acc_set_default
 };
index f364f5974d479869a009ec8bd2bed65026a3b351..40abd874ccd6fc27b08b3a1b577081a202815bf0 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: addr_families.c 22039 2007-11-10 11:47:35Z lha $");
+RCSID("$Id: addr_families.c 23316 2008-06-23 04:32:32Z lha $");
 
 struct addr_operations {
     int af;
@@ -202,7 +202,8 @@ ipv4_mask_boundary(krb5_context context, const krb5_address *inaddr,
     uint32_t l, h, m = 0xffffffff;
 
     if (len > 32) {
-       krb5_set_error_string(context, "IPv4 prefix too large (%ld)", len);
+       krb5_set_error_message(context, KRB5_PROG_ATYPE_NOSUPP,
+                              "IPv4 prefix too large (%ld)", len);
        return KRB5_PROG_ATYPE_NOSUPP;
     }
     m = m << (32 - len);
@@ -395,12 +396,14 @@ ipv6_mask_boundary(krb5_context context, const krb5_address *inaddr,
     int i, sub_len;
 
     if (len > 128) {
-       krb5_set_error_string(context, "IPv6 prefix too large (%ld)", len);
+       krb5_set_error_message(context, KRB5_PROG_ATYPE_NOSUPP,
+                              "IPv6 prefix too large (%ld)", len);
        return KRB5_PROG_ATYPE_NOSUPP;
     }
 
     if (inaddr->address.length != sizeof(addr)) {
-       krb5_set_error_string(context, "IPv6 addr bad length");
+       krb5_set_error_message(context, KRB5_PROG_ATYPE_NOSUPP,
+                              "IPv6 addr bad length");
        return KRB5_PROG_ATYPE_NOSUPP;
     }
 
@@ -786,8 +789,9 @@ krb5_sockaddr2address (krb5_context context,
 {
     struct addr_operations *a = find_af(sa->sa_family);
     if (a == NULL) {
-       krb5_set_error_string (context, "Address family %d not supported",
-                              sa->sa_family);
+       krb5_set_error_message (context, KRB5_PROG_ATYPE_NOSUPP,
+                               "Address family %d not supported",
+                               sa->sa_family);
        return KRB5_PROG_ATYPE_NOSUPP;
     }
     return (*a->sockaddr2addr)(sa, addr);
@@ -813,8 +817,9 @@ krb5_sockaddr2port (krb5_context context,
 {
     struct addr_operations *a = find_af(sa->sa_family);
     if (a == NULL) {
-       krb5_set_error_string (context, "Address family %d not supported",
-                              sa->sa_family);
+       krb5_set_error_message (context, KRB5_PROG_ATYPE_NOSUPP,
+                               "Address family %d not supported",
+                               sa->sa_family);
        return KRB5_PROG_ATYPE_NOSUPP;
     }
     return (*a->sockaddr2port)(sa, port);
@@ -851,14 +856,16 @@ krb5_addr2sockaddr (krb5_context context,
     struct addr_operations *a = find_atype(addr->addr_type);
 
     if (a == NULL) {
-       krb5_set_error_string (context, "Address type %d not supported",
-                              addr->addr_type);
+       krb5_set_error_message (context, KRB5_PROG_ATYPE_NOSUPP,
+                               "Address type %d not supported",
+                               addr->addr_type);
        return KRB5_PROG_ATYPE_NOSUPP;
     }
     if (a->addr2sockaddr == NULL) {
-       krb5_set_error_string (context,
-                              "Can't convert address type %d to sockaddr",
-                              addr->addr_type);
+       krb5_set_error_message (context,
+                               KRB5_PROG_ATYPE_NOSUPP,
+                               "Can't convert address type %d to sockaddr",
+                               addr->addr_type);
        return KRB5_PROG_ATYPE_NOSUPP;
     }
     (*a->addr2sockaddr)(addr, sa, sa_size, port);
@@ -935,7 +942,8 @@ krb5_h_addr2sockaddr (krb5_context context,
 {
     struct addr_operations *a = find_af(af);
     if (a == NULL) {
-       krb5_set_error_string (context, "Address family %d not supported", af);
+       krb5_set_error_message (context, KRB5_PROG_ATYPE_NOSUPP,
+                               "Address family %d not supported", af);
        return KRB5_PROG_ATYPE_NOSUPP;
     }
     (*a->h_addr2sockaddr)(addr, sa, sa_size, port);
@@ -963,7 +971,8 @@ krb5_h_addr2addr (krb5_context context,
 {
     struct addr_operations *a = find_af(af);
     if (a == NULL) {
-       krb5_set_error_string (context, "Address family %d not supported", af);
+       krb5_set_error_message (context, KRB5_PROG_ATYPE_NOSUPP,
+                               "Address family %d not supported", af);
        return KRB5_PROG_ATYPE_NOSUPP;
     }
     return (*a->h_addr2addr)(haddr, addr);
@@ -996,7 +1005,8 @@ krb5_anyaddr (krb5_context context,
     struct addr_operations *a = find_af (af);
 
     if (a == NULL) {
-       krb5_set_error_string (context, "Address family %d not supported", af);
+       krb5_set_error_message (context, KRB5_PROG_ATYPE_NOSUPP,
+                               "Address family %d not supported", af);
        return KRB5_PROG_ATYPE_NOSUPP;
     }
 
@@ -1089,7 +1099,8 @@ krb5_parse_address(krb5_context context,
            if((*at[i].parse_addr)(context, string, &addr) == 0) {
                ALLOC_SEQ(addresses, 1);
                if (addresses->val == NULL) {
-                   krb5_set_error_string(context, "malloc: out of memory");
+                   krb5_set_error_message(context, ENOMEM,
+                                          "malloc: out of memory");
                    return ENOMEM;
                }
                addresses->val[0] = addr;
@@ -1100,9 +1111,12 @@ krb5_parse_address(krb5_context context,
 
     error = getaddrinfo (string, NULL, NULL, &ai);
     if (error) {
+       krb5_error_code ret2;
        save_errno = errno;
-       krb5_set_error_string (context, "%s: %s", string, gai_strerror(error));
-       return krb5_eai_to_heim_errno(error, save_errno);
+       ret2 = krb5_eai_to_heim_errno(error, save_errno);
+       krb5_set_error_message (context, ret2, "%s: %s",
+                               string, gai_strerror(error));
+       return ret2;
     }
     
     n = 0;
@@ -1111,7 +1125,8 @@ krb5_parse_address(krb5_context context,
 
     ALLOC_SEQ(addresses, n);
     if (addresses->val == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, 
+                              "malloc: out of memory");
        freeaddrinfo(ai);
        return ENOMEM;
     }
@@ -1154,15 +1169,17 @@ krb5_address_order(krb5_context context,
     struct addr_operations *a;
     a = find_atype(addr1->addr_type); 
     if(a == NULL) {
-       krb5_set_error_string (context, "Address family %d not supported", 
-                              addr1->addr_type);
+       krb5_set_error_message (context, KRB5_PROG_ATYPE_NOSUPP,
+                               "Address family %d not supported", 
+                               addr1->addr_type);
        return KRB5_PROG_ATYPE_NOSUPP;
     }
     if(a->order_addr != NULL) 
        return (*a->order_addr)(context, addr1, addr2); 
     a = find_atype(addr2->addr_type); 
     if(a == NULL) {
-       krb5_set_error_string (context, "Address family %d not supported", 
+       krb5_set_error_message (context, KRB5_PROG_ATYPE_NOSUPP,
+                               "Address family %d not supported", 
                               addr2->addr_type);
        return KRB5_PROG_ATYPE_NOSUPP;
     }
@@ -1349,7 +1366,8 @@ krb5_append_addresses(krb5_context context,
     if(source->len > 0) {
        tmp = realloc(dest->val, (dest->len + source->len) * sizeof(*tmp));
        if(tmp == NULL) {
-           krb5_set_error_string(context, "realloc: out of memory");
+           krb5_set_error_message (context, ENOMEM,
+                                   "realloc: out of memory");
            return ENOMEM;
        }
        dest->val = tmp;
@@ -1391,13 +1409,15 @@ krb5_make_addrport (krb5_context context,
 
     *res = malloc (sizeof(**res));
     if (*res == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message (context, ENOMEM,
+                               "malloc: out of memory");
        return ENOMEM;
     }
     (*res)->addr_type = KRB5_ADDRESS_ADDRPORT;
     ret = krb5_data_alloc (&(*res)->address, len);
     if (ret) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message (context, ret,
+                               "malloc: out of memory");
        free (*res);
        *res = NULL;
        return ret;
@@ -1457,7 +1477,8 @@ krb5_address_prefixlen_boundary(krb5_context context,
     struct addr_operations *a = find_atype (inaddr->addr_type);
     if(a != NULL && a->mask_boundary != NULL)
        return (*a->mask_boundary)(context, inaddr, prefixlen, low, high);
-    krb5_set_error_string(context, "Address family %d doesn't support "
+    krb5_set_error_message(context, KRB5_PROG_ATYPE_NOSUPP,
+                         "Address family %d doesn't support "
                          "address mask operation", inaddr->addr_type);
     return KRB5_PROG_ATYPE_NOSUPP;
 }
index 323f17a24534edd229ebdc6e1577bc166ef1dfb8..e4fb50e5b820fcb4b176460a05fa85c686b00b2b 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: auth_context.c 21745 2007-07-31 16:11:25Z lha $");
+RCSID("$Id: auth_context.c 23273 2008-06-23 03:25:00Z lha $");
 
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_auth_con_init(krb5_context context,
@@ -43,13 +43,13 @@ krb5_auth_con_init(krb5_context context,
 
     ALLOC(p, 1);
     if(!p) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     memset(p, 0, sizeof(*p));
     ALLOC(p->authenticator, 1);
     if (!p->authenticator) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        free(p);
        return ENOMEM;
     }
@@ -174,7 +174,8 @@ krb5_auth_con_genaddrs(krb5_context context,
            len = sizeof(ss_local);
            if(getsockname(fd, local, &len) < 0) {
                ret = errno;
-               krb5_set_error_string (context, "getsockname: %s",
+               krb5_set_error_message(context, ret,
+                                      "getsockname: %s",
                                       strerror(ret));
                goto out;
            }
@@ -191,7 +192,8 @@ krb5_auth_con_genaddrs(krb5_context context,
        len = sizeof(ss_remote);
        if(getpeername(fd, remote, &len) < 0) {
            ret = errno;
-           krb5_set_error_string (context, "getpeername: %s", strerror(ret));
+           krb5_set_error_message(context, ret, 
+                                  "getpeername: %s", strerror(ret));
            goto out;
        }
        ret = krb5_sockaddr2address (context, remote, &remote_k_address);
@@ -239,7 +241,7 @@ krb5_auth_con_getaddrs(krb5_context context,
        krb5_free_address (context, *local_addr);
     *local_addr = malloc (sizeof(**local_addr));
     if (*local_addr == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     krb5_copy_address(context,
@@ -250,7 +252,7 @@ krb5_auth_con_getaddrs(krb5_context context,
        krb5_free_address (context, *remote_addr);
     *remote_addr = malloc (sizeof(**remote_addr));
     if (*remote_addr == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        krb5_free_address (context, *local_addr);
        *local_addr = NULL;
        return ENOMEM;
@@ -450,7 +452,7 @@ krb5_auth_con_getauthenticator(krb5_context context,
 {
     *authenticator = malloc(sizeof(**authenticator));
     if (*authenticator == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
 
index f8739c044d161f5a69a2e5676e50f2f5584861f7..fe3a5f523c0d1285007f607e4db827d72a1f64f7 100644 (file)
@@ -33,7 +33,7 @@
 
 #include <krb5_locl.h>
 
-RCSID("$Id: build_auth.c 17033 2006-04-10 08:53:21Z lha $");
+RCSID("$Id: build_auth.c 23273 2008-06-23 03:25:00Z lha $");
 
 static krb5_error_code
 make_etypelist(krb5_context context,
@@ -62,7 +62,7 @@ make_etypelist(krb5_context context,
     ALLOC_SEQ(&ad, 1);
     if (ad.val == NULL) {
        free(buf);
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
 
@@ -81,14 +81,14 @@ make_etypelist(krb5_context context,
 
     ALLOC(*auth_data, 1);
     if (*auth_data == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
 
     ALLOC_SEQ(*auth_data, 1);
     if ((*auth_data)->val == NULL) {
        free(buf);
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
 
@@ -118,7 +118,7 @@ krb5_build_authenticator (krb5_context context,
 
     auth = calloc(1, sizeof(*auth));
     if (auth == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
 
index 5db6d2b2cf8a9c51e358e4dcce68f02eb8c4a6e6..34bfb4a350f5ddc1af3d33618192d94d4c976f00 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: cache.c 22127 2007-12-04 00:54:37Z lha $");
+RCSID("$Id: cache.c 23417 2008-07-26 18:36:33Z lha $");
 
 /**
  * Add a new ccache type with operations `ops', overwriting any
@@ -59,9 +59,10 @@ krb5_cc_register(krb5_context context,
     for(i = 0; i < context->num_cc_ops && context->cc_ops[i].prefix; i++) {
        if(strcmp(context->cc_ops[i].prefix, ops->prefix) == 0) {
            if(!override) {
-               krb5_set_error_string(context,
-                                     "ccache type %s already exists",
-                                     ops->prefix);
+               krb5_set_error_message(context, 
+                                      KRB5_CC_TYPE_EXISTS,
+                                      "ccache type %s already exists",
+                                      ops->prefix);
                return KRB5_CC_TYPE_EXISTS;
            }
            break;
@@ -72,7 +73,8 @@ krb5_cc_register(krb5_context context,
                                 (context->num_cc_ops + 1) *
                                 sizeof(*context->cc_ops));
        if(o == NULL) {
-           krb5_set_error_string(context, "malloc: out of memory");
+           krb5_set_error_message(context, KRB5_CC_NOMEM, 
+                                  "malloc: out of memory");
            return KRB5_CC_NOMEM;
        }
        context->num_cc_ops++;
@@ -98,7 +100,7 @@ _krb5_cc_allocate(krb5_context context,
 
     p = malloc (sizeof(*p));
     if(p == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, KRB5_CC_NOMEM, "malloc: out of memory");
        return KRB5_CC_NOMEM;
     }
     p->ops = ops;
@@ -166,7 +168,8 @@ krb5_cc_resolve(krb5_context context,
     if (strchr (name, ':') == NULL)
        return allocate_ccache (context, &krb5_fcc_ops, name, id);
     else {
-       krb5_set_error_string(context, "unknown ccache type %s", name);
+       krb5_set_error_message(context, KRB5_CC_UNKNOWN_TYPE,
+                              "unknown ccache type %s", name);
        return KRB5_CC_UNKNOWN_TYPE;
     }
 }
@@ -204,16 +207,14 @@ krb5_error_code KRB5_LIB_FUNCTION
 krb5_cc_new_unique(krb5_context context, const char *type, 
                   const char *hint, krb5_ccache *id)
 {
-    const krb5_cc_ops *ops = KRB5_DEFAULT_CCTYPE;
+    const krb5_cc_ops *ops;
     krb5_error_code ret;
 
-    if (type) {
-       ops = krb5_cc_get_prefix_ops(context, type);
-       if (ops == NULL) {
-           krb5_set_error_string(context,
-                                 "Credential cache type %s is unknown", type);
-           return KRB5_CC_UNKNOWN_TYPE;
-       }
+    ops = krb5_cc_get_prefix_ops(context, type);
+    if (ops == NULL) {
+       krb5_set_error_message(context, KRB5_CC_UNKNOWN_TYPE,
+                             "Credential cache type %s is unknown", type);
+       return KRB5_CC_UNKNOWN_TYPE;
     }
 
     ret = _krb5_cc_allocate(context, ops, id);
@@ -270,18 +271,20 @@ krb5_cc_get_full_name(krb5_context context,
 
     type = krb5_cc_get_type(context, id);
     if (type == NULL) {
-       krb5_set_error_string(context, "cache have no name of type");
+       krb5_set_error_message(context, KRB5_CC_UNKNOWN_TYPE,
+                              "cache have no name of type");
        return KRB5_CC_UNKNOWN_TYPE;
     }
 
     name = krb5_cc_get_name(context, id);
     if (name == NULL) {
-       krb5_set_error_string(context, "cache of type %s have no name", type);
+       krb5_set_error_message(context, KRB5_CC_BADNAME,
+                              "cache of type %s have no name", type);
        return KRB5_CC_BADNAME;
     }
     
     if (asprintf(str, "%s:%s", type, name) == -1) {
-       krb5_set_error_string(context, "malloc - out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        *str = NULL;
        return ENOMEM;
     }
@@ -327,7 +330,8 @@ _krb5_expand_default_cc_name(krb5_context context, const char *str, char **res)
            if (tmp2 == NULL) {
                free(*res);
                *res = NULL;
-               krb5_set_error_string(context, "variable missing }");
+               krb5_set_error_message(context, KRB5_CONFIG_BADFORMAT,
+                                      "variable missing }");
                return KRB5_CONFIG_BADFORMAT;
            }
            if (strncasecmp(tmp, "%{uid}", 6) == 0)
@@ -337,10 +341,11 @@ _krb5_expand_default_cc_name(krb5_context context, const char *str, char **res)
            else {
                free(*res);
                *res = NULL;
-               krb5_set_error_string(context, 
-                                     "expand default cache unknown "
-                                     "variable \"%.*s\"",
-                                     (int)(tmp2 - tmp) - 2, tmp + 2);
+               krb5_set_error_message(context, 
+                                      KRB5_CONFIG_BADFORMAT,
+                                      "expand default cache unknown "
+                                      "variable \"%.*s\"",
+                                      (int)(tmp2 - tmp) - 2, tmp + 2);
                return KRB5_CONFIG_BADFORMAT;
            }
            str = tmp2 + 1;
@@ -351,7 +356,7 @@ _krb5_expand_default_cc_name(krb5_context context, const char *str, char **res)
        if (append == NULL) {
            free(*res);
            *res = NULL;
-           krb5_set_error_string(context, "malloc - out of memory");
+           krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
            return ENOMEM;
        }
        
@@ -361,7 +366,8 @@ _krb5_expand_default_cc_name(krb5_context context, const char *str, char **res)
            free(append);
            free(*res);
            *res = NULL;
-           krb5_set_error_string(context, "malloc - out of memory");
+           krb5_set_error_message(context, ENOMEM, 
+                                  "malloc: out of memory");
            return ENOMEM;
        }
        *res = tmp;
@@ -406,11 +412,29 @@ environment_changed(krb5_context context)
 }
 
 /**
- * Set the default cc name for `context' to `name'.
+ * Switch the default default credential cache for a specific
+ * credcache type (and name for some implementations).
+ *
+ * @return Returns 0 or an error code.
  *
  * @ingroup krb5_ccache
  */
 
+krb5_error_code
+krb5_cc_switch(krb5_context context, krb5_ccache id)
+{
+
+    if (id->ops->set_default == NULL)
+       return 0;
+
+    return (*id->ops->set_default)(context, id);
+}
+
+/**
+ * Set the default cc name for `context' to `name'.
+ *
+ * @ingroup krb5_ccache
+ */
 
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_cc_set_default_name(krb5_context context, const char *name)
@@ -440,7 +464,19 @@ krb5_cc_set_default_name(krb5_context context, const char *name)
            }
            if (e == NULL) {
                const krb5_cc_ops *ops = KRB5_DEFAULT_CCTYPE;
-               ret = (*ops->default_name)(context, &p);
+               e = krb5_config_get_string(context, NULL, "libdefaults",
+                                          "default_cc_type", NULL);
+               if (e) {
+                   ops = krb5_cc_get_prefix_ops(context, e);
+                   if (ops == NULL) {
+                       krb5_set_error_message(context,
+                                              KRB5_CC_UNKNOWN_TYPE,
+                                              "Credential cache type %s "
+                                             "is unknown", e);
+                       return KRB5_CC_UNKNOWN_TYPE;
+                   }
+               }
+               ret = (*ops->get_default_name)(context, &p);
                if (ret)
                    return ret;
            }
@@ -452,7 +488,7 @@ krb5_cc_set_default_name(krb5_context context, const char *name)
     }
 
     if (p == NULL) {
-       krb5_set_error_string(context, "malloc - out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
 
@@ -499,7 +535,7 @@ krb5_cc_default(krb5_context context,
     const char *p = krb5_cc_default_name(context);
 
     if (p == NULL) {
-       krb5_set_error_string(context, "malloc - out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     return krb5_cc_resolve(context, p, id);
@@ -728,9 +764,10 @@ krb5_cc_remove_cred(krb5_context context,
                    krb5_creds *cred)
 {
     if(id->ops->remove_cred == NULL) {
-       krb5_set_error_string(context,
-                             "ccache %s does not support remove_cred",
-                             id->ops->prefix);
+       krb5_set_error_message(context,
+                              EACCES,
+                              "ccache %s does not support remove_cred",
+                              id->ops->prefix);
        return EACCES; /* XXX */
     }
     return (*id->ops->remove_cred)(context, id, which, cred);
@@ -846,10 +883,12 @@ krb5_cc_clear_mcred(krb5_creds *mcred)
 
 /**
  * Get the cc ops that is registered in `context' to handle the
- * `prefix'. `prefix' can be a complete credential cache name or a
+ * prefix. prefix can be a complete credential cache name or a
  * prefix, the function will only use part up to the first colon (:)
- * if there is one.
- * Returns NULL if ops not found.
+ * if there is one. If prefix the argument is NULL, the default ccache
+ * implemtation is returned.
+ * @return Returns NULL if ops not found.
  *
  * @ingroup krb5_ccache
  */
@@ -861,12 +900,14 @@ krb5_cc_get_prefix_ops(krb5_context context, const char *prefix)
     char *p, *p1;
     int i;
     
+    if (prefix == NULL)
+       return KRB5_DEFAULT_CCTYPE;
     if (prefix[0] == '/')
        return &krb5_fcc_ops;
 
     p = strdup(prefix);
     if (p == NULL) {
-       krb5_set_error_string(context, "malloc - out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return NULL;
     }
     p1 = strchr(p, ':');
@@ -911,20 +952,22 @@ krb5_cc_cache_get_first (krb5_context context,
 
     ops = krb5_cc_get_prefix_ops(context, type);
     if (ops == NULL) {
-       krb5_set_error_string(context, "Unknown type \"%s\" when iterating "
-                             "trying to iterate the credential caches", type);
+       krb5_set_error_message(context, KRB5_CC_UNKNOWN_TYPE,
+                              "Unknown type \"%s\" when iterating "
+                              "trying to iterate the credential caches", type);
        return KRB5_CC_UNKNOWN_TYPE;
     }
 
     if (ops->get_cache_first == NULL) {
-       krb5_set_error_string(context, "Credential cache type %s doesn't support "
-                             "iterations over caches", ops->prefix);
+       krb5_set_error_message(context, KRB5_CC_NOSUPP,
+                              "Credential cache type %s doesn't support "
+                              "iterations over caches", ops->prefix);
        return KRB5_CC_NOSUPP;
     }
 
     *cursor = calloc(1, sizeof(**cursor));
     if (*cursor == NULL) {
-       krb5_set_error_string(context, "malloc - out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
 
@@ -1028,8 +1071,10 @@ krb5_cc_cache_match (krb5_context context,
 
        krb5_unparse_name(context, client, &str);
 
-       krb5_set_error_string(context, "Principal %s not found in a "
-                         "credential cache", str ? str : "<out of memory>");
+       krb5_set_error_message(context, KRB5_CC_NOTFOUND,
+                              "Principal %s not found in a "
+                              "credential cache", 
+                              str ? str : "<out of memory>");
        if (str)
            free(str);
        return KRB5_CC_NOTFOUND;
@@ -1059,8 +1104,9 @@ krb5_cc_move(krb5_context context, krb5_ccache from, krb5_ccache to)
     krb5_error_code ret;
 
     if (strcmp(from->ops->prefix, to->ops->prefix) != 0) {
-       krb5_set_error_string(context, "Moving credentials between diffrent "
-                             "types not yet supported");
+       krb5_set_error_message(context, KRB5_CC_NOSUPP,
+                              "Moving credentials between diffrent "
+                              "types not yet supported");
        return KRB5_CC_NOSUPP;
     }
 
@@ -1071,3 +1117,123 @@ krb5_cc_move(krb5_context context, krb5_ccache from, krb5_ccache to)
     }
     return ret;
 }
+
+#define KRB5_CONF_NAME "@krb5_ccache_conf_data"
+
+static krb5_error_code
+build_conf_principals(krb5_context context, krb5_ccache id,
+                     krb5_const_principal principal,
+                     const char *name, krb5_creds *cred)
+{
+    krb5_principal client;
+    krb5_error_code ret;
+    char *pname = NULL;
+
+    memset(cred, 0, sizeof(*cred));
+
+    ret = krb5_cc_get_principal(context, id, &client);
+    if (ret)
+       return ret;
+       
+    if (principal) {
+       ret = krb5_unparse_name(context, principal, &pname);
+       if (ret)
+           return ret;
+    }
+
+    ret = krb5_make_principal(context, &cred->server,
+                             krb5_principal_get_realm(context, client),
+                             KRB5_CONF_NAME, name, pname, NULL);
+    free(pname);
+    if (ret) {
+       krb5_free_principal(context, client);
+       return ret;
+    }
+    ret = krb5_copy_principal(context, client, &cred->client);
+    krb5_free_principal(context, client);
+    return ret;
+}
+                     
+/**
+ * Store some configuration for the credential cache in the cache.
+ * Existing configuration under the same name is over-written.
+ *
+ * @param context a Keberos context
+ * @param id the credential cache to store the data for
+ * @param principal configuration for a specific principal, if
+ * NULL, global for the whole cache.
+ * @param name name under which the configuraion is stored.
+ * @param data data to store
+ */
+
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_cc_set_config(krb5_context context, krb5_ccache id, 
+                  krb5_const_principal principal,
+                  const char *name, krb5_data *data)
+{
+    krb5_error_code ret;
+    krb5_creds cred;
+
+    ret = build_conf_principals(context, id, principal, name, &cred);
+    if (ret)
+       goto out;
+
+    /* Remove old configuration */
+    ret = krb5_cc_remove_cred(context, id, 0, &cred);
+    if (ret)
+       goto out;
+
+    /* not that anyone care when this expire */
+    cred.times.authtime = time(NULL);
+    cred.times.endtime = cred.times.authtime + 3600 * 24 * 30; 
+
+    ret = krb5_data_copy(&cred.ticket, data->data, data->length);
+    if (ret)
+       goto out;
+
+    ret = krb5_cc_store_cred(context, id, &cred);
+
+out:
+    krb5_free_cred_contents (context, &cred);
+    return ret;
+}
+
+/**
+ * Get some configuration for the credential cache in the cache.
+ *
+ * @param context a Keberos context
+ * @param id the credential cache to store the data for
+ * @param principal configuration for a specific principal, if
+ * NULL, global for the whole cache.
+ * @param name name under which the configuraion is stored.
+ * @param data data to fetched, free with krb5_data_free()
+ */
+
+
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_cc_get_config(krb5_context context, krb5_ccache id,
+                  krb5_const_principal principal,
+                  const char *name, krb5_data *data)
+{
+    krb5_creds mcred, cred;
+    krb5_error_code ret;
+
+    memset(&cred, 0, sizeof(cred));
+    krb5_data_zero(data);
+
+    ret = build_conf_principals(context, id, principal, name, &mcred);
+    if (ret)
+       goto out;
+
+    ret = krb5_cc_retrieve_cred(context, id, 0, &mcred, &cred);
+    if (ret)
+       goto out;
+
+    ret = krb5_data_copy(data, cred.ticket.data, cred.ticket.length);
+
+out:
+    krb5_free_cred_contents (context, &cred);
+    krb5_free_cred_contents (context, &mcred);
+    return ret;
+}
+
index 703cf43eb6fb99b6c9a5821f7d57c82a160e580b..ac1a2d312ec69569c33b7385a4f150e8326dfd9d 100644 (file)
 
 #include <krb5_locl.h>
 
-RCSID("$Id: changepw.c 21505 2007-07-12 12:28:38Z lha $");
+RCSID("$Id: changepw.c 23445 2008-07-27 12:08:03Z lha $");
+
+#undef __attribute__
+#define __attribute__(X)
+
 
 static void
 str2data (krb5_data *d,
@@ -141,7 +145,8 @@ chgpw_send_request (krb5_context context,
 
     if (sendmsg (sock, &msghdr, 0) < 0) {
        ret = errno;
-       krb5_set_error_string(context, "sendmsg %s: %s", host, strerror(ret));
+       krb5_set_error_message(context, ret, "sendmsg %s: %s",
+                              host, strerror(ret));
     }
 
     krb5_data_free (&krb_priv_data);
@@ -250,7 +255,8 @@ setpw_send_request (krb5_context context,
 
     if (sendmsg (sock, &msghdr, 0) < 0) {
        ret = errno;
-       krb5_set_error_string(context, "sendmsg %s: %s", host, strerror(ret));
+       krb5_set_error_message(context, ret, "sendmsg %s: %s", 
+                              host, strerror(ret));
     }
 
     krb5_data_free (&krb_priv_data);
@@ -286,11 +292,12 @@ process_reply (krb5_context context,
                            0, NULL, NULL);
            if (ret < 0) {
                save_errno = errno;
-               krb5_set_error_string(context, "recvfrom %s: %s",
-                                     host, strerror(save_errno));
+               krb5_set_error_message(context, save_errno,
+                                      "recvfrom %s: %s",
+                                      host, strerror(save_errno));
                return save_errno;
            } else if (ret == 0) {
-               krb5_set_error_string(context, "recvfrom timeout %s", host);
+               krb5_set_error_message(context, 1,"recvfrom timeout %s", host);
                return 1;
            }
            len += ret;
@@ -304,16 +311,18 @@ process_reply (krb5_context context,
            break;
        }
        if (len == sizeof(reply)) {
-           krb5_set_error_string(context, "message too large from %s",
-                                 host);
+           krb5_set_error_message(context, ENOMEM,
+                                  "message too large from %s",
+                                  host);
            return ENOMEM;
        }
     } else {
        ret = recvfrom (sock, reply, sizeof(reply), 0, NULL, NULL);
        if (ret < 0) {
            save_errno = errno;
-           krb5_set_error_string(context, "recvfrom %s: %s",
-                                 host, strerror(save_errno));
+           krb5_set_error_message(context, save_errno,
+                                  "recvfrom %s: %s",
+                                  host, strerror(save_errno));
            return save_errno;
        }
        len = ret;
@@ -522,7 +531,7 @@ change_password_loop (krb5_context  context,
     krb5_krbhst_handle handle = NULL;
     krb5_krbhst_info *hi;
     int sock;
-    int i;
+    unsigned int i;
     int done = 0;
     krb5_realm realm;
 
@@ -571,6 +580,7 @@ change_password_loop (krb5_context  context,
            sock = socket (a->ai_family, a->ai_socktype, a->ai_protocol);
            if (sock < 0)
                continue;
+           rk_cloexec(sock);
 
            ret = connect(sock, a->ai_addr, a->ai_addrlen);
            if (ret < 0) {
@@ -607,8 +617,9 @@ change_password_loop (krb5_context  context,
                }
            
                if (sock >= FD_SETSIZE) {
-                   krb5_set_error_string(context, "fd %d too large", sock);
                    ret = ERANGE;
+                   krb5_set_error_message(context, ret,
+                                          "fd %d too large", sock);
                    close (sock);
                    goto out;
                }
@@ -647,24 +658,32 @@ change_password_loop (krb5_context        context,
  out:
     krb5_krbhst_free (context, handle);
     krb5_auth_con_free (context, auth_context);
-    if (done)
-       return 0;
-    else {
-       if (ret == KRB5_KDC_UNREACH) {
-           krb5_set_error_string(context,
-                                 "unable to reach any changepw server "
-                                 " in realm %s", realm);
-           *result_code = KRB5_KPASSWD_HARDERROR;
-       }
-       return ret;
+
+    if (ret == KRB5_KDC_UNREACH) {
+       krb5_set_error_message(context,
+                              ret,
+                              "unable to reach any changepw server "
+                              " in realm %s", realm);
+       *result_code = KRB5_KPASSWD_HARDERROR;
     }
+    return ret;
 }
 
+#ifndef HEIMDAL_SMALLER
 
-/*
- * change the password using the credentials in `creds' (for the
- * principal indicated in them) to `newpw', storing the result of
- * the operation in `result_*' and an error code or 0.
+/**
+ * krb5_change_password() is deprecated, use krb5_set_password().
+ *
+ * @param context a Keberos context
+ * @param creds
+ * @param newpw
+ * @param result_code
+ * @param result_code_string
+ * @param result_string
+ *
+ * @return On sucess password is changed.
+
+ * @ingroup @krb5_deprecated
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
@@ -674,6 +693,7 @@ krb5_change_password (krb5_context  context,
                      int               *result_code,
                      krb5_data         *result_code_string,
                      krb5_data         *result_string)
+    __attribute__((deprecated))
 {
     struct kpwd_proc *p = find_chpw_proto("change password");
 
@@ -688,9 +708,24 @@ krb5_change_password (krb5_context context,
                                result_code, result_code_string, 
                                result_string, p);
 }
+#endif /* HEIMDAL_SMALLER */
 
-/*
+/**
+ * Change passwrod using creds.
+ *
+ * @param context a Keberos context
+ * @param creds The initial kadmin/passwd for the principal or an admin principal
+ * @param newpw The new password to set
+ * @param targprinc if unset, the default principal is used.
+ * @param result_code Result code, KRB5_KPASSWD_SUCCESS is when password is changed.
+ * @param result_code_string binary message from the server, contains
+ * at least the result_code.
+ * @param result_string A message from the kpasswd service or the
+ * library in human printable form. The string is NUL terminated.
  *
+ * @return On sucess and *result_code is KRB5_KPASSWD_SUCCESS, the password is changed.
+
+ * @ingroup @krb5
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
@@ -707,8 +742,8 @@ krb5_set_password(krb5_context context,
     int i;
 
     *result_code = KRB5_KPASSWD_MALFORMED;
-    result_code_string->data = result_string->data = NULL;
-    result_code_string->length = result_string->length = 0;
+    krb5_data_zero(result_code_string);
+    krb5_data_zero(result_string);
 
     if (targprinc == NULL) {
        ret = krb5_get_default_principal(context, &principal);
@@ -732,6 +767,8 @@ krb5_set_password(krb5_context context,
     return ret;
 }
 
+#ifndef HEIMDAL_SMALLER
+
 /*
  *
  */
@@ -797,6 +834,8 @@ krb5_set_password_using_ccache(krb5_context context,
     return ret;
 }
 
+#endif /* !HEIMDAL_SMALLER */
+
 /*
  *
  */
index ac5eba39dcff4e4bcf29fae134c68269ca574618..bf3c4323977009c89b099af5d4efbd4312e499f4 100644 (file)
@@ -32,7 +32,7 @@
  */
 
 #include "krb5_locl.h"
-RCSID("$Id: config_file.c 19213 2006-12-04 23:36:36Z lha $");
+RCSID("$Id: config_file.c 23280 2008-06-23 03:26:18Z lha $");
 
 #ifndef HAVE_NETINFO
 
@@ -295,7 +295,8 @@ krb5_config_parse_string_multi(krb5_context context,
 
     ret = krb5_config_parse_debug (&f, res, &lineno, &str);
     if (ret) {
-       krb5_set_error_string (context, "%s:%u: %s", "<constant>", lineno, str);
+       krb5_set_error_message (context, ret, "%s:%u: %s",
+                               "<constant>", lineno, str);
        return ret;
     }
     return 0;
@@ -314,14 +315,15 @@ krb5_config_parse_file_multi (krb5_context context,
     f.s = NULL;
     if(f.f == NULL) {
        ret = errno;
-       krb5_set_error_string (context, "open %s: %s", fname, strerror(ret));
+       krb5_set_error_message (context, ret, "open %s: %s", 
+                               fname, strerror(ret));
        return ret;
     }
 
     ret = krb5_config_parse_debug (&f, res, &lineno, &str);
     fclose(f.f);
     if (ret) {
-       krb5_set_error_string (context, "%s:%u: %s", fname, lineno, str);
+       krb5_set_error_message (context, ret, "%s:%u: %s", fname, lineno, str);
        return ret;
     }
     return 0;
index 5188a1d3a86479663256c95dc9e79a669295a583..8fffb0f4028d2e61383965161182ee0f7cb4e8e9 100644 (file)
 
 #include "krb5_locl.h"
 
-RCSID("$Id: constants.c 14253 2004-09-23 07:57:37Z joda $");
+RCSID("$Id: constants.c 23026 2008-04-17 10:02:03Z lha $");
 
-const char *krb5_config_file = 
+KRB5_LIB_VARIABLE const char *krb5_config_file = 
 #ifdef __APPLE__
 "/Library/Preferences/edu.mit.Kerberos:"
 #endif
 SYSCONFDIR "/krb5.conf:/etc/krb5.conf";
-const char *krb5_defkeyname = KEYTAB_DEFAULT;
+KRB5_LIB_VARIABLE const char *krb5_defkeyname = KEYTAB_DEFAULT;
index 256783310e935026b98800427c484d52c36dd341..543dba396df6e7088b03db4ed52a947c659135a2 100644 (file)
@@ -34,7 +34,7 @@
 #include "krb5_locl.h"
 #include <com_err.h>
 
-RCSID("$Id: context.c 22293 2007-12-14 05:25:59Z lha $");
+RCSID("$Id: context.c 23420 2008-07-26 18:37:48Z lha $");
 
 #define INIT_FIELD(C, T, E, D, F)                                      \
     (C)->E = krb5_config_get_ ## T ## _default ((C), NULL, (D),        \
@@ -68,7 +68,7 @@ set_etypes (krb5_context context,
        etypes = malloc((i+1) * sizeof(*etypes));
        if (etypes == NULL) {
            krb5_config_free_strings (etypes_str);
-           krb5_set_error_string (context, "malloc: out of memory");
+           krb5_set_error_message (context, ENOMEM, "malloc: out of memory");
            return ENOMEM;
        }
        for(j = 0, k = 0; j < i; j++) {
@@ -246,6 +246,9 @@ krb5_init_context(krb5_context *context)
     krb5_cc_register(p, &krb5_acc_ops, TRUE);
     krb5_cc_register(p, &krb5_fcc_ops, TRUE);
     krb5_cc_register(p, &krb5_mcc_ops, TRUE);
+#if 0
+    krb5_cc_register(p, &krb5_scc_ops, TRUE);
+#endif
 #ifdef HAVE_KCM
     krb5_cc_register(p, &krb5_kcm_ops, TRUE);
 #endif
@@ -257,8 +260,6 @@ krb5_init_context(krb5_context *context)
     krb5_kt_register (p, &krb5_javakt_ops);
     krb5_kt_register (p, &krb5_mkt_ops);
     krb5_kt_register (p, &krb5_akf_ops);
-    krb5_kt_register (p, &krb4_fkt_ops);
-    krb5_kt_register (p, &krb5_srvtab_fkt_ops);
     krb5_kt_register (p, &krb5_any_ops);
 
 out:
@@ -552,7 +553,7 @@ default_etypes(krb5_context context, krb5_enctype **etype)
        ep = realloc(e, (n + 2) * sizeof(*e));
        if (ep == NULL) {
            free(e);
-           krb5_set_error_string (context, "malloc: out of memory");
+           krb5_set_error_message (context, ENOMEM, "malloc: out of memory");
            return ENOMEM;
        }
        e = ep;
@@ -594,7 +595,7 @@ krb5_set_default_in_tkt_etypes(krb5_context context,
        ++i;
        ALLOC(p, i);
        if(!p) {
-           krb5_set_error_string (context, "malloc: out of memory");
+           krb5_set_error_message (context, ENOMEM, "malloc: out of memory");
            return ENOMEM;
        }
        memmove(p, etypes, i * sizeof(krb5_enctype));
@@ -623,26 +624,26 @@ krb5_error_code KRB5_LIB_FUNCTION
 krb5_get_default_in_tkt_etypes(krb5_context context,
                               krb5_enctype **etypes)
 {
-  krb5_enctype *p;
-  int i;
-  krb5_error_code ret;
-
-  if(context->etypes) {
-    for(i = 0; context->etypes[i]; i++);
-    ++i;
-    ALLOC(p, i);
-    if(!p) {
-      krb5_set_error_string (context, "malloc: out of memory");
-      return ENOMEM;
+    krb5_enctype *p;
+    int i;
+    krb5_error_code ret;
+    
+    if(context->etypes) {
+       for(i = 0; context->etypes[i]; i++);
+       ++i;
+       ALLOC(p, i);
+       if(!p) {
+           krb5_set_error_message (context, ENOMEM, "malloc: out of memory");
+           return ENOMEM;
+       }
+       memmove(p, context->etypes, i * sizeof(krb5_enctype));
+    } else {
+       ret = default_etypes(context, &p);
+       if (ret)
+           return ret;
     }
-    memmove(p, context->etypes, i * sizeof(krb5_enctype));
-  } else {
-    ret = default_etypes(context, &p);
-    if (ret)
-      return ret;
-  }
-  *etypes = p;
-  return 0;
+    *etypes = p;
+    return 0;
 }
 
 /**
@@ -776,7 +777,7 @@ krb5_set_extra_addresses(krb5_context context, const krb5_addresses *addresses)
     if(context->extra_addresses == NULL) {
        context->extra_addresses = malloc(sizeof(*context->extra_addresses));
        if(context->extra_addresses == NULL) {
-           krb5_set_error_string (context, "malloc: out of memory");
+           krb5_set_error_message (context, ENOMEM, "malloc: out of memory");
            return ENOMEM;
        }
     }
@@ -858,7 +859,7 @@ krb5_set_ignore_addresses(krb5_context context, const krb5_addresses *addresses)
     if(context->ignore_addresses == NULL) {
        context->ignore_addresses = malloc(sizeof(*context->ignore_addresses));
        if(context->ignore_addresses == NULL) {
-           krb5_set_error_string (context, "malloc: out of memory");
+           krb5_set_error_message (context, ENOMEM, "malloc: out of memory");
            return ENOMEM;
        }
     }
@@ -986,7 +987,7 @@ krb5_get_dns_canonicalize_hostname (krb5_context context)
  * @param sec seconds part of offset.
  * @param usec micro seconds part of offset.
  *
- * @return return non zero if the library uses DNS to canonicalize hostnames.
+ * @return returns zero
  *
  * @ingroup krb5
  */
@@ -1001,6 +1002,27 @@ krb5_get_kdc_sec_offset (krb5_context context, int32_t *sec, int32_t *usec)
     return 0;
 }
 
+/**
+ * Set current offset in time to the KDC.
+ *
+ * @param context Kerberos 5 context.
+ * @param sec seconds part of offset.
+ * @param usec micro seconds part of offset.
+ *
+ * @return returns zero
+ *
+ * @ingroup krb5
+ */
+
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_set_kdc_sec_offset (krb5_context context, int32_t sec, int32_t usec)
+{
+    context->kdc_sec_offset = sec;
+    if (usec >= 0)
+       context->kdc_usec_offset = usec;
+    return 0;
+}
+
 /**
  * Get max time skew allowed.
  *
index b2af0187eac31a3e7dcf43fa41982511f3dccc45..07943efb289382d1a19c8a5a25390697adc59c1f 100644 (file)
@@ -32,7 +32,7 @@
  */
 
 #include "krb5_locl.h"
-RCSID("$Id: convert_creds.c 22050 2007-11-11 11:20:46Z lha $");
+RCSID("$Id: convert_creds.c 23280 2008-06-23 03:26:18Z lha $");
 
 #include "krb5-v4compat.h"
 
@@ -97,7 +97,7 @@ krb524_convert_creds_kdc(krb5_context context,
     sp = krb5_storage_from_mem(reply.data, reply.length);
     if(sp == NULL) {
        ret = ENOMEM;
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message (context, ENOMEM, "malloc: out of memory");
        goto out2;
     }
     krb5_ret_int32(sp, &tmp);
@@ -132,8 +132,8 @@ krb524_convert_creds_kdc(krb5_context context,
            goto out;
        memcpy(v4creds->session, v5_creds->session.keyvalue.data, 8);
     } else {
-       krb5_set_error_string(context, "converting credentials: %s", 
-                             krb5_get_err_text(context, ret));
+       krb5_set_error_message (context, ret, "converting credentials: %s", 
+                               krb5_get_err_text(context, ret));
     }
 out:
     krb5_storage_free(sp);
index 8c4f39b4ac4c0f05f3b9a3d61e5ed158fb399c95..cbe333850cb98b80664d131750e5d9c6163e729f 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: copy_host_realm.c 22057 2007-11-11 15:13:13Z lha $");
+RCSID("$Id: copy_host_realm.c 23280 2008-06-23 03:26:18Z lha $");
 
 /**
  * Copy the list of realms from `from' to `to'.
@@ -53,24 +53,23 @@ krb5_copy_host_realm(krb5_context context,
                     const krb5_realm *from,
                     krb5_realm **to)
 {
-    int n, i;
+    unsigned int n, i;
     const krb5_realm *p;
 
-    for (n = 0, p = from; *p != NULL; ++p)
+    for (n = 1, p = from; *p != NULL; ++p)
        ++n;
-    ++n;
-    *to = malloc (n * sizeof(**to));
+
+    *to = calloc (n, sizeof(**to));
     if (*to == NULL) {
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message (context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
-    for (i = 0; i < n; ++i)
-       (*to)[i] = NULL;
+
     for (i = 0, p = from; *p != NULL; ++p, ++i) {
        (*to)[i] = strdup(*p);
        if ((*to)[i] == NULL) {
            krb5_free_host_realm (context, *to);
-           krb5_set_error_string (context, "malloc: out of memory");
+           krb5_set_error_message (context, ENOMEM, "malloc: out of memory");
            return ENOMEM;
        }
     }
index 072c29d68974735a2399cbb09730e4cfa14dfea4..e8ddecf7babb08bc96744d9d2c506a2756d0b402 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: crc.c 17442 2006-05-05 09:31:15Z lha $");
+RCSID("$Id: crc.c 22862 2008-04-07 18:49:55Z lha $");
 
 static u_long table[256];
 
@@ -44,7 +44,7 @@ _krb5_crc_init_table(void)
 {
     static int flag = 0;
     unsigned long crc, poly;
-    int     i, j;
+    unsigned int i, j;
     
     if(flag) return;
     poly = CRC_GEN;
index 17ef46dfa3b6736f2fbf6a210910203f5cf254b7..938ec294a45cf7f4fe15b65db481fe98d8a87a7b 100644 (file)
 
 #include "krb5_locl.h"
 
-RCSID("$Id: creds.c 22062 2007-11-11 15:41:50Z lha $");
+RCSID("$Id: creds.c 23280 2008-06-23 03:26:18Z lha $");
 
 #undef __attribute__
 #define __attribute__(X)
 
+#ifndef HEIMDAL_SMALLER
+
 /* keep this for compatibility with older code */
 krb5_error_code KRB5_LIB_FUNCTION __attribute__((deprecated))
 krb5_free_creds_contents (krb5_context context, krb5_creds *c)
@@ -45,6 +47,8 @@ krb5_free_creds_contents (krb5_context context, krb5_creds *c)
     return krb5_free_cred_contents (context, c);
 }    
 
+#endif /* HEIMDAL_SMALLER */
+
 /**
  * Free content of krb5_creds.
  *
@@ -152,7 +156,7 @@ krb5_copy_creds (krb5_context context,
 
     c = malloc (sizeof (*c));
     if (c == NULL) {
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message (context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     memset (c, 0, sizeof(*c));
index 2e6349094683b7ef9a82920477906bf68ee9a498..e91cb9391a6431397e1994b12294d1bea74f0354 100644 (file)
@@ -32,7 +32,8 @@
  */
 
 #include "krb5_locl.h"
-RCSID("$Id: crypto.c 22200 2007-12-07 13:48:01Z lha $");
+RCSID("$Id: crypto.c 23454 2008-07-27 12:11:44Z lha $");
+#include <pkinit_asn1.h>
 
 #undef CRYPTO_DEBUG
 #ifdef CRYPTO_DEBUG
@@ -111,7 +112,6 @@ struct checksum_type {
 struct encryption_type {
     krb5_enctype type;
     const char *name;
-    heim_oid *oid;
     size_t blocksize;
     size_t padsize;
     size_t confoundersize;
@@ -178,7 +178,7 @@ static void
 krb5_DES_schedule(krb5_context context,
                  struct key_data *key)
 {
-    DES_set_key(key->key->keyvalue.data, key->schedule->data);
+    DES_set_key_unchecked(key->key->keyvalue.data, key->schedule->data);
 }
 
 #ifdef ENABLE_AFS_STRING_TO_KEY
@@ -245,12 +245,12 @@ krb5_DES_AFS3_Transarc_string_to_key (krb5_data pw,
     memcpy(&ivec, "kerberos", 8);
     memcpy(&temp_key, "kerberos", 8);
     DES_set_odd_parity (&temp_key);
-    DES_set_key (&temp_key, &schedule);
+    DES_set_key_unchecked (&temp_key, &schedule);
     DES_cbc_cksum ((void*)password, &ivec, passlen, &schedule, &ivec);
 
     memcpy(&temp_key, &ivec, 8);
     DES_set_odd_parity (&temp_key);
-    DES_set_key (&temp_key, &schedule);
+    DES_set_key_unchecked (&temp_key, &schedule);
     DES_cbc_cksum ((void*)password, key, passlen, &schedule, &ivec);
     memset(&schedule, 0, sizeof(schedule));
     memset(&temp_key, 0, sizeof(temp_key));
@@ -305,7 +305,7 @@ DES_string_to_key_int(unsigned char *data, size_t length, DES_cblock *key)
     DES_set_odd_parity(key);
     if(DES_is_weak_key(key))
        (*key)[7] ^= 0xF0;
-    DES_set_key(key, &schedule);
+    DES_set_key_unchecked(key, &schedule);
     DES_cbc_cksum((void*)data, key, length, &schedule, key);
     memset(&schedule, 0, sizeof(schedule));
     DES_set_odd_parity(key);
@@ -338,7 +338,7 @@ krb5_DES_string_to_key(krb5_context context,
     len = password.length + salt.saltvalue.length;
     s = malloc(len);
     if(len > 0 && s == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message (context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     memcpy(s, password.data, password.length);
@@ -390,9 +390,9 @@ DES3_schedule(krb5_context context,
 {
     DES_cblock *k = key->key->keyvalue.data;
     DES_key_schedule *s = key->schedule->data;
-    DES_set_key(&k[0], &s[0]);
-    DES_set_key(&k[1], &s[1]);
-    DES_set_key(&k[2], &s[2]);
+    DES_set_key_unchecked(&k[0], &s[0]);
+    DES_set_key_unchecked(&k[1], &s[1]);
+    DES_set_key_unchecked(&k[2], &s[2]);
 }
 
 /*
@@ -430,7 +430,7 @@ DES3_string_to_key(krb5_context context,
     len = password.length + salt.saltvalue.length;
     str = malloc(len);
     if(len != 0 && str == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message (context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     memcpy(str, password.data, password.length);
@@ -444,7 +444,7 @@ DES3_string_to_key(krb5_context context,
        if (ret) {
            memset(str, 0, len);
            free(str);
-           krb5_set_error_string(context, "out of memory");
+           krb5_set_error_message (context, ret, "malloc: out of memory");
            return ret;
        }
        
@@ -453,7 +453,7 @@ DES3_string_to_key(krb5_context context,
            DES_set_odd_parity(keys + i);
            if(DES_is_weak_key(keys + i))
                xor(keys + i, (const unsigned char*)"\0\0\0\0\0\0\0\xf0");
-           DES_set_key(keys + i, &s[i]);
+           DES_set_key_unchecked(keys + i, &s[i]);
        }
        memset(&ivec, 0, sizeof(ivec));
        DES_ede3_cbc_encrypt(tmp,
@@ -491,7 +491,7 @@ DES3_string_to_key_derived(krb5_context context,
 
     s = malloc(len);
     if(len != 0 && s == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message (context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     memcpy(s, password.data, password.length);
@@ -560,35 +560,49 @@ ARCFOUR_string_to_key(krb5_context context,
                  krb5_data opaque,
                  krb5_keyblock *key)
 {
-    char *s, *p;
-    size_t len;
-    int i;
-    MD4_CTX m;
     krb5_error_code ret;
+    uint16_t *s;
+    size_t len, i;
+    MD4_CTX m;
 
-    len = 2 * password.length;
-    s = malloc (len);
+    ret = wind_utf8ucs2_length(password.data, &len);
+    if (ret) {
+       krb5_set_error_message (context, ret, "Password not an UCS2 string");
+       return ret;
+    }
+       
+    s = malloc (len * sizeof(s[0]));
     if (len != 0 && s == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
-       ret = ENOMEM;
-       goto out;
+       krb5_set_error_message (context, ENOMEM, "malloc: out of memory");
+       return ENOMEM;
     }
-    for (p = s, i = 0; i < password.length; ++i) {
-       *p++ = ((char *)password.data)[i];
-       *p++ = 0;
+
+    ret = wind_utf8ucs2(password.data, s, &len);
+    if (ret) {
+       krb5_set_error_message (context, ret, "Password not an UCS2 string");
+       goto out;
     }
+
+    /* LE encoding */
     MD4_Init (&m);
-    MD4_Update (&m, s, len);
+    for (i = 0; i < len; i++) {
+       unsigned char p;
+       p = (s[i] & 0xff);
+       MD4_Update (&m, &p, 1);
+       p = (s[i] >> 8) & 0xff;
+       MD4_Update (&m, &p, 1);
+    }
+
     key->keytype = enctype;
     ret = krb5_data_alloc (&key->keyvalue, 16);
     if (ret) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message (context, ENOMEM, "malloc: out of memory");
        goto out;
     }
     MD4_Final (key->keyvalue.data, &m);
-    memset (s, 0, len);
     ret = 0;
 out:
+    memset (s, 0, len);
     free (s);
     return ret;
 }
@@ -628,13 +642,13 @@ AES_string_to_key(krb5_context context,
     kd.schedule = NULL;
     ALLOC(kd.key, 1);
     if(kd.key == NULL) {
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message (context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     kd.key->keytype = enctype;
     ret = krb5_data_alloc(&kd.key->keyvalue, et->keytype->size);
     if (ret) {
-       krb5_set_error_string(context, "Failed to allocate pkcs5 key");
+       krb5_set_error_message (context, ret, "malloc: out of memory");
        return ret;
     }
 
@@ -644,7 +658,8 @@ AES_string_to_key(krb5_context context,
                                 et->keytype->size, kd.key->keyvalue.data);
     if (ret != 1) {
        free_key_data(context, &kd);
-       krb5_set_error_string(context, "Error calculating s2k");
+       krb5_set_error_message(context, KRB5_PROG_KEYTYPE_NOSUPP,
+                              "Error calculating s2k");
        return KRB5_PROG_KEYTYPE_NOSUPP;
     }
 
@@ -847,21 +862,24 @@ krb5_salttype_to_string (krb5_context context,
 
     e = _find_enctype (etype);
     if (e == NULL) {
-       krb5_set_error_string(context, "encryption type %d not supported",
-                             etype);
+       krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP,
+                              "encryption type %d not supported",
+                              etype);
        return KRB5_PROG_ETYPE_NOSUPP;
     }
     for (st = e->keytype->string_to_key; st && st->type; st++) {
        if (st->type == stype) {
            *string = strdup (st->name);
            if (*string == NULL) {
-               krb5_set_error_string(context, "malloc: out of memory");
+               krb5_set_error_message (context, ENOMEM,
+                                       "malloc: out of memory");
                return ENOMEM;
            }
            return 0;
        }
     }
-    krb5_set_error_string(context, "salttype %d not supported", stype);
+    krb5_set_error_message (context, HEIM_ERR_SALTTYPE_NOSUPP,
+                           "salttype %d not supported", stype);
     return HEIM_ERR_SALTTYPE_NOSUPP;
 }
 
@@ -876,8 +894,9 @@ krb5_string_to_salttype (krb5_context context,
 
     e = _find_enctype (etype);
     if (e == NULL) {
-       krb5_set_error_string(context, "encryption type %d not supported",
-                             etype);
+       krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP,
+                              "encryption type %d not supported",
+                              etype);
        return KRB5_PROG_ETYPE_NOSUPP;
     }
     for (st = e->keytype->string_to_key; st && st->type; st++) {
@@ -886,7 +905,8 @@ krb5_string_to_salttype (krb5_context context,
            return 0;
        }
     }
-    krb5_set_error_string(context, "salttype %s not supported", string);
+    krb5_set_error_message(context, HEIM_ERR_SALTTYPE_NOSUPP,
+                          "salttype %s not supported", string);
     return HEIM_ERR_SALTTYPE_NOSUPP;
 }
 
@@ -988,16 +1008,18 @@ krb5_string_to_key_data_salt_opaque (krb5_context context,
     struct encryption_type *et =_find_enctype(enctype);
     struct salt_type *st;
     if(et == NULL) {
-       krb5_set_error_string(context, "encryption type %d not supported",
-                             enctype);
+       krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP,
+                              "encryption type %d not supported",
+                              enctype);
        return KRB5_PROG_ETYPE_NOSUPP;
     }
     for(st = et->keytype->string_to_key; st && st->type; st++) 
        if(st->type == salt.salttype)
            return (*st->string_to_key)(context, enctype, password, 
                                        salt, opaque, key);
-    krb5_set_error_string(context, "salt type %d not supported",
-                         salt.salttype);
+    krb5_set_error_message(context, HEIM_ERR_SALTTYPE_NOSUPP,
+                          "salt type %d not supported",
+                          salt.salttype);
     return HEIM_ERR_SALTTYPE_NOSUPP;
 }
 
@@ -1042,12 +1064,13 @@ krb5_keytype_to_string(krb5_context context,
 {
     struct key_type *kt = _find_keytype(keytype);
     if(kt == NULL) {
-       krb5_set_error_string(context, "key type %d not supported", keytype);
+       krb5_set_error_message(context, KRB5_PROG_KEYTYPE_NOSUPP,
+                              "key type %d not supported", keytype);
        return KRB5_PROG_KEYTYPE_NOSUPP;
     }
     *string = strdup(kt->name);
     if(*string == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     return 0;
@@ -1058,13 +1081,24 @@ krb5_string_to_keytype(krb5_context context,
                       const char *string,
                       krb5_keytype *keytype)
 {
+    char *end;
     int i;
+
     for(i = 0; i < num_keytypes; i++)
        if(strcasecmp(keytypes[i]->name, string) == 0){
            *keytype = keytypes[i]->type;
            return 0;
        }
-    krb5_set_error_string(context, "key type %s not supported", string);
+
+    /* check if the enctype is a number */
+    *keytype = strtol(string, &end, 0);
+    if(*end == '\0' && *keytype != 0) {
+       if (krb5_enctype_valid(context, *keytype) == 0)
+           return 0;
+    }
+
+    krb5_set_error_message(context, KRB5_PROG_KEYTYPE_NOSUPP,
+                          "key type %s not supported", string);
     return KRB5_PROG_KEYTYPE_NOSUPP;
 }
 
@@ -1075,8 +1109,9 @@ krb5_enctype_keysize(krb5_context context,
 {
     struct encryption_type *et = _find_enctype(type);
     if(et == NULL) {
-       krb5_set_error_string(context, "encryption type %d not supported",
-                             type);
+       krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP,
+                              "encryption type %d not supported",
+                              type);
        return KRB5_PROG_ETYPE_NOSUPP;
     }
     *keysize = et->keytype->size;
@@ -1090,7 +1125,8 @@ krb5_enctype_keybits(krb5_context context,
 {
     struct encryption_type *et = _find_enctype(type);
     if(et == NULL) {
-       krb5_set_error_string(context, "encryption type %d not supported",
+       krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP,
+                              "encryption type %d not supported",
                              type);
        return KRB5_PROG_ETYPE_NOSUPP;
     }
@@ -1106,8 +1142,9 @@ krb5_generate_random_keyblock(krb5_context context,
     krb5_error_code ret;
     struct encryption_type *et = _find_enctype(type);
     if(et == NULL) {
-       krb5_set_error_string(context, "encryption type %d not supported",
-                             type);
+       krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP,
+                              "encryption type %d not supported",
+                              type);
        return KRB5_PROG_ETYPE_NOSUPP;
     }
     ret = krb5_data_alloc(&key->keyvalue, et->keytype->size);
@@ -1136,7 +1173,7 @@ _key_schedule(krb5_context context,
        return 0;
     ALLOC(key->schedule, 1);
     if(key->schedule == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     ret = krb5_data_alloc(key->schedule, kt->schedule_size);
@@ -1481,8 +1518,9 @@ krb5_hmac(krb5_context context,
     krb5_error_code ret;
 
     if (c == NULL) {
-       krb5_set_error_string (context, "checksum type %d not supported",
-                              cktype);
+       krb5_set_error_message (context, KRB5_PROG_SUMTYPE_NOSUPP,
+                               "checksum type %d not supported",
+                               cktype);
        return KRB5_PROG_SUMTYPE_NOSUPP;
     }
 
@@ -1797,7 +1835,7 @@ get_checksum_key(krb5_context context,
 
        *key = _new_derived_key(crypto, 0xff/* KRB5_KU_RFC1510_VARIANT */);
        if(*key == NULL) {
-           krb5_set_error_string(context, "malloc: out of memory");
+           krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
            return ENOMEM;
        }
        ret = krb5_copy_keyblock(context, crypto->key.key, &(*key)->key);
@@ -1832,9 +1870,10 @@ create_checksum (krb5_context context,
     }
     keyed_checksum = (ct->flags & F_KEYED) != 0;
     if(keyed_checksum && crypto == NULL) {
-       krb5_set_error_string (context, "Checksum type %s is keyed "
-                              "but no crypto context (key) was passed in",
-                              ct->name);
+       krb5_set_error_message (context, KRB5_PROG_SUMTYPE_NOSUPP,
+                               "Checksum type %s is keyed "
+                               "but no crypto context (key) was passed in",
+                               ct->name);
        return KRB5_PROG_SUMTYPE_NOSUPP; /* XXX */
     }
     if(keyed_checksum) {
@@ -1880,8 +1919,9 @@ krb5_create_checksum(krb5_context context,
     }
 
     if(ct == NULL) {
-       krb5_set_error_string (context, "checksum type %d not supported",
-                              type);
+       krb5_set_error_message (context, KRB5_PROG_SUMTYPE_NOSUPP,
+                               "checksum type %d not supported",
+                               type);
        return KRB5_PROG_SUMTYPE_NOSUPP;
     }
 
@@ -1911,7 +1951,8 @@ verify_checksum(krb5_context context,
 
     ct = _find_checksum(cksum->cksumtype);
     if (ct == NULL || (ct->flags & F_DISABLED)) {
-       krb5_set_error_string (context, "checksum type %d not supported",
+       krb5_set_error_message (context, KRB5_PROG_SUMTYPE_NOSUPP,
+                               "checksum type %d not supported",
                               cksum->cksumtype);
        return KRB5_PROG_SUMTYPE_NOSUPP;
     }
@@ -1921,9 +1962,10 @@ verify_checksum(krb5_context context,
     }
     keyed_checksum = (ct->flags & F_KEYED) != 0;
     if(keyed_checksum && crypto == NULL) {
-       krb5_set_error_string (context, "Checksum type %s is keyed "
-                              "but no crypto context (key) was passed in",
-                              ct->name);
+       krb5_set_error_message (context, KRB5_PROG_SUMTYPE_NOSUPP,
+                               "Checksum type %s is keyed "
+                               "but no crypto context (key) was passed in",
+                               ct->name);
        return KRB5_PROG_SUMTYPE_NOSUPP; /* XXX */
     }
     if(keyed_checksum)
@@ -1963,8 +2005,9 @@ krb5_verify_checksum(krb5_context context,
 
     ct = _find_checksum(cksum->cksumtype);
     if(ct == NULL) {
-       krb5_set_error_string (context, "checksum type %d not supported",
-                              cksum->cksumtype);
+       krb5_set_error_message (context, KRB5_PROG_SUMTYPE_NOSUPP,
+                               "checksum type %d not supported",
+                               cksum->cksumtype);
        return KRB5_PROG_SUMTYPE_NOSUPP;
     }
 
@@ -1992,7 +2035,8 @@ krb5_crypto_get_checksum_type(krb5_context context,
     }
     
     if (ct == NULL) {
-       krb5_set_error_string (context, "checksum type not found");
+       krb5_set_error_message (context, KRB5_PROG_SUMTYPE_NOSUPP,
+                               "checksum type not found");
         return KRB5_PROG_SUMTYPE_NOSUPP;
     }    
 
@@ -2009,8 +2053,9 @@ krb5_checksumsize(krb5_context context,
 {
     struct checksum_type *ct = _find_checksum(type);
     if(ct == NULL) {
-       krb5_set_error_string (context, "checksum type %d not supported",
-                              type);
+       krb5_set_error_message (context, KRB5_PROG_SUMTYPE_NOSUPP,
+                               "checksum type %d not supported",
+                               type);
        return KRB5_PROG_SUMTYPE_NOSUPP;
     }
     *size = ct->checksumsize;
@@ -2024,8 +2069,9 @@ krb5_checksum_is_keyed(krb5_context context,
     struct checksum_type *ct = _find_checksum(type);
     if(ct == NULL) {
        if (context)
-           krb5_set_error_string (context, "checksum type %d not supported",
-                                  type);
+           krb5_set_error_message (context, KRB5_PROG_SUMTYPE_NOSUPP,
+                                   "checksum type %d not supported",
+                                   type);
        return KRB5_PROG_SUMTYPE_NOSUPP;
     }
     return ct->flags & F_KEYED;
@@ -2038,8 +2084,9 @@ krb5_checksum_is_collision_proof(krb5_context context,
     struct checksum_type *ct = _find_checksum(type);
     if(ct == NULL) {
        if (context)
-           krb5_set_error_string (context, "checksum type %d not supported",
-                                  type);
+           krb5_set_error_message (context, KRB5_PROG_SUMTYPE_NOSUPP,
+                                   "checksum type %d not supported",
+                                   type);
        return KRB5_PROG_SUMTYPE_NOSUPP;
     }
     return ct->flags & F_CPROOF;
@@ -2052,8 +2099,9 @@ krb5_checksum_disable(krb5_context context,
     struct checksum_type *ct = _find_checksum(type);
     if(ct == NULL) {
        if (context)
-           krb5_set_error_string (context, "checksum type %d not supported",
-                                  type);
+           krb5_set_error_message (context, KRB5_PROG_SUMTYPE_NOSUPP,
+                                   "checksum type %d not supported",
+                                   type);
        return KRB5_PROG_SUMTYPE_NOSUPP;
     }
     ct->flags |= F_DISABLED;
@@ -2478,7 +2526,7 @@ AES_PRF(krb5_context context,
     result.cksumtype = ct->type;
     ret = krb5_data_alloc(&result.checksum, ct->checksumsize);
     if (ret) {
-       krb5_set_error_string(context, "out memory");
+       krb5_set_error_message(context, ret, "out memory");
        return ret;
     }
 
@@ -2519,7 +2567,6 @@ AES_PRF(krb5_context context,
 static struct encryption_type enctype_null = {
     ETYPE_NULL,
     "null",
-    NULL,
     1,
     1,
     0,
@@ -2534,7 +2581,6 @@ static struct encryption_type enctype_null = {
 static struct encryption_type enctype_des_cbc_crc = {
     ETYPE_DES_CBC_CRC,
     "des-cbc-crc",
-    NULL,
     8,
     8,
     8,
@@ -2549,7 +2595,6 @@ static struct encryption_type enctype_des_cbc_crc = {
 static struct encryption_type enctype_des_cbc_md4 = {
     ETYPE_DES_CBC_MD4,
     "des-cbc-md4",
-    NULL,
     8,
     8,
     8,
@@ -2564,7 +2609,6 @@ static struct encryption_type enctype_des_cbc_md4 = {
 static struct encryption_type enctype_des_cbc_md5 = {
     ETYPE_DES_CBC_MD5,
     "des-cbc-md5",
-    NULL,
     8,
     8,
     8,
@@ -2579,7 +2623,6 @@ static struct encryption_type enctype_des_cbc_md5 = {
 static struct encryption_type enctype_arcfour_hmac_md5 = {
     ETYPE_ARCFOUR_HMAC_MD5,
     "arcfour-hmac-md5",
-    NULL,
     1,
     1,
     8,
@@ -2594,7 +2637,6 @@ static struct encryption_type enctype_arcfour_hmac_md5 = {
 static struct encryption_type enctype_des3_cbc_md5 = { 
     ETYPE_DES3_CBC_MD5,
     "des3-cbc-md5",
-    NULL,
     8,
     8,
     8,
@@ -2609,7 +2651,6 @@ static struct encryption_type enctype_des3_cbc_md5 = {
 static struct encryption_type enctype_des3_cbc_sha1 = {
     ETYPE_DES3_CBC_SHA1,
     "des3-cbc-sha1",
-    NULL,
     8,
     8,
     8,
@@ -2624,7 +2665,6 @@ static struct encryption_type enctype_des3_cbc_sha1 = {
 static struct encryption_type enctype_old_des3_cbc_sha1 = {
     ETYPE_OLD_DES3_CBC_SHA1,
     "old-des3-cbc-sha1",
-    NULL,
     8,
     8,
     8,
@@ -2639,7 +2679,6 @@ static struct encryption_type enctype_old_des3_cbc_sha1 = {
 static struct encryption_type enctype_aes128_cts_hmac_sha1 = {
     ETYPE_AES128_CTS_HMAC_SHA1_96,
     "aes128-cts-hmac-sha1-96",
-    NULL,
     16,
     1,
     16,
@@ -2654,7 +2693,6 @@ static struct encryption_type enctype_aes128_cts_hmac_sha1 = {
 static struct encryption_type enctype_aes256_cts_hmac_sha1 = {
     ETYPE_AES256_CTS_HMAC_SHA1_96,
     "aes256-cts-hmac-sha1-96",
-    NULL,
     16,
     1,
     16,
@@ -2669,7 +2707,6 @@ static struct encryption_type enctype_aes256_cts_hmac_sha1 = {
 static struct encryption_type enctype_des_cbc_none = {
     ETYPE_DES_CBC_NONE,
     "des-cbc-none",
-    NULL,
     8,
     8,
     0,
@@ -2684,7 +2721,6 @@ static struct encryption_type enctype_des_cbc_none = {
 static struct encryption_type enctype_des_cfb64_none = {
     ETYPE_DES_CFB64_NONE,
     "des-cfb64-none",
-    NULL,
     1,
     1,
     0,
@@ -2699,7 +2735,6 @@ static struct encryption_type enctype_des_cfb64_none = {
 static struct encryption_type enctype_des_pcbc_none = {
     ETYPE_DES_PCBC_NONE,
     "des-pcbc-none",
-    NULL,
     8,
     8,
     0,
@@ -2714,7 +2749,6 @@ static struct encryption_type enctype_des_pcbc_none = {
 static struct encryption_type enctype_des3_cbc_none = {
     ETYPE_DES3_CBC_NONE,
     "des3-cbc-none",
-    NULL,
     8,
     8,
     0,
@@ -2766,14 +2800,15 @@ krb5_enctype_to_string(krb5_context context,
     struct encryption_type *e;
     e = _find_enctype(etype);
     if(e == NULL) {
-       krb5_set_error_string (context, "encryption type %d not supported",
-                              etype);
+       krb5_set_error_message (context, KRB5_PROG_ETYPE_NOSUPP,
+                               "encryption type %d not supported",
+                               etype);
        *string = NULL;
        return KRB5_PROG_ETYPE_NOSUPP;
     }
     *string = strdup(e->name);
     if(*string == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     return 0;
@@ -2790,43 +2825,9 @@ krb5_string_to_enctype(krb5_context context,
            *etype = etypes[i]->type;
            return 0;
        }
-    krb5_set_error_string (context, "encryption type %s not supported",
-                          string);
-    return KRB5_PROG_ETYPE_NOSUPP;
-}
-
-krb5_error_code KRB5_LIB_FUNCTION
-_krb5_enctype_to_oid(krb5_context context,
-                   krb5_enctype etype,
-                   heim_oid *oid)
-{
-    struct encryption_type *et = _find_enctype(etype);
-    if(et == NULL) {
-       krb5_set_error_string (context, "encryption type %d not supported",
-                              etype);
-       return KRB5_PROG_ETYPE_NOSUPP;
-    }
-    if(et->oid == NULL) {
-       krb5_set_error_string (context, "%s have not oid", et->name);
-       return KRB5_PROG_ETYPE_NOSUPP;
-    }
-    krb5_clear_error_string(context);
-    return der_copy_oid(et->oid, oid);
-}
-
-krb5_error_code KRB5_LIB_FUNCTION
-_krb5_oid_to_enctype(krb5_context context,
-                    const heim_oid *oid,
-                    krb5_enctype *etype)
-{
-    int i;
-    for(i = 0; i < num_etypes; i++) {
-       if(etypes[i]->oid && der_heim_oid_cmp(etypes[i]->oid, oid) == 0) {
-           *etype = etypes[i]->type;
-           return 0;
-       }
-    }
-    krb5_set_error_string(context, "enctype for oid not supported");
+    krb5_set_error_message (context, KRB5_PROG_ETYPE_NOSUPP,
+                           "encryption type %s not supported",
+                           string);
     return KRB5_PROG_ETYPE_NOSUPP;
 }
 
@@ -2837,7 +2838,8 @@ krb5_enctype_to_keytype(krb5_context context,
 {
     struct encryption_type *e = _find_enctype(etype);
     if(e == NULL) {
-       krb5_set_error_string (context, "encryption type %d not supported",
+       krb5_set_error_message (context, KRB5_PROG_ETYPE_NOSUPP,
+                               "encryption type %d not supported",
                               etype);
        return KRB5_PROG_ETYPE_NOSUPP;
     }
@@ -2845,21 +2847,6 @@ krb5_enctype_to_keytype(krb5_context context,
     return 0;
 }
 
-#if 0
-krb5_error_code KRB5_LIB_FUNCTION
-krb5_keytype_to_enctype(krb5_context context,
-                       krb5_keytype keytype,
-                       krb5_enctype *etype)
-{
-    struct key_type *kt = _find_keytype(keytype);
-    krb5_warnx(context, "krb5_keytype_to_enctype(%u)", keytype);
-    if(kt == NULL)
-       return KRB5_PROG_KEYTYPE_NOSUPP;
-    *etype = kt->best_etype;
-    return 0;
-}
-#endif
-    
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_keytype_to_enctypes (krb5_context context,
                          krb5_keytype keytype,
@@ -2877,7 +2864,7 @@ krb5_keytype_to_enctypes (krb5_context context,
     }
     ret = malloc(n * sizeof(*ret));
     if (ret == NULL && n != 0) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     n = 0;
@@ -2902,7 +2889,7 @@ krb5_keytype_to_enctypes_default (krb5_context context,
                                  unsigned *len,
                                  krb5_enctype **val)
 {
-    int i, n;
+    unsigned int i, n;
     krb5_enctype *ret;
 
     if (keytype != KEYTYPE_DES || context->etypes_des == NULL)
@@ -2912,7 +2899,7 @@ krb5_keytype_to_enctypes_default (krb5_context context,
        ;
     ret = malloc (n * sizeof(*ret));
     if (ret == NULL && n != 0) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     for (i = 0; i < n; ++i)
@@ -2928,13 +2915,15 @@ krb5_enctype_valid(krb5_context context,
 {
     struct encryption_type *e = _find_enctype(etype);
     if(e == NULL) {
-       krb5_set_error_string (context, "encryption type %d not supported",
-                              etype);
+       krb5_set_error_message (context, KRB5_PROG_ETYPE_NOSUPP,
+                               "encryption type %d not supported",
+                               etype);
        return KRB5_PROG_ETYPE_NOSUPP;
     }
     if (e->flags & F_DISABLED) {
-       krb5_set_error_string (context, "encryption type %s is disabled",
-                              e->name);
+       krb5_set_error_message (context, KRB5_PROG_ETYPE_NOSUPP,
+                               "encryption type %s is disabled",
+                               e->name);
        return KRB5_PROG_ETYPE_NOSUPP;
     }
     return 0;
@@ -2946,13 +2935,15 @@ krb5_cksumtype_valid(krb5_context context,
 {
     struct checksum_type *c = _find_checksum(ctype);
     if (c == NULL) {
-       krb5_set_error_string (context, "checksum type %d not supported",
-                              ctype);
+       krb5_set_error_message (context, KRB5_PROG_SUMTYPE_NOSUPP,
+                               "checksum type %d not supported",
+                               ctype);
        return KRB5_PROG_SUMTYPE_NOSUPP;
     }
     if (c->flags & F_DISABLED) {
-       krb5_set_error_string (context, "checksum type %s is disabled",
-                              c->name);
+       krb5_set_error_message (context, KRB5_PROG_SUMTYPE_NOSUPP,
+                               "checksum type %s is disabled",
+                               c->name);
        return KRB5_PROG_SUMTYPE_NOSUPP;
     }
     return 0;
@@ -3010,7 +3001,7 @@ encrypt_internal_derived(krb5_context context,
     total_sz = block_sz + checksum_sz;
     p = calloc(1, total_sz);
     if(p == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     
@@ -3077,7 +3068,7 @@ encrypt_internal(krb5_context context,
     block_sz = (sz + et->padsize - 1) &~ (et->padsize - 1); /* pad */
     p = calloc(1, block_sz);
     if(p == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     
@@ -3142,7 +3133,7 @@ encrypt_internal_special(krb5_context context,
 
     tmp = malloc (sz);
     if (tmp == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     p = tmp;
@@ -3181,8 +3172,9 @@ decrypt_internal_derived(krb5_context context,
     
     checksum_sz = CHECKSUMSIZE(et->keyed_checksum);
     if (len < checksum_sz + et->confoundersize) {
-       krb5_set_error_string(context, "Encrypted data shorter then "
-                             "checksum + confunder");
+       krb5_set_error_message(context, KRB5_BAD_MSIZE,
+                              "Encrypted data shorter then "
+                              "checksum + confunder");
        return KRB5_BAD_MSIZE;
     }
 
@@ -3193,7 +3185,7 @@ decrypt_internal_derived(krb5_context context,
 
     p = malloc(len);
     if(len != 0 && p == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     memcpy(p, data, len);
@@ -3238,7 +3230,7 @@ decrypt_internal_derived(krb5_context context,
     result->data = realloc(p, l);
     if(result->data == NULL && l != 0) {
        free(p);
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     result->length = l;
@@ -3267,7 +3259,7 @@ decrypt_internal(krb5_context context,
     checksum_sz = CHECKSUMSIZE(et->checksum);
     p = malloc(len);
     if(len != 0 && p == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     memcpy(p, data, len);
@@ -3303,7 +3295,7 @@ decrypt_internal(krb5_context context,
     result->data = realloc(p, l);
     if(result->data == NULL && l != 0) {
        free(p);
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     result->length = l;
@@ -3332,7 +3324,7 @@ decrypt_internal_special(krb5_context context,
 
     p = malloc (len);
     if (p == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     memcpy(p, data, len);
@@ -3347,7 +3339,7 @@ decrypt_internal_special(krb5_context context,
     result->data = realloc(p, sz);
     if(result->data == NULL && sz != 0) {
        free(p);
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     result->length = sz;
@@ -3463,6 +3455,7 @@ seed_something(void)
        fd = open(seedfile, O_RDONLY);
        if (fd >= 0) {
            ssize_t ret;
+           rk_cloexec(fd);
            ret = read(fd, buf, sizeof(buf));
            if (ret > 0)
                RAND_add(buf, ret, 0.0);
@@ -3547,13 +3540,13 @@ derive_key(krb5_context context,
        nblocks = (kt->bits + et->blocksize * 8 - 1) / (et->blocksize * 8);
        k = malloc(nblocks * et->blocksize);
        if(k == NULL) {
-           krb5_set_error_string(context, "malloc: out of memory");
+           krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
            return ENOMEM;
        }
        ret = _krb5_n_fold(constant, len, k, et->blocksize);
        if (ret) {
            free(k);
-           krb5_set_error_string(context, "out of memory");
+           krb5_set_error_message(context, ret, "malloc: out of memory");
            return ret;
        }
        for(i = 0; i < nblocks; i++) {
@@ -3570,7 +3563,7 @@ derive_key(krb5_context context,
        size_t res_len = (kt->bits + 7) / 8;
 
        if(len != 0 && c == NULL) {
-           krb5_set_error_string(context, "malloc: out of memory");
+           krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
            return ENOMEM;
        }
        memcpy(c, constant, len);
@@ -3578,13 +3571,13 @@ derive_key(krb5_context context,
        k = malloc(res_len);
        if(res_len != 0 && k == NULL) {
            free(c);
-           krb5_set_error_string(context, "malloc: out of memory");
+           krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
            return ENOMEM;
        }
        ret = _krb5_n_fold(c, len, k, res_len);
        if (ret) {
            free(k);
-           krb5_set_error_string(context, "out of memory");
+           krb5_set_error_message(context, ret, "malloc: out of memory");
            return ret;
        }
        free(c);
@@ -3600,10 +3593,10 @@ derive_key(krb5_context context,
        memcpy(key->key->keyvalue.data, k, key->key->keyvalue.length);
        break;
     default:
-       krb5_set_error_string(context,
-                             "derive_key() called with unknown keytype (%u)", 
-                             kt->type);
        ret = KRB5_CRYPTO_INTERNAL;
+       krb5_set_error_message(context, ret,
+                              "derive_key() called with unknown keytype (%u)", 
+                              kt->type);
        break;
     }
     if (key->schedule) {
@@ -3645,8 +3638,9 @@ krb5_derive_key(krb5_context context,
 
     et = _find_enctype (etype);
     if (et == NULL) {
-       krb5_set_error_string(context, "encryption type %d not supported",
-                             etype);
+       krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP,
+                              "encryption type %d not supported",
+                              etype);
        return KRB5_PROG_ETYPE_NOSUPP;
     }
 
@@ -3679,7 +3673,7 @@ _get_derived_key(krb5_context context,
        }
     d = _new_derived_key(crypto, usage);
     if(d == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     krb5_copy_keyblock(context, crypto->key.key, &d->key);
@@ -3699,7 +3693,7 @@ krb5_crypto_init(krb5_context context,
     krb5_error_code ret;
     ALLOC(*crypto, 1);
     if(*crypto == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     if(etype == ETYPE_NULL)
@@ -3708,14 +3702,16 @@ krb5_crypto_init(krb5_context context,
     if((*crypto)->et == NULL || ((*crypto)->et->flags & F_DISABLED)) {
        free(*crypto);
        *crypto = NULL;
-       krb5_set_error_string (context, "encryption type %d not supported",
-                              etype);
+       krb5_set_error_message (context, KRB5_PROG_ETYPE_NOSUPP,
+                               "encryption type %d not supported",
+                               etype);
        return KRB5_PROG_ETYPE_NOSUPP;
     }
     if((*crypto)->et->keytype->size != key->keyvalue.length) {
        free(*crypto);
        *crypto = NULL;
-       krb5_set_error_string (context, "encryption key has bad length");
+       krb5_set_error_message (context, KRB5_BAD_KEYSIZE,
+                               "encryption key has bad length");
        return KRB5_BAD_KEYSIZE;
     }
     ret = krb5_copy_keyblock(context, key, &(*crypto)->key.key);
@@ -3803,8 +3799,9 @@ krb5_enctype_disable(krb5_context context,
     struct encryption_type *et = _find_enctype(enctype);
     if(et == NULL) {
        if (context)
-           krb5_set_error_string (context, "encryption type %d not supported",
-                                  enctype);
+           krb5_set_error_message (context, KRB5_PROG_ETYPE_NOSUPP,
+                                   "encryption type %d not supported",
+                                   enctype);
        return KRB5_PROG_ETYPE_NOSUPP;
     }
     et->flags |= F_DISABLED;
@@ -3825,15 +3822,17 @@ krb5_string_to_key_derived(krb5_context context,
     u_char *tmp;
 
     if(et == NULL) {
-       krb5_set_error_string (context, "encryption type %d not supported",
-                              etype);
+       krb5_set_error_message (context, KRB5_PROG_ETYPE_NOSUPP,
+                               "encryption type %d not supported",
+                               etype);
        return KRB5_PROG_ETYPE_NOSUPP;
     }
     keylen = et->keytype->bits / 8;
 
     ALLOC(kd.key, 1);
     if(kd.key == NULL) {
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message (context, ENOMEM,
+                               "malloc: out of memory");
        return ENOMEM;
     }
     ret = krb5_data_alloc(&kd.key->keyvalue, et->keytype->size);
@@ -3845,13 +3844,13 @@ krb5_string_to_key_derived(krb5_context context,
     tmp = malloc (keylen);
     if(tmp == NULL) {
        krb5_free_keyblock(context, kd.key);
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message (context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     ret = _krb5_n_fold(str, len, tmp, keylen);
     if (ret) {
        free(tmp);
-       krb5_set_error_string(context, "out of memory");
+       krb5_set_error_message (context, ENOMEM, "malloc: out of memory");
        return ret;
     }
     kd.schedule = NULL;
@@ -3970,14 +3969,16 @@ krb5_random_to_key(krb5_context context,
     krb5_error_code ret;
     struct encryption_type *et = _find_enctype(type);
     if(et == NULL) {
-       krb5_set_error_string(context, "encryption type %d not supported",
-                             type);
+       krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP, 
+                              "encryption type %d not supported",
+                              type);
        return KRB5_PROG_ETYPE_NOSUPP;
     }
     if ((et->keytype->bits + 7) / 8 > size) {
-       krb5_set_error_string(context, "encryption key %s needs %d bytes "
-                             "of random to make an encryption key out of it",
-                             et->name, (int)et->keytype->size);
+       krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP,
+                              "encryption key %s needs %d bytes "
+                              "of random to make an encryption key out of it",
+                              et->name, (int)et->keytype->size);
        return KRB5_PROG_ETYPE_NOSUPP;
     }
     ret = krb5_data_alloc(&key->keyvalue, et->keytype->size);
@@ -4009,15 +4010,16 @@ _krb5_pk_octetstring2key(krb5_context context,
     unsigned char shaoutput[20];
 
     if(et == NULL) {
-       krb5_set_error_string(context, "encryption type %d not supported",
-                             type);
+       krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP,
+                              "encryption type %d not supported",
+                              type);
        return KRB5_PROG_ETYPE_NOSUPP;
     }
     keylen = (et->keytype->bits + 7) / 8;
 
     keydata = malloc(keylen);
     if (keydata == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
 
@@ -4050,6 +4052,182 @@ _krb5_pk_octetstring2key(krb5_context context,
     return ret;
 }
 
+static krb5_error_code
+encode_uvinfo(krb5_context context, krb5_const_principal p, krb5_data *data)
+{
+    KRB5PrincipalName pn;
+    krb5_error_code ret;
+    size_t size;
+
+    pn.principalName = p->name;
+    pn.realm = p->realm;
+
+    ASN1_MALLOC_ENCODE(KRB5PrincipalName, data->data, data->length,
+                      &pn, &size, ret);
+    if (ret) {
+       krb5_data_zero(data);
+       krb5_set_error_message(context, ret,
+                              "Failed to encode KRB5PrincipalName");
+       return ret;
+    }
+    if (data->length != size)
+       krb5_abortx(context, "asn1 compiler internal error");
+    return 0;
+}
+
+static krb5_error_code
+encode_otherinfo(krb5_context context,
+                const AlgorithmIdentifier *ai,
+                krb5_const_principal client,
+                krb5_const_principal server,
+                krb5_enctype enctype,
+                const krb5_data *as_req,
+                const krb5_data *pk_as_rep,
+                const Ticket *ticket,
+                krb5_data *other)
+{
+    PkinitSP80056AOtherInfo otherinfo;
+    PkinitSuppPubInfo pubinfo;
+    krb5_error_code ret;
+    krb5_data pub;
+    size_t size;
+
+    krb5_data_zero(other);
+    memset(&otherinfo, 0, sizeof(otherinfo));
+    memset(&pubinfo, 0, sizeof(pubinfo));
+
+    pubinfo.enctype = enctype;
+    pubinfo.as_REQ = *as_req;
+    pubinfo.pk_as_rep = *pk_as_rep;
+    pubinfo.ticket = *ticket;
+    ASN1_MALLOC_ENCODE(PkinitSuppPubInfo, pub.data, pub.length,
+                      &pubinfo, &size, ret);
+    if (ret) {
+       krb5_set_error_message(context, ret, "out of memory");
+       return ret;
+    }
+    if (pub.length != size)
+       krb5_abortx(context, "asn1 compiler internal error");
+
+    ret = encode_uvinfo(context, client, &otherinfo.partyUInfo);
+    if (ret) {
+       free(pub.data);
+       return ret;
+    }
+    ret = encode_uvinfo(context, server, &otherinfo.partyVInfo);
+    if (ret) {
+       free(otherinfo.partyUInfo.data);
+       free(pub.data);
+       return ret;
+    }
+
+    otherinfo.algorithmID = *ai;
+    otherinfo.suppPubInfo = &pub;
+    
+    ASN1_MALLOC_ENCODE(PkinitSP80056AOtherInfo, other->data, other->length, 
+                      &otherinfo, &size, ret);
+    free(otherinfo.partyUInfo.data);
+    free(otherinfo.partyVInfo.data);
+    free(pub.data);
+    if (ret) {
+       krb5_set_error_message(context, ret, "out of memory");
+       return ret;
+    }
+    if (other->length != size)
+       krb5_abortx(context, "asn1 compiler internal error");
+
+    return 0;
+}
+
+krb5_error_code
+_krb5_pk_kdf(krb5_context context,
+            const struct AlgorithmIdentifier *ai,
+            const void *dhdata,
+            size_t dhsize,
+            krb5_const_principal client,
+            krb5_const_principal server,
+            krb5_enctype enctype,
+            const krb5_data *as_req,
+            const krb5_data *pk_as_rep,
+            const Ticket *ticket,
+            krb5_keyblock *key)
+{
+    struct encryption_type *et;
+    krb5_error_code ret;
+    krb5_data other;
+    size_t keylen, offset;
+    uint32_t counter;
+    unsigned char *keydata;
+    unsigned char shaoutput[20];
+
+    if (der_heim_oid_cmp(oid_id_pkinit_kdf_ah_sha1(), &ai->algorithm) != 0) {
+       krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP,
+                              "kdf not supported");
+       return KRB5_PROG_ETYPE_NOSUPP;
+    }
+    if (ai->parameters != NULL &&
+       (ai->parameters->length != 2 || 
+        memcmp(ai->parameters->data, "\x05\x00", 2) != 0)) 
+    {
+       krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP,
+                              "kdf params not NULL or the NULL-type");
+       return KRB5_PROG_ETYPE_NOSUPP;
+    }
+
+    et = _find_enctype(enctype);
+    if(et == NULL) {
+       krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP,
+                              "encryption type %d not supported",
+                              enctype);
+       return KRB5_PROG_ETYPE_NOSUPP;
+    }
+    keylen = (et->keytype->bits + 7) / 8;
+
+    keydata = malloc(keylen);
+    if (keydata == NULL) {
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
+       return ENOMEM;
+    }
+
+    ret = encode_otherinfo(context, ai, client, server, 
+                          enctype, as_req, pk_as_rep, ticket, &other);
+    if (ret) {
+       free(keydata);
+       return ret;
+    }
+
+    offset = 0;
+    counter = 1;
+    do {
+       unsigned char cdata[4];
+       SHA_CTX m;
+       
+       SHA1_Init(&m);
+       _krb5_put_int(cdata, counter, 4);
+       SHA1_Update(&m, cdata, 4);
+       SHA1_Update(&m, dhdata, dhsize);
+       SHA1_Update(&m, other.data, other.length);
+       SHA1_Final(shaoutput, &m);
+
+       memcpy((unsigned char *)keydata + offset,
+              shaoutput,
+              min(keylen - offset, sizeof(shaoutput)));
+
+       offset += sizeof(shaoutput);
+       counter++;
+    } while(offset < keylen);
+    memset(shaoutput, 0, sizeof(shaoutput));
+
+    free(other.data);
+
+    ret = krb5_random_to_key(context, enctype, keydata, keylen, key);
+    memset(keydata, 0, sizeof(keylen));
+    free(keydata);
+
+    return ret;
+}
+
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_crypto_prf_length(krb5_context context,
                       krb5_enctype type,
@@ -4058,8 +4236,9 @@ krb5_crypto_prf_length(krb5_context context,
     struct encryption_type *et = _find_enctype(type);
 
     if(et == NULL || et->prf_length == 0) {
-       krb5_set_error_string(context, "encryption type %d not supported",
-                             type);
+       krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP,
+                              "encryption type %d not supported",
+                              type);
        return KRB5_PROG_ETYPE_NOSUPP;
     }
 
@@ -4078,8 +4257,9 @@ krb5_crypto_prf(krb5_context context,
     krb5_data_zero(output);
 
     if(et->prf == NULL) {
-       krb5_set_error_string(context, "kerberos prf for %s not supported",
-                             et->name);
+       krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP,
+                              "kerberos prf for %s not supported",
+                              et->name);
        return KRB5_PROG_ETYPE_NOSUPP;
     }
 
index eda1a8b2598b710d24757f278d317f9c588171a9..2b78bfb32b42ebfc18f1f35ba169c7c4b51fec98 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: data.c 22064 2007-11-11 16:28:14Z lha $");
+RCSID("$Id: data.c 23280 2008-06-23 03:26:18Z lha $");
 
 /**
  * Reset the (potentially uninitalized) krb5_data structure.
@@ -192,7 +192,7 @@ krb5_copy_data(krb5_context context,
     krb5_error_code ret;
     ALLOC(*outdata, 1);
     if(*outdata == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     ret = der_copy_octet_string(indata, *outdata);
index ff6e98a3dcafd3737d87d3bf42e9fd9efe7b2bc2..6679b76749283869f44fc9a6bd4a60a43f06dd72 100644 (file)
 
 #include "krb5_locl.h"
 
-RCSID("$Id: error_string.c 22142 2007-12-04 16:56:02Z lha $");
+RCSID("$Id: error_string.c 23274 2008-06-23 03:25:08Z lha $");
 
 #undef __attribute__
 #define __attribute__(X)
 
-void KRB5_LIB_FUNCTION
-krb5_free_error_string(krb5_context context, char *str)
-{
-    HEIMDAL_MUTEX_lock(context->mutex);
-    if (str != context->error_buf)
-       free(str);
-    HEIMDAL_MUTEX_unlock(context->mutex);
-}
-
 void KRB5_LIB_FUNCTION
 krb5_clear_error_string(krb5_context context)
 {
     HEIMDAL_MUTEX_lock(context->mutex);
-    if (context->error_string != NULL
-       && context->error_string != context->error_buf)
+    if (context->error_string)
        free(context->error_string);
+    context->error_code = 0;
     context->error_string = NULL;
     HEIMDAL_MUTEX_unlock(context->mutex);
 }
 
-krb5_error_code KRB5_LIB_FUNCTION
-krb5_set_error_string(krb5_context context, const char *fmt, ...)
-    __attribute__((format (printf, 2, 3)))
+/**
+ * Set the context full error string for a specific error code.
+ *
+ * @param context Kerberos 5 context
+ * @param ret The error code
+ * @param fmt Error string for the error code
+ * @param ... printf(3) style parameters.
+ *
+ * @ingroup krb5_error
+ */
+
+void KRB5_LIB_FUNCTION
+krb5_set_error_message(krb5_context context, krb5_error_code ret,
+                      const char *fmt, ...)
+    __attribute__ ((format (printf, 3, 4)))
 {
-    krb5_error_code ret;
     va_list ap;
 
     va_start(ap, fmt);
-    ret = krb5_vset_error_string (context, fmt, ap);
+    krb5_vset_error_message (context, ret, fmt, ap);
     va_end(ap);
-    return ret;
 }
 
-krb5_error_code KRB5_LIB_FUNCTION
-krb5_vset_error_string(krb5_context context, const char *fmt, va_list args)
-    __attribute__ ((format (printf, 2, 0)))
+/**
+ * Set the context full error string for a specific error code.
+ *
+ * @param context Kerberos 5 context
+ * @param ret The error code
+ * @param fmt Error string for the error code
+ * @param args printf(3) style parameters.
+ *
+ * @ingroup krb5_error
+ */
+
+
+void KRB5_LIB_FUNCTION
+krb5_vset_error_message (krb5_context context, krb5_error_code ret,
+                        const char *fmt, va_list args)
+    __attribute__ ((format (printf, 3, 0)))
 {
+
     krb5_clear_error_string(context);
     HEIMDAL_MUTEX_lock(context->mutex);
+    context->error_code = ret;
     vasprintf(&context->error_string, fmt, args);
-    if(context->error_string == NULL) {
-       vsnprintf (context->error_buf, sizeof(context->error_buf), fmt, args);
-       context->error_string = context->error_buf;
-    }
     HEIMDAL_MUTEX_unlock(context->mutex);
-    return 0;
 }
 
+
 /**
  * Return the error message in context. On error or no error string,
  * the function returns NULL.
@@ -93,7 +105,7 @@ krb5_vset_error_string(krb5_context context, const char *fmt, va_list args)
  * @param context Kerberos 5 context
  *
  * @return an error string, needs to be freed with
- * krb5_free_error_string(). The functions return NULL on error.
+ * krb5_free_error_message(). The functions return NULL on error.
  *
  * @ingroup krb5_error
  */
@@ -121,35 +133,99 @@ krb5_have_error_string(krb5_context context)
 }
 
 /**
- * Return the error message for `code' in context. On error the
- * function returns NULL.
+ * Return the error message for `code' in context. On memory
+ * allocation error the function returns NULL.
  *
  * @param context Kerberos 5 context
  * @param code Error code related to the error
  *
  * @return an error string, needs to be freed with
- * krb5_free_error_string(). The functions return NULL on error.
+ * krb5_free_error_message(). The functions return NULL on error.
  *
  * @ingroup krb5_error
  */
 
-char * KRB5_LIB_FUNCTION
+const char * KRB5_LIB_FUNCTION
 krb5_get_error_message(krb5_context context, krb5_error_code code)
 {
     const char *cstr;
     char *str;
 
-    str = krb5_get_error_string(context);
-    if (str)
-       return str;
+    HEIMDAL_MUTEX_lock(context->mutex);
+    if (context->error_string && 
+       (code == context->error_code || context->error_code == 0))
+    {
+       str = strdup(context->error_string);
+       if (str) {
+           HEIMDAL_MUTEX_unlock(context->mutex);
+           return str;
+       }
+    }
+    HEIMDAL_MUTEX_unlock(context->mutex);
 
     cstr = krb5_get_err_text(context, code);
     if (cstr)
        return strdup(cstr);
 
-    if (asprintf(&str, "<unknown error: %d>", code) == -1)
+    if (asprintf(&str, "<unknown error: %d>", (int)code) == -1)
        return NULL;
 
     return str;
 }
 
+
+/**
+ * Free the error message returned by krb5_get_error_message().
+ *
+ * @param context Kerberos context
+ * @param msg error message to free, returned byg
+ *        krb5_get_error_message().
+ *
+ * @ingroup krb5_error
+ */
+
+void KRB5_LIB_FUNCTION
+krb5_free_error_message(krb5_context context, const char *msg)
+{
+    free(rk_UNCONST(msg));
+}
+
+#ifndef HEIMDAL_SMALLER
+
+/**
+ * Free the error message returned by krb5_get_error_string(),
+ * deprecated, use krb5_free_error_message().
+ *
+ * @param context Kerberos context
+ * @param msg error message to free
+ *
+ * @ingroup krb5_error
+ */
+
+void KRB5_LIB_FUNCTION __attribute__((deprecated))
+krb5_free_error_string(krb5_context context, char *str)
+{
+    krb5_free_error_message(context, str);
+}
+
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_set_error_string(krb5_context context, const char *fmt, ...)
+    __attribute__((format (printf, 2, 3))) __attribute__((deprecated))
+{
+    va_list ap;
+
+    va_start(ap, fmt);
+    krb5_vset_error_message (context, 0, fmt, ap);
+    va_end(ap);
+    return 0;
+}
+
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_vset_error_string(krb5_context context, const char *fmt, va_list args)
+    __attribute__ ((format (printf, 2, 0))) __attribute__((deprecated))
+{
+    krb5_vset_error_message(context, 0, fmt, args);
+    return 0;
+}
+
+#endif /* !HEIMDAL_SMALLER */
index 28e39afb42f74d094fd8bcb16cb838f16d423164..d06d5764327297abe83f0a8282ceb638a2ea5b0f 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: expand_hostname.c 22229 2007-12-08 21:40:59Z lha $");
+RCSID("$Id: expand_hostname.c 23280 2008-06-23 03:26:18Z lha $");
 
 static krb5_error_code
 copy_hostname(krb5_context context,
@@ -42,7 +42,7 @@ copy_hostname(krb5_context context,
 {
     *new_hostname = strdup (orig_hostname);
     if (*new_hostname == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     strlwr (*new_hostname);
@@ -76,7 +76,8 @@ krb5_expand_hostname (krb5_context context,
            *new_hostname = strdup (a->ai_canonname);
            freeaddrinfo (ai);
            if (*new_hostname == NULL) {
-               krb5_set_error_string(context, "malloc: out of memory");
+               krb5_set_error_message(context, ENOMEM,
+                                      "malloc: out of memory");
                return ENOMEM;
            } else {
                return 0;
index 484df059abd6cd032710d13430ae653c11b55076..8951bdb24e38b13d140a0a410cb5b4ef6d8e611b 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: fcache.c 22517 2008-01-24 11:45:51Z lha $");
+RCSID("$Id: fcache.c 23444 2008-07-27 12:07:47Z lha $");
 
 typedef struct krb5_fcache{
     char *filename;
@@ -93,12 +93,12 @@ _krb5_xlock(krb5_context context, int fd, krb5_boolean exclusive,
        ret = 0; 
        break;
     case EAGAIN:
-       krb5_set_error_string(context, "timed out locking cache file %s", 
-                             filename);
+       krb5_set_error_message(context, ret, "timed out locking cache file %s", 
+                              filename);
        break;
     default:
-       krb5_set_error_string(context, "error locking cache file %s: %s",
-                             filename, strerror(ret));
+       krb5_set_error_message(context, ret, "error locking cache file %s: %s",
+                              filename, strerror(ret));
        break;
     }
     return ret;
@@ -127,13 +127,39 @@ _krb5_xunlock(krb5_context context, int fd)
        ret = 0; 
        break;
     default:
-       krb5_set_error_string(context, 
-                             "Failed to unlock file: %s", strerror(ret));
+       krb5_set_error_message(context, ret,
+                              "Failed to unlock file: %s",
+                              strerror(ret));
        break;
     }
     return ret;
 }
 
+static krb5_error_code
+write_storage(krb5_context context, krb5_storage *sp, int fd)
+{
+    krb5_error_code ret;
+    krb5_data data;
+    ssize_t sret;
+
+    ret = krb5_storage_to_data(sp, &data);
+    if (ret) {
+       krb5_set_error_message(context, ret, "malloc: out of memory");
+       return ret;
+    }
+    sret = write(fd, data.data, data.length);
+    ret = (sret != data.length);
+    krb5_data_free(&data);
+    if (ret) {
+       ret = errno;
+       krb5_set_error_message(context, ret,
+                              "Failed to write FILE credential data");
+       return ret;
+    }
+    return 0;
+}
+
+
 static krb5_error_code
 fcc_lock(krb5_context context, krb5_ccache id,
         int fd, krb5_boolean exclusive)
@@ -153,13 +179,15 @@ fcc_resolve(krb5_context context, krb5_ccache *id, const char *res)
     krb5_fcache *f;
     f = malloc(sizeof(*f));
     if(f == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, KRB5_CC_NOMEM,
+                              "malloc: out of memory");
        return KRB5_CC_NOMEM;
     }
     f->filename = strdup(res);
     if(f->filename == NULL){
        free(f);
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, KRB5_CC_NOMEM,
+                              "malloc: out of memory");
        return KRB5_CC_NOMEM;
     }
     f->version = 0;
@@ -203,7 +231,7 @@ scrub_file (int fd)
  */
 
 static krb5_error_code
-erase_file(const char *filename)
+erase_file(krb5_context context, const char *filename)
 {
     int fd;
     struct stat sb1, sb2;
@@ -220,12 +248,20 @@ erase_file(const char *filename)
        else
            return errno;
     }
+    rk_cloexec(fd);
+    ret = _krb5_xlock(context, fd, 1, filename);
+    if (ret) {
+       close(fd);
+       return ret;
+    }
     if (unlink(filename) < 0) {
+       _krb5_xunlock(context, fd);
         close (fd);
         return errno;
     }
     ret = fstat (fd, &sb2);
     if (ret < 0) {
+       _krb5_xunlock(context, fd);
        close (fd);
        return errno;
     }
@@ -233,6 +269,7 @@ erase_file(const char *filename)
     /* check if someone was playing with symlinks */
 
     if (sb1.st_dev != sb2.st_dev || sb1.st_ino != sb2.st_ino) {
+       _krb5_xunlock(context, fd);
        close (fd);
        return EPERM;
     }
@@ -240,11 +277,18 @@ erase_file(const char *filename)
     /* there are still hard links to this file */
 
     if (sb2.st_nlink != 0) {
+       _krb5_xunlock(context, fd);
         close (fd);
         return 0;
     }
 
     ret = scrub_file (fd);
+    if (ret) {
+       _krb5_xunlock(context, fd);
+       close(fd);
+       return ret;
+    }
+    ret = _krb5_xunlock(context, fd);
     close (fd);
     return ret;
 }
@@ -258,19 +302,21 @@ fcc_gen_new(krb5_context context, krb5_ccache *id)
 
     f = malloc(sizeof(*f));
     if(f == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, KRB5_CC_NOMEM,
+                              "malloc: out of memory");
        return KRB5_CC_NOMEM;
     }
     asprintf (&file, "%sXXXXXX", KRB5_DEFAULT_CCFILE_ROOT);
     if(file == NULL) {
        free(f);
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, KRB5_CC_NOMEM,
+                              "malloc: out of memory");
        return KRB5_CC_NOMEM;
     }
     fd = mkstemp(file);
     if(fd < 0) {
        int ret = errno;
-       krb5_set_error_string(context, "mkstemp %s", file);
+       krb5_set_error_message(context, ret, "mkstemp %s", file);
        free(f);
        free(file);
        return ret;
@@ -323,11 +369,12 @@ fcc_open(krb5_context context,
     fd = open(filename, flags, mode);
     if(fd < 0) {
        ret = errno;
-       krb5_set_error_string(context, "open(%s): %s", filename,
-                             strerror(ret));
+       krb5_set_error_message(context, ret, "open(%s): %s", filename,
+                              strerror(ret));
        return ret;
     }
-       
+    rk_cloexec(fd);
+    
     if((ret = fcc_lock(context, id, fd, exclusive)) != 0) {
        close(fd);
        return ret;
@@ -353,7 +400,7 @@ fcc_initialize(krb5_context context,
        return ret;
     {
        krb5_storage *sp;    
-       sp = krb5_storage_from_fd(fd);
+       sp = krb5_storage_emem();
        krb5_storage_set_eof_code(sp, KRB5_CC_END);
        if(context->fcache_vno != 0)
            f->version = context->fcache_vno;
@@ -376,14 +423,16 @@ fcc_initialize(krb5_context context,
        }
        ret |= krb5_store_principal(sp, primary_principal);
        
+       ret |= write_storage(context, sp, fd);
+
        krb5_storage_free(sp);
     }
     fcc_unlock(context, fd);
     if (close(fd) < 0)
        if (ret == 0) {
            ret = errno;
-           krb5_set_error_string (context, "close %s: %s", 
-                                  FILENAME(id), strerror(ret));
+           krb5_set_error_message (context, ret, "close %s: %s", 
+                                   FILENAME(id), strerror(ret));
        }
     return ret;
 }
@@ -401,7 +450,7 @@ static krb5_error_code
 fcc_destroy(krb5_context context,
            krb5_ccache id)
 {
-    erase_file(FILENAME(id));
+    erase_file(context, FILENAME(id));
     return 0;
 }
 
@@ -418,7 +467,8 @@ fcc_store_cred(krb5_context context,
        return ret;
     {
        krb5_storage *sp;
-       sp = krb5_storage_from_fd(fd);
+
+       sp = krb5_storage_emem();
        krb5_storage_set_eof_code(sp, KRB5_CC_END);
        storage_set_flags(context, sp, FCACHE(id)->version);
        if (!krb5_config_get_bool_default(context, NULL, TRUE,
@@ -427,15 +477,18 @@ fcc_store_cred(krb5_context context,
                                          NULL))
            krb5_storage_set_flags(sp, KRB5_STORAGE_CREDS_FLAGS_WRONG_BITORDER);
        ret = krb5_store_creds(sp, creds);
+       if (ret == 0)
+           ret = write_storage(context, sp, fd);
        krb5_storage_free(sp);
     }
     fcc_unlock(context, fd);
-    if (close(fd) < 0)
+    if (close(fd) < 0) {
        if (ret == 0) {
            ret = errno;
-           krb5_set_error_string (context, "close %s: %s", 
-                                  FILENAME(id), strerror(ret));
+           krb5_set_error_message (context, ret, "close %s: %s", 
+                                   FILENAME(id), strerror(ret));
        }
+    }
     return ret;
 }
 
@@ -464,25 +517,27 @@ init_fcc (krb5_context context,
     ret = krb5_ret_int8(sp, &pvno);
     if(ret != 0) {
        if(ret == KRB5_CC_END) {
-           krb5_set_error_string(context, "Empty credential cache file: %s",
-                                 FILENAME(id));
            ret = ENOENT;
+           krb5_set_error_message(context, ret, 
+                                  "Empty credential cache file: %s",
+                                  FILENAME(id));
        } else
-           krb5_set_error_string(context, "Error reading pvno in "
-                                 "cache file: %s", FILENAME(id));
+           krb5_set_error_message(context, ret,  "Error reading pvno in "
+                                  "cache file: %s", FILENAME(id));
        goto out;
     }
     if(pvno != 5) {
-       krb5_set_error_string(context, "Bad version number in credential "
-                             "cache file: %s", FILENAME(id));
        ret = KRB5_CCACHE_BADVNO;
+       krb5_set_error_message(context, ret, "Bad version number in "
+                              "credential cache file: %s",
+                              FILENAME(id));
        goto out;
     }
     ret = krb5_ret_int8(sp, &tag); /* should not be host byte order */
     if(ret != 0) {
-       krb5_set_error_string(context, "Error reading tag in "
-                             "cache file: %s", FILENAME(id));
        ret = KRB5_CC_FORMAT;
+       krb5_set_error_message(context, ret, "Error reading tag in "
+                             "cache file: %s", FILENAME(id));
        goto out;
     }
     FCACHE(id)->version = tag;
@@ -494,8 +549,9 @@ init_fcc (krb5_context context,
        ret = krb5_ret_int16 (sp, &length);
        if(ret) {
            ret = KRB5_CC_FORMAT;
-           krb5_set_error_string(context, "Error reading tag length in "
-                             "cache file: %s", FILENAME(id));
+           krb5_set_error_message(context, ret, 
+                                  "Error reading tag length in "
+                                  "cache file: %s", FILENAME(id));
            goto out;
        }
        while(length > 0) {
@@ -505,32 +561,32 @@ init_fcc (krb5_context context,
 
            ret = krb5_ret_int16 (sp, &dtag);
            if(ret) {
-               krb5_set_error_string(context, "Error reading dtag in "
-                                     "cache file: %s", FILENAME(id));
                ret = KRB5_CC_FORMAT;
+               krb5_set_error_message(context, ret, "Error reading dtag in "
+                                      "cache file: %s", FILENAME(id));
                goto out;
            }
            ret = krb5_ret_int16 (sp, &data_len);
            if(ret) {
-               krb5_set_error_string(context, "Error reading dlength in "
-                                     "cache file: %s", FILENAME(id));
                ret = KRB5_CC_FORMAT;
+               krb5_set_error_message(context, ret, "Error reading dlength in "
+                                      "cache file: %s", FILENAME(id));
                goto out;
            }
            switch (dtag) {
            case FCC_TAG_DELTATIME :
                ret = krb5_ret_int32 (sp, &context->kdc_sec_offset);
                if(ret) {
-                   krb5_set_error_string(context, "Error reading kdc_sec in "
-                                         "cache file: %s", FILENAME(id));
                    ret = KRB5_CC_FORMAT;
+                   krb5_set_error_message(context, ret, "Error reading kdc_sec in "
+                                          "cache file: %s", FILENAME(id));
                    goto out;
                }
                ret = krb5_ret_int32 (sp, &context->kdc_usec_offset);
                if(ret) {
-                   krb5_set_error_string(context, "Error reading kdc_usec in "
-                                         "cache file: %s", FILENAME(id));
                    ret = KRB5_CC_FORMAT;
+                   krb5_set_error_message(context, ret, "Error reading kdc_usec in "
+                                          "cache file: %s", FILENAME(id));
                    goto out;
                }
                break;
@@ -538,10 +594,11 @@ init_fcc (krb5_context context,
                for (i = 0; i < data_len; ++i) {
                    ret = krb5_ret_int8 (sp, &dummy);
                    if(ret) {
-                       krb5_set_error_string(context, "Error reading unknown "
-                                             "tag in cache file: %s", 
-                                             FILENAME(id));
                        ret = KRB5_CC_FORMAT;
+                       krb5_set_error_message(context, ret,
+                                              "Error reading unknown "
+                                              "tag in cache file: %s", 
+                                              FILENAME(id));
                        goto out;
                    }
                }
@@ -557,9 +614,9 @@ init_fcc (krb5_context context,
        break;
     default :
        ret = KRB5_CCACHE_BADVNO;
-       krb5_set_error_string(context, "Unknown version number (%d) in "
-                             "credential cache file: %s",
-                             (int)tag, FILENAME(id));
+       krb5_set_error_message(context, ret, "Unknown version number (%d) in "
+                              "credential cache file: %s",
+                              (int)tag, FILENAME(id));
        goto out;
     }
     *ret_sp = sp;
@@ -610,7 +667,7 @@ fcc_get_first (krb5_context context,
 
     *cursor = malloc(sizeof(struct fcc_cursor));
     if (*cursor == NULL) {
-        krb5_set_error_string (context, "malloc: out of memory");
+        krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     memset(*cursor, 0, sizeof(struct fcc_cursor));
@@ -670,7 +727,7 @@ fcc_remove_cred(krb5_context context,
                 krb5_creds *cred)
 {
     krb5_error_code ret;
-    krb5_ccache copy;
+    krb5_ccache copy, newfile;
 
     ret = krb5_cc_gen_new(context, &krb5_mcc_ops, &copy);
     if (ret)
@@ -688,12 +745,20 @@ fcc_remove_cred(krb5_context context,
        return ret;
     }
 
-    fcc_destroy(context, id);
+    ret = krb5_cc_gen_new(context, &krb5_fcc_ops, &newfile);
+    if (ret) {
+       krb5_cc_destroy(context, copy);
+       return ret;
+    }
 
-    ret = krb5_cc_copy_cache(context, copy, id);
+    ret = krb5_cc_copy_cache(context, copy, newfile);
     krb5_cc_destroy(context, copy);
+    if (ret) {
+       krb5_cc_destroy(context, newfile);
+       return ret;
+    }
 
-    return ret;
+    return krb5_cc_move(context, newfile, id);
 }
 
 static krb5_error_code
@@ -704,7 +769,7 @@ fcc_set_flags(krb5_context context,
     return 0; /* XXX */
 }
 
-static krb5_error_code
+static int
 fcc_get_version(krb5_context context,
                krb5_ccache id)
 {
@@ -722,7 +787,7 @@ fcc_get_cache_first(krb5_context context, krb5_cc_cursor *cursor)
 
     iter = calloc(1, sizeof(*iter));
     if (iter == NULL) {
-       krb5_set_error_string(context, "malloc - out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }    
     iter->first = 1;
@@ -775,10 +840,10 @@ fcc_move(krb5_context context, krb5_ccache from, krb5_ccache to)
     ret = rename(FILENAME(from), FILENAME(to));
     if (ret && errno != EXDEV) {
        ret = errno;
-       krb5_set_error_string(context,
-                             "Rename of file from %s to %s failed: %s", 
-                             FILENAME(from), FILENAME(to),
-                             strerror(ret));
+       krb5_set_error_message(context, ret,
+                              "Rename of file from %s to %s failed: %s", 
+                              FILENAME(from), FILENAME(to),
+                              strerror(ret));
        return ret;
     } else if (ret && errno == EXDEV) {
        /* make a copy and delete the orignal */
@@ -801,21 +866,19 @@ fcc_move(krb5_context context, krb5_ccache from, krb5_ccache to)
            sz2 = write(fd2, buf, sz1);
            if (sz1 != sz2) {
                ret = EIO;
-               krb5_set_error_string(context,
-                                     "Failed to write data from one file "
-                                     "credential cache to the other");
+               krb5_set_error_message(context, ret,
+                                      "Failed to write data from one file "
+                                      "credential cache to the other");
                goto out2;
            }
        }
        if (sz1 < 0) {
            ret = EIO;
-           krb5_set_error_string(context,
-                                 "Failed to read data from one file "
-                                 "credential cache to the other");
+           krb5_set_error_message(context, ret,
+                                  "Failed to read data from one file "
+                                  "credential cache to the other");
            goto out2;
        }
-       erase_file(FILENAME(from));
-           
     out2:
        fcc_unlock(context, fd2);
        close(fd2);
@@ -824,8 +887,10 @@ fcc_move(krb5_context context, krb5_ccache from, krb5_ccache to)
        fcc_unlock(context, fd1);
        close(fd1);
 
+       erase_file(context, FILENAME(from));
+
        if (ret) {
-           erase_file(FILENAME(to));
+           erase_file(context, FILENAME(to));
            return ret;
        }
     }
@@ -856,7 +921,8 @@ fcc_default_name(krb5_context context, char **str)
  * @ingroup krb5_ccache
  */
 
-const krb5_cc_ops krb5_fcc_ops = {
+KRB5_LIB_VARIABLE const krb5_cc_ops krb5_fcc_ops = {
+    KRB5_CC_OPS_VERSION,
     "FILE",
     fcc_get_name,
     fcc_resolve,
index fb99cbbf3f7448e10cbf4e878405c12cff79fcb3..fb7efbcd296645ea999cc16dcaec69a269483507 100644 (file)
@@ -33,7 +33,7 @@
 
 #include <krb5_locl.h>
 
-RCSID("$Id: generate_subkey.c 14455 2005-01-05 02:39:21Z lukeh $");
+RCSID("$Id: generate_subkey.c 23280 2008-06-23 03:26:18Z lha $");
 
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_generate_subkey(krb5_context context,
@@ -53,7 +53,7 @@ krb5_generate_subkey_extended(krb5_context context,
 
     ALLOC(*subkey, 1);
     if (*subkey == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
 
index fc78945c63a3bb977144472088e26b66472c1a3c..268550b22930bb8a35666208e93e796349aa1e7c 100644 (file)
@@ -1,39 +1,39 @@
 /*
- * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden). 
- * All rights reserved. 
+ * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
  *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions 
- * are met: 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
  *
- * 1. Redistributions of source code must retain the above copyright 
- *    notice, this list of conditions and the following disclaimer. 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
  *
- * 2. Redistributions in binary form must reproduce the above copyright 
- *    notice, this list of conditions and the following disclaimer in the 
- *    documentation and/or other materials provided with the distribution. 
+ * 2. Redistributions in binary form must 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. 
+ * 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. 
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
  */
 
 #include <krb5_locl.h>
 
-RCSID("$Id: get_cred.c 22530 2008-01-27 11:48:16Z lha $");
+RCSID("$Id: get_cred.c 23280 2008-06-23 03:26:18Z lha $");
 
 /*
  * Take the `body' and encode it into `padata' using the credentials
@@ -41,12 +41,11 @@ RCSID("$Id: get_cred.c 22530 2008-01-27 11:48:16Z lha $");
  */
 
 static krb5_error_code
-make_pa_tgs_req(krb5_context context, 
+make_pa_tgs_req(krb5_context context,
                krb5_auth_context ac,
                KDC_REQ_BODY *body,
                PA_DATA *padata,
-               krb5_creds *creds,
-               krb5_key_usage usage)
+               krb5_creds *creds)
 {
     u_char *buf;
     size_t buf_size;
@@ -65,8 +64,7 @@ make_pa_tgs_req(krb5_context context,
     ret = _krb5_mk_req_internal(context, &ac, 0, &in_data, creds,
                                &padata->padata_value,
                                KRB5_KU_TGS_REQ_AUTH_CKSUM,
-                               usage
-                               /* KRB5_KU_TGS_REQ_AUTH */);
+                               KRB5_KU_TGS_REQ_AUTH);
  out:
     free (buf);
     if(ret)
@@ -101,7 +99,7 @@ set_auth_data (krb5_context context,
        ALLOC(req_body->enc_authorization_data, 1);
        if (req_body->enc_authorization_data == NULL) {
            free (buf);
-           krb5_set_error_string(context, "malloc: out of memory");
+           krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
            return ENOMEM;
        }
        ret = krb5_crypto_init(context, key, 0, &crypto);
@@ -111,9 +109,9 @@ set_auth_data (krb5_context context,
            req_body->enc_authorization_data = NULL;
            return ret;
        }
-       krb5_encrypt_EncryptedData(context, 
+       krb5_encrypt_EncryptedData(context,
                                   crypto,
-                                  KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY, 
+                                  KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY,
                                   /* KRB5_KU_TGS_REQ_AUTH_DAT_SESSION? */
                                   buf,
                                   len,
@@ -125,7 +123,7 @@ set_auth_data (krb5_context context,
        req_body->enc_authorization_data = NULL;
     }
     return 0;
-}    
+}
 
 /*
  * Create a tgs-req in `t' with `addresses', `flags', `second_ticket'
@@ -144,8 +142,7 @@ init_tgs_req (krb5_context context,
              unsigned nonce,
              const METHOD_DATA *padata,
              krb5_keyblock **subkey,
-             TGS_REQ *t,
-             krb5_key_usage usage)
+             TGS_REQ *t)
 {
     krb5_error_code ret = 0;
 
@@ -156,14 +153,14 @@ init_tgs_req (krb5_context context,
        ALLOC_SEQ(&t->req_body.etype, 1);
        if(t->req_body.etype.val == NULL) {
            ret = ENOMEM;
-           krb5_set_error_string(context, "malloc: out of memory");
+           krb5_set_error_message(context, ret, "malloc: out of memory");
            goto fail;
        }
        t->req_body.etype.val[0] = in_creds->session.keytype;
     } else {
-       ret = krb5_init_etype(context, 
-                             &t->req_body.etype.len, 
-                             &t->req_body.etype.val, 
+       ret = krb5_init_etype(context,
+                             &t->req_body.etype.len,
+                             &t->req_body.etype.val,
                              NULL);
     }
     if (ret)
@@ -176,7 +173,7 @@ init_tgs_req (krb5_context context,
     ALLOC(t->req_body.sname, 1);
     if (t->req_body.sname == NULL) {
        ret = ENOMEM;
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ret, "malloc: out of memory");
        goto fail;
     }
 
@@ -192,39 +189,39 @@ init_tgs_req (krb5_context context,
     ALLOC(t->req_body.till, 1);
     if(t->req_body.till == NULL){
        ret = ENOMEM;
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ret, "malloc: out of memory");
        goto fail;
     }
     *t->req_body.till = in_creds->times.endtime;
-    
+
     t->req_body.nonce = nonce;
     if(second_ticket){
        ALLOC(t->req_body.additional_tickets, 1);
        if (t->req_body.additional_tickets == NULL) {
            ret = ENOMEM;
-           krb5_set_error_string(context, "malloc: out of memory");
+           krb5_set_error_message(context, ret, "malloc: out of memory");
            goto fail;
        }
        ALLOC_SEQ(t->req_body.additional_tickets, 1);
        if (t->req_body.additional_tickets->val == NULL) {
            ret = ENOMEM;
-           krb5_set_error_string(context, "malloc: out of memory");
+           krb5_set_error_message(context, ret, "malloc: out of memory");
            goto fail;
        }
-       ret = copy_Ticket(second_ticket, t->req_body.additional_tickets->val); 
+       ret = copy_Ticket(second_ticket, t->req_body.additional_tickets->val);
        if (ret)
            goto fail;
     }
     ALLOC(t->padata, 1);
     if (t->padata == NULL) {
        ret = ENOMEM;
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ret, "malloc: out of memory");
        goto fail;
     }
     ALLOC_SEQ(t->padata, 1 + padata->len);
     if (t->padata->val == NULL) {
        ret = ENOMEM;
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ret, "malloc: out of memory");
        goto fail;
     }
     {
@@ -232,7 +229,7 @@ init_tgs_req (krb5_context context,
        for (i = 0; i < padata->len; i++) {
            ret = copy_PA_DATA(&padata->val[i], &t->padata->val[i + 1]);
            if (ret) {
-               krb5_set_error_string(context, "malloc: out of memory");
+               krb5_set_error_message(context, ret, "malloc: out of memory");
                goto fail;
            }
        }
@@ -278,10 +275,9 @@ init_tgs_req (krb5_context context,
 
        ret = make_pa_tgs_req(context,
                              ac,
-                             &t->req_body, 
+                             &t->req_body,
                              &t->padata->val[0],
-                             krbtgt,
-                             usage);
+                             krbtgt);
        if(ret) {
            if (key)
                krb5_free_keyblock (context, key);
@@ -315,7 +311,7 @@ _krb5_get_krbtgt(krb5_context context,
     if (ret)
        return ret;
 
-    ret = krb5_make_principal(context, 
+    ret = krb5_make_principal(context,
                              &tmp_cred.server,
                              realm,
                              KRB5_TGS_NAME,
@@ -349,7 +345,7 @@ decrypt_tkt_with_subkey (krb5_context context,
     krb5_data data;
     size_t size;
     krb5_crypto crypto;
-    
+
     ret = krb5_crypto_init(context, key, 0, &crypto);
     if (ret)
        return ret;
@@ -373,33 +369,32 @@ decrypt_tkt_with_subkey (krb5_context context,
     }
     if (ret)
        return ret;
-    
+
     ret = krb5_decode_EncASRepPart(context,
                                   data.data,
                                   data.length,
-                                  &dec_rep->enc_part, 
+                                  &dec_rep->enc_part,
                                   &size);
     if (ret)
        ret = krb5_decode_EncTGSRepPart(context,
                                        data.data,
                                        data.length,
-                                       &dec_rep->enc_part, 
+                                       &dec_rep->enc_part,
                                        &size);
     krb5_data_free (&data);
     return ret;
 }
 
 static krb5_error_code
-get_cred_kdc_usage(krb5_context context, 
-                  krb5_ccache id, 
-                  krb5_kdc_flags flags,
-                  krb5_addresses *addresses, 
-                  krb5_creds *in_creds,
-                  krb5_creds *krbtgt,
-                  krb5_principal impersonate_principal,
-                  Ticket *second_ticket,
-                  krb5_creds *out_creds,
-                  krb5_key_usage usage)
+get_cred_kdc(krb5_context context,
+            krb5_ccache id,
+            krb5_kdc_flags flags,
+            krb5_addresses *addresses,
+            krb5_creds *in_creds,
+            krb5_creds *krbtgt,
+            krb5_principal impersonate_principal,
+            Ticket *second_ticket,
+            krb5_creds *out_creds)
 {
     TGS_REQ req;
     krb5_data enc;
@@ -412,7 +407,7 @@ get_cred_kdc_usage(krb5_context context,
     size_t len;
     Ticket second_ticket_data;
     METHOD_DATA padata;
-    
+
     krb5_data_zero(&resp);
     krb5_data_zero(&enc);
     padata.val = NULL;
@@ -420,10 +415,10 @@ get_cred_kdc_usage(krb5_context context,
 
     krb5_generate_random_block(&nonce, sizeof(nonce));
     nonce &= 0xffffffff;
-    
+
     if(flags.b.enc_tkt_in_skey && second_ticket == NULL){
-       ret = decode_Ticket(in_creds->second_ticket.data, 
-                           in_creds->second_ticket.length, 
+       ret = decode_Ticket(in_creds->second_ticket.data,
+                           in_creds->second_ticket.length,
                            &second_ticket_data, &len);
        if(ret)
            return ret;
@@ -460,7 +455,7 @@ get_cred_kdc_usage(krb5_context context,
                                   KRB5_KU_OTHER_CKSUM,
                                   0,
                                   data.data,
-                                  data.length, 
+                                  data.length,
                                   &self.cksum);
        krb5_crypto_destroy(context, crypto);
        krb5_data_free(&data);
@@ -491,14 +486,13 @@ get_cred_kdc_usage(krb5_context context,
                        krbtgt,
                        nonce,
                        &padata,
-                       &subkey, 
-                       &req,
-                       usage);
+                       &subkey,
+                       &req);
     if (ret)
        goto out;
 
     ASN1_MALLOC_ENCODE(TGS_REQ, enc.data, enc.length, &req, &len, ret);
-    if (ret) 
+    if (ret)
        goto out;
     if(enc.length != len)
        krb5_abortx(context, "internal error in ASN.1 encoder");
@@ -526,20 +520,26 @@ get_cred_kdc_usage(krb5_context context,
        goto out;
 
     memset(&rep, 0, sizeof(rep));
-    if(decode_TGS_REP(resp.data, resp.length, &rep.kdc_rep, &len) == 0){
-       ret = krb5_copy_principal(context, 
-                                 in_creds->client, 
+    if(decode_TGS_REP(resp.data, resp.length, &rep.kdc_rep, &len) == 0) {
+       unsigned eflags = 0;
+
+       ret = krb5_copy_principal(context,
+                                 in_creds->client,
                                  &out_creds->client);
        if(ret)
-           goto out;
-       ret = krb5_copy_principal(context, 
-                                 in_creds->server, 
+           goto out2;
+       ret = krb5_copy_principal(context,
+                                 in_creds->server,
                                  &out_creds->server);
        if(ret)
-           goto out;
+           goto out2;
        /* this should go someplace else */
        out_creds->times.endtime = in_creds->times.endtime;
 
+       /* XXX should do better testing */
+       if (flags.b.constrained_delegation || impersonate_principal)
+           eflags |= EXTRACT_TICKET_ALLOW_CNAME_MISMATCH;
+
        ret = _krb5_extract_ticket(context,
                                   &rep,
                                   out_creds,
@@ -548,10 +548,10 @@ get_cred_kdc_usage(krb5_context context,
                                   KRB5_KU_TGS_REP_ENC_PART_SESSION,
                                   &krbtgt->addresses,
                                   nonce,
-                                  EXTRACT_TICKET_ALLOW_CNAME_MISMATCH|
-                                  EXTRACT_TICKET_ALLOW_SERVER_MISMATCH,
+                                  eflags,
                                   decrypt_tkt_with_subkey,
                                   subkey);
+    out2:
        krb5_free_kdc_rep(context, &rep);
     } else if(krb5_rd_error(context, &resp, &error) == 0) {
        ret = krb5_error_from_rd_error(context, &error, in_creds);
@@ -575,52 +575,50 @@ out:
        free(subkey);
     }
     return ret;
-    
+
 }
 
+/*
+ * same as above, just get local addresses first if the krbtgt have
+ * them and the realm is not addressless
+ */
+
 static krb5_error_code
-get_cred_kdc(krb5_context context, 
-            krb5_ccache id, 
-            krb5_kdc_flags flags,
-            krb5_addresses *addresses, 
-            krb5_creds *in_creds, 
-            krb5_creds *krbtgt,
-            krb5_principal impersonate_principal,
-            Ticket *second_ticket,
-            krb5_creds *out_creds)
+get_cred_kdc_address(krb5_context context,
+                    krb5_ccache id,
+                    krb5_kdc_flags flags,
+                    krb5_addresses *addrs,
+                    krb5_creds *in_creds,
+                    krb5_creds *krbtgt,
+                    krb5_principal impersonate_principal,
+                    Ticket *second_ticket,
+                    krb5_creds *out_creds)
 {
     krb5_error_code ret;
+    krb5_addresses addresses = { 0, NULL };
 
-    ret = get_cred_kdc_usage(context, id, flags, addresses, in_creds,
-                            krbtgt, impersonate_principal, second_ticket,
-                            out_creds, KRB5_KU_TGS_REQ_AUTH);
-    if (ret == KRB5KRB_AP_ERR_BAD_INTEGRITY) {
-       krb5_clear_error_string (context);
-       ret = get_cred_kdc_usage(context, id, flags, addresses, in_creds,
-                                krbtgt, impersonate_principal, second_ticket,
-                                out_creds, KRB5_KU_AP_REQ_AUTH);
-    }
-    return ret;
-}
+    /*
+     * Inherit the address-ness of the krbtgt if the address is not
+     * specified.
+     */
 
-/* same as above, just get local addresses first */
+    if (addrs == NULL && krbtgt->addresses.len != 0) {
+       krb5_boolean noaddr;
 
-static krb5_error_code
-get_cred_kdc_la(krb5_context context, krb5_ccache id, krb5_kdc_flags flags, 
-               krb5_creds *in_creds, krb5_creds *krbtgt, 
-               krb5_principal impersonate_principal, Ticket *second_ticket,
-               krb5_creds *out_creds)
-{
-    krb5_error_code ret;
-    krb5_addresses addresses, *addrs = &addresses;
-    
-    krb5_get_all_client_addrs(context, &addresses);
-    /* XXX this sucks. */
-    if(addresses.len == 0)
-       addrs = NULL;
-    ret = get_cred_kdc(context, id, flags, addrs, 
-                      in_creds, krbtgt, impersonate_principal, second_ticket,
-                      out_creds);
+       krb5_appdefault_boolean(context, NULL, krbtgt->server->realm,
+                               "no-addresses", FALSE, &noaddr);
+       
+       if (!noaddr) {
+           krb5_get_all_client_addrs(context, &addresses);
+           /* XXX this sucks. */
+           addrs = &addresses;
+           if(addresses.len == 0)
+               addrs = NULL;
+       }
+    }
+    ret = get_cred_kdc(context, id, flags, addrs, in_creds,
+                      krbtgt, impersonate_principal,
+                      second_ticket, out_creds);
     krb5_free_addresses(context, &addresses);
     return ret;
 }
@@ -640,7 +638,7 @@ krb5_get_kdc_cred(krb5_context context,
 
     *out_creds = calloc(1, sizeof(**out_creds));
     if(*out_creds == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     ret = _krb5_get_krbtgt (context,
@@ -651,7 +649,7 @@ krb5_get_kdc_cred(krb5_context context,
        free(*out_creds);
        return ret;
     }
-    ret = get_cred_kdc(context, id, flags, addresses, 
+    ret = get_cred_kdc(context, id, flags, addresses,
                       in_creds, krbtgt, NULL, NULL, *out_creds);
     krb5_free_creds (context, krbtgt);
     if(ret)
@@ -659,8 +657,8 @@ krb5_get_kdc_cred(krb5_context context,
     return ret;
 }
 
-static void
-not_found(krb5_context context, krb5_const_principal p)
+static int
+not_found(krb5_context context, krb5_const_principal p, krb5_error_code code)
 {
     krb5_error_code ret;
     char *str;
@@ -668,10 +666,11 @@ not_found(krb5_context context, krb5_const_principal p)
     ret = krb5_unparse_name(context, p, &str);
     if(ret) {
        krb5_clear_error_string(context);
-       return;
+       return code;
     }
-    krb5_set_error_string(context, "Matching credential (%s) not found", str);
+    krb5_set_error_message(context, code, "Matching credential (%s) not found", str);
     free(str);
+    return code;
 }
 
 static krb5_error_code
@@ -686,24 +685,23 @@ find_cred(krb5_context context,
 
     krb5_cc_clear_mcred(&mcreds);
     mcreds.server = server;
-    ret = krb5_cc_retrieve_cred(context, id, KRB5_TC_DONT_MATCH_REALM, 
+    ret = krb5_cc_retrieve_cred(context, id, KRB5_TC_DONT_MATCH_REALM,
                                &mcreds, out_creds);
     if(ret == 0)
        return 0;
     while(tgts && *tgts){
-       if(krb5_compare_creds(context, KRB5_TC_DONT_MATCH_REALM, 
+       if(krb5_compare_creds(context, KRB5_TC_DONT_MATCH_REALM,
                              &mcreds, *tgts)){
            ret = krb5_copy_creds_contents(context, *tgts, out_creds);
            return ret;
        }
        tgts++;
     }
-    not_found(context, server);
-    return KRB5_CC_NOTFOUND;
+    return not_found(context, server, KRB5_CC_NOTFOUND);
 }
 
 static krb5_error_code
-add_cred(krb5_context context, krb5_creds ***tgts, krb5_creds *tkt)
+add_cred(krb5_context context, krb5_creds const *tkt, krb5_creds ***tgts)
 {
     int i;
     krb5_error_code ret;
@@ -712,7 +710,7 @@ add_cred(krb5_context context, krb5_creds ***tgts, krb5_creds *tkt)
     for(i = 0; tmp && tmp[i]; i++); /* XXX */
     tmp = realloc(tmp, (i+2)*sizeof(*tmp));
     if(tmp == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     *tgts = tmp;
@@ -737,14 +735,14 @@ get_cred(server)
        */
 
 static krb5_error_code
-get_cred_from_kdc_flags(krb5_context context,
-                       krb5_kdc_flags flags,
-                       krb5_ccache ccache,
-                       krb5_creds *in_creds,
-                       krb5_principal impersonate_principal,
-                       Ticket *second_ticket,                  
-                       krb5_creds **out_creds,
-                       krb5_creds ***ret_tgts)
+get_cred_kdc_capath(krb5_context context,
+                   krb5_kdc_flags flags,
+                   krb5_ccache ccache,
+                   krb5_creds *in_creds,
+                   krb5_principal impersonate_principal,
+                   Ticket *second_ticket,                      
+                   krb5_creds **out_creds,
+                   krb5_creds ***ret_tgts)
 {
     krb5_error_code ret;
     krb5_creds *tgt, tmp_creds;
@@ -759,7 +757,7 @@ get_cred_from_kdc_flags(krb5_context context,
     if(ret)
        return ret;
 
-    try_realm = krb5_config_get_string(context, NULL, "capaths", 
+    try_realm = krb5_config_get_string(context, NULL, "capaths",
                                       client_realm, server_realm, NULL);
     if (try_realm == NULL)
        try_realm = client_realm;
@@ -768,7 +766,7 @@ get_cred_from_kdc_flags(krb5_context context,
                              &tmp_creds.server,
                              try_realm,
                              KRB5_TGS_NAME,
-                             server_realm, 
+                             server_realm,
                              NULL);
     if(ret){
        krb5_free_principal(context, tmp_creds.client);
@@ -776,32 +774,20 @@ get_cred_from_kdc_flags(krb5_context context,
     }
     {
        krb5_creds tgts;
-       /* XXX try krb5_cc_retrieve_cred first? */
-       ret = find_cred(context, ccache, tmp_creds.server, 
+
+       ret = find_cred(context, ccache, tmp_creds.server,
                        *ret_tgts, &tgts);
        if(ret == 0){
            *out_creds = calloc(1, sizeof(**out_creds));
            if(*out_creds == NULL) {
-               krb5_set_error_string(context, "malloc: out of memory");
                ret = ENOMEM;
+               krb5_set_error_message(context, ret, "malloc: out of memory");
            } else {
-               krb5_boolean noaddr;
-
-               krb5_appdefault_boolean(context, NULL, tgts.server->realm,
-                                       "no-addresses", FALSE, &noaddr);
-
-               if (noaddr)
-                   ret = get_cred_kdc(context, ccache, flags, NULL,
-                                      in_creds, &tgts,
-                                      impersonate_principal, 
-                                      second_ticket,
-                                      *out_creds);
-               else
-                   ret = get_cred_kdc_la(context, ccache, flags, 
-                                         in_creds, &tgts, 
-                                         impersonate_principal, 
-                                         second_ticket,
-                                         *out_creds);
+               ret = get_cred_kdc_address(context, ccache, flags, NULL,
+                                          in_creds, &tgts,
+                                          impersonate_principal,
+                                          second_ticket,
+                                          *out_creds);
                if (ret) {
                    free (*out_creds);
                    *out_creds = NULL;
@@ -813,22 +799,21 @@ get_cred_from_kdc_flags(krb5_context context,
            return ret;
        }
     }
-    if(krb5_realm_compare(context, in_creds->client, in_creds->server)) {
-       not_found(context, in_creds->server);
-       return KRB5_CC_NOTFOUND;
-    }
+    if(krb5_realm_compare(context, in_creds->client, in_creds->server))
+       return not_found(context, in_creds->server, KRB5_CC_NOTFOUND);
+
     /* XXX this can loop forever */
     while(1){
        heim_general_string tgt_inst;
 
-       ret = get_cred_from_kdc_flags(context, flags, ccache, &tmp_creds, 
-                                     NULL, NULL, &tgt, ret_tgts);
+       ret = get_cred_kdc_capath(context, flags, ccache, &tmp_creds,
+                                 NULL, NULL, &tgt, ret_tgts);
        if(ret) {
            krb5_free_principal(context, tmp_creds.server);
            krb5_free_principal(context, tmp_creds.client);
            return ret;
        }
-       ret = add_cred(context, ret_tgts, tgt);
+       ret = add_cred(context, tgt, ret_tgts);
        if(ret) {
            krb5_free_principal(context, tmp_creds.server);
            krb5_free_principal(context, tmp_creds.client);
@@ -838,7 +823,7 @@ get_cred_from_kdc_flags(krb5_context context,
        if(strcmp(tgt_inst, server_realm) == 0)
            break;
        krb5_free_principal(context, tmp_creds.server);
-       ret = krb5_make_principal(context, &tmp_creds.server, 
+       ret = krb5_make_principal(context, &tmp_creds.server,
                                  tgt_inst, KRB5_TGS_NAME, server_realm, NULL);
        if(ret) {
            krb5_free_principal(context, tmp_creds.server);
@@ -857,22 +842,12 @@ get_cred_from_kdc_flags(krb5_context context,
     krb5_free_principal(context, tmp_creds.client);
     *out_creds = calloc(1, sizeof(**out_creds));
     if(*out_creds == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
        ret = ENOMEM;
+       krb5_set_error_message(context, ret, "malloc: out of memory");
     } else {
-       krb5_boolean noaddr;
-
-       krb5_appdefault_boolean(context, NULL, tgt->server->realm,
-                               "no-addresses", KRB5_ADDRESSLESS_DEFAULT,
-                               &noaddr);
-       if (noaddr)
-           ret = get_cred_kdc (context, ccache, flags, NULL,
-                               in_creds, tgt, NULL, NULL,
-                               *out_creds);
-       else
-           ret = get_cred_kdc_la(context, ccache, flags, 
-                                 in_creds, tgt, NULL, NULL,
-                                 *out_creds);
+       ret = get_cred_kdc_address (context, ccache, flags, NULL,
+                                   in_creds, tgt, impersonate_principal, 
+                                   second_ticket, *out_creds);
        if (ret) {
            free (*out_creds);
            *out_creds = NULL;
@@ -882,6 +857,185 @@ get_cred_from_kdc_flags(krb5_context context,
     return ret;
 }
 
+static krb5_error_code
+get_cred_kdc_referral(krb5_context context,
+                     krb5_kdc_flags flags,
+                     krb5_ccache ccache,
+                     krb5_creds *in_creds,
+                     krb5_principal impersonate_principal,
+                     Ticket *second_ticket,                    
+                     krb5_creds **out_creds,
+                     krb5_creds ***ret_tgts)
+{
+    krb5_const_realm client_realm;
+    krb5_error_code ret;
+    krb5_creds tgt, referral, ticket;
+    int loop = 0;
+
+    memset(&tgt, 0, sizeof(tgt));
+    memset(&ticket, 0, sizeof(ticket));
+
+    flags.b.canonicalize = 1;
+
+    *out_creds = NULL;
+
+    client_realm = krb5_principal_get_realm(context, in_creds->client);
+
+    /* find tgt for the clients base realm */
+    {
+       krb5_principal tgtname;
+       
+       ret = krb5_make_principal(context, &tgtname,
+                                 client_realm,
+                                 KRB5_TGS_NAME,
+                                 client_realm,
+                                 NULL);
+       if(ret)
+           return ret;
+       
+       ret = find_cred(context, ccache, tgtname, *ret_tgts, &tgt);
+       krb5_free_principal(context, tgtname);
+       if (ret)
+           return ret;
+    }
+
+    referral = *in_creds;
+    ret = krb5_copy_principal(context, in_creds->server, &referral.server);
+    if (ret) {
+       krb5_free_cred_contents(context, &tgt);
+       return ret;
+    }
+    ret = krb5_principal_set_realm(context, referral.server, client_realm);
+    if (ret) {
+       krb5_free_cred_contents(context, &tgt);
+       krb5_free_principal(context, referral.server);
+       return ret;
+    }
+
+    while (loop++ < 17) {
+       krb5_creds **tickets;
+       krb5_creds mcreds;
+       char *referral_realm;
+
+       /* Use cache if we are not doing impersonation or contrainte deleg */
+       if (impersonate_principal == NULL || flags.b.constrained_delegation) {
+           krb5_cc_clear_mcred(&mcreds);
+           mcreds.server = referral.server;
+           ret = krb5_cc_retrieve_cred(context, ccache, 0, &mcreds, &ticket);
+       } else
+           ret = EINVAL;
+
+       if (ret) {
+           ret = get_cred_kdc_address (context, ccache, flags, NULL,
+                                       &referral, &tgt, impersonate_principal,
+                                       second_ticket, &ticket);
+           if (ret)
+               goto out;
+       }
+
+       /* Did we get the right ticket ? */
+       if (krb5_principal_compare_any_realm(context,
+                                            referral.server,
+                                            ticket.server))
+           break;
+
+       if (ticket.server->name.name_string.len != 2 &&
+           strcmp(ticket.server->name.name_string.val[0], KRB5_TGS_NAME) != 0)
+       {
+           krb5_set_error_message(context, KRB5KRB_AP_ERR_NOT_US,
+                                  "Got back an non krbtgt ticket referrals");
+           krb5_free_cred_contents(context, &ticket);
+           return KRB5KRB_AP_ERR_NOT_US;
+       }
+
+       referral_realm = ticket.server->name.name_string.val[1];
+
+       /* check that there are no referrals loops */
+       tickets = *ret_tgts;
+
+       krb5_cc_clear_mcred(&mcreds);
+       mcreds.server = ticket.server;
+
+       while(tickets && *tickets){
+           if(krb5_compare_creds(context,
+                                 KRB5_TC_DONT_MATCH_REALM,
+                                 &mcreds,
+                                 *tickets))
+           {
+               krb5_set_error_message(context, KRB5_GET_IN_TKT_LOOP,
+                                      "Referral from %s loops back to realm %s",
+                                      tgt.server->realm,
+                                      referral_realm);
+               krb5_free_cred_contents(context, &ticket);
+               return KRB5_GET_IN_TKT_LOOP;
+           }
+           tickets++;
+       }       
+
+       ret = add_cred(context, &ticket, ret_tgts);
+       if (ret) {
+           krb5_free_cred_contents(context, &ticket);
+           goto out;
+       }
+
+       /* try realm in the referral */
+       ret = krb5_principal_set_realm(context, 
+                                      referral.server,
+                                      referral_realm);
+       krb5_free_cred_contents(context, &tgt);
+       tgt = ticket;
+       memset(&ticket, 0, sizeof(ticket));
+       if (ret)
+           goto out;
+    }
+
+    ret = krb5_copy_creds(context, &ticket, out_creds);
+
+out:
+    krb5_free_principal(context, referral.server);
+    krb5_free_cred_contents(context, &tgt);
+    return ret;
+}
+
+
+/*
+ * Glue function between referrals version and old client chasing
+ * codebase.
+ */
+
+static krb5_error_code
+get_cred_kdc_any(krb5_context context,
+                krb5_kdc_flags flags,
+                krb5_ccache ccache,
+                krb5_creds *in_creds,
+                krb5_principal impersonate_principal,
+                Ticket *second_ticket,                 
+                krb5_creds **out_creds,
+                krb5_creds ***ret_tgts)
+{
+    krb5_error_code ret;
+
+    ret = get_cred_kdc_referral(context,
+                               flags,
+                               ccache,
+                               in_creds,
+                               impersonate_principal, 
+                               second_ticket,
+                               out_creds,
+                               ret_tgts);
+    if (ret == 0 || flags.b.canonicalize)
+       return ret;
+    return get_cred_kdc_capath(context,
+                               flags,
+                               ccache,
+                               in_creds,
+                               impersonate_principal, 
+                               second_ticket,
+                               out_creds,
+                               ret_tgts);
+}
+
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_get_cred_from_kdc_opt(krb5_context context,
                           krb5_ccache ccache,
@@ -892,9 +1046,9 @@ krb5_get_cred_from_kdc_opt(krb5_context context,
 {
     krb5_kdc_flags f;
     f.i = flags;
-    return get_cred_from_kdc_flags(context, f, ccache, 
-                                  in_creds, NULL, NULL,
-                                  out_creds, ret_tgts);
+    return get_cred_kdc_any(context, f, ccache,
+                           in_creds, NULL, NULL,
+                           out_creds, ret_tgts);
 }
 
 krb5_error_code KRB5_LIB_FUNCTION
@@ -904,10 +1058,10 @@ krb5_get_cred_from_kdc(krb5_context context,
                       krb5_creds **out_creds,
                       krb5_creds ***ret_tgts)
 {
-    return krb5_get_cred_from_kdc_opt(context, ccache, 
+    return krb5_get_cred_from_kdc_opt(context, ccache,
                                      in_creds, out_creds, ret_tgts, 0);
 }
-     
+
 
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_get_credentials_with_flags(krb5_context context,
@@ -921,18 +1075,18 @@ krb5_get_credentials_with_flags(krb5_context context,
     krb5_creds **tgts;
     krb5_creds *res_creds;
     int i;
-    
+
     *out_creds = NULL;
     res_creds = calloc(1, sizeof(*res_creds));
     if (res_creds == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
 
     if (in_creds->session.keytype)
        options |= KRB5_TC_MATCH_KEYTYPE;
 
-    /* 
+    /*
      * If we got a credential, check if credential is expired before
      * returning it.
      */
@@ -941,7 +1095,7 @@ krb5_get_credentials_with_flags(krb5_context context,
                                 in_creds->session.keytype ?
                                 KRB5_TC_MATCH_KEYTYPE : 0,
                                 in_creds, res_creds);
-    /* 
+    /*
      * If we got a credential, check if credential is expired before
      * returning it, but only if KRB5_GC_EXPIRED_OK is not set.
      */
@@ -953,7 +1107,7 @@ krb5_get_credentials_with_flags(krb5_context context,
             *out_creds = res_creds;
             return 0;
         }
-           
+       
        krb5_timeofday(context, &timeret);
        if(res_creds->times.endtime > timeret) {
            *out_creds = res_creds;
@@ -967,18 +1121,17 @@ krb5_get_credentials_with_flags(krb5_context context,
         return ret;
     }
     free(res_creds);
-    if(options & KRB5_GC_CACHED) {
-       not_found(context, in_creds->server);
-        return KRB5_CC_NOTFOUND;
-    }
+    if(options & KRB5_GC_CACHED)
+       return not_found(context, in_creds->server, KRB5_CC_NOTFOUND);
+
     if(options & KRB5_GC_USER_USER)
        flags.b.enc_tkt_in_skey = 1;
     if (flags.b.enc_tkt_in_skey)
        options |= KRB5_GC_NO_STORE;
 
     tgts = NULL;
-    ret = get_cred_from_kdc_flags(context, flags, ccache, 
-                                 in_creds, NULL, NULL, out_creds, &tgts);
+    ret = get_cred_kdc_any(context, flags, ccache,
+                          in_creds, NULL, NULL, out_creds, &tgts);
     for(i = 0; tgts && tgts[i]; i++) {
        krb5_cc_store_cred(context, ccache, tgts[i]);
        krb5_free_creds(context, tgts[i]);
@@ -1015,7 +1168,7 @@ krb5_get_creds_opt_alloc(krb5_context context, krb5_get_creds_opt *opt)
 {
     *opt = calloc(1, sizeof(**opt));
     if (*opt == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     return 0;
@@ -1079,14 +1232,14 @@ krb5_get_creds_opt_set_ticket(krb5_context context,
 
        opt->ticket = malloc(sizeof(*ticket));
        if (opt->ticket == NULL) {
-           krb5_set_error_string(context, "malloc: out of memory");
+           krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
            return ENOMEM;
        }
        ret = copy_Ticket(ticket, opt->ticket);
        if (ret) {
            free(opt->ticket);
            opt->ticket = NULL;
-           krb5_set_error_string(context, "malloc: out of memory");
+           krb5_set_error_message(context, ret, "malloc: out of memory");
            return ret;
        }
     }
@@ -1109,7 +1262,7 @@ krb5_get_creds(krb5_context context,
     krb5_creds **tgts;
     krb5_creds *res_creds;
     int i;
-    
+
     memset(&in_creds, 0, sizeof(in_creds));
     in_creds.server = rk_UNCONST(inprinc);
 
@@ -1124,7 +1277,7 @@ krb5_get_creds(krb5_context context,
     res_creds = calloc(1, sizeof(*res_creds));
     if (res_creds == NULL) {
        krb5_free_principal(context, in_creds.client);
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
 
@@ -1133,7 +1286,7 @@ krb5_get_creds(krb5_context context,
        options |= KRB5_TC_MATCH_KEYTYPE;
     }
 
-    /* 
+    /*
      * If we got a credential, check if credential is expired before
      * returning it.
      */
@@ -1141,7 +1294,7 @@ krb5_get_creds(krb5_context context,
                                 ccache,
                                opt->enctype ? KRB5_TC_MATCH_KEYTYPE : 0,
                                 &in_creds, res_creds);
-    /* 
+    /*
      * If we got a credential, check if credential is expired before
      * returning it, but only if KRB5_GC_EXPIRED_OK is not set.
      */
@@ -1154,7 +1307,7 @@ krb5_get_creds(krb5_context context,
            krb5_free_principal(context, in_creds.client);
             return 0;
         }
-           
+       
        krb5_timeofday(context, &timeret);
        if(res_creds->times.endtime > timeret) {
            *out_creds = res_creds;
@@ -1171,9 +1324,8 @@ krb5_get_creds(krb5_context context,
     }
     free(res_creds);
     if(options & KRB5_GC_CACHED) {
-       not_found(context, in_creds.server);
        krb5_free_principal(context, in_creds.client);
-        return KRB5_CC_NOTFOUND;
+       return not_found(context, in_creds.server, KRB5_CC_NOTFOUND);
     }
     if(options & KRB5_GC_USER_USER) {
        flags.b.enc_tkt_in_skey = 1;
@@ -1187,11 +1339,13 @@ krb5_get_creds(krb5_context context,
        flags.b.request_anonymous = 1; /* XXX ARGH confusion */
        flags.b.constrained_delegation = 1;
     }
+    if (options & KRB5_GC_CANONICALIZE)
+       flags.b.canonicalize = 1;
 
     tgts = NULL;
-    ret = get_cred_from_kdc_flags(context, flags, ccache, 
-                                 &in_creds, opt->self, opt->ticket,
-                                 out_creds, &tgts);
+    ret = get_cred_kdc_any(context, flags, ccache,
+                          &in_creds, opt->self, opt->ticket,
+                          out_creds, &tgts);
     krb5_free_principal(context, in_creds.client);
     for(i = 0; tgts && tgts[i]; i++) {
        krb5_cc_store_cred(context, ccache, tgts[i]);
index 83fb2b0fa984fd63c5622158d98af0ad942f9c8a..5a7a7829fc0e09ab89ec7cf47bed60c84464fec8 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: get_default_principal.c 14870 2005-04-20 20:53:29Z lha $");
+RCSID("$Id: get_default_principal.c 23280 2008-06-23 03:26:18Z lha $");
 
 /*
  * Try to find out what's a reasonable default principal.
@@ -85,8 +85,8 @@ _krb5_get_default_principal_local (krb5_context context,
                user = getlogin();
        }
        if(user == NULL) {
-           krb5_set_error_string(context,
-                                 "unable to figure out current principal");
+           krb5_set_error_message(context, ENOTTY,
+                                  "unable to figure out current principal");
            return ENOTTY; /* XXX */
        }
        ret = krb5_make_principal(context, princ, NULL, user, NULL);
index 09c8577b260184b12b579e0a734855d0ab008682..1c996031e8da0764b495b3cf6e25df3f8837847e 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: get_default_realm.c 13863 2004-05-25 21:46:46Z lha $");
+RCSID("$Id: get_default_realm.c 23280 2008-06-23 03:26:18Z lha $");
 
 /*
  * Return a NULL-terminated list of default realms in `realms'.
@@ -76,7 +76,7 @@ krb5_get_default_realm(krb5_context context,
 
     res = strdup (context->default_realms[0]);
     if (res == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     *realm = res;
index cb8b7c8641a6f1e3805bc5af29513a61da240f58..a8aac950ec7da838a2414d353b5d3563289bd497 100644 (file)
@@ -33,7 +33,7 @@
 
 #include <krb5_locl.h>
 
-RCSID("$Id: get_for_creds.c 22504 2008-01-21 15:49:58Z lha $");
+RCSID("$Id: get_for_creds.c 23316 2008-06-23 04:32:32Z lha $");
 
 static krb5_error_code
 add_addrs(krb5_context context,
@@ -51,8 +51,8 @@ add_addrs(krb5_context context,
 
     tmp = realloc(addr->val, (addr->len + n) * sizeof(*addr->val));
     if (tmp == NULL && (addr->len + n) != 0) {
-       krb5_set_error_string(context, "malloc: out of memory");
        ret = ENOMEM;
+       krb5_set_error_message(context, ret, "malloc: out of memory");
        goto fail;
     }
     addr->val = tmp;
@@ -207,7 +207,6 @@ krb5_get_forwarded_creds (krb5_context          context,
     krb5_kdc_flags kdc_flags;
     krb5_crypto crypto;
     struct addrinfo *ai;
-    int save_errno;
     krb5_creds *ticket;
 
     paddrs = NULL;
@@ -238,10 +237,10 @@ krb5_get_forwarded_creds (krb5_context        context,
 
        ret = getaddrinfo (hostname, NULL, NULL, &ai);
        if (ret) {
-           save_errno = errno;
-           krb5_set_error_string(context, "resolving %s: %s",
+           krb5_error_code ret2 = krb5_eai_to_heim_errno(ret, errno);
+           krb5_set_error_message(context, ret2, "resolving %s: %s",
                                  hostname, gai_strerror(ret));
-           return krb5_eai_to_heim_errno(ret, save_errno);
+           return ret2;
        }
        
        ret = add_addrs (context, &addrs, ai);
@@ -269,7 +268,7 @@ krb5_get_forwarded_creds (krb5_context          context,
     ALLOC_SEQ(&cred.tickets, 1);
     if (cred.tickets.val == NULL) {
        ret = ENOMEM;
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ret, "malloc: out of memory");
        goto out2;
     }
     ret = decode_Ticket(out_creds->ticket.data,
@@ -282,7 +281,7 @@ krb5_get_forwarded_creds (krb5_context          context,
     ALLOC_SEQ(&enc_krb_cred_part.ticket_info, 1);
     if (enc_krb_cred_part.ticket_info.val == NULL) {
        ret = ENOMEM;
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ret, "malloc: out of memory");
        goto out4;
     }
     
@@ -295,14 +294,14 @@ krb5_get_forwarded_creds (krb5_context        context,
        ALLOC(enc_krb_cred_part.timestamp, 1);
        if (enc_krb_cred_part.timestamp == NULL) {
            ret = ENOMEM;
-           krb5_set_error_string(context, "malloc: out of memory");
+           krb5_set_error_message(context, ret, "malloc: out of memory");
            goto out4;
        }
        *enc_krb_cred_part.timestamp = sec;
        ALLOC(enc_krb_cred_part.usec, 1);
        if (enc_krb_cred_part.usec == NULL) {
            ret = ENOMEM;
-           krb5_set_error_string(context, "malloc: out of memory");
+           krb5_set_error_message(context, ret, "malloc: out of memory");
            goto out4;
        }
        *enc_krb_cred_part.usec      = usec;
@@ -346,7 +345,7 @@ krb5_get_forwarded_creds (krb5_context          context,
            ALLOC(enc_krb_cred_part.r_address, 1);
            if (enc_krb_cred_part.r_address == NULL) {
                ret = ENOMEM;
-               krb5_set_error_string(context, "malloc: out of memory");
+               krb5_set_error_message(context, ret, "malloc: out of memory");
                goto out4;
            }
 
index d709e4b38d17aef14915761a1f5523c13add2313..f4c875b347dd0598a69850e4e236520750528c3c 100644 (file)
@@ -34,7 +34,7 @@
 #include "krb5_locl.h"
 #include <resolve.h>
 
-RCSID("$Id: get_host_realm.c 18541 2006-10-17 19:28:36Z lha $");
+RCSID("$Id: get_host_realm.c 23316 2008-06-23 04:32:32Z lha $");
 
 /* To automagically find the correct realm of a host (without
  * [domain_realm] in krb5.conf) add a text record for your domain with
@@ -55,7 +55,7 @@ copy_txt_to_realms (struct resource_record *head,
                    krb5_realm **realms)
 {
     struct resource_record *rr;
-    int n, i;
+    unsigned int n, i;
 
     for(n = 0, rr = head; rr; rr = rr->next)
        if (rr->type == T_TXT)
@@ -192,21 +192,22 @@ _krb5_get_host_realm_int (krb5_context context,
        p++;
        *realms = malloc(2 * sizeof(krb5_realm));
        if (*realms == NULL) {
-           krb5_set_error_string(context, "malloc: out of memory");
+           krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
            return ENOMEM;
        }
 
        (*realms)[0] = strdup(p);
        if((*realms)[0] == NULL) {
            free(*realms);
-           krb5_set_error_string(context, "malloc: out of memory");
+           krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
            return ENOMEM;
        }
        strupr((*realms)[0]);
        (*realms)[1] = NULL;
        return 0;
     }
-    krb5_set_error_string(context, "unable to find realm of host %s", host);
+    krb5_set_error_message(context, KRB5_ERR_HOST_REALM_UNKNOWN,
+                          "unable to find realm of host %s", host);
     return KRB5_ERR_HOST_REALM_UNKNOWN;
 }
 
@@ -248,8 +249,9 @@ krb5_get_host_realm(krb5_context context,
         */
        ret = krb5_get_default_realms(context, realms);
        if (ret) {
-           krb5_set_error_string(context, "Unable to find realm of host %s",
-                                 host);
+           krb5_set_error_message(context, KRB5_ERR_HOST_REALM_UNKNOWN,
+                                  "Unable to find realm of host %s",
+                                  host);
            return KRB5_ERR_HOST_REALM_UNKNOWN;
        }
     }
index a9ed3857d036448ebef074b5a73fb43502e016a4..8bdc8c0eb2698aacb32d0ff12cf425b08bb00593 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997 - 2002 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
  * All rights reserved. 
  *
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: get_in_tkt.c 20226 2007-02-16 03:31:50Z lha $");
+RCSID("$Id: get_in_tkt.c 23316 2008-06-23 04:32:32Z lha $");
 
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_init_etype (krb5_context context,
@@ -41,7 +41,7 @@ krb5_init_etype (krb5_context context,
                 krb5_enctype **val,
                 const krb5_enctype *etypes)
 {
-    int i;
+    unsigned int i;
     krb5_error_code ret;
     krb5_enctype *tmp = NULL;
 
@@ -60,7 +60,7 @@ krb5_init_etype (krb5_context context,
     *val = malloc(i * sizeof(**val));
     if (i != 0 && *val == NULL) {
        ret = ENOMEM;
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ret, "malloc: out of memory");
        goto cleanup;
     }
     memmove (*val,
@@ -72,6 +72,225 @@ cleanup:
     return ret;
 }
 
+static krb5_error_code
+check_server_referral(krb5_context context,
+                     krb5_kdc_rep *rep,
+                     unsigned flags,
+                     krb5_const_principal requested,
+                     krb5_const_principal returned,
+                     const krb5_keyblock const * key)
+{
+    krb5_error_code ret;
+    PA_ServerReferralData ref;
+    krb5_crypto session;
+    EncryptedData ed;
+    size_t len;
+    krb5_data data;
+    PA_DATA *pa;
+    int i = 0, cmp;
+
+    if (rep->kdc_rep.padata == NULL)
+       goto noreferral;
+
+    pa = krb5_find_padata(rep->kdc_rep.padata->val,
+                         rep->kdc_rep.padata->len, 
+                         KRB5_PADATA_SERVER_REFERRAL, &i);
+    if (pa == NULL)
+       goto noreferral;
+
+    memset(&ed, 0, sizeof(ed));
+    memset(&ref, 0, sizeof(ref));
+    
+    ret = decode_EncryptedData(pa->padata_value.data, 
+                              pa->padata_value.length,
+                              &ed, &len);
+    if (ret)
+       return ret;
+    if (len != pa->padata_value.length) {
+       free_EncryptedData(&ed);
+       krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED, "Referral EncryptedData wrong");
+       return KRB5KRB_AP_ERR_MODIFIED;
+    }
+    
+    ret = krb5_crypto_init(context, key, 0, &session);
+    if (ret) {
+       free_EncryptedData(&ed);
+       return ret;
+    }
+    
+    ret = krb5_decrypt_EncryptedData(context, session,
+                                    KRB5_KU_PA_SERVER_REFERRAL,
+                                    &ed, &data);
+    free_EncryptedData(&ed);
+    krb5_crypto_destroy(context, session);
+    if (ret)
+       return ret;
+    
+    ret = decode_PA_ServerReferralData(data.data, data.length, &ref, &len);
+    if (ret) {
+       krb5_data_free(&data);
+       return ret;
+    }
+    krb5_data_free(&data);
+    
+    if (strcmp(requested->realm, returned->realm) != 0) {
+       free_PA_ServerReferralData(&ref);
+       krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED,
+                              "server ref realm mismatch");
+       return KRB5KRB_AP_ERR_MODIFIED;
+    }
+
+    if (returned->name.name_string.len == 2 &&
+       strcmp(returned->name.name_string.val[0], KRB5_TGS_NAME) == 0)
+    {
+       const char *realm = returned->name.name_string.val[1];
+
+       if (ref.referred_realm == NULL
+           || strcmp(*ref.referred_realm, realm) != 0)
+       {
+           free_PA_ServerReferralData(&ref);
+           krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED,
+                                  "tgt returned with wrong ref");
+           return KRB5KRB_AP_ERR_MODIFIED;
+       }
+    } else if (krb5_principal_compare(context, returned, requested) == 0) {
+       free_PA_ServerReferralData(&ref);
+       krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED,
+                             "req princ no same as returned");
+       return KRB5KRB_AP_ERR_MODIFIED;
+    }
+
+    if (ref.requested_principal_name) {
+       cmp = _krb5_principal_compare_PrincipalName(context,
+                                                   requested,
+                                                   ref.requested_principal_name);
+       if (!cmp) {
+           free_PA_ServerReferralData(&ref);
+           krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED,
+                                  "compare requested failed");
+           return KRB5KRB_AP_ERR_MODIFIED;
+       }
+    } else if (flags & EXTRACT_TICKET_AS_REQ) {
+       free_PA_ServerReferralData(&ref);
+       krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED,
+                              "Requested principal missing on AS-REQ");
+       return KRB5KRB_AP_ERR_MODIFIED;
+    }
+
+    free_PA_ServerReferralData(&ref);
+
+    return ret;
+noreferral:
+    if (krb5_principal_compare(context, requested, returned) == FALSE) {
+       krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED,
+                              "Not same server principal returned "
+                             "as requested");
+       return KRB5KRB_AP_ERR_MODIFIED;
+    }
+    return 0;
+}
+
+
+/*
+ * Verify referral data
+ */
+
+
+static krb5_error_code
+check_client_referral(krb5_context context,
+                     krb5_kdc_rep *rep,
+                     krb5_const_principal requested,
+                     krb5_const_principal mapped,
+                     krb5_keyblock const * key)
+{
+    krb5_error_code ret;
+    PA_ClientCanonicalized canon;
+    krb5_crypto crypto;
+    krb5_data data;
+    PA_DATA *pa;
+    size_t len;
+    int i = 0;
+
+    if (rep->kdc_rep.padata == NULL)
+       goto noreferral;
+
+    pa = krb5_find_padata(rep->kdc_rep.padata->val,
+                         rep->kdc_rep.padata->len, 
+                         KRB5_PADATA_CLIENT_CANONICALIZED, &i);
+    if (pa == NULL)
+       goto noreferral;
+
+    ret = decode_PA_ClientCanonicalized(pa->padata_value.data, 
+                                       pa->padata_value.length,
+                                       &canon, &len);
+    if (ret) {
+       krb5_set_error_message(context, ret, "Failed to decode "
+                              "PA_ClientCanonicalized");
+       return ret;
+    }
+    
+    ASN1_MALLOC_ENCODE(PA_ClientCanonicalizedNames, data.data, data.length,
+                      &canon.names, &len, ret);
+    if (ret) {
+       free_PA_ClientCanonicalized(&canon);
+       return ret;
+    }
+    if (data.length != len)
+       krb5_abortx(context, "internal asn.1 error");
+    
+    ret = krb5_crypto_init(context, key, 0, &crypto);
+    if (ret) {
+       free(data.data);
+       free_PA_ClientCanonicalized(&canon);
+       return ret;
+    }
+    
+    ret = krb5_verify_checksum(context, crypto, KRB5_KU_CANONICALIZED_NAMES,
+                              data.data, data.length,
+                              &canon.canon_checksum);
+    krb5_crypto_destroy(context, crypto);
+    free(data.data);
+    if (ret) {
+       krb5_set_error_message(context, ret, "Failed to verify "
+                             "client canonicalized data");
+       free_PA_ClientCanonicalized(&canon);
+       return ret;
+    }
+
+    if (!_krb5_principal_compare_PrincipalName(context, 
+                                              requested,
+                                              &canon.names.requested_name))
+    {
+       free_PA_ClientCanonicalized(&canon);
+       krb5_set_error_message(context, KRB5_PRINC_NOMATCH,
+                              "Requested name doesn't match"
+                             " in client referral");
+       return KRB5_PRINC_NOMATCH;
+    }
+    if (!_krb5_principal_compare_PrincipalName(context,
+                                              mapped,
+                                              &canon.names.mapped_name))
+    {
+       free_PA_ClientCanonicalized(&canon);
+       krb5_set_error_message(context, KRB5_PRINC_NOMATCH,
+                              "Mapped name doesn't match"
+                             " in client referral");
+       return KRB5_PRINC_NOMATCH;
+    }
+
+    return 0;
+
+noreferral:
+    if (krb5_principal_compare(context, requested, mapped) == FALSE) {
+       krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED,
+                              "Not same client principal returned "
+                             "as requested");
+       return KRB5KRB_AP_ERR_MODIFIED;
+    }
+    return 0;
+}
+
+
 
 static krb5_error_code
 decrypt_tkt (krb5_context context,
@@ -117,9 +336,9 @@ decrypt_tkt (krb5_context context,
 }
 
 int
-_krb5_extract_ticket(krb5_context context, 
-                    krb5_kdc_rep *rep, 
-                    krb5_creds *creds,         
+_krb5_extract_ticket(krb5_context context,
+                    krb5_kdc_rep *rep,
+                    krb5_creds *creds,
                     krb5_keyblock *key,
                     krb5_const_pointer keyseed,
                     krb5_key_usage key_usage,
@@ -131,83 +350,86 @@ _krb5_extract_ticket(krb5_context context,
 {
     krb5_error_code ret;
     krb5_principal tmp_principal;
-    int tmp;
     size_t len;
     time_t tmp_time;
     krb5_timestamp sec_now;
 
-/*
- * HACK:
- * this is really a ugly hack, to support using the Netbios Domain Name
- * as realm against windows KDC's, they always return the full realm
- * based on the DNS Name.
- */
-flags |= EXTRACT_TICKET_ALLOW_SERVER_MISMATCH;
-flags |=EXTRACT_TICKET_ALLOW_CNAME_MISMATCH ;
+    /* decrypt */
+
+    if (decrypt_proc == NULL)
+       decrypt_proc = decrypt_tkt;
+    
+    ret = (*decrypt_proc)(context, key, key_usage, decryptarg, rep);
+    if (ret)
+       goto out;
+
+    /* save session key */
+
+    creds->session.keyvalue.length = 0;
+    creds->session.keyvalue.data   = NULL;
+    creds->session.keytype = rep->enc_part.key.keytype;
+    ret = krb5_data_copy (&creds->session.keyvalue,
+                         rep->enc_part.key.keyvalue.data,
+                         rep->enc_part.key.keyvalue.length);
+    if (ret) {
+       krb5_clear_error_string(context);
+       goto out;
+    }
+
+    /*
+     * HACK:
+     * this is really a ugly hack, to support using the Netbios Domain Name
+     * as realm against windows KDC's, they always return the full realm
+     * based on the DNS Name.
+     */
+    flags |= EXTRACT_TICKET_ALLOW_SERVER_MISMATCH;
+    flags |=EXTRACT_TICKET_ALLOW_CNAME_MISMATCH ;
+    
 
-   ret = _krb5_principalname2krb5_principal (context,
+   /* compare client and save */
+    ret = _krb5_principalname2krb5_principal (context,
                                              &tmp_principal,
                                              rep->kdc_rep.cname,
                                              rep->kdc_rep.crealm);
     if (ret)
        goto out;
 
-    /* compare client */
-
-    if((flags & EXTRACT_TICKET_ALLOW_CNAME_MISMATCH) == 0){
-       tmp = krb5_principal_compare (context, tmp_principal, creds->client);
-       if (!tmp) {
+    /* check client referral and save principal */
+    /* anonymous here ? */
+    if((flags & EXTRACT_TICKET_ALLOW_CNAME_MISMATCH) == 0) {
+       ret = check_client_referral(context, rep,
+                                   creds->client,
+                                   tmp_principal,
+                                   &creds->session);
+       if (ret) {
            krb5_free_principal (context, tmp_principal);
-           krb5_clear_error_string (context);
-           ret = KRB5KRB_AP_ERR_MODIFIED;
            goto out;
        }
     }
-
     krb5_free_principal (context, creds->client);
     creds->client = tmp_principal;
 
-    /* extract ticket */
-    ASN1_MALLOC_ENCODE(Ticket, creds->ticket.data, creds->ticket.length, 
-                      &rep->kdc_rep.ticket, &len, ret);
-    if(ret)
-       goto out;
-    if (creds->ticket.length != len)
-       krb5_abortx(context, "internal error in ASN.1 encoder");
-    creds->second_ticket.length = 0;
-    creds->second_ticket.data   = NULL;
-
-    /* compare server */
-
+    /* check server referral and save principal */
     ret = _krb5_principalname2krb5_principal (context,
                                              &tmp_principal,
                                              rep->kdc_rep.ticket.sname,
                                              rep->kdc_rep.ticket.realm);
     if (ret)
        goto out;
-    if(flags & EXTRACT_TICKET_ALLOW_SERVER_MISMATCH){
-       krb5_free_principal(context, creds->server);
-       creds->server = tmp_principal;
-       tmp_principal = NULL;
-    } else {
-       tmp = krb5_principal_compare (context, tmp_principal,
-                                     creds->server);
-       krb5_free_principal (context, tmp_principal);
-       if (!tmp) {
-           ret = KRB5KRB_AP_ERR_MODIFIED;
-           krb5_clear_error_string (context);
+    if((flags & EXTRACT_TICKET_ALLOW_SERVER_MISMATCH) == 0){
+       ret = check_server_referral(context,
+                                   rep, 
+                                   flags,
+                                   creds->server,
+                                   tmp_principal,
+                                   &creds->session);
+       if (ret) {
+           krb5_free_principal (context, tmp_principal);
            goto out;
        }
     }
-    
-    /* decrypt */
-
-    if (decrypt_proc == NULL)
-       decrypt_proc = decrypt_tkt;
-    
-    ret = (*decrypt_proc)(context, key, key_usage, decryptarg, rep);
-    if (ret)
-       goto out;
+    krb5_free_principal(context, creds->server);
+    creds->server = tmp_principal;
 
     /* verify names */
     if(flags & EXTRACT_TICKET_MATCH_REALM){
@@ -227,7 +449,7 @@ flags |=EXTRACT_TICKET_ALLOW_CNAME_MISMATCH ;
 
     if (nonce != rep->enc_part.nonce) {
        ret = KRB5KRB_AP_ERR_MODIFIED;
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ret, "malloc: out of memory");
        goto out;
     }
 
@@ -254,7 +476,7 @@ flags |=EXTRACT_TICKET_ALLOW_CNAME_MISMATCH ;
     if (creds->times.starttime == 0
        && abs(tmp_time - sec_now) > context->max_skew) {
        ret = KRB5KRB_AP_ERR_SKEW;
-       krb5_set_error_string (context,
+       krb5_set_error_message (context, ret,
                               "time skew (%d) larger than max (%d)",
                               abs(tmp_time - sec_now),
                               (int)context->max_skew);
@@ -307,12 +529,17 @@ flags |=EXTRACT_TICKET_ALLOW_CNAME_MISMATCH ;
          
     creds->authdata.len = 0;
     creds->authdata.val = NULL;
-    creds->session.keyvalue.length = 0;
-    creds->session.keyvalue.data   = NULL;
-    creds->session.keytype = rep->enc_part.key.keytype;
-    ret = krb5_data_copy (&creds->session.keyvalue,
-                         rep->enc_part.key.keyvalue.data,
-                         rep->enc_part.key.keyvalue.length);
+
+    /* extract ticket */
+    ASN1_MALLOC_ENCODE(Ticket, creds->ticket.data, creds->ticket.length, 
+                      &rep->kdc_rep.ticket, &len, ret);
+    if(ret)
+       goto out;
+    if (creds->ticket.length != len)
+       krb5_abortx(context, "internal error in ASN.1 encoder");
+    creds->second_ticket.length = 0;
+    creds->second_ticket.data   = NULL;
+
 
 out:
     memset (rep->enc_part.key.keyvalue.data, 0,
@@ -402,7 +629,7 @@ add_padata(krb5_context context,
     }
     pa2 = realloc (md->val, (md->len + netypes) * sizeof(*md->val));
     if (pa2 == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     md->val = pa2;
@@ -449,13 +676,13 @@ init_as_req (krb5_context context,
     a->req_body.cname = malloc(sizeof(*a->req_body.cname));
     if (a->req_body.cname == NULL) {
        ret = ENOMEM;
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ret, "malloc: out of memory");
        goto fail;
     }
     a->req_body.sname = malloc(sizeof(*a->req_body.sname));
     if (a->req_body.sname == NULL) {
        ret = ENOMEM;
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ret, "malloc: out of memory");
        goto fail;
     }
     ret = _krb5_principal2principalname (a->req_body.cname, creds->client);
@@ -472,7 +699,7 @@ init_as_req (krb5_context context,
        a->req_body.from = malloc(sizeof(*a->req_body.from));
        if (a->req_body.from == NULL) {
            ret = ENOMEM;
-           krb5_set_error_string(context, "malloc: out of memory");
+           krb5_set_error_message(context, ret, "malloc: out of memory");
            goto fail;
        }
        *a->req_body.from = creds->times.starttime;
@@ -485,7 +712,7 @@ init_as_req (krb5_context context,
        a->req_body.rtime = malloc(sizeof(*a->req_body.rtime));
        if (a->req_body.rtime == NULL) {
            ret = ENOMEM;
-           krb5_set_error_string(context, "malloc: out of memory");
+           krb5_set_error_message(context, ret, "malloc: out of memory");
            goto fail;
        }
        *a->req_body.rtime = creds->times.renew_till;
@@ -508,7 +735,7 @@ init_as_req (krb5_context context,
        a->req_body.addresses = malloc(sizeof(*a->req_body.addresses));
        if (a->req_body.addresses == NULL) {
            ret = ENOMEM;
-           krb5_set_error_string(context, "malloc: out of memory");
+           krb5_set_error_message(context, ret, "malloc: out of memory");
            goto fail;
        }
 
@@ -533,7 +760,7 @@ init_as_req (krb5_context context,
        ALLOC(a->padata, 1);
        if(a->padata == NULL) {
            ret = ENOMEM;
-           krb5_set_error_string(context, "malloc: out of memory");
+           krb5_set_error_message(context, ret, "malloc: out of memory");
            goto fail;
        }
        a->padata->val = NULL;
@@ -572,7 +799,7 @@ init_as_req (krb5_context context,
        ALLOC(a->padata, 1);
        if (a->padata == NULL) {
            ret = ENOMEM;
-           krb5_set_error_string(context, "malloc: out of memory");
+           krb5_set_error_message(context, ret, "malloc: out of memory");
            goto fail;
        }
        a->padata->len = 0;
@@ -590,9 +817,9 @@ init_as_req (krb5_context context,
                   key_proc, keyseed, a->req_body.etype.val,
                   a->req_body.etype.len, &salt);
     } else {
-       krb5_set_error_string (context, "pre-auth type %d not supported",
-                              *ptypes);
        ret = KRB5_PREAUTH_BAD_TYPE;
+       krb5_set_error_message (context, ret, "pre-auth type %d not supported",
+                              *ptypes);
        goto fail;
     }
     return 0;
index a59c903bd9e1f49a4ff4ecb967784c2dbe99057f..74c9ff78e58cc7d41a4a6df9535272e7cc0b7b17 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: init_creds.c 21711 2007-07-27 14:22:02Z lha $");
+RCSID("$Id: init_creds.c 23316 2008-06-23 04:32:32Z lha $");
 
 void KRB5_LIB_FUNCTION
 krb5_get_init_creds_opt_init(krb5_get_init_creds_opt *opt)
@@ -52,13 +52,13 @@ krb5_get_init_creds_opt_alloc(krb5_context context,
     *opt = NULL;
     o = calloc(1, sizeof(*o));
     if (o == NULL) {
-       krb5_set_error_string(context, "out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     krb5_get_init_creds_opt_init(o);
     o->opt_private = calloc(1, sizeof(*o->opt_private));
     if (o->opt_private == NULL) {
-       krb5_set_error_string(context, "out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        free(o);
        return ENOMEM;
     }
@@ -77,7 +77,7 @@ _krb5_get_init_creds_opt_copy(krb5_context context,
     *out = NULL;
     opt = calloc(1, sizeof(*opt));
     if (opt == NULL) {
-       krb5_set_error_string(context, "out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     if (in)
@@ -85,7 +85,7 @@ _krb5_get_init_creds_opt_copy(krb5_context context,
     if(opt->opt_private == NULL) {
        opt->opt_private = calloc(1, sizeof(*opt->opt_private));
        if (opt->opt_private == NULL) {
-           krb5_set_error_string(context, "out of memory");
+           krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
            free(opt);
            return ENOMEM;
        }
@@ -327,7 +327,7 @@ require_ext_opt(krb5_context context,
                const char *type)
 {
     if (opt->opt_private == NULL) {
-       krb5_set_error_string(context, "%s on non extendable opt", type);
+       krb5_set_error_message(context, EINVAL, "%s on non extendable opt", type);
        return EINVAL;
     }
     return 0;
@@ -381,7 +381,7 @@ krb5_get_init_creds_opt_get_error(krb5_context context,
 
     *error = malloc(sizeof(**error));
     if (*error == NULL) {
-       krb5_set_error_string(context, "malloc - out memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
 
index 441adff8fdf9e75f9fcb63ec926db345db12b8e6..e3098b0a9283bf637ad9670273b2114a541bba51 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: init_creds_pw.c 21931 2007-08-27 14:11:55Z lha $");
+RCSID("$Id: init_creds_pw.c 23316 2008-06-23 04:32:32Z lha $");
 
 typedef struct krb5_get_init_creds_ctx {
     KDCOptions flags;
@@ -165,14 +165,10 @@ init_cred (krb5_context context,
     }
 
     if (in_tkt_service) {
-       krb5_realm server_realm;
-
        ret = krb5_parse_name (context, in_tkt_service, &cred->server);
        if (ret)
            goto out;
-       server_realm = strdup (client_realm);
-       free (*krb5_princ_realm(context, cred->server));
-       krb5_princ_set_realm (context, cred->server, &server_realm);
+       krb5_principal_set_realm (context, cred->server, client_realm);
     } else {
        ret = krb5_make_principal(context, &cred->server, 
                                  client_realm, KRB5_TGS_NAME, client_realm,
@@ -340,7 +336,7 @@ get_init_creds_common(krb5_context context,
        etypes = malloc((options->etype_list_length + 1)
                        * sizeof(krb5_enctype));
        if (etypes == NULL) {
-           krb5_set_error_string(context, "malloc: out of memory");
+           krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
            return ENOMEM;
        }
        memcpy (etypes, options->etype_list,
@@ -352,7 +348,7 @@ get_init_creds_common(krb5_context context,
        pre_auth_types = malloc((options->preauth_list_length + 1)
                                * sizeof(krb5_preauthtype));
        if (pre_auth_types == NULL) {
-           krb5_set_error_string(context, "malloc: out of memory");
+           krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
            return ENOMEM;
        }
        memcpy (pre_auth_types, options->preauth_list,
@@ -445,12 +441,13 @@ change_password (krb5_context context,
        memset (buf2, 0, sizeof(buf2));
     }
     
-    ret = krb5_change_password (context,
-                               &cpw_cred,
-                               buf1,
-                               &result_code,
-                               &result_code_string,
-                               &result_string);
+    ret = krb5_set_password (context,
+                            &cpw_cred,
+                            buf1,
+                            client,
+                            &result_code,
+                            &result_code_string,
+                            &result_string);
     if (ret)
        goto out;
     asprintf (&p, "%s: %.*s\n",
@@ -464,8 +461,8 @@ change_password (krb5_context context,
        strlcpy (newpw, buf1, newpw_sz);
        ret = 0;
     } else {
-       krb5_set_error_string (context, "failed changing password");
        ret = ENOTTY;
+       krb5_set_error_message(context, ret, "failed changing password");
     }
 
 out:
@@ -507,8 +504,8 @@ krb5_get_init_creds_keytab(krb5_context context,
 
     a = malloc (sizeof(*a));
     if (a == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
        ret = ENOMEM;
+       krb5_set_error_message(context, ret, "malloc: out of memory");
        goto out;
     }
     a->principal = ctx.cred.client;
@@ -560,13 +557,13 @@ init_creds_init_as_req (krb5_context context,
     a->req_body.cname = malloc(sizeof(*a->req_body.cname));
     if (a->req_body.cname == NULL) {
        ret = ENOMEM;
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ret, "malloc: out of memory");
        goto fail;
     }
     a->req_body.sname = malloc(sizeof(*a->req_body.sname));
     if (a->req_body.sname == NULL) {
        ret = ENOMEM;
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ret, "malloc: out of memory");
        goto fail;
     }
 
@@ -585,7 +582,7 @@ init_creds_init_as_req (krb5_context context,
        a->req_body.from = malloc(sizeof(*a->req_body.from));
        if (a->req_body.from == NULL) {
            ret = ENOMEM;
-           krb5_set_error_string(context, "malloc: out of memory");
+           krb5_set_error_message(context, ret, "malloc: out of memory");
            goto fail;
        }
        *a->req_body.from = creds->times.starttime;
@@ -598,7 +595,7 @@ init_creds_init_as_req (krb5_context context,
        a->req_body.rtime = malloc(sizeof(*a->req_body.rtime));
        if (a->req_body.rtime == NULL) {
            ret = ENOMEM;
-           krb5_set_error_string(context, "malloc: out of memory");
+           krb5_set_error_message(context, ret, "malloc: out of memory");
            goto fail;
        }
        *a->req_body.rtime = creds->times.renew_till;
@@ -621,7 +618,7 @@ init_creds_init_as_req (krb5_context context,
        a->req_body.addresses = malloc(sizeof(*a->req_body.addresses));
        if (a->req_body.addresses == NULL) {
            ret = ENOMEM;
-           krb5_set_error_string(context, "malloc: out of memory");
+           krb5_set_error_message(context, ret, "malloc: out of memory");
            goto fail;
        }
 
@@ -1036,7 +1033,7 @@ pa_data_to_md_pkinit(krb5_context context,
                             ctx->pk_nonce,
                             md);
 #else
-    krb5_set_error_string(context, "no support for PKINIT compiled in");
+    krb5_set_error_message(context, EINVAL, "no support for PKINIT compiled in");
     return EINVAL;
 #endif
 }
@@ -1093,7 +1090,7 @@ process_pa_data_to_md(krb5_context context,
 
     ALLOC(*out_md, 1);
     if (*out_md == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     (*out_md)->len = 0;
@@ -1191,15 +1188,15 @@ process_pa_data_to_key(krb5_context context,
                                   pa,
                                   key);
 #else
-       krb5_set_error_string(context, "no support for PKINIT compiled in");
        ret = EINVAL;
+       krb5_set_error_message(context, ret, "no support for PKINIT compiled in");
 #endif
     } else if (ctx->password)
        ret = pa_data_to_key_plain(context, creds->client, ctx, 
                                   paid.salt, paid.s2kparams, etype, key);
     else {
-       krb5_set_error_string(context, "No usable pa data type");
        ret = EINVAL;
+       krb5_set_error_message(context, ret, "No usable pa data type");
     }
 
     free_paid(context, &paid);
@@ -1325,8 +1322,8 @@ init_cred_loop(krb5_context context,
                                             &md, 
                                             NULL);
                    if (ret)
-                       krb5_set_error_string(context,
-                                             "failed to decode METHOD DATA");
+                       krb5_set_error_message(context, ret,
+                                              "failed to decode METHOD DATA");
                } else {
                    /* XXX guess what the server want here add add md */
                }
@@ -1348,15 +1345,16 @@ init_cred_loop(krb5_context context,
 
     {
        krb5_keyblock *key = NULL;
-       unsigned flags = 0;
+       unsigned flags = EXTRACT_TICKET_AS_REQ;
 
        if (ctx->flags.request_anonymous)
            flags |= EXTRACT_TICKET_ALLOW_SERVER_MISMATCH;
        if (ctx->flags.canonicalize) {
-           flags |= EXTRACT_TICKET_ALLOW_CNAME_MISMATCH;
            flags |= EXTRACT_TICKET_ALLOW_SERVER_MISMATCH;
            flags |= EXTRACT_TICKET_MATCH_REALM;
        }
+       if (ctx->ic_flags & KRB5_INIT_CREDS_NO_C_CANON_CHECK)
+           flags |= EXTRACT_TICKET_ALLOW_CNAME_MISMATCH;
 
        ret = process_pa_data_to_key(context, ctx, creds, 
                                     &ctx->as_req, &rep, hi, &key);
@@ -1376,60 +1374,6 @@ init_cred_loop(krb5_context context,
                                   NULL);
        krb5_free_keyblock(context, key);
     }
-    /*
-     * Verify referral data
-     */
-    if ((ctx->ic_flags & KRB5_INIT_CREDS_CANONICALIZE) &&
-       (ctx->ic_flags & KRB5_INIT_CREDS_NO_C_CANON_CHECK) == 0)
-    {
-       PA_ClientCanonicalized canon;
-       krb5_crypto crypto;
-       krb5_data data;
-       PA_DATA *pa;
-       size_t len;
-
-       pa = find_pa_data(rep.kdc_rep.padata, KRB5_PADATA_CLIENT_CANONICALIZED);
-       if (pa == NULL) {
-           ret = EINVAL;
-           krb5_set_error_string(context, "Client canonicalizion not signed");
-           goto out;
-       }
-       
-       ret = decode_PA_ClientCanonicalized(pa->padata_value.data, 
-                                           pa->padata_value.length,
-                                           &canon, &len);
-       if (ret) {
-           krb5_set_error_string(context, "Failed to decode "
-                                 "PA_ClientCanonicalized");
-           goto out;
-       }
-
-       ASN1_MALLOC_ENCODE(PA_ClientCanonicalizedNames, data.data, data.length,
-                          &canon.names, &len, ret);
-       if (ret) 
-           goto out;
-       if (data.length != len)
-           krb5_abortx(context, "internal asn.1 error");
-
-       ret = krb5_crypto_init(context, &creds->session, 0, &crypto);
-       if (ret) {
-           free(data.data);
-           free_PA_ClientCanonicalized(&canon);
-           goto out;
-       }
-
-       ret = krb5_verify_checksum(context, crypto, KRB5_KU_CANONICALIZED_NAMES,
-                                  data.data, data.length,
-                                  &canon.canon_checksum);
-       krb5_crypto_destroy(context, crypto);
-       free(data.data);
-       free_PA_ClientCanonicalized(&canon);
-       if (ret) {
-           krb5_set_error_string(context, "Failed to verify "
-                                 "client canonicalized data");
-           goto out;
-       }
-    }
 out:
     if (stctx)
        krb5_sendto_ctx_free(context, stctx);
index 8afaa6ea80a171cf1296e74e6a27ed4e355c4a07..0c91fbb3a0e882dda313866142fd0e5f0fca886f 100644 (file)
@@ -43,7 +43,7 @@
 
 #include "kcm.h"
 
-RCSID("$Id: kcm.c 22108 2007-12-03 17:23:53Z lha $");
+RCSID("$Id: kcm.c 23446 2008-07-27 12:08:37Z lha $");
 
 typedef struct krb5_kcmcache {
     char *name;
@@ -56,7 +56,8 @@ typedef struct krb5_kcmcache {
 #define KCMCURSOR(C)   (*(uint32_t *)(C))
 
 static krb5_error_code
-try_door(krb5_context context, const krb5_kcmcache *k,
+try_door(krb5_context context,
+        krb5_kcmcache *k,
         krb5_data *request_data,
         krb5_data *response_data)
 {
@@ -70,6 +71,7 @@ try_door(krb5_context context, const krb5_kcmcache *k,
     fd = open(k->door_path, O_RDWR);
     if (fd < 0)
        return KRB5_CC_IO;
+    rk_cloexec(fd);
 
     arg.data_ptr = request_data->data;
     arg.data_size = request_data->length;
@@ -95,7 +97,8 @@ try_door(krb5_context context, const krb5_kcmcache *k,
 }
 
 static krb5_error_code
-try_unix_socket(krb5_context context, const krb5_kcmcache *k,
+try_unix_socket(krb5_context context,
+               krb5_kcmcache *k,
                krb5_data *request_data,
                krb5_data *response_data)
 {
@@ -105,7 +108,8 @@ try_unix_socket(krb5_context context, const krb5_kcmcache *k,
     fd = socket(AF_UNIX, SOCK_STREAM, 0);
     if (fd < 0)
        return KRB5_CC_IO;
-    
+    rk_cloexec(fd);
+
     if (connect(fd, rk_UNCONST(&k->path), sizeof(k->path)) != 0) {
        close(fd);
        return KRB5_CC_IO;
@@ -136,7 +140,7 @@ kcm_send_request(krb5_context context,
        return KRB5_CC_NOMEM;
     }
 
-    ret = KRB5_CC_IO;
+    ret = KRB5_CC_NOSUPP;
 
     for (i = 0; i < context->max_retries; i++) {
        ret = try_door(context, k, &request_data, response_data);
@@ -151,7 +155,7 @@ kcm_send_request(krb5_context context,
 
     if (ret) {
        krb5_clear_error_string(context);
-       ret = KRB5_CC_IO;
+       ret = KRB5_CC_NOSUPP;
     }
 
     return ret;
@@ -169,7 +173,7 @@ kcm_storage_request(krb5_context context,
 
     sp = krb5_storage_emem();
     if (sp == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, KRB5_CC_NOMEM, "malloc: out of memory");
        return KRB5_CC_NOMEM;
     }
 
@@ -187,7 +191,7 @@ kcm_storage_request(krb5_context context,
     *storage_p = sp;
  fail:
     if (ret) {
-       krb5_set_error_string(context, "Failed to encode request");
+       krb5_set_error_message(context, ret, "Failed to encode request");
        krb5_storage_free(sp);
     }
    
@@ -202,7 +206,7 @@ kcm_alloc(krb5_context context, const char *name, krb5_ccache *id)
 
     k = malloc(sizeof(*k));
     if (k == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, KRB5_CC_NOMEM, "malloc: out of memory");
        return KRB5_CC_NOMEM;
     }
 
@@ -210,7 +214,7 @@ kcm_alloc(krb5_context context, const char *name, krb5_ccache *id)
        k->name = strdup(name);
        if (k->name == NULL) {
            free(k);
-           krb5_set_error_string(context, "malloc: out of memory");
+           krb5_set_error_message(context, KRB5_CC_NOMEM, "malloc: out of memory");
            return KRB5_CC_NOMEM;
        }
     } else
@@ -822,7 +826,7 @@ kcm_set_flags(krb5_context context,
     return ret;
 }
 
-static krb5_error_code
+static int
 kcm_get_version(krb5_context context,
                krb5_ccache id)
 {
@@ -832,8 +836,30 @@ kcm_get_version(krb5_context context,
 static krb5_error_code
 kcm_move(krb5_context context, krb5_ccache from, krb5_ccache to)
 {
-    krb5_set_error_string(context, "kcm_move not implemented");
-    return EINVAL;
+    krb5_error_code ret;
+    krb5_kcmcache *oldk = KCMCACHE(from);
+    krb5_kcmcache *newk = KCMCACHE(to);
+    krb5_storage *request;
+
+    ret = kcm_storage_request(context, KCM_OP_MOVE_CACHE, &request);
+    if (ret)
+       return ret;
+
+    ret = krb5_store_stringz(request, oldk->name);
+    if (ret) {
+       krb5_storage_free(request);
+       return ret;
+    }
+
+    ret = krb5_store_stringz(request, newk->name);
+    if (ret) {
+       krb5_storage_free(request);
+       return ret;
+    }
+    ret = kcm_call(context, oldk, request, NULL, NULL);
+
+    krb5_storage_free(request);
+    return ret;
 }
 
 static krb5_error_code
@@ -850,7 +876,8 @@ kcm_default_name(krb5_context context, char **str)
  * @ingroup krb5_ccache
  */
 
-const krb5_cc_ops krb5_kcm_ops = {
+KRB5_LIB_VARIABLE const krb5_cc_ops krb5_kcm_ops = {
+    KRB5_CC_OPS_VERSION,
     "KCM",
     kcm_get_name,
     kcm_resolve,
@@ -1118,5 +1145,4 @@ _krb5_kcm_get_ticket(krb5_context context,
     return ret;
 }
 
-
 #endif /* HAVE_KCM */
index ff4f972e57d79cd0c60a79a3353a678792503498..fa19e1e726e9035463b7f3f08d2867bbe3562b1d 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: keyblock.c 15167 2005-05-18 04:21:57Z lha $");
+RCSID("$Id: keyblock.c 23316 2008-06-23 04:32:32Z lha $");
 
 void KRB5_LIB_FUNCTION
 krb5_keyblock_zero(krb5_keyblock *keyblock)
@@ -81,7 +81,7 @@ krb5_copy_keyblock (krb5_context context,
 
     k = malloc (sizeof(*k));
     if (k == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     *to = k;
@@ -116,15 +116,16 @@ krb5_keyblock_init(krb5_context context,
        return ret;
 
     if (len != size) {
-       krb5_set_error_string(context, "Encryption key %d is %lu bytes "
-                             "long, %lu was passed in",
-                             type, (unsigned long)len, (unsigned long)size);
+       krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP,
+                              "Encryption key %d is %lu bytes "
+                              "long, %lu was passed in",
+                              type, (unsigned long)len, (unsigned long)size);
        return KRB5_PROG_ETYPE_NOSUPP;
     }
     ret = krb5_data_copy(&key->keyvalue, data, len);
     if(ret) {
-       krb5_set_error_string(context, "malloc failed: %lu",
-                             (unsigned long)len);
+       krb5_set_error_message(context, ret, "malloc failed: %lu",
+                              (unsigned long)len);
        return ret;
     }
     key->keytype = type;
index 79a3f20e79d794bb6f3fa553a86937a2bddcc57c..09e130d8501dfa90cd323a61dd5cb6c156432ba4 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: keytab.c 22532 2008-01-27 11:59:18Z lha $");
+RCSID("$Id: keytab.c 23316 2008-06-23 04:32:32Z lha $");
 
 /*
  * Register a new keytab in `ops'
@@ -47,14 +47,15 @@ krb5_kt_register(krb5_context context,
     struct krb5_keytab_data *tmp;
 
     if (strlen(ops->prefix) > KRB5_KT_PREFIX_MAX_LEN - 1) {
-       krb5_set_error_string(context, "krb5_kt_register; prefix too long");
+       krb5_set_error_message(context, KRB5_KT_BADNAME, 
+                              "krb5_kt_register; prefix too long");
        return KRB5_KT_BADNAME;
     }
 
     tmp = realloc(context->kt_types,
                  (context->num_kt_types + 1) * sizeof(*context->kt_types));
     if(tmp == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     memcpy(&tmp[context->num_kt_types], ops,
@@ -97,14 +98,15 @@ krb5_kt_resolve(krb5_context context,
            break;
     }
     if(i == context->num_kt_types) {
-       krb5_set_error_string(context, "unknown keytab type %.*s", 
-                             (int)type_len, type);
+       krb5_set_error_message(context, KRB5_KT_UNKNOWN_TYPE,
+                              "unknown keytab type %.*s", 
+                              (int)type_len, type);
        return KRB5_KT_UNKNOWN_TYPE;
     }
     
     k = malloc (sizeof(*k));
     if (k == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     memcpy(k, &context->kt_types[i], sizeof(*k));
@@ -265,7 +267,7 @@ krb5_kt_get_full_name(krb5_context context,
        return ret;
 
     if (asprintf(str, "%s:%s", type, name) == -1) {
-       krb5_set_error_string(context, "malloc - out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        *str = NULL;
        return ENOMEM;
     }
@@ -377,12 +379,12 @@ krb5_kt_get_entry(krb5_context context,
        else
            kvno_str[0] = '\0';
 
-       krb5_set_error_string (context,
-                              "Failed to find %s%s in keytab %s (%s)",
-                              princ,
-                              kvno_str,
-                              kt_name ? kt_name : "unknown keytab",
-                              enctype_str ? enctype_str : "unknown enctype");
+       krb5_set_error_message (context, KRB5_KT_NOTFOUND,
+                               "Failed to find %s%s in keytab %s (%s)",
+                               princ,
+                               kvno_str,
+                               kt_name ? kt_name : "unknown keytab",
+                               enctype_str ? enctype_str : "unknown enctype");
        free(kt_name);
        free(enctype_str);
        return KRB5_KT_NOTFOUND;
@@ -443,9 +445,9 @@ krb5_kt_start_seq_get(krb5_context context,
                      krb5_kt_cursor *cursor)
 {
     if(id->start_seq_get == NULL) {
-       krb5_set_error_string(context,
-                             "start_seq_get is not supported in the %s "
-                             " keytab", id->prefix);
+       krb5_set_error_message(context, HEIM_ERR_OPNOTSUPP,
+                              "start_seq_get is not supported in the %s "
+                              " keytab", id->prefix);
        return HEIM_ERR_OPNOTSUPP;
     }
     return (*id->start_seq_get)(context, id, cursor);
@@ -464,9 +466,9 @@ krb5_kt_next_entry(krb5_context context,
                   krb5_kt_cursor *cursor)
 {
     if(id->next_entry == NULL) {
-       krb5_set_error_string(context,
-                             "next_entry is not supported in the %s "
-                             " keytab", id->prefix);
+       krb5_set_error_message(context, HEIM_ERR_OPNOTSUPP,
+                              "next_entry is not supported in the %s "
+                              " keytab", id->prefix);
        return HEIM_ERR_OPNOTSUPP;
     }
     return (*id->next_entry)(context, id, entry, cursor);
@@ -482,9 +484,9 @@ krb5_kt_end_seq_get(krb5_context context,
                    krb5_kt_cursor *cursor)
 {
     if(id->end_seq_get == NULL) {
-       krb5_set_error_string(context,
-                             "end_seq_get is not supported in the %s "
-                             " keytab", id->prefix);
+       krb5_set_error_message(context, HEIM_ERR_OPNOTSUPP,
+                              "end_seq_get is not supported in the %s "
+                              " keytab", id->prefix);
        return HEIM_ERR_OPNOTSUPP;
     }
     return (*id->end_seq_get)(context, id, cursor);
@@ -501,8 +503,9 @@ krb5_kt_add_entry(krb5_context context,
                  krb5_keytab_entry *entry)
 {
     if(id->add == NULL) {
-       krb5_set_error_string(context, "Add is not supported in the %s keytab",
-                             id->prefix);
+       krb5_set_error_message(context, KRB5_KT_NOWRITE,
+                              "Add is not supported in the %s keytab",
+                              id->prefix);
        return KRB5_KT_NOWRITE;
     }
     entry->timestamp = time(NULL);
@@ -520,9 +523,9 @@ krb5_kt_remove_entry(krb5_context context,
                     krb5_keytab_entry *entry)
 {
     if(id->remove == NULL) {
-       krb5_set_error_string(context,
-                             "Remove is not supported in the %s keytab",
-                             id->prefix);
+       krb5_set_error_message(context, KRB5_KT_NOWRITE,
+                              "Remove is not supported in the %s keytab",
+                              id->prefix);
        return KRB5_KT_NOWRITE;
     }
     return (*id->remove)(context, id, entry);
index 54272d48453fd4da9c9f261fc7e1c52dcebc5fa9..9e93191045585e5417ba75ec27d873e3cd20578a 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: keytab_any.c 17035 2006-04-10 09:20:13Z lha $");
+RCSID("$Id: keytab_any.c 23316 2008-06-23 04:32:32Z lha $");
 
 struct any_data {
     krb5_keytab kt;
@@ -72,8 +72,8 @@ any_resolve(krb5_context context, const char *name, krb5_keytab id)
            a0 = a;
            a->name = strdup(buf);
            if (a->name == NULL) {
-               krb5_set_error_string(context, "malloc: out of memory");
                ret = ENOMEM;
+               krb5_set_error_message(context, ret, "malloc: out of memory");
                goto fail;
            }
        } else
@@ -87,7 +87,7 @@ any_resolve(krb5_context context, const char *name, krb5_keytab id)
        prev = a;
     }
     if (a0 == NULL) {
-       krb5_set_error_string(context, "empty ANY: keytab");
+       krb5_set_error_message(context, ENOENT, "empty ANY: keytab");
        return ENOENT;
     }
     id->data = a0;
@@ -134,7 +134,7 @@ any_start_seq_get(krb5_context context,
 
     c->data = malloc (sizeof(struct any_cursor_extra_data));
     if(c->data == NULL){
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     ed = (struct any_cursor_extra_data *)c->data;
@@ -206,8 +206,8 @@ any_add_entry(krb5_context context,
     while(a != NULL) {
        ret = krb5_kt_add_entry(context, a->kt, entry);
        if(ret != 0 && ret != KRB5_KT_NOWRITE) {
-           krb5_set_error_string(context, "failed to add entry to %s", 
-                                 a->name);
+           krb5_set_error_message(context, ret, "failed to add entry to %s", 
+                                  a->name);
            return ret;
        }
        a = a->next;
@@ -229,8 +229,9 @@ any_remove_entry(krb5_context context,
            found++;
        else {
            if(ret != KRB5_KT_NOWRITE && ret != KRB5_KT_NOTFOUND) {
-               krb5_set_error_string(context, "failed to remove entry from %s", 
-                                     a->name);
+               krb5_set_error_message(context, ret, 
+                                      "Failed to remove keytab entry from %s", 
+                                      a->name);
                return ret;
            }
        }
index be195d96c26d67104c80d71bb2cf3078ab2a203d..e830ab34129f4aec93284ea7e1f30c6c9d85eea1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
  * All rights reserved. 
  *
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: keytab_file.c 22532 2008-01-27 11:59:18Z lha $");
+RCSID("$Id: keytab_file.c 23469 2008-07-27 12:17:12Z lha $");
 
 #define KRB5_KT_VNO_1 1
 #define KRB5_KT_VNO_2 2
@@ -62,7 +62,7 @@ krb5_kt_ret_data(krb5_context context,
     data->length = size;
     data->data = malloc(size);
     if (data->data == NULL) {
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     ret = krb5_storage_read(sp, data->data, size);
@@ -83,7 +83,7 @@ krb5_kt_ret_string(krb5_context context,
        return ret;
     *data = malloc(size + 1);
     if (*data == NULL) {
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     ret = krb5_storage_read(sp, *data, size);
@@ -168,22 +168,22 @@ krb5_kt_ret_principal(krb5_context context,
     
     ALLOC(p, 1);
     if(p == NULL) {
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
 
     ret = krb5_ret_int16(sp, &len);
     if(ret) {
-       krb5_set_error_string(context,
-                             "Failed decoding length of keytab principal");
+       krb5_set_error_message(context, ret,
+                              "Failed decoding length of keytab principal");
        goto out;
     }
     if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS))
        len--;
     if (len < 0) {
-       krb5_set_error_string(context, 
-                             "Keytab principal contains invalid length");
        ret = KRB5_KT_END;
+       krb5_set_error_message(context, ret,
+                              "Keytab principal contains invalid length");
        goto out;
     }
     ret = krb5_kt_ret_string(context, sp, &p->realm);
@@ -191,8 +191,8 @@ krb5_kt_ret_principal(krb5_context context,
        goto out;
     p->name.name_string.val = calloc(len, sizeof(*p->name.name_string.val));
     if(p->name.name_string.val == NULL) {
-       krb5_set_error_string (context, "malloc: out of memory");
        ret = ENOMEM;
+       krb5_set_error_message(context, ret, "malloc: out of memory");
        goto out;
     }
     p->name.name_string.len = len;
@@ -253,13 +253,13 @@ fkt_resolve(krb5_context context, const char *name, krb5_keytab id)
 
     d = malloc(sizeof(*d));
     if(d == NULL) {
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     d->filename = strdup(name);
     if(d->filename == NULL) {
        free(d);
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     d->flags = 0;
@@ -334,10 +334,11 @@ fkt_start_seq_get_int(krb5_context context,
     c->fd = open (d->filename, flags);
     if (c->fd < 0) {
        ret = errno;
-       krb5_set_error_string(context, "keytab %s open failed: %s", 
-                             d->filename, strerror(ret));
+       krb5_set_error_message(context, ret, "keytab %s open failed: %s",
+                              d->filename, strerror(ret));
        return ret;
     }
+    rk_cloexec(c->fd);
     ret = _krb5_xlock(context, c->fd, exclusive, d->filename);
     if (ret) {
        close(c->fd);
@@ -347,7 +348,7 @@ fkt_start_seq_get_int(krb5_context context,
     if (c->sp == NULL) {
        _krb5_xunlock(context, c->fd);
        close(c->fd);
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     krb5_storage_set_eof_code(c->sp, KRB5_KT_END);
@@ -492,10 +493,12 @@ fkt_add_entry(krb5_context context,
        fd = open (d->filename, O_RDWR | O_CREAT | O_EXCL | O_BINARY, 0600);
        if (fd < 0) {
            ret = errno;
-           krb5_set_error_string(context, "open(%s): %s", d->filename,
-                                 strerror(ret));
+           krb5_set_error_message(context, ret, "open(%s): %s", d->filename,
+                                  strerror(ret));
            return ret;
        }
+       rk_cloexec(fd);
+
        ret = _krb5_xlock(context, fd, 1, d->filename);
        if (ret) {
            close(fd);
@@ -510,6 +513,9 @@ fkt_add_entry(krb5_context context,
        storage_set_flags(context, sp, id->version);
     } else {
        int8_t pvno, tag;
+
+       rk_cloexec(fd);
+
        ret = _krb5_xlock(context, fd, 1, d->filename);
        if (ret) {
            close(fd);
@@ -523,22 +529,22 @@ fkt_add_entry(krb5_context context,
                properly */
            ret = fkt_setup_keytab(context, id, sp);
            if(ret) {
-               krb5_set_error_string(context, "%s: keytab is corrupted: %s", 
-                                     d->filename, strerror(ret));
+               krb5_set_error_message(context, ret, "%s: keytab is corrupted: %s", 
+                                      d->filename, strerror(ret));
                goto out;
            }
            storage_set_flags(context, sp, id->version);
        } else {
            if(pvno != 5) {
                ret = KRB5_KEYTAB_BADVNO;
-               krb5_set_error_string(context, "%s: %s", 
-                                     d->filename, strerror(ret));
+               krb5_set_error_message(context, ret, "%s: %s", 
+                                      d->filename, strerror(ret));
                goto out;
            }
            ret = krb5_ret_int8 (sp, &tag);
            if (ret) {
-               krb5_set_error_string(context, "%s: reading tag: %s", 
-                                     d->filename, strerror(ret));
+               krb5_set_error_message(context, ret, "%s: reading tag: %s", 
+                                      d->filename, strerror(ret));
                goto out;
            }
            id->version = tag;
@@ -551,7 +557,7 @@ fkt_add_entry(krb5_context context,
        emem = krb5_storage_emem();
        if(emem == NULL) {
            ret = ENOMEM;
-           krb5_set_error_string (context, "malloc: out of memory");
+           krb5_set_error_message(context, ret, "malloc: out of memory");
            goto out;
        }
        ret = krb5_kt_store_principal(context, emem, entry->principal);
index aa612add09780557ecf1368950517bd0335a0126..7e14cbd32983ef7b0e14b67e13d061bc790b4686 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: keytab_keyfile.c 22532 2008-01-27 11:59:18Z lha $");
+RCSID("$Id: keytab_keyfile.c 23316 2008-06-23 04:32:32Z lha $");
 
 /* afs keyfile operations --------------------------------------- */
 
@@ -52,7 +52,7 @@ RCSID("$Id: keytab_keyfile.c 22532 2008-01-27 11:59:18Z lha $");
 #define AFS_SERVERMAGICKRBCONF "/usr/afs/etc/krb.conf"
 
 struct akf_data {
-    int num_entries;
+    uint32_t num_entries;
     char *filename;
     char *cell;
     char *realm;
@@ -72,13 +72,13 @@ get_cell_and_realm (krb5_context context, struct akf_data *d)
     f = fopen (AFS_SERVERTHISCELL, "r");
     if (f == NULL) {
        ret = errno;
-       krb5_set_error_string (context, "open %s: %s", AFS_SERVERTHISCELL,
-                              strerror(ret));
+       krb5_set_error_message (context, ret, "open %s: %s", AFS_SERVERTHISCELL,
+                               strerror(ret));
        return ret;
     }
     if (fgets (buf, sizeof(buf), f) == NULL) {
        fclose (f);
-       krb5_set_error_string (context, "no cell in %s", AFS_SERVERTHISCELL);
+       krb5_set_error_message (context, EINVAL, "no cell in %s", AFS_SERVERTHISCELL);
        return EINVAL;
     }
     buf[strcspn(buf, "\n")] = '\0';
@@ -86,7 +86,7 @@ get_cell_and_realm (krb5_context context, struct akf_data *d)
 
     d->cell = strdup (buf);
     if (d->cell == NULL) {
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
 
@@ -96,8 +96,8 @@ get_cell_and_realm (krb5_context context, struct akf_data *d)
            free (d->cell);
            d->cell = NULL;
            fclose (f);
-           krb5_set_error_string (context, "no realm in %s",
-                                  AFS_SERVERMAGICKRBCONF);
+           krb5_set_error_message (context, EINVAL, "no realm in %s",
+                                   AFS_SERVERMAGICKRBCONF);
            return EINVAL;
        }
        buf[strcspn(buf, "\n")] = '\0';
@@ -111,7 +111,7 @@ get_cell_and_realm (krb5_context context, struct akf_data *d)
     if (d->realm == NULL) {
        free (d->cell);
        d->cell = NULL;
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     return 0;
@@ -128,7 +128,7 @@ akf_resolve(krb5_context context, const char *name, krb5_keytab id)
     struct akf_data *d = malloc(sizeof (struct akf_data));
 
     if (d == NULL) {
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     
@@ -143,7 +143,7 @@ akf_resolve(krb5_context context, const char *name, krb5_keytab id)
        free (d->cell);
        free (d->realm);
        free (d);
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     id->data = d;
@@ -197,13 +197,13 @@ akf_start_seq_get(krb5_context context,
     c->fd = open (d->filename, O_RDONLY|O_BINARY, 0600);
     if (c->fd < 0) {
        ret = errno;
-       krb5_set_error_string(context, "keytab afs keyfil open %s failed: %s",
-                             d->filename, strerror(ret));
+       krb5_set_error_message(context, ret, "keytab afs keyfil open %s failed: %s",
+                              d->filename, strerror(ret));
        return ret;
     }
 
     c->sp = krb5_storage_from_fd(c->fd);
-    ret = krb5_ret_int32(c->sp, &d->num_entries);
+    ret = krb5_ret_uint32(c->sp, &d->num_entries);
     if(ret) {
        krb5_storage_free(c->sp);
        close(c->fd);
@@ -250,7 +250,7 @@ akf_next_entry(krb5_context context,
     entry->keyblock.keyvalue.data   = malloc (8);
     if (entry->keyblock.keyvalue.data == NULL) {
        krb5_free_principal (context, entry->principal);
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        ret = ENOMEM;
        goto out;
     }
@@ -307,8 +307,8 @@ akf_add_entry(krb5_context context,
                   O_RDWR | O_BINARY | O_CREAT | O_EXCL, 0600);
        if (fd < 0) {
            ret = errno;
-           krb5_set_error_string(context, "open(%s): %s", d->filename,
-                                 strerror(ret));
+           krb5_set_error_message(context, ret, "open(%s): %s", d->filename,
+                                  strerror(ret));
            return ret;
        }
        created = 1;
@@ -317,7 +317,7 @@ akf_add_entry(krb5_context context,
     sp = krb5_storage_from_fd(fd);
     if(sp == NULL) {
        close(fd);
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     if (created)
@@ -327,7 +327,7 @@ akf_add_entry(krb5_context context,
            ret = errno;
            krb5_storage_free(sp);
            close(fd);
-           krb5_set_error_string (context, "seek: %s", strerror(ret));
+           krb5_set_error_message(context, ret, "seek: %s", strerror(ret));
            return ret;
        }
            
@@ -350,11 +350,12 @@ akf_add_entry(krb5_context context,
        for (i = 0; i < len; i++) {
            ret = krb5_ret_int32(sp, &kvno);
            if (ret) {
-               krb5_set_error_string (context, "Failed to get kvno ");
+               krb5_set_error_message (context, ret, "Failed to get kvno ");
                goto out;
            }
            if(krb5_storage_seek(sp, 8, SEEK_CUR) < 0) {
-               krb5_set_error_string (context, "seek: %s", strerror(ret));
+               ret = errno;
+               krb5_set_error_message (context, ret, "seek: %s", strerror(ret));
                goto out;
            }
            if (kvno == entry->vno) {
@@ -368,25 +369,26 @@ akf_add_entry(krb5_context context,
        
     if(krb5_storage_seek(sp, 0, SEEK_SET) < 0) {
        ret = errno;
-       krb5_set_error_string (context, "seek: %s", strerror(ret));
+       krb5_set_error_message (context, ret, "seek: %s", strerror(ret));
        goto out;
     }
        
     ret = krb5_store_int32(sp, len);
     if(ret) {
-       krb5_set_error_string(context, "keytab keyfile failed new length");
+       ret = errno;
+       krb5_set_error_message (context, ret, "keytab keyfile failed new length");
        return ret;
     }
 
     if(krb5_storage_seek(sp, (len - 1) * (8 + 4), SEEK_CUR) < 0) {
        ret = errno;
-       krb5_set_error_string (context, "seek to end: %s", strerror(ret));
+       krb5_set_error_message (context, ret, "seek to end: %s", strerror(ret));
        goto out;
     }
        
     ret = krb5_store_int32(sp, entry->vno);
     if(ret) {
-       krb5_set_error_string(context, "keytab keyfile failed store kvno");
+       krb5_set_error_message(context, ret, "keytab keyfile failed store kvno");
        goto out;
     }
     ret = krb5_storage_write(sp, entry->keyblock.keyvalue.data, 
@@ -396,7 +398,7 @@ akf_add_entry(krb5_context context,
            ret = errno;
        else
            ret = ENOTTY;
-       krb5_set_error_string(context, "keytab keyfile failed to add key");
+       krb5_set_error_message(context, ret, "keytab keyfile failed to add key");
        goto out;
     }
     ret = 0;
index 0ad8720c3fb8ccfb4583a0a299b174df9253998d..eabee7c69379fdc7db168fc00cbe61953b77816d 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: keytab_memory.c 16352 2005-12-05 18:39:46Z lha $");
+RCSID("$Id: keytab_memory.c 23293 2008-06-23 03:28:22Z lha $");
 
 /* memory operations -------------------------------------------- */
 
@@ -75,14 +75,14 @@ mkt_resolve(krb5_context context, const char *name, krb5_keytab id)
     d = calloc(1, sizeof(*d));
     if(d == NULL) {
        HEIMDAL_MUTEX_unlock(&mkt_mutex);
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     d->name = strdup(name);
     if (d->name == NULL) {
        HEIMDAL_MUTEX_unlock(&mkt_mutex);
        free(d);
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     d->entries = NULL;
@@ -176,7 +176,7 @@ mkt_add_entry(krb5_context context,
     krb5_keytab_entry *tmp;
     tmp = realloc(d->entries, (d->num_entries + 1) * sizeof(*d->entries));
     if(tmp == NULL) {
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     d->entries = tmp;
index 7e04446fe07ccbfc529522acf8875e560e2fa963..867d08e3e51896e920cebbb96aa9aabc98acbbb7 100644 (file)
@@ -38,12 +38,6 @@ _krb5_dh_group_ok (
        struct krb5_dh_moduli **/*moduli*/,
        char **/*name*/);
 
-krb5_error_code KRB5_LIB_FUNCTION
-_krb5_enctype_to_oid (
-       krb5_context /*context*/,
-       krb5_enctype /*etype*/,
-       heim_oid */*oid*/);
-
 krb5_error_code
 _krb5_expand_default_cc_name (
        krb5_context /*context*/,
@@ -283,12 +277,6 @@ _krb5_n_fold (
        void */*key*/,
        size_t /*size*/);
 
-krb5_error_code KRB5_LIB_FUNCTION
-_krb5_oid_to_enctype (
-       krb5_context /*context*/,
-       const heim_oid */*oid*/,
-       krb5_enctype */*etype*/);
-
 krb5_error_code
 _krb5_pac_sign (
        krb5_context /*context*/,
@@ -321,6 +309,20 @@ _krb5_pk_allow_proxy_certificate (
 void KRB5_LIB_FUNCTION
 _krb5_pk_cert_free (struct krb5_pk_cert */*cert*/);
 
+krb5_error_code
+_krb5_pk_kdf (
+       krb5_context /*context*/,
+       const struct AlgorithmIdentifier */*ai*/,
+       const void */*dhdata*/,
+       size_t /*dhsize*/,
+       krb5_const_principal /*client*/,
+       krb5_const_principal /*server*/,
+       krb5_enctype /*enctype*/,
+       const krb5_data */*as_req*/,
+       const krb5_data */*pk_as_rep*/,
+       const Ticket */*ticket*/,
+       krb5_keyblock */*key*/);
+
 krb5_error_code KRB5_LIB_FUNCTION
 _krb5_pk_load_id (
        krb5_context /*context*/,
@@ -401,6 +403,12 @@ _krb5_principal2principalname (
        PrincipalName */*p*/,
        const krb5_principal /*from*/);
 
+krb5_boolean KRB5_LIB_FUNCTION
+_krb5_principal_compare_PrincipalName (
+       krb5_context /*context*/,
+       krb5_const_principal /*princ1*/,
+       PrincipalName */*princ2*/);
+
 krb5_error_code KRB5_LIB_FUNCTION
 _krb5_principalname2krb5_principal (
        krb5_context /*context*/,
index 647d8886b7ccf7317e1083512411499e8c5ff919..ead66565e7690f37c5ebf54d9f08bc47095845e0 100644 (file)
 extern "C" {
 #endif
 
-#ifndef KRB5_LIB_FUNCTION
+#ifndef KRB5_LIB
 #if defined(_WIN32)
-#define KRB5_LIB_FUNCTION _stdcall
+#define KRB5_LIB_FUNCTION _stdcall __declspec(dllimport)
+#define KRB5_LIB_VARIABLE __declspec(dllimport)
 #else
 #define KRB5_LIB_FUNCTION
+#define KRB5_LIB_VARIABLE
 #endif
 #endif
 
@@ -627,6 +629,14 @@ krb5_cc_gen_new (
        const krb5_cc_ops */*ops*/,
        krb5_ccache */*id*/);
 
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_cc_get_config (
+       krb5_context /*context*/,
+       krb5_ccache /*id*/,
+       krb5_const_principal /*principal*/,
+       const char */*name*/,
+       krb5_data */*data*/);
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_cc_get_full_name (
        krb5_context /*context*/,
@@ -726,6 +736,14 @@ krb5_cc_retrieve_cred (
        const krb5_creds */*mcreds*/,
        krb5_creds */*creds*/);
 
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_cc_set_config (
+       krb5_context /*context*/,
+       krb5_ccache /*id*/,
+       krb5_const_principal /*principal*/,
+       const char */*name*/,
+       krb5_data */*data*/);
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_cc_set_default_name (
        krb5_context /*context*/,
@@ -749,6 +767,11 @@ krb5_cc_store_cred (
        krb5_ccache /*id*/,
        krb5_creds */*creds*/);
 
+krb5_error_code
+krb5_cc_switch (
+       krb5_context /*context*/,
+       krb5_ccache /*id*/);
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_change_password (
        krb5_context /*context*/,
@@ -756,7 +779,8 @@ krb5_change_password (
        const char */*newpw*/,
        int */*result_code*/,
        krb5_data */*result_code_string*/,
-       krb5_data */*result_string*/);
+       krb5_data */*result_string*/)
+    __attribute__((deprecated));
 
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_check_transited (
@@ -764,14 +788,14 @@ krb5_check_transited (
        krb5_const_realm /*client_realm*/,
        krb5_const_realm /*server_realm*/,
        krb5_realm */*realms*/,
-       int /*num_realms*/,
+       unsigned int /*num_realms*/,
        int */*bad_realm*/);
 
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_check_transited_realms (
        krb5_context /*context*/,
        const char *const */*realms*/,
-       int /*num_realms*/,
+       unsigned int /*num_realms*/,
        int */*bad_realm*/);
 
 krb5_error_code KRB5_LIB_FUNCTION
@@ -1462,14 +1486,14 @@ krb5_domain_x500_decode (
        krb5_context /*context*/,
        krb5_data /*tr*/,
        char ***/*realms*/,
-       int */*num_realms*/,
+       unsigned int */*num_realms*/,
        const char */*client_realm*/,
        const char */*server_realm*/);
 
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_domain_x500_encode (
        char **/*realms*/,
-       int /*num_realms*/,
+       unsigned int /*num_realms*/,
        krb5_data */*encoding*/);
 
 krb5_error_code KRB5_LIB_FUNCTION
@@ -1731,9 +1755,9 @@ krb5_free_error_contents (
        krb5_error */*error*/);
 
 void KRB5_LIB_FUNCTION
-krb5_free_error_string (
+krb5_free_error_message (
        krb5_context /*context*/,
-       char */*str*/);
+       const char */*msg*/);
 
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_free_host_realm (
@@ -1939,7 +1963,7 @@ krb5_get_err_text (
        krb5_context /*context*/,
        krb5_error_code /*code*/);
 
-char * KRB5_LIB_FUNCTION
+const char * KRB5_LIB_FUNCTION
 krb5_get_error_message (
        krb5_context /*context*/,
        krb5_error_code /*code*/);
@@ -2969,6 +2993,12 @@ krb5_principal_match (
        krb5_const_principal /*princ*/,
        krb5_const_principal /*pattern*/);
 
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_principal_set_realm (
+       krb5_context /*context*/,
+       krb5_principal /*principal*/,
+       krb5_const_realm /*realm*/);
+
 void KRB5_LIB_FUNCTION
 krb5_principal_set_type (
        krb5_context /*context*/,
@@ -3450,12 +3480,20 @@ krb5_set_dns_canonicalize_hostname (
        krb5_context /*context*/,
        krb5_boolean /*flag*/);
 
+void KRB5_LIB_FUNCTION
+krb5_set_error_message (
+       krb5_context /*context*/,
+       krb5_error_code /*ret*/,
+       const char */*fmt*/,
+       ...)
+    __attribute__ ((format (printf, 3, 4)));
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_set_error_string (
        krb5_context /*context*/,
        const char */*fmt*/,
-       ...)
-    __attribute__((format (printf, 2, 3)));
+       ...) __attribute__((format (printf, 2, 3)))
+    __attribute__((deprecated));
 
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_set_extra_addresses (
@@ -3472,6 +3510,12 @@ krb5_set_ignore_addresses (
        krb5_context /*context*/,
        const krb5_addresses */*addresses*/);
 
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_set_kdc_sec_offset (
+       krb5_context /*context*/,
+       int32_t /*sec*/,
+       int32_t /*usec*/);
+
 void KRB5_LIB_FUNCTION
 krb5_set_max_time_skew (
        krb5_context /*context*/,
@@ -4047,12 +4091,20 @@ krb5_vlog_msg (
        va_list /*ap*/)
     __attribute__((format (printf, 5, 0)));
 
+void KRB5_LIB_FUNCTION
+krb5_vset_error_message (
+       krb5_context /*context*/,
+       krb5_error_code /*ret*/,
+       const char */*fmt*/,
+       va_list /*args*/)
+    __attribute__ ((format (printf, 3, 0)));
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_vset_error_string (
        krb5_context /*context*/,
        const char */*fmt*/,
-       va_list /*args*/)
-    __attribute__ ((format (printf, 2, 0)));
+       va_list args) __attribute__ ((format (printf, 2, 0)))
+    __attribute__((deprecated));
 
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_vwarn (
@@ -4107,6 +4159,9 @@ krb5_write_safe_message (
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_xfree (void */*ptr*/);
 
+void KRB5_LIB_FUNCTION 
+    __attribute__((deprecated)) krb5_free_error_string(krb5_context context, char *str);
+
 #ifdef __cplusplus
 }
 #endif
index 571eb6192ae09b9e33c1e7a540f5a1b4d5db1be6..b1e2781d520982f22b762edc7790a859001a647a 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE. 
  */
 
-/* $Id: krb5.h 22100 2007-12-03 17:15:00Z lha $ */
+/* $Id: krb5.h 23026 2008-04-17 10:02:03Z lha $ */
 
 #ifndef __KRB5_H__
 #define __KRB5_H__
@@ -363,6 +363,7 @@ typedef union {
 #define KRB5_GC_FORWARDABLE            (1U << 4)
 #define KRB5_GC_NO_TRANSIT_CHECK       (1U << 5)
 #define KRB5_GC_CONSTRAINED_DELEGATION (1U << 6)
+#define KRB5_GC_CANONICALIZE           (1U << 7)
 
 /* constants for compare_creds (and cc_retrieve_cred) */
 #define KRB5_TC_DONT_MATCH_REALM       (1U << 31)
@@ -395,7 +396,10 @@ typedef struct krb5_creds {
 
 typedef struct krb5_cc_cache_cursor_data *krb5_cc_cache_cursor;
 
+#define KRB5_CC_OPS_VERSION 1
+
 typedef struct krb5_cc_ops {
+    int version;
     const char *prefix;
     const char* (*get_name)(krb5_context, krb5_ccache);
     krb5_error_code (*resolve)(krb5_context, krb5_ccache *, const char *);
@@ -419,7 +423,8 @@ typedef struct krb5_cc_ops {
     krb5_error_code (*get_cache_next)(krb5_context, krb5_cc_cursor, krb5_ccache *);
     krb5_error_code (*end_cache_get)(krb5_context, krb5_cc_cursor);
     krb5_error_code (*move)(krb5_context, krb5_ccache, krb5_ccache);
-    krb5_error_code (*default_name)(krb5_context, char **);
+    krb5_error_code (*get_default_name)(krb5_context, char **);
+    krb5_error_code (*set_default)(krb5_context, krb5_ccache);
 } krb5_cc_ops;
 
 struct krb5_log_facility;
@@ -589,11 +594,6 @@ typedef EncAPRepPart krb5_ap_rep_enc_part;
 
 #define KRB5_DIGEST_NAME ("digest")
 
-/* variables */
-
-extern const char *krb5_config_file;
-extern const char *krb5_defkeyname;
-
 typedef enum {
     KRB5_PROMPT_TYPE_PASSWORD          = 0x1,
     KRB5_PROMPT_TYPE_NEW_PASSWORD      = 0x2,
@@ -681,20 +681,6 @@ typedef struct krb5_verify_opt {
 #define KRB5_VERIFY_LREALMS            1
 #define KRB5_VERIFY_NO_ADDRESSES       2
 
-extern const krb5_cc_ops krb5_acc_ops;
-extern const krb5_cc_ops krb5_fcc_ops;
-extern const krb5_cc_ops krb5_mcc_ops;
-extern const krb5_cc_ops krb5_kcm_ops;
-
-extern const krb5_kt_ops krb5_fkt_ops;
-extern const krb5_kt_ops krb5_wrfkt_ops;
-extern const krb5_kt_ops krb5_javakt_ops;
-extern const krb5_kt_ops krb5_mkt_ops;
-extern const krb5_kt_ops krb5_akf_ops;
-extern const krb5_kt_ops krb4_fkt_ops;
-extern const krb5_kt_ops krb5_srvtab_fkt_ops;
-extern const krb5_kt_ops krb5_any_ops;
-
 #define KRB5_KPASSWD_VERS_CHANGEPW      1
 #define KRB5_KPASSWD_VERS_SETPW         0xff80
 
@@ -739,6 +725,7 @@ enum {
 typedef krb5_error_code (*krb5_send_to_kdc_func)(krb5_context, 
                                                 void *, 
                                                 krb5_krbhst_info *,
+                                                time_t timeout,
                                                 const krb5_data *,
                                                 krb5_data *);
 
@@ -776,5 +763,26 @@ struct sockaddr;
 
 #include <krb5-protos.h>
 
+/* variables */
+
+extern KRB5_LIB_VARIABLE const char *krb5_config_file;
+extern KRB5_LIB_VARIABLE const char *krb5_defkeyname;
+
+
+extern KRB5_LIB_VARIABLE const krb5_cc_ops krb5_acc_ops;
+extern KRB5_LIB_VARIABLE const krb5_cc_ops krb5_fcc_ops;
+extern KRB5_LIB_VARIABLE const krb5_cc_ops krb5_mcc_ops;
+extern KRB5_LIB_VARIABLE const krb5_cc_ops krb5_kcm_ops;
+extern KRB5_LIB_VARIABLE const krb5_cc_ops krb5_scc_ops;
+
+extern KRB5_LIB_VARIABLE const krb5_kt_ops krb5_fkt_ops;
+extern KRB5_LIB_VARIABLE const krb5_kt_ops krb5_wrfkt_ops;
+extern KRB5_LIB_VARIABLE const krb5_kt_ops krb5_javakt_ops;
+extern KRB5_LIB_VARIABLE const krb5_kt_ops krb5_mkt_ops;
+extern KRB5_LIB_VARIABLE const krb5_kt_ops krb5_akf_ops;
+extern KRB5_LIB_VARIABLE const krb5_kt_ops krb4_fkt_ops;
+extern KRB5_LIB_VARIABLE const krb5_kt_ops krb5_srvtab_fkt_ops;
+extern KRB5_LIB_VARIABLE const krb5_kt_ops krb5_any_ops;
+
 #endif /* __KRB5_H__ */
 
index 6714401e4503f1e880269986955de2ec65700465..8e49ffcc4afc0927baf19edf722a22143b78d2fb 100644 (file)
@@ -3,7 +3,7 @@
 #
 # This might look like a com_err file, but is not
 #
-id "$Id: krb5_err.et 21050 2007-06-12 02:00:40Z lha $"
+id "$Id: krb5_err.et 23354 2008-07-15 11:23:34Z lha $"
 
 error_table krb5
 
@@ -110,7 +110,7 @@ error_code PUBLIC_KEY_ENCRYPTION_NOT_SUPPORTED, "Public key encryption not suppo
 
 index 128
 prefix
-error_code KRB5_ERR_RCSID,     "$Id: krb5_err.et 21050 2007-06-12 02:00:40Z lha $"
+error_code KRB5_ERR_RCSID,     "$Id: krb5_err.et 23354 2008-07-15 11:23:34Z lha $"
 
 error_code KRB5_LIBOS_BADLOCKFLAG,     "Invalid flag for file lock mode"
 error_code KRB5_LIBOS_CANTREADPWD,     "Cannot read password"
@@ -262,5 +262,7 @@ error_code KRB5_ERR_BAD_S2K_PARAMS, "Invalid key generation parameters from KDC"
 error_code KRB5_ERR_NO_SERVICE,        "Service not available"
 error_code KRB5_CC_NOSUPP,      "Credential cache function not supported"
 error_code KRB5_DELTAT_BADFORMAT,      "Invalid format of Kerberos lifetime or clock skew string"
+error_code KRB5_PLUGIN_NO_HANDLE,      "Supplied data not handled by this plugin"
+error_code KRB5_PLUGIN_OP_NOTSUPP,     "Plugin does not support the operaton"
 
 end
index 8b7c41cc80d957af40104a7d43f7401e8dddae3e..aaabd4541bef1f7497c44b647bbb537ec9e14632 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE. 
  */
 
-/* $Id: krb5_locl.h 22226 2007-12-08 21:31:53Z lha $ */
+/* $Id: krb5_locl.h 23324 2008-06-26 03:54:45Z lha $ */
 
 #ifndef __KRB5_LOCL_H__
 #define __KRB5_LOCL_H__
@@ -131,6 +131,8 @@ struct sockaddr_dl;
 #include <parse_time.h>
 #include <base64.h>
 
+#include <wind.h>
+
 #include "crypto-headers.h"
 
 
@@ -142,6 +144,7 @@ struct send_to_kdc;
 struct krb5_pk_identity;
 struct krb5_pk_cert;
 struct ContentInfo;
+struct AlgorithmIdentifier;
 typedef struct krb5_pk_init_ctx_data *krb5_pk_init_ctx;
 struct krb5_dh_moduli;
 
@@ -154,7 +157,7 @@ struct _krb5_krb_auth_data;
 #include <krb5_err.h>
 #include <asn1_err.h>
 #ifdef PKINIT
-#include <hx509_err.h>
+#include <hx509.h>
 #endif
 #include <krb5-private.h>
 
@@ -164,7 +167,7 @@ struct _krb5_krb_auth_data;
 #define ALLOC_SEQ(X, N) do { (X)->len = (N); ALLOC((X)->val, (N)); } while(0)
 
 /* should this be public? */
-#define KEYTAB_DEFAULT "ANY:FILE:" SYSCONFDIR "/krb5.keytab,krb4:" SYSCONFDIR "/srvtab"
+#define KEYTAB_DEFAULT "FILE:" SYSCONFDIR "/krb5.keytab"
 #define KEYTAB_DEFAULT_MODIFY "FILE:" SYSCONFDIR "/krb5.keytab"
 
 #define MODULI_FILE SYSCONFDIR "/krb5.moduli"
@@ -227,7 +230,7 @@ typedef struct krb5_context_data {
     struct krb5_keytab_data *kt_types;  /* registered keytab types */
     const char *date_fmt;
     char *error_string;
-    char error_buf[256];
+    krb5_error_code error_code;
     krb5_addresses *ignore_addresses;
     char *default_cc_name;
     char *default_cc_name_env;
@@ -247,6 +250,7 @@ typedef struct krb5_context_data {
 #define EXTRACT_TICKET_ALLOW_CNAME_MISMATCH            1
 #define EXTRACT_TICKET_ALLOW_SERVER_MISMATCH           2
 #define EXTRACT_TICKET_MATCH_REALM                     4
+#define EXTRACT_TICKET_AS_REQ                          8
 
 /*
  * Configurable options
@@ -264,4 +268,22 @@ typedef struct krb5_context_data {
 #define KRB5_ADDRESSLESS_DEFAULT TRUE
 #endif
 
+#ifdef PKINIT
+
+struct krb5_pk_identity {
+    hx509_context hx509ctx;
+    hx509_verify_ctx verify_ctx;
+    hx509_certs certs;
+    hx509_certs anchors;
+    hx509_certs certpool;
+    hx509_revoke_ctx revokectx;
+};
+
+enum krb5_pk_type {
+    PKINIT_WIN2K = 1,
+    PKINIT_27 = 2
+};
+
+#endif /* PKINIT */
+
 #endif /* __KRB5_LOCL_H__ */
index 094fd4f9c64d9e88f596bbcdbf1526c25030f5f8..3514a026b74baa41d20329bb291c9d153674fc4d 100644 (file)
@@ -35,7 +35,7 @@
 #include <resolve.h>
 #include "locate_plugin.h"
 
-RCSID("$Id: krbhst.c 21457 2007-07-10 12:53:25Z lha $");
+RCSID("$Id: krbhst.c 23447 2008-07-27 12:09:05Z lha $");
 
 static int
 string_to_proto(const char *string)
@@ -72,7 +72,8 @@ srv_find_realm(krb5_context context, krb5_krbhst_info ***res, int *count,
 
     proto_num = string_to_proto(proto);
     if(proto_num < 0) {
-       krb5_set_error_string(context, "unknown protocol `%s'", proto);
+       krb5_set_error_message(context, EINVAL,
+                              "unknown protocol `%s'", proto);
        return EINVAL;
     }
 
@@ -96,7 +97,7 @@ srv_find_realm(krb5_context context, krb5_krbhst_info ***res, int *count,
     *res = malloc(num_srv * sizeof(**res));
     if(*res == NULL) {
        dns_free_data(r);
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
 
@@ -247,7 +248,7 @@ _krb5_krbhost_info_move(krb5_context context,
     /* trailing NUL is included in structure */
     *to = calloc(1, sizeof(**to) + hostnamelen); 
     if(*to == NULL) {
-       krb5_set_error_string(context, "malloc - out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
 
@@ -522,7 +523,8 @@ plugin_get_hosts(krb5_context context,
     struct krb5_plugin *list = NULL, *e;
     krb5_error_code ret;
 
-    ret = _krb5_plugin_find(context, PLUGIN_TYPE_DATA, "resolve", &list);
+    ret = _krb5_plugin_find(context, PLUGIN_TYPE_DATA,
+                           KRB5_PLUGIN_LOCATE, &list);
     if(ret != 0 || list == NULL)
        return;
 
@@ -539,8 +541,9 @@ plugin_get_hosts(krb5_context context,
        (*service->init)(context, &ctx);
        ret = (*service->lookup)(ctx, type, kd->realm, 0, 0, add_locate, kd);
        (*service->fini)(ctx);
-       if (ret) {
-           krb5_set_error_string(context, "Plugin failed to lookup");
+       if (ret && ret != KRB5_PLUGIN_NO_HANDLE) {
+           krb5_set_error_message(context, ret, 
+                                  "Locate plugin failed to lookup: %d", ret);
            break;
        }
     }
@@ -832,7 +835,7 @@ krb5_krbhst_init_flags(krb5_context context,
        def_port = ntohs(krb5_getportbyname (context, "krb524", "udp", 4444));
        break;
     default:
-       krb5_set_error_string(context, "unknown krbhst type (%u)", type);
+       krb5_set_error_message(context, ENOTTY, "unknown krbhst type (%u)", type);
        return ENOTTY;
     }
     if((kd = common_init(context, realm, flags)) == NULL)
@@ -920,7 +923,8 @@ gethostlist(krb5_context context, const char *realm,
     while(krb5_krbhst_next(context, handle, &hostinfo) == 0)
        nhost++;
     if(nhost == 0) {
-       krb5_set_error_string(context, "No KDC found for realm %s", realm);
+       krb5_set_error_message(context, KRB5_KDC_UNREACH, 
+                              "No KDC found for realm %s", realm);
        return KRB5_KDC_UNREACH;
     }
     *hostlist = calloc(nhost + 1, sizeof(**hostlist));
index 251712c8940db4c86e2b74913e014542f22f6e1e..a342617d384f49ffe62b54a405649a4f75a9433b 100644 (file)
  * SUCH DAMAGE. 
  */
 
-/* $Id: locate_plugin.h 18998 2006-11-12 19:00:03Z lha $ */
+/* $Id: locate_plugin.h 23351 2008-07-15 11:22:39Z lha $ */
 
 #ifndef HEIMDAL_KRB5_LOCATE_PLUGIN_H
 #define HEIMDAL_KRB5_LOCATE_PLUGIN_H 1
 
 #include <krb5.h>
 
+#define KRB5_PLUGIN_LOCATE "resolve"
+
 enum locate_service_type {
     locate_service_kdc = 1,
     locate_service_master_kdc,
index c04f50fd9aa87776c507a40a7e25affe3e010a00..721e3691cab15305367b54434aaa247e7e8007fd 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: log.c 19088 2006-11-21 08:08:46Z lha $");
+RCSID("$Id: log.c 23443 2008-07-27 12:07:25Z lha $");
 
 struct facility {
     int min;
@@ -121,13 +121,13 @@ krb5_initlog(krb5_context context,
 {
     krb5_log_facility *f = calloc(1, sizeof(*f));
     if(f == NULL) {
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     f->program = strdup(program);
     if(f->program == NULL){
        free(f);
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     *fac = f;
@@ -145,7 +145,7 @@ krb5_addlog_func(krb5_context context,
 {
     struct facility *fp = log_realloc(fac);
     if(fp == NULL) {
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     fp->min = min;
@@ -187,7 +187,7 @@ open_syslog(krb5_context context,
     int i;
 
     if(sd == NULL) {
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     i = find_value(sev, syslogvals);
@@ -242,7 +242,7 @@ open_file(krb5_context context, krb5_log_facility *fac, int min, int max,
 {
     struct file_data *fd = malloc(sizeof(*fd));
     if(fd == NULL) {
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     fd->filename = filename;
@@ -277,7 +277,8 @@ krb5_addlog_dest(krb5_context context, krb5_log_facility *f, const char *orig)
     if(n){
        p = strchr(p, '/');
        if(p == NULL) {
-           krb5_set_error_string (context, "failed to parse \"%s\"", orig);
+           krb5_set_error_message(context, HEIM_ERR_LOG_PARSE,
+                                  "failed to parse \"%s\"", orig);
            return HEIM_ERR_LOG_PARSE;
        }
        p++;
@@ -292,7 +293,7 @@ krb5_addlog_dest(krb5_context context, krb5_log_facility *f, const char *orig)
        int keep_open = 0;
        fn = strdup(p + 5);
        if(fn == NULL) {
-           krb5_set_error_string (context, "malloc: out of memory");
+           krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
            return ENOMEM;
        }
        if(p[4] == '='){
@@ -300,16 +301,17 @@ krb5_addlog_dest(krb5_context context, krb5_log_facility *f, const char *orig)
                         O_TRUNC | O_APPEND, 0666);
            if(i < 0) {
                ret = errno;
-               krb5_set_error_string (context, "open(%s): %s", fn,
+               krb5_set_error_message(context, ret, "open(%s): %s", fn,
                                       strerror(ret));
                free(fn);
                return ret;
            }
+           rk_cloexec(i);
            file = fdopen(i, "a");
            if(file == NULL){
                ret = errno;
                close(i);
-               krb5_set_error_string (context, "fdopen(%s): %s", fn,
+               krb5_set_error_message(context, ret, "fdopen(%s): %s", fn,
                                       strerror(ret));
                free(fn);
                return ret;
@@ -333,8 +335,8 @@ krb5_addlog_dest(krb5_context context, krb5_log_facility *f, const char *orig)
            strlcpy(facility, "AUTH", sizeof(facility));
        ret = open_syslog(context, f, min, max, severity, facility);
     }else{
-       krb5_set_error_string (context, "unknown log type: %s", p);
        ret = HEIM_ERR_LOG_PARSE; /* XXX */
+       krb5_set_error_message (context, ret, "unknown log type: %s", p);
     }
     return ret;
 }
index 01bcb09d3bea173a95b422d7bd46996fef54274c..682f9f6abd3531e45398b595825896f8b6b61bee 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: mcache.c 22107 2007-12-03 17:22:51Z lha $");
+RCSID("$Id: mcache.c 23316 2008-06-23 04:32:32Z lha $");
 
 typedef struct krb5_mcache {
     char *name;
@@ -119,7 +119,7 @@ mcc_resolve(krb5_context context, krb5_ccache *id, const char *res)
 
     m = mcc_alloc(res);
     if (m == NULL) {
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message(context, KRB5_CC_NOMEM, "malloc: out of memory");
        return KRB5_CC_NOMEM;
     }
     
@@ -138,7 +138,7 @@ mcc_gen_new(krb5_context context, krb5_ccache *id)
     m = mcc_alloc(NULL);
 
     if (m == NULL) {
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message(context, KRB5_CC_NOMEM, "malloc: out of memory");
        return KRB5_CC_NOMEM;
     }
 
@@ -237,7 +237,7 @@ mcc_store_cred(krb5_context context,
 
     l = malloc (sizeof(*l));
     if (l == NULL) {
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message(context, KRB5_CC_NOMEM, "malloc: out of memory");
        return KRB5_CC_NOMEM;
     }
     l->next = m->creds;
@@ -348,7 +348,7 @@ mcc_get_cache_first(krb5_context context, krb5_cc_cursor *cursor)
 
     iter = calloc(1, sizeof(*iter));
     if (iter == NULL) {
-       krb5_set_error_string(context, "malloc - out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }    
 
@@ -439,7 +439,7 @@ mcc_default_name(krb5_context context, char **str)
 {
     *str = strdup("MEMORY:");
     if (*str == NULL) {
-       krb5_set_error_string(context, "out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     return 0;
@@ -452,7 +452,8 @@ mcc_default_name(krb5_context context, char **str)
  * @ingroup krb5_ccache
  */
 
-const krb5_cc_ops krb5_mcc_ops = {
+KRB5_LIB_VARIABLE const krb5_cc_ops krb5_mcc_ops = {
+    KRB5_CC_OPS_VERSION,
     "MEMORY",
     mcc_get_name,
     mcc_resolve,
index 87e429af8cba50c4e4c206f0945afb4cf15e07b8..3b4b6e30b7491e7ed9be5184ea2bc79ae69acb5f 100644 (file)
@@ -33,7 +33,7 @@
 
 #include <krb5_locl.h>
 
-RCSID("$Id: mk_priv.c 16680 2006-02-01 12:39:26Z lha $");
+RCSID("$Id: mk_priv.c 23297 2008-06-23 03:28:53Z lha $");
 
       
 krb5_error_code KRB5_LIB_FUNCTION
@@ -138,7 +138,7 @@ krb5_mk_priv(krb5_context context,
 
     ret = krb5_data_copy(outbuf, buf + buf_size - len, len);
     if (ret) {
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        free(buf);
        return ENOMEM;
     }
index 570a83720132dbe576c2cfd79e9a2f438a47cacd..069df42e26801d272b628a62c680583aeb377f7c 100644 (file)
@@ -33,7 +33,7 @@
 
 #include <krb5_locl.h>
 
-RCSID("$Id: mk_rep.c 13863 2004-05-25 21:46:46Z lha $");
+RCSID("$Id: mk_rep.c 23316 2008-06-23 04:32:32Z lha $");
 
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_mk_rep(krb5_context context,
@@ -61,18 +61,18 @@ krb5_mk_rep(krb5_context context,
                                                    auth_context,
                                                    auth_context->keyblock);
            if(ret) {
-               krb5_set_error_string (context,
-                                      "krb5_mk_rep: generating subkey");
                free_EncAPRepPart(&body);
+               krb5_set_error_message(context, ret,
+                                      "krb5_mk_rep: generating subkey");
                return ret;
            }
        }
        ret = krb5_copy_keyblock(context, auth_context->local_subkey,
                                 &body.subkey);
        if (ret) {
-           krb5_set_error_string (context,
-                                  "krb5_copy_keyblock: out of memory");
            free_EncAPRepPart(&body);
+           krb5_set_error_message(context, ENOMEM,
+                                  "krb5_copy_keyblock: out of memory");
            return ENOMEM;
        }
     } else
@@ -84,7 +84,7 @@ krb5_mk_rep(krb5_context context,
                                      &auth_context->local_seqnumber);
        ALLOC(body.seq_number, 1);
        if (body.seq_number == NULL) {
-           krb5_set_error_string (context, "malloc: out of memory");
+           krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
            free_EncAPRepPart(&body);
            return ENOMEM;
        }
index 53528cfd1f781b44022fe3e43ccde37348930bb1..287f8cf64fa57e92ce64dd21868556c3e7604bb4 100644 (file)
@@ -32,7 +32,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: n-fold.c 22190 2007-12-06 16:24:22Z lha $");
+RCSID("$Id: n-fold.c 22923 2008-04-08 14:51:33Z lha $");
 
 static krb5_error_code
 rr13(unsigned char *buf, size_t len)
index 0b44ca1da381fe9605983e0be37d645d786eda25..fbc754efda3294eec6e21931b5a37f2cbd0fd115 100644 (file)
@@ -34,7 +34,7 @@
 #include "krb5_locl.h"
 #include <wind.h>
 
-RCSID("$Id: pac.c 22562 2008-02-03 17:38:35Z lha $");
+RCSID("$Id: pac.c 23316 2008-06-23 04:32:32Z lha $");
 
 struct PAC_INFO_BUFFER {
     uint32_t type;
@@ -93,14 +93,14 @@ krb5_pac_parse(krb5_context context, const void *ptr, size_t len,
     p = calloc(1, sizeof(*p));
     if (p == NULL) {
        ret = ENOMEM;
-       krb5_set_error_string(context, "out of memory");
+       krb5_set_error_message(context, ret, "malloc: out of memory");
        goto out;
     }
 
     sp = krb5_storage_from_readonly_mem(ptr, len);
     if (sp == NULL) {
        ret = ENOMEM;
-       krb5_set_error_string(context, "out of memory");
+       krb5_set_error_message(context, ret, "malloc: out of memory");
        goto out;
     }
     krb5_storage_set_flags(sp, KRB5_STORAGE_BYTEORDER_LE);
@@ -108,21 +108,21 @@ krb5_pac_parse(krb5_context context, const void *ptr, size_t len,
     CHECK(ret, krb5_ret_uint32(sp, &tmp), out);
     CHECK(ret, krb5_ret_uint32(sp, &tmp2), out);
     if (tmp < 1) {
-       krb5_set_error_string(context, "PAC have too few buffer");
        ret = EINVAL; /* Too few buffers */
+       krb5_set_error_message(context, ret, "PAC have too few buffer");
        goto out;
     }
     if (tmp2 != 0) {
-       krb5_set_error_string(context, "PAC have wrong version");
        ret = EINVAL; /* Wrong version */
+       krb5_set_error_message(context, ret, "PAC have wrong version");
        goto out;
     }
 
     p->pac = calloc(1, 
                    sizeof(*p->pac) + (sizeof(p->pac->buffers[0]) * (tmp - 1)));
     if (p->pac == NULL) {
-       krb5_set_error_string(context, "out of memory");
        ret = ENOMEM;
+       krb5_set_error_message(context, ret, "malloc: out of memory");
        goto out;
     }
 
@@ -143,51 +143,52 @@ krb5_pac_parse(krb5_context context, const void *ptr, size_t len,
 
        /* consistency checks */
        if (p->pac->buffers[i].offset_lo & (PAC_ALIGNMENT - 1)) {
-           krb5_set_error_string(context, "PAC out of allignment");
            ret = EINVAL;
+           krb5_set_error_message(context, ret, "PAC out of allignment");
            goto out;
        }
        if (p->pac->buffers[i].offset_hi) {
-           krb5_set_error_string(context, "PAC high offset set");
            ret = EINVAL;
+           krb5_set_error_message(context, ret, "PAC high offset set");
            goto out;
        }
        if (p->pac->buffers[i].offset_lo > len) {
-           krb5_set_error_string(context, "PAC offset off end");
            ret = EINVAL;
+           krb5_set_error_message(context, ret, "PAC offset off end");
            goto out;
        }
        if (p->pac->buffers[i].offset_lo < header_end) {
-           krb5_set_error_string(context, "PAC offset inside header: %d %d",
-                                 p->pac->buffers[i].offset_lo, header_end);
            ret = EINVAL;
+           krb5_set_error_message(context, ret, "PAC offset inside header: %lu %lu",
+                                 (unsigned long)p->pac->buffers[i].offset_lo, 
+                                 (unsigned long)header_end);
            goto out;
        }
        if (p->pac->buffers[i].buffersize > len - p->pac->buffers[i].offset_lo){
-           krb5_set_error_string(context, "PAC length off end");
            ret = EINVAL;
+           krb5_set_error_message(context, ret, "PAC length off end");
            goto out;
        }
 
        /* let save pointer to data we need later */
        if (p->pac->buffers[i].type == PAC_SERVER_CHECKSUM) {
            if (p->server_checksum) {
-               krb5_set_error_string(context, "PAC have two server checksums");
                ret = EINVAL;
+               krb5_set_error_message(context, ret, "PAC have two server checksums");
                goto out;
            }
            p->server_checksum = &p->pac->buffers[i];
        } else if (p->pac->buffers[i].type == PAC_PRIVSVR_CHECKSUM) {
            if (p->privsvr_checksum) {
-               krb5_set_error_string(context, "PAC have two KDC checksums");
                ret = EINVAL;
+               krb5_set_error_message(context, ret, "PAC have two KDC checksums");
                goto out;
            }
            p->privsvr_checksum = &p->pac->buffers[i];
        } else if (p->pac->buffers[i].type == PAC_LOGON_NAME) {
            if (p->logon_name) {
-               krb5_set_error_string(context, "PAC have two logon names");
                ret = EINVAL;
+               krb5_set_error_message(context, ret, "PAC have two logon names");
                goto out;
            }
            p->logon_name = &p->pac->buffers[i];
@@ -224,14 +225,14 @@ krb5_pac_init(krb5_context context, krb5_pac *pac)
 
     p = calloc(1, sizeof(*p));
     if (p == NULL) {
-       krb5_set_error_string(context, "out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
 
     p->pac = calloc(1, sizeof(*p->pac));
     if (p->pac == NULL) {
        free(p);
-       krb5_set_error_string(context, "out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
 
@@ -239,7 +240,7 @@ krb5_pac_init(krb5_context context, krb5_pac *pac)
     if (ret) {
        free (p->pac);
        free(p);
-       krb5_set_error_string(context, "out of memory");
+       krb5_set_error_message(context, ret, "malloc: out of memory");
        return ret;
     }
 
@@ -262,7 +263,7 @@ krb5_pac_add_buffer(krb5_context context, krb5_pac p,
     ptr = realloc(p->pac,
                  sizeof(*p->pac) + (sizeof(p->pac->buffers[0]) * len));
     if (ptr == NULL) {
-       krb5_set_error_string(context, "out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     p->pac = ptr;
@@ -280,7 +281,7 @@ krb5_pac_add_buffer(krb5_context context, krb5_pac p,
     old_end = p->data.length;
     len = p->data.length + data->length + PAC_INFO_BUFFER_SIZE;
     if (len < p->data.length) {
-       krb5_set_error_string(context, "integer overrun");
+       krb5_set_error_message(context, EINVAL, "integer overrun");
        return EINVAL;
     }
     
@@ -289,7 +290,7 @@ krb5_pac_add_buffer(krb5_context context, krb5_pac p,
 
     ret = krb5_data_realloc(&p->data, len);
     if (ret) {
-       krb5_set_error_string(context, "out of memory");
+       krb5_set_error_message(context, ret, "malloc: out of memory");
        return ret;
     }
 
@@ -330,7 +331,7 @@ krb5_pac_get_buffer(krb5_context context, krb5_pac p,
     if (type == PAC_PRIVSVR_CHECKSUM || type == PAC_SERVER_CHECKSUM) {
        ret = krb5_data_alloc(data, 16);
        if (ret) {
-           krb5_set_error_string(context, "out of memory");
+           krb5_set_error_message(context, ret, "malloc: out of memory");
            return ret;
        }
        memset(data->data, 0, data->length);
@@ -346,13 +347,13 @@ krb5_pac_get_buffer(krb5_context context, krb5_pac p,
 
        ret = krb5_data_copy(data, (unsigned char *)p->data.data + offset, len);
        if (ret) {
-           krb5_set_error_string(context, "Out of memory");
+           krb5_set_error_message(context, ret, "malloc: out of memory");
            return ret;
        }
        return 0;
     }
-    krb5_set_error_string(context, "No PAC buffer of type %lu was found",
-                         (unsigned long)type);
+    krb5_set_error_message(context, ENOENT, "No PAC buffer of type %lu was found",
+                          (unsigned long)type);
     return ENOENT;
 }
 
@@ -371,7 +372,7 @@ krb5_pac_get_types(krb5_context context,
     *types = calloc(p->pac->numbuffers, sizeof(*types));
     if (*types == NULL) {
        *len = 0;
-       krb5_set_error_string(context, "out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     for (i = 0; i < p->pac->numbuffers; i++)
@@ -415,7 +416,7 @@ verify_checksum(krb5_context context,
     sp = krb5_storage_from_mem((char *)data->data + sig->offset_lo,
                               sig->buffersize);
     if (sp == NULL) {
-       krb5_set_error_string(context, "out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     krb5_storage_set_flags(sp, KRB5_STORAGE_BYTEORDER_LE);
@@ -426,21 +427,21 @@ verify_checksum(krb5_context context,
        sig->buffersize - krb5_storage_seek(sp, 0, SEEK_CUR);
     cksum.checksum.data = malloc(cksum.checksum.length);
     if (cksum.checksum.data == NULL) {
-       krb5_set_error_string(context, "out of memory");
        ret = ENOMEM;
+       krb5_set_error_message(context, ret, "malloc: out of memory");
        goto out;
     }
     ret = krb5_storage_read(sp, cksum.checksum.data, cksum.checksum.length);
     if (ret != cksum.checksum.length) {
-       krb5_set_error_string(context, "PAC checksum missing checksum");
        ret = EINVAL;
+       krb5_set_error_message(context, ret, "PAC checksum missing checksum");
        goto out;
     }
 
     if (!krb5_checksum_is_keyed(context, cksum.cksumtype)) {
-       krb5_set_error_string (context, "Checksum type %d not keyed",
-                              cksum.cksumtype);
        ret = EINVAL;
+       krb5_set_error_message(context, ret, "Checksum type %d not keyed",
+                              cksum.cksumtype);
        goto out;
     }
 
@@ -487,7 +488,7 @@ create_checksum(krb5_context context,
        return ret;
 
     if (cksum.checksum.length != siglen) {
-       krb5_set_error_string(context, "pac checksum wrong length");
+       krb5_set_error_message(context, EINVAL, "pac checksum wrong length");
        free_Checksum(&cksum);
        return EINVAL;
     }
@@ -530,7 +531,7 @@ verify_logonname(krb5_context context,
     sp = krb5_storage_from_readonly_mem((const char *)data->data + logon_name->offset_lo,
                                        logon_name->buffersize);
     if (sp == NULL) {
-       krb5_set_error_string(context, "Out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
 
@@ -545,27 +546,27 @@ verify_logonname(krb5_context context,
        t2 = ((uint64_t)time2 << 32) | time1;
        if (t1 != t2) {
            krb5_storage_free(sp);
-           krb5_set_error_string(context, "PAC timestamp mismatch");
+           krb5_set_error_message(context, EINVAL, "PAC timestamp mismatch");
            return EINVAL;
        }
     }
     CHECK(ret, krb5_ret_uint16(sp, &len), out);
     if (len == 0) {
        krb5_storage_free(sp);
-       krb5_set_error_string(context, "PAC logon name length missing");
+       krb5_set_error_message(context, EINVAL, "PAC logon name length missing");
        return EINVAL;
     }
 
     s = malloc(len);
     if (s == NULL) {
        krb5_storage_free(sp);
-       krb5_set_error_string(context, "Out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     ret = krb5_storage_read(sp, s, len);
     if (ret != len) {
        krb5_storage_free(sp);
-       krb5_set_error_string(context, "Failed to read PAC logon name");
+       krb5_set_error_message(context, EINVAL, "Failed to read PAC logon name");
        return EINVAL;
     }
     krb5_storage_free(sp);
@@ -577,33 +578,33 @@ verify_logonname(krb5_context context,
 
        ucs2 = malloc(sizeof(ucs2[0]) * ucs2len);
        if (ucs2 == NULL) {
-           krb5_set_error_string(context, "malloc: out of memory");
+           krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
            return ENOMEM;
        }
        ret = wind_ucs2read(s, len, &flags, ucs2, &ucs2len);
        free(s);
        if (ret) {
            free(ucs2);
-           krb5_set_error_string(context, "Failed to convert string to UCS-2");
+           krb5_set_error_message(context, ret, "Failed to convert string to UCS-2");
            return ret;
        }
        ret = wind_ucs2utf8_length(ucs2, ucs2len, &u8len);
        if (ret) {
            free(ucs2);
-           krb5_set_error_string(context, "Failed to count length of UCS-2 string");
+           krb5_set_error_message(context, ret, "Failed to count length of UCS-2 string");
            return ret;
        }
        u8len += 1; /* Add space for NUL */
        s = malloc(u8len);
        if (s == NULL) {
            free(ucs2);
-           krb5_set_error_string(context, "malloc: out of memory");
+           krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
            return ENOMEM;
        }
        ret = wind_ucs2utf8(ucs2, ucs2len, s, &u8len);
        free(ucs2);
        if (ret) {
-           krb5_set_error_string(context, "Failed to convert to UTF-8");
+           krb5_set_error_message(context, ret, "Failed to convert to UTF-8");
            return ret;
        }
     }
@@ -613,8 +614,8 @@ verify_logonname(krb5_context context,
        return ret;
     
     if (krb5_principal_compare_any_realm(context, principal, p2) != TRUE) {
-       krb5_set_error_string(context, "PAC logon name mismatch");
        ret = EINVAL;
+       krb5_set_error_message(context, ret, "PAC logon name mismatch");
     }
     krb5_free_principal(context, p2);
     return ret;
@@ -644,7 +645,7 @@ build_logon_name(krb5_context context,
 
     sp = krb5_storage_emem();
     if (sp == NULL) {
-       krb5_set_error_string(context, "out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     krb5_storage_set_flags(sp, KRB5_STORAGE_BYTEORDER_LE);
@@ -710,15 +711,15 @@ krb5_pac_verify(krb5_context context,
     krb5_error_code ret;
 
     if (pac->server_checksum == NULL) {
-       krb5_set_error_string(context, "PAC missing server checksum");
+       krb5_set_error_message(context, EINVAL, "PAC missing server checksum");
        return EINVAL;
     }
     if (pac->privsvr_checksum == NULL) {
-       krb5_set_error_string(context, "PAC missing kdc checksum");
+       krb5_set_error_message(context, EINVAL, "PAC missing kdc checksum");
        return EINVAL;
     }
     if (pac->logon_name == NULL) {
-       krb5_set_error_string(context, "PAC missing logon name");
+       krb5_set_error_message(context, EINVAL, "PAC missing logon name");
        return EINVAL;
     }
 
@@ -795,7 +796,7 @@ fill_zeros(krb5_context context, krb5_storage *sp, size_t len)
            l = sizeof(zeros);
        sret = krb5_storage_write(sp, zeros, l);
        if (sret <= 0) {
-           krb5_set_error_string(context, "out of memory");
+           krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
            return ENOMEM;
        }
        len -= sret;
@@ -823,7 +824,7 @@ pac_checksum(krb5_context context,
        return ret;
 
     if (krb5_checksum_is_keyed(context, cktype) == FALSE) {
-       krb5_set_error_string(context, "PAC checksum type is not keyed");
+       krb5_set_error_message(context, EINVAL, "PAC checksum type is not keyed");
        return EINVAL;
     }
 
@@ -868,7 +869,7 @@ _krb5_pac_sign(krb5_context context,
 
        ptr = realloc(p->pac, sizeof(*p->pac) + (sizeof(p->pac->buffers[0]) * (p->pac->numbuffers + num - 1)));
        if (ptr == NULL) {
-           krb5_set_error_string(context, "out of memory");
+           krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
            return ENOMEM;
        }
        p->pac = ptr;
@@ -906,7 +907,7 @@ _krb5_pac_sign(krb5_context context,
     /* Encode PAC */
     sp = krb5_storage_emem();
     if (sp == NULL) {
-       krb5_set_error_string(context, "out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     krb5_storage_set_flags(sp, KRB5_STORAGE_BYTEORDER_LE);
@@ -914,7 +915,7 @@ _krb5_pac_sign(krb5_context context,
     spdata = krb5_storage_emem();
     if (spdata == NULL) {
        krb5_storage_free(sp);
-       krb5_set_error_string(context, "out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     krb5_storage_set_flags(spdata, KRB5_STORAGE_BYTEORDER_LE);
@@ -953,8 +954,8 @@ _krb5_pac_sign(krb5_context context,
 
            sret = krb5_storage_write(spdata, ptr, len);
            if (sret != len) {
-               krb5_set_error_string(context, "out of memory");
                ret = ENOMEM;
+               krb5_set_error_message(context, ret, "malloc: out of memory");
                goto out;
            }
            /* XXX if not aligned, fill_zeros */
@@ -985,21 +986,21 @@ _krb5_pac_sign(krb5_context context,
     /* export PAC */
     ret = krb5_storage_to_data(spdata, &d);
     if (ret) {
-       krb5_set_error_string(context, "out of memory");
+       krb5_set_error_message(context, ret, "malloc: out of memory");
        goto out;
     }
     ret = krb5_storage_write(sp, d.data, d.length);
     if (ret != d.length) {
        krb5_data_free(&d);
-       krb5_set_error_string(context, "out of memory");
        ret = ENOMEM;
+       krb5_set_error_message(context, ret, "malloc: out of memory");
        goto out;
     }
     krb5_data_free(&d);
 
     ret = krb5_storage_to_data(sp, &d);
     if (ret) {
-       krb5_set_error_string(context, "out of memory");
+       krb5_set_error_message(context, ret, "malloc: out of memory");
        goto out;
     }
 
index b2b70f52e786b1781962b4430166927f34aa247e..9dc3fe69a59e6ce6ea6ea2e54a4ad6f93ebcfa3e 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: padata.c 15469 2005-06-17 04:28:35Z lha $");
+RCSID("$Id: padata.c 23300 2008-06-23 03:29:22Z lha $");
 
 PA_DATA *
 krb5_find_padata(PA_DATA *val, unsigned len, int type, int *idx)
@@ -52,7 +52,7 @@ krb5_padata_add(krb5_context context, METHOD_DATA *md,
 
     pa = realloc (md->val, (md->len + 1) * sizeof(*md->val));
     if (pa == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     md->val = pa;
index 4a585bff070dade2c57b63285d90b9d705809dc2..1e82971c6ea3f335da84d6f77acff1576caef176 100755 (executable)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: pkinit.c 22673 2008-03-10 15:00:05Z lha $");
+RCSID("$Id: pkinit.c 23450 2008-07-27 12:10:10Z lha $");
 
 struct krb5_dh_moduli {
     char *name;
@@ -45,8 +45,6 @@ struct krb5_dh_moduli {
 
 #ifdef PKINIT
 
-#include <heim_asn1.h>
-#include <rfc2459_asn1.h>
 #include <cms_asn1.h>
 #include <pkcs8_asn1.h>
 #include <pkcs9_asn1.h>
@@ -56,22 +54,6 @@ struct krb5_dh_moduli {
 
 #include <der.h>
 
-#include <hx509.h>
-
-enum {
-    COMPAT_WIN2K = 1,
-    COMPAT_IETF = 2
-};
-
-struct krb5_pk_identity {
-    hx509_context hx509ctx;
-    hx509_verify_ctx verify_ctx;
-    hx509_certs certs;
-    hx509_certs anchors;
-    hx509_certs certpool;
-    hx509_revoke_ctx revokectx;
-};
-
 struct krb5_pk_cert {
     hx509_cert cert;
 };
@@ -82,7 +64,7 @@ struct krb5_pk_init_ctx_data {
     krb5_data *clientDHNonce;
     struct krb5_dh_moduli **m;
     hx509_peer_info peer;
-    int type;
+    enum krb5_pk_type type;
     unsigned int require_binding:1;
     unsigned int require_eku:1;
     unsigned int require_krbtgt_otherName:1;
@@ -91,11 +73,11 @@ struct krb5_pk_init_ctx_data {
 };
 
 static void
-_krb5_pk_copy_error(krb5_context context,
-                   hx509_context hx509ctx,
-                   int hxret,
-                   const char *fmt,
-                   ...)
+pk_copy_error(krb5_context context,
+             hx509_context hx509ctx,
+             int hxret,
+             const char *fmt,
+             ...)
     __attribute__ ((format (printf, 4, 5)));
 
 /*
@@ -132,7 +114,7 @@ integer_to_BN(krb5_context context, const char *field, const heim_integer *f)
 
     bn = BN_bin2bn((const unsigned char *)f->data, f->length, NULL);
     if (bn == NULL) {
-       krb5_set_error_string(context, "PKINIT: parsing BN failed %s", field);
+       krb5_set_error_message(context, ENOMEM, "PKINIT: parsing BN failed %s", field);
        return NULL;
     }
     BN_set_negative(bn, f->negative);
@@ -167,16 +149,16 @@ find_cert(krb5_context context, struct krb5_pk_identity *id,
     for (i = 0; i < sizeof(cf)/sizeof(cf[0]); i++) {
        ret = hx509_query_match_eku(q, cf[i].oid);
        if (ret) {
-           _krb5_pk_copy_error(context, id->hx509ctx, ret, 
-                               "Failed setting %s OID", cf[i].type);
+           pk_copy_error(context, id->hx509ctx, ret, 
+                         "Failed setting %s OID", cf[i].type);
            return ret;
        }
 
        ret = hx509_certs_find(id->hx509ctx, id->certs, q, cert);
        if (ret == 0)
            break;
-       _krb5_pk_copy_error(context, id->hx509ctx, ret, 
-                           "Failed cert for finding %s OID", cf[i].type);
+       pk_copy_error(context, id->hx509ctx, ret, 
+                     "Failed cert for finding %s OID", cf[i].type);
     }
     return ret;
 }
@@ -196,8 +178,8 @@ create_signature(krb5_context context,
 
     ret = hx509_query_alloc(id->hx509ctx, &q);
     if (ret) {
-       _krb5_pk_copy_error(context, id->hx509ctx, ret, 
-                           "Allocate query to find signing certificate");
+       pk_copy_error(context, id->hx509ctx, ret, 
+                     "Allocate query to find signing certificate");
        return ret;
     }
 
@@ -222,8 +204,8 @@ create_signature(krb5_context context,
                                    sd_data);
     hx509_cert_free(cert);
     if (ret) {
-       _krb5_pk_copy_error(context, id->hx509ctx, ret,
-                           "Create CMS signedData");
+       pk_copy_error(context, id->hx509ctx, ret,
+                     "Create CMS signedData");
        return ret;
     }
 
@@ -374,7 +356,7 @@ build_auth_pack(krb5_context context,
 
     ALLOC(a->pkAuthenticator.paChecksum, 1);
     if (a->pkAuthenticator.paChecksum == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
 
@@ -524,7 +506,7 @@ pk_mk_padata(krb5_context context,
     krb5_data_zero(&sd_buf);
     memset(&content_info, 0, sizeof(content_info));
 
-    if (ctx->type == COMPAT_WIN2K) {
+    if (ctx->type == PKINIT_WIN2K) {
        AuthPack_Win2k ap;
        krb5_timestamp sec;
        int32_t usec;
@@ -554,14 +536,15 @@ pk_mk_padata(krb5_context context,
                           &ap, &size, ret);
        free_AuthPack_Win2k(&ap);
        if (ret) {
-           krb5_set_error_string(context, "AuthPack_Win2k: %d", ret);
+           krb5_set_error_message(context, ret, "AuthPack_Win2k: %d", 
+                                  (int)ret);
            goto out;
        }
        if (buf.length != size)
            krb5_abortx(context, "internal ASN1 encoder error");
 
        oid = oid_id_pkcs7_data();
-    } else if (ctx->type == COMPAT_IETF) {
+    } else if (ctx->type == PKINIT_27) {
        AuthPack ap;
        
        memset(&ap, 0, sizeof(ap));
@@ -575,7 +558,7 @@ pk_mk_padata(krb5_context context,
        ASN1_MALLOC_ENCODE(AuthPack, buf.data, buf.length, &ap, &size, ret);
        free_AuthPack(&ap);
        if (ret) {
-           krb5_set_error_string(context, "AuthPack: %d", ret);
+           krb5_set_error_message(context, ret, "AuthPack: %d", (int)ret);
            goto out;
        }
        if (buf.length != size)
@@ -594,12 +577,12 @@ pk_mk_padata(krb5_context context,
     ret = hx509_cms_wrap_ContentInfo(oid_id_pkcs7_signedData(), &sd_buf, &buf);
     krb5_data_free(&sd_buf);
     if (ret) {
-       krb5_set_error_string(context,
-                             "ContentInfo wrapping of signedData failed");
+       krb5_set_error_message(context, ret,
+                              "ContentInfo wrapping of signedData failed");
        goto out;
     }
 
-    if (ctx->type == COMPAT_WIN2K) {
+    if (ctx->type == PKINIT_WIN2K) {
        PA_PK_AS_REQ_Win2k winreq;
 
        pa_type = KRB5_PADATA_PK_AS_REQ_WIN;
@@ -612,7 +595,7 @@ pk_mk_padata(krb5_context context,
                           &winreq, &size, ret);
        free_PA_PK_AS_REQ_Win2k(&winreq);
 
-    } else if (ctx->type == COMPAT_IETF) {
+    } else if (ctx->type == PKINIT_27) {
        PA_PK_AS_REQ req;
 
        pa_type = KRB5_PADATA_PK_AS_REQ;
@@ -624,14 +607,15 @@ pk_mk_padata(krb5_context context,
 
            req.trustedCertifiers = calloc(1, sizeof(*req.trustedCertifiers));
            if (req.trustedCertifiers == NULL) {
-               krb5_set_error_string(context, "malloc: out of memory");
+               ret = ENOMEM;
+               krb5_set_error_message(context, ret, "malloc: out of memory");
                free_PA_PK_AS_REQ(&req);
                goto out;
            }
            ret = build_edi(context, ctx->id->hx509ctx, 
                            ctx->id->anchors, req.trustedCertifiers);
            if (ret) {
-               krb5_set_error_string(context, "pk-init: failed to build trustedCertifiers");
+               krb5_set_error_message(context, ret, "pk-init: failed to build trustedCertifiers");
                free_PA_PK_AS_REQ(&req);
                goto out;
            }
@@ -646,7 +630,7 @@ pk_mk_padata(krb5_context context,
     } else
        krb5_abortx(context, "internal pkinit error");
     if (ret) {
-       krb5_set_error_string(context, "PA-PK-AS-REQ %d", ret);
+       krb5_set_error_message(context, ret, "PA-PK-AS-REQ %d", (int)ret);
        goto out;
     }
     if (buf.length != size)
@@ -656,10 +640,10 @@ pk_mk_padata(krb5_context context,
     if (ret)
        free(buf.data);
 
-    if (ret == 0 && ctx->type == COMPAT_WIN2K)
+    if (ret == 0 && ctx->type == PKINIT_WIN2K)
        krb5_padata_add(context, md, KRB5_PADATA_PK_AS_09_BINDING, NULL, 0);
 
-out:
+ out:
     free_ContentInfo(&content_info);
 
     return ret;
@@ -691,9 +675,9 @@ _krb5_pk_mk_padata(krb5_context context,
                                         req_body->realm,
                                         "pkinit_win2k_require_binding",
                                         NULL);
-       ctx->type = COMPAT_WIN2K;
+       ctx->type = PKINIT_WIN2K;
     } else
-       ctx->type = COMPAT_IETF;
+       ctx->type = PKINIT_27;
 
     ctx->require_eku = 
        krb5_config_get_bool_default(context, NULL,
@@ -753,8 +737,8 @@ _krb5_pk_verify_sign(krb5_context context,
                                  content,
                                  &signer_certs);
     if (ret) {
-       _krb5_pk_copy_error(context, id->hx509ctx, ret,
-                           "CMS verify signed failed");
+       pk_copy_error(context, id->hx509ctx, ret,
+                     "CMS verify signed failed");
        return ret;
     }
 
@@ -767,12 +751,12 @@ _krb5_pk_verify_sign(krb5_context context,
        
     ret = hx509_get_one_cert(id->hx509ctx, signer_certs, &(*signer)->cert);
     if (ret) {
-       _krb5_pk_copy_error(context, id->hx509ctx, ret,
-                           "Failed to get on of the signer certs");
+       pk_copy_error(context, id->hx509ctx, ret,
+                     "Failed to get on of the signer certs");
        goto out;
     }
 
-out:
+ out:
     hx509_certs_free(&signer_certs);
     if (ret) {
        if (*signer) {
@@ -800,29 +784,28 @@ get_reply_key_win(krb5_context context,
                                    &key_pack,
                                    &size);
     if (ret) {
-       krb5_set_error_string(context, "PKINIT decoding reply key failed");
+       krb5_set_error_message(context, ret, "PKINIT decoding reply key failed");
        free_ReplyKeyPack_Win2k(&key_pack);
        return ret;
     }
      
     if (key_pack.nonce != nonce) {
-       krb5_set_error_string(context, "PKINIT enckey nonce is wrong");
+       krb5_set_error_message(context, ret, "PKINIT enckey nonce is wrong");
        free_ReplyKeyPack_Win2k(&key_pack);
        return KRB5KRB_AP_ERR_MODIFIED;
     }
 
     *key = malloc (sizeof (**key));
     if (*key == NULL) {
-       krb5_set_error_string(context, "PKINIT failed allocating reply key");
        free_ReplyKeyPack_Win2k(&key_pack);
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
 
     ret = copy_EncryptionKey(&key_pack.replyKey, *key);
     free_ReplyKeyPack_Win2k(&key_pack);
     if (ret) {
-       krb5_set_error_string(context, "PKINIT failed copying reply key");
+       krb5_set_error_message(context, ret, "PKINIT failed copying reply key");
        free(*key);
        *key = NULL;
     }
@@ -845,7 +828,7 @@ get_reply_key(krb5_context context,
                              &key_pack,
                              &size);
     if (ret) {
-       krb5_set_error_string(context, "PKINIT decoding reply key failed");
+       krb5_set_error_message(context, ret, "PKINIT decoding reply key failed");
        free_ReplyKeyPack(&key_pack);
        return ret;
     }
@@ -876,16 +859,15 @@ get_reply_key(krb5_context context,
 
     *key = malloc (sizeof (**key));
     if (*key == NULL) {
-       krb5_set_error_string(context, "PKINIT failed allocating reply key");
        free_ReplyKeyPack(&key_pack);
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
 
     ret = copy_EncryptionKey(&key_pack.replyKey, *key);
     free_ReplyKeyPack(&key_pack);
     if (ret) {
-       krb5_set_error_string(context, "PKINIT failed copying reply key");
+       krb5_set_error_message(context, ret, "PKINIT failed copying reply key");
        free(*key);
        *key = NULL;
     }
@@ -907,7 +889,7 @@ pk_verify_host(krb5_context context,
        ret = hx509_cert_check_eku(ctx->id->hx509ctx, host->cert,
                                   oid_id_pkkdcekuoid(), 0);
        if (ret) {
-           krb5_set_error_string(context, "No PK-INIT KDC EKU in kdc certificate");
+           krb5_set_error_message(context, ret, "No PK-INIT KDC EKU in kdc certificate");
            return ret;
        }
     }
@@ -920,8 +902,8 @@ pk_verify_host(krb5_context context,
                                                       oid_id_pkinit_san(),
                                                       &list);
        if (ret) {
-           krb5_set_error_string(context, "Failed to find the PK-INIT "
-                                 "subjectAltName in the KDC certificate");
+           krb5_set_error_message(context, ret, "Failed to find the PK-INIT "
+                                  "subjectAltName in the KDC certificate");
 
            return ret;
        }
@@ -934,8 +916,8 @@ pk_verify_host(krb5_context context,
                                           &r,
                                           NULL);
            if (ret) {
-               krb5_set_error_string(context, "Failed to decode the PK-INIT "
-                                     "subjectAltName in the KDC certificate");
+               krb5_set_error_message(context, ret, "Failed to decode the PK-INIT "
+                                      "subjectAltName in the KDC certificate");
 
                break;
            }
@@ -944,11 +926,11 @@ pk_verify_host(krb5_context context,
                strcmp(r.principalName.name_string.val[0], KRB5_TGS_NAME) != 0 ||
                strcmp(r.principalName.name_string.val[1], realm) != 0 ||
                strcmp(r.realm, realm) != 0)
-           {
-               krb5_set_error_string(context, "KDC have wrong realm name in "
-                                     "the certificate");
-               ret = KRB5_KDC_ERR_INVALID_CERTIFICATE;
-           }
+               {
+                   ret = KRB5_KDC_ERR_INVALID_CERTIFICATE;
+                   krb5_set_error_message(context, ret, "KDC have wrong realm name in "
+                                          "the certificate");
+               }
 
            free_KRB5PrincipalName(&r);
            if (ret)
@@ -967,8 +949,8 @@ pk_verify_host(krb5_context context,
                                    hi->ai->ai_addr, hi->ai->ai_addrlen);
 
        if (ret)
-           krb5_set_error_string(context, "Address mismatch in "
-                                 "the KDC certificate");
+           krb5_set_error_message(context, ret, "Address mismatch in "
+                                  "the KDC certificate");
     }
     return ret;
 }
@@ -993,7 +975,7 @@ pk_rd_pa_reply_enckey(krb5_context context,
     heim_oid contentType = { 0, NULL };
 
     if (der_heim_oid_cmp(oid_id_pkcs7_envelopedData(), dataType)) {
-       krb5_set_error_string(context, "PKINIT: Invalid content type");
+       krb5_set_error_message(context, EINVAL, "PKINIT: Invalid content type");
        return EINVAL;
     }
 
@@ -1003,11 +985,12 @@ pk_rd_pa_reply_enckey(krb5_context context,
                               indata->data,
                               indata->length,
                               NULL,
+                              0,
                               &contentType,
                               &content);
     if (ret) {
-       _krb5_pk_copy_error(context, ctx->id->hx509ctx, ret,
-                           "Failed to unenvelope CMS data in PK-INIT reply");
+       pk_copy_error(context, ctx->id->hx509ctx, ret,
+                     "Failed to unenvelope CMS data in PK-INIT reply");
        return ret;
     }
     der_free_oid(&contentType);
@@ -1031,14 +1014,14 @@ pk_rd_pa_reply_enckey(krb5_context context,
 #endif
 
     /* win2k uses ContentInfo */
-    if (type == COMPAT_WIN2K) {
+    if (type == PKINIT_WIN2K) {
        heim_oid type;
        heim_octet_string out;
 
        ret = hx509_cms_unwrap_ContentInfo(&content, &type, &out, NULL);
        if (der_heim_oid_cmp(&type, oid_id_pkcs7_signedData())) {
            ret = EINVAL; /* XXX */
-           krb5_set_error_string(context, "PKINIT: Invalid content type");
+           krb5_set_error_message(context, ret, "PKINIT: Invalid content type");
            der_free_oid(&type);
            der_free_octet_string(&out);
            goto out;
@@ -1048,7 +1031,7 @@ pk_rd_pa_reply_enckey(krb5_context context,
        ret = krb5_data_copy(&content, out.data, out.length);
        der_free_octet_string(&out);
        if (ret) {
-           krb5_set_error_string(context, "PKINIT: out of memory");
+           krb5_set_error_message(context, ret, "PKINIT: out of memory");
            goto out;
        }
     }
@@ -1070,28 +1053,28 @@ pk_rd_pa_reply_enckey(krb5_context context,
     }
 
 #if 0
-    if (type == COMPAT_WIN2K) {
+    if (type == PKINIT_WIN2K) {
        if (der_heim_oid_cmp(&contentType, oid_id_pkcs7_data()) != 0) {
-           krb5_set_error_string(context, "PKINIT: reply key, wrong oid");
            ret = KRB5KRB_AP_ERR_MSG_TYPE;
+           krb5_set_error_message(context, ret, "PKINIT: reply key, wrong oid");
            goto out;
        }
     } else {
        if (der_heim_oid_cmp(&contentType, oid_id_pkrkeydata()) != 0) {
-           krb5_set_error_string(context, "PKINIT: reply key, wrong oid");
            ret = KRB5KRB_AP_ERR_MSG_TYPE;
+           krb5_set_error_message(context, ret, "PKINIT: reply key, wrong oid");
            goto out;
        }
     }
 #endif
 
     switch(type) {
-    case COMPAT_WIN2K:
+    case PKINIT_WIN2K:
        ret = get_reply_key(context, &content, req_buffer, key);
        if (ret != 0 && ctx->require_binding == 0)
            ret = get_reply_key_win(context, &content, nonce, key);
        break;
-    case COMPAT_IETF:
+    case PKINIT_27:
        ret = get_reply_key(context, &content, req_buffer, key);
        break;
     }
@@ -1137,7 +1120,7 @@ pk_rd_pa_reply_dh(krb5_context context,
     memset(&kdc_dh_info, 0, sizeof(kdc_dh_info));
 
     if (der_heim_oid_cmp(oid_id_pkcs7_signedData(), dataType)) {
-       krb5_set_error_string(context, "PKINIT: Invalid content type");
+       krb5_set_error_message(context, EINVAL, "PKINIT: Invalid content type");
        return EINVAL;
     }
 
@@ -1157,8 +1140,8 @@ pk_rd_pa_reply_dh(krb5_context context,
        goto out;
 
     if (der_heim_oid_cmp(&contentType, oid_id_pkdhkeydata())) {
-       krb5_set_error_string(context, "pkinit - dh reply contains wrong oid");
        ret = KRB5KRB_AP_ERR_MSG_TYPE;
+       krb5_set_error_message(context, ret, "pkinit - dh reply contains wrong oid");
        goto out;
     }
 
@@ -1168,35 +1151,35 @@ pk_rd_pa_reply_dh(krb5_context context,
                              &size);
 
     if (ret) {
-       krb5_set_error_string(context, "pkinit - "
-                             "failed to decode KDC DH Key Info");
+       krb5_set_error_message(context, ret, "pkinit - "
+                              "failed to decode KDC DH Key Info");
        goto out;
     }
 
     if (kdc_dh_info.nonce != nonce) {
-       krb5_set_error_string(context, "PKINIT: DH nonce is wrong");
        ret = KRB5KRB_AP_ERR_MODIFIED;
+       krb5_set_error_message(context, ret, "PKINIT: DH nonce is wrong");
        goto out;
     }
 
     if (kdc_dh_info.dhKeyExpiration) {
        if (k_n == NULL) {
-           krb5_set_error_string(context, "pkinit; got key expiration "
-                                 "without server nonce");
            ret = KRB5KRB_ERR_GENERIC;
+           krb5_set_error_message(context, ret, "pkinit; got key expiration "
+                                  "without server nonce");
            goto out;
        }
        if (c_n == NULL) {
-           krb5_set_error_string(context, "pkinit; got DH reuse but no "
-                                 "client nonce");
            ret = KRB5KRB_ERR_GENERIC;
+           krb5_set_error_message(context, ret, "pkinit; got DH reuse but no "
+                                  "client nonce");
            goto out;
        }
     } else {
        if (k_n) {
-           krb5_set_error_string(context, "pkinit: got server nonce "
-                                 "without key expiration");
            ret = KRB5KRB_ERR_GENERIC;
+           krb5_set_error_message(context, ret, "pkinit: got server nonce "
+                                  "without key expiration");
            goto out;
        }
        c_n = NULL;
@@ -1210,15 +1193,15 @@ pk_rd_pa_reply_dh(krb5_context context,
        DHPublicKey k;
        ret = decode_DHPublicKey(p, size, &k, NULL);
        if (ret) {
-           krb5_set_error_string(context, "pkinit: can't decode "
-                                 "without key expiration");
+           krb5_set_error_message(context, ret, "pkinit: can't decode "
+                                  "without key expiration");
            goto out;
        }
 
        kdc_dh_pubkey = integer_to_BN(context, "DHPublicKey", &k);
        free_DHPublicKey(&k);
        if (kdc_dh_pubkey == NULL) {
-           ret = KRB5KRB_ERR_GENERIC;
+           ret = ENOMEM;
            goto out;
        }
     }
@@ -1230,8 +1213,8 @@ pk_rd_pa_reply_dh(krb5_context context,
 
     dh_gen_key = malloc(size);
     if (dh_gen_key == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
        ret = ENOMEM;
+       krb5_set_error_message(context, ret, "malloc: out of memory");
        goto out;
     }
     memset(dh_gen_key, 0, size - dh_gen_keylen);
@@ -1239,16 +1222,16 @@ pk_rd_pa_reply_dh(krb5_context context,
     dh_gen_keylen = DH_compute_key(dh_gen_key + (size - dh_gen_keylen),
                                   kdc_dh_pubkey, ctx->dh);
     if (dh_gen_keylen == -1) {
-       krb5_set_error_string(context, 
-                             "PKINIT: Can't compute Diffie-Hellman key");
        ret = KRB5KRB_ERR_GENERIC;
+       krb5_set_error_message(context, ret, 
+                              "PKINIT: Can't compute Diffie-Hellman key");
        goto out;
     }
 
     *key = malloc (sizeof (**key));
     if (*key == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
        ret = ENOMEM;
+       krb5_set_error_message(context, ret, "malloc: out of memory");
        goto out;
     }
 
@@ -1258,8 +1241,8 @@ pk_rd_pa_reply_dh(krb5_context context,
                                   c_n, k_n,
                                   *key);
     if (ret) {
-       krb5_set_error_string(context,
-                             "PKINIT: can't create key from DH key");
+       krb5_set_error_message(context, ret,
+                              "PKINIT: can't create key from DH key");
        free(*key);
        *key = NULL;
        goto out;
@@ -1298,13 +1281,13 @@ _krb5_pk_rd_pa_reply(krb5_context context,
     size_t size;
 
     /* Check for IETF PK-INIT first */
-    if (ctx->type == COMPAT_IETF) {
+    if (ctx->type == PKINIT_27) {
        PA_PK_AS_REP rep;
        heim_octet_string os, data;
        heim_oid oid;
        
        if (pa->padata_type != KRB5_PADATA_PK_AS_REP) {
-           krb5_set_error_string(context, "PKINIT: wrong padata recv");
+           krb5_set_error_message(context, EINVAL, "PKINIT: wrong padata recv");
            return EINVAL;
        }
 
@@ -1313,7 +1296,7 @@ _krb5_pk_rd_pa_reply(krb5_context context,
                                  &rep,
                                  &size);
        if (ret) {
-           krb5_set_error_string(context, "Failed to decode pkinit AS rep");
+           krb5_set_error_message(context, ret, "Failed to decode pkinit AS rep");
            return ret;
        }
 
@@ -1326,15 +1309,15 @@ _krb5_pk_rd_pa_reply(krb5_context context,
            break;
        default:
            free_PA_PK_AS_REP(&rep);
-           krb5_set_error_string(context, "PKINIT: -27 reply "
-                                 "invalid content type");
+           krb5_set_error_message(context, EINVAL, "PKINIT: -27 reply "
+                                  "invalid content type");
            return EINVAL;
        }
 
        ret = hx509_cms_unwrap_ContentInfo(&os, &oid, &data, NULL);
        if (ret) {
            free_PA_PK_AS_REP(&rep);
-           krb5_set_error_string(context, "PKINIT: failed to unwrap CI");
+           krb5_set_error_message(context, ret, "PKINIT: failed to unwrap CI");
            return ret;
        }
 
@@ -1346,7 +1329,7 @@ _krb5_pk_rd_pa_reply(krb5_context context,
                                    nonce, pa, key);
            break;
        case choice_PA_PK_AS_REP_encKeyPack:
-           ret = pk_rd_pa_reply_enckey(context, COMPAT_IETF, &data, &oid, realm, 
+           ret = pk_rd_pa_reply_enckey(context, PKINIT_27, &data, &oid, realm, 
                                        ctx, etype, hi, nonce, req_buffer, pa, key);
            break;
        default:
@@ -1356,14 +1339,14 @@ _krb5_pk_rd_pa_reply(krb5_context context,
        der_free_oid(&oid);
        free_PA_PK_AS_REP(&rep);
 
-    } else if (ctx->type == COMPAT_WIN2K) {
+    } else if (ctx->type == PKINIT_WIN2K) {
        PA_PK_AS_REP_Win2k w2krep;
 
        /* Check for Windows encoding of the AS-REP pa data */ 
 
 #if 0 /* should this be ? */
        if (pa->padata_type != KRB5_PADATA_PK_AS_REP) {
-           krb5_set_error_string(context, "PKINIT: wrong padata recv");
+           krb5_set_error_message(context, EINVAL, "PKINIT: wrong padata recv");
            return EINVAL;
        }
 #endif
@@ -1375,8 +1358,8 @@ _krb5_pk_rd_pa_reply(krb5_context context,
                                        &w2krep,
                                        &size);
        if (ret) {
-           krb5_set_error_string(context, "PKINIT: Failed decoding windows "
-                                 "pkinit reply %d", ret);
+           krb5_set_error_message(context, ret, "PKINIT: Failed decoding windows "
+                                  "pkinit reply %d", (int)ret);
            return ret;
        }
 
@@ -1391,11 +1374,11 @@ _krb5_pk_rd_pa_reply(krb5_context context,
                                               &oid, &data, NULL);
            free_PA_PK_AS_REP_Win2k(&w2krep);
            if (ret) {
-               krb5_set_error_string(context, "PKINIT: failed to unwrap CI");
+               krb5_set_error_message(context, ret, "PKINIT: failed to unwrap CI");
                return ret;
            }
 
-           ret = pk_rd_pa_reply_enckey(context, COMPAT_WIN2K, &data, &oid, realm,
+           ret = pk_rd_pa_reply_enckey(context, PKINIT_WIN2K, &data, &oid, realm,
                                        ctx, etype, hi, nonce, req_buffer, pa, key);
            der_free_octet_string(&data);
            der_free_oid(&oid);
@@ -1404,15 +1387,15 @@ _krb5_pk_rd_pa_reply(krb5_context context,
        }
        default:
            free_PA_PK_AS_REP_Win2k(&w2krep);
-           krb5_set_error_string(context, "PKINIT: win2k reply invalid "
-                                 "content type");
            ret = EINVAL;
+           krb5_set_error_message(context, ret, "PKINIT: win2k reply invalid "
+                                  "content type");
            break;
        }
     
     } else {
-       krb5_set_error_string(context, "PKINIT: unknown reply type");
        ret = EINVAL;
+       krb5_set_error_message(context, ret, "PKINIT: unknown reply type");
     }
 
     return ret;
@@ -1486,13 +1469,14 @@ _krb5_pk_load_id(krb5_context context,
     *ret_id = NULL;
 
     if (anchor_id == NULL) {
-       krb5_set_error_string(context, "PKINIT: No anchor given");
+       krb5_set_error_message(context, HEIM_PKINIT_NO_VALID_CA,
+                              "PKINIT: No anchor given");
        return HEIM_PKINIT_NO_VALID_CA;
     }
 
     if (user_id == NULL) {
-       krb5_set_error_string(context,
-                             "PKINIT: No user certificate given");
+       krb5_set_error_message(context, HEIM_PKINIT_NO_PRIVATE_KEY,
+                              "PKINIT: No user certificate given");
        return HEIM_PKINIT_NO_PRIVATE_KEY;
     }
 
@@ -1500,7 +1484,7 @@ _krb5_pk_load_id(krb5_context context,
 
     id = calloc(1, sizeof(*id));
     if (id == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }  
 
@@ -1524,23 +1508,23 @@ _krb5_pk_load_id(krb5_context context,
 
     ret = hx509_certs_init(id->hx509ctx, user_id, 0, lock, &id->certs);
     if (ret) {
-       _krb5_pk_copy_error(context, id->hx509ctx, ret,
-                           "Failed to init cert certs");
+       pk_copy_error(context, id->hx509ctx, ret,
+                     "Failed to init cert certs");
        goto out;
     }
 
     ret = hx509_certs_init(id->hx509ctx, anchor_id, 0, NULL, &id->anchors);
     if (ret) {
-       _krb5_pk_copy_error(context, id->hx509ctx, ret,
-                           "Failed to init anchors");
+       pk_copy_error(context, id->hx509ctx, ret,
+                     "Failed to init anchors");
        goto out;
     }
 
     ret = hx509_certs_init(id->hx509ctx, "MEMORY:pkinit-cert-chain", 
                           0, NULL, &id->certpool);
     if (ret) {
-       _krb5_pk_copy_error(context, id->hx509ctx, ret,
-                           "Failed to init chain");
+       pk_copy_error(context, id->hx509ctx, ret,
+                     "Failed to init chain");
        goto out;
     }
 
@@ -1548,9 +1532,9 @@ _krb5_pk_load_id(krb5_context context,
        ret = hx509_certs_append(id->hx509ctx, id->certpool,
                                 NULL, *chain_list);
        if (ret) {
-           _krb5_pk_copy_error(context, id->hx509ctx, ret,
-                               "Failed to laod chain %s",
-                               *chain_list);
+           pk_copy_error(context, id->hx509ctx, ret,
+                         "Failed to laod chain %s",
+                         *chain_list);
            goto out;
        }
        chain_list++;
@@ -1559,8 +1543,8 @@ _krb5_pk_load_id(krb5_context context,
     if (revoke_list) {
        ret = hx509_revoke_init(id->hx509ctx, &id->revokectx);
        if (ret) {
-           _krb5_pk_copy_error(context, id->hx509ctx, ret,
-                               "Failed init revoke list");
+           pk_copy_error(context, id->hx509ctx, ret,
+                         "Failed init revoke list");
            goto out;
        }
 
@@ -1569,8 +1553,8 @@ _krb5_pk_load_id(krb5_context context,
                                       id->revokectx,
                                       *revoke_list);
            if (ret) {
-               _krb5_pk_copy_error(context, id->hx509ctx, ret, 
-                                   "Failed load revoke list");
+               pk_copy_error(context, id->hx509ctx, ret, 
+                             "Failed load revoke list");
                goto out;
            }
            revoke_list++;
@@ -1580,15 +1564,15 @@ _krb5_pk_load_id(krb5_context context,
 
     ret = hx509_verify_init_ctx(id->hx509ctx, &id->verify_ctx);
     if (ret) {
-       _krb5_pk_copy_error(context, id->hx509ctx, ret, 
-                           "Failed init verify context");
+       pk_copy_error(context, id->hx509ctx, ret, 
+                     "Failed init verify context");
        goto out;
     }
 
     hx509_verify_attach_anchors(id->verify_ctx, id->anchors);
     hx509_verify_attach_revoke(id->verify_ctx, id->revokectx);
 
-out:
+ out:
     if (ret) {
        hx509_verify_destroy_ctx(id->verify_ctx);
        hx509_certs_free(&id->certs);
@@ -1622,10 +1606,10 @@ select_dh_group(krb5_context context, DH *dh, unsigned long bits,
                break;
        }
        if (moduli[i] == NULL) {
-           krb5_set_error_string(context, 
-                                 "Did not find a DH group parameter "
-                                 "matching requirement of %lu bits",
-                                 bits);
+           krb5_set_error_message(context, EINVAL,
+                                  "Did not find a DH group parameter "
+                                  "matching requirement of %lu bits",
+                                  bits);
            return EINVAL;
        }
        m = moduli[i];
@@ -1644,6 +1628,39 @@ select_dh_group(krb5_context context, DH *dh, unsigned long bits,
     return 0;
 }
 
+/*
+ *
+ */
+
+static void
+pk_copy_error(krb5_context context,
+             hx509_context hx509ctx,
+             int hxret,
+             const char *fmt,
+             ...)
+{
+    va_list va;
+    char *s, *f;
+
+    va_start(va, fmt);
+    vasprintf(&f, fmt, va);
+    va_end(va);
+    if (f == NULL) {
+       krb5_clear_error_string(context);
+       return;
+    }
+
+    s = hx509_get_error_string(hx509ctx, hxret);
+    if (s == NULL) {
+       krb5_clear_error_string(context);
+       free(f);
+       return;
+    }
+    krb5_set_error_message(context, hxret, "%s: %s", f, s);
+    free(s);
+    free(f);
+}
+
 #endif /* PKINIT */
 
 static int
@@ -1654,15 +1671,15 @@ parse_integer(krb5_context context, char **p, const char *file, int lineno,
     char *p1;
     p1 = strsep(p, " \t");
     if (p1 == NULL) {
-       krb5_set_error_string(context, "moduli file %s missing %s on line %d",
-                             file, name, lineno);
+       krb5_set_error_message(context, EINVAL, "moduli file %s missing %s on line %d",
+                              file, name, lineno);
        return EINVAL;
     }
     ret = der_parse_hex_heim_integer(p1, integer);
     if (ret) {
-       krb5_set_error_string(context, "moduli file %s failed parsing %s "
-                             "on line %d",
-                             file, name, lineno);
+       krb5_set_error_message(context, ret, "moduli file %s failed parsing %s "
+                              "on line %d",
+                              file, name, lineno);
        return ret;
     }
 
@@ -1684,7 +1701,7 @@ _krb5_parse_moduli_line(krb5_context context,
 
     m1 = calloc(1, sizeof(*m1));
     if (m1 == NULL) {
-       krb5_set_error_string(context, "malloc - out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
 
@@ -1696,28 +1713,28 @@ _krb5_parse_moduli_line(krb5_context context,
 
     p1 = strsep(&p, " \t");
     if (p1 == NULL) {
-       krb5_set_error_string(context, "moduli file %s missing name "
-                             "on line %d", file, lineno);
+       krb5_set_error_message(context, ret, "moduli file %s missing name "
+                              "on line %d", file, lineno);
        goto out;
     }
     m1->name = strdup(p1);
     if (p1 == NULL) {
-       krb5_set_error_string(context, "malloc - out of memeory");
        ret = ENOMEM;
+       krb5_set_error_message(context, ret, "malloc - out of memeory");
        goto out;
     }
 
     p1 = strsep(&p, " \t");
     if (p1 == NULL) {
-       krb5_set_error_string(context, "moduli file %s missing bits on line %d",
-                             file, lineno);
+       krb5_set_error_message(context, ret, "moduli file %s missing bits on line %d",
+                              file, lineno);
        goto out;
     }
 
     m1->bits = atoi(p1);
     if (m1->bits == 0) {
-       krb5_set_error_string(context, "moduli file %s have un-parsable "
-                             "bits on line %d", file, lineno);
+       krb5_set_error_message(context, ret, "moduli file %s have un-parsable "
+                              "bits on line %d", file, lineno);
        goto out;
     }
        
@@ -1734,7 +1751,7 @@ _krb5_parse_moduli_line(krb5_context context,
     *m = m1;
 
     return 0;
-out:
+ out:
     free(m1->name);
     der_free_heim_integer(&m1->p);
     der_free_heim_integer(&m1->g);
@@ -1826,7 +1843,7 @@ _krb5_parse_moduli(krb5_context context, const char *file,
 
     m = calloc(1, sizeof(m[0]) * 3);
     if (m == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
 
@@ -1855,6 +1872,7 @@ _krb5_parse_moduli(krb5_context context, const char *file,
        *moduli = m;
        return 0;
     }
+    rk_cloexec_file(f);
 
     while(fgets(buf, sizeof(buf), f) != NULL) {
        struct krb5_dh_moduli *element;
@@ -1864,8 +1882,8 @@ _krb5_parse_moduli(krb5_context context, const char *file,
 
        m2 = realloc(m, (n + 2) * sizeof(m[0]));
        if (m2 == NULL) {
-           krb5_set_error_string(context, "malloc: out of memory");
            _krb5_free_moduli(m);
+           krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
            return ENOMEM;
        }
        m = m2;
@@ -1903,19 +1921,23 @@ _krb5_dh_group_ok(krb5_context context, unsigned long bits,
        if (der_heim_integer_cmp(&moduli[i]->g, g) == 0 &&
            der_heim_integer_cmp(&moduli[i]->p, p) == 0 &&
            (q == NULL || der_heim_integer_cmp(&moduli[i]->q, q) == 0))
-       {
-           if (bits && bits > moduli[i]->bits) {
-               krb5_set_error_string(context, "PKINIT: DH group parameter %s "
-                                     "no accepted, not enough bits generated",
-                                     moduli[i]->name);
-               return KRB5_KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED;
+           {
+               if (bits && bits > moduli[i]->bits) {
+                   krb5_set_error_message(context, 
+                                          KRB5_KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED,
+                                          "PKINIT: DH group parameter %s "
+                                          "no accepted, not enough bits generated",
+                                          moduli[i]->name);
+                   return KRB5_KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED;
+               }
+               if (name)
+                   *name = strdup(moduli[i]->name);
+               return 0;
            }
-           if (name)
-               *name = strdup(moduli[i]->name);
-           return 0;
-       }
     }
-    krb5_set_error_string(context, "PKINIT: DH group parameter no ok");
+    krb5_set_error_message(context,
+                          KRB5_KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED,
+                          "PKINIT: DH group parameter no ok");
     return KRB5_KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED;
 }
 
@@ -1930,7 +1952,7 @@ _krb5_get_init_creds_opt_free_pkinit(krb5_get_init_creds_opt *opt)
     ctx = opt->opt_private->pk_init_ctx;
     if (ctx->dh)
        DH_free(ctx->dh);
-       ctx->dh = NULL;
+    ctx->dh = NULL;
     if (ctx->id) {
        hx509_verify_destroy_ctx(ctx->id->verify_ctx);
        hx509_certs_free(&ctx->id->certs);
@@ -1970,14 +1992,14 @@ krb5_get_init_creds_opt_set_pkinit(krb5_context context,
     char *anchors = NULL;
 
     if (opt->opt_private == NULL) {
-       krb5_set_error_string(context, "PKINIT: on non extendable opt");
+       krb5_set_error_message(context, EINVAL, "PKINIT: on non extendable opt");
        return EINVAL;
     }
 
     opt->opt_private->pk_init_ctx = 
        calloc(1, sizeof(*opt->opt_private->pk_init_ctx));
     if (opt->opt_private->pk_init_ctx == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     opt->opt_private->pk_init_ctx->dh = NULL;
@@ -2047,8 +2069,8 @@ krb5_get_init_creds_opt_set_pkinit(krb5_context context,
        
        opt->opt_private->pk_init_ctx->dh = DH_new();
        if (opt->opt_private->pk_init_ctx->dh == NULL) {
-           krb5_set_error_string(context, "malloc: out of memory");
            _krb5_get_init_creds_opt_free_pkinit(opt);
+           krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
            return ENOMEM;
        }
 
@@ -2061,48 +2083,15 @@ krb5_get_init_creds_opt_set_pkinit(krb5_context context,
        }
 
        if (DH_generate_key(opt->opt_private->pk_init_ctx->dh) != 1) {
-           krb5_set_error_string(context, "pkinit: failed to generate DH key");
            _krb5_get_init_creds_opt_free_pkinit(opt);
+           krb5_set_error_message(context, ENOMEM, "pkinit: failed to generate DH key");
            return ENOMEM;
        }
     }
 
     return 0;
 #else
-    krb5_set_error_string(context, "no support for PKINIT compiled in");
+    krb5_set_error_message(context, EINVAL, "no support for PKINIT compiled in");
     return EINVAL;
 #endif
 }
-
-/*
- *
- */
-
-static void
-_krb5_pk_copy_error(krb5_context context,
-                   hx509_context hx509ctx,
-                   int hxret,
-                   const char *fmt,
-                   ...)
-{
-    va_list va;
-    char *s, *f;
-
-    va_start(va, fmt);
-    vasprintf(&f, fmt, va);
-    va_end(va);
-    if (f == NULL) {
-       krb5_clear_error_string(context);
-       return;
-    }
-
-    s = hx509_get_error_string(hx509ctx, hxret);
-    if (s == NULL) {
-       krb5_clear_error_string(context);
-       free(f);
-       return;
-    }
-    krb5_set_error_string(context, "%s: %s", f, s);
-    free(s);
-    free(f);
-}
index bae28496aaf823405fbfa1b852e0f9f2e0045612..8dda27fa596c30c3da3f6b5046e0a1e70c5623df 100644 (file)
@@ -32,7 +32,7 @@
  */
 
 #include "krb5_locl.h"
-RCSID("$Id: plugin.c 22033 2007-11-10 10:39:47Z lha $");
+RCSID("$Id: plugin.c 23451 2008-07-27 12:10:30Z lha $");
 #ifdef HAVE_DLFCN_H
 #include <dlfcn.h>
 #endif
@@ -87,7 +87,7 @@ loadlib(krb5_context context,
 {
     *e = calloc(1, sizeof(**e));
     if (*e == NULL) {
-       krb5_set_error_string(context, "out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
 
@@ -99,8 +99,8 @@ loadlib(krb5_context context,
     if ((*e)->dsohandle == NULL) {
        free(*e);
        *e = NULL;
-       krb5_set_error_string(context, "Failed to load %s: %s", 
-                             lib, dlerror());
+       krb5_set_error_message(context, ENOMEM, "Failed to load %s: %s", 
+                              lib, dlerror());
        return ENOMEM;
     }
 
@@ -139,14 +139,14 @@ krb5_plugin_register(krb5_context context,
 
     e = calloc(1, sizeof(*e));
     if (e == NULL) {
-       krb5_set_error_string(context, "out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     e->type = type;
     e->name = strdup(name);
     if (e->name == NULL) {
        free(e);
-       krb5_set_error_string(context, "out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     e->symbol = symbol;
@@ -185,8 +185,8 @@ _krb5_plugin_find(krb5_context context,
        e = calloc(1, sizeof(*e));
        if (e == NULL) {
            HEIMDAL_MUTEX_unlock(&plugin_mutex);
-           krb5_set_error_string(context, "out of memory");
            ret = ENOMEM;
+           krb5_set_error_message(context, ret, "malloc: out of memory");
            goto out;
        }
        e->symbol = p->symbol;
@@ -210,12 +210,13 @@ _krb5_plugin_find(krb5_context context,
        d = opendir(*di);
        if (d == NULL)
            continue;
+       rk_cloexec(dirfd(d));
 
        while ((entry = readdir(d)) != NULL) {
            asprintf(&path, "%s/%s", *di, entry->d_name);
            if (path == NULL) {
-               krb5_set_error_string(context, "out of memory");
                ret = ENOMEM;
+               krb5_set_error_message(context, ret, "malloc: out of memory");
                goto out;
            }
            ret = loadlib(context, type, name, path, &e);
@@ -233,7 +234,7 @@ _krb5_plugin_find(krb5_context context,
 #endif /* HAVE_DLOPEN */
 
     if (*list == NULL) {
-       krb5_set_error_string(context, "Did not find a plugin for %s", name);
+       krb5_set_error_message(context, ENOENT, "Did not find a plugin for %s", name);
        return ENOENT;
     }
 
index cdad4771153ede8d0361120441d71118eab6a8f5..0d6d72dbcf2e362f74a224258bf8c336fbc3792c 100644 (file)
@@ -57,7 +57,7 @@ host/admin@H5L.ORG
 #include <fnmatch.h>
 #include "resolve.h"
 
-RCSID("$Id: principal.c 22549 2008-01-29 09:37:25Z lha $");
+RCSID("$Id: principal.c 23316 2008-06-23 04:32:32Z lha $");
 
 #define princ_num_comp(P) ((P)->name.name_string.len)
 #define princ_type(P) ((P)->name.name_type)
@@ -149,8 +149,9 @@ krb5_parse_name_flags(krb5_context context,
 #define RFLAGS (KRB5_PRINCIPAL_PARSE_NO_REALM|KRB5_PRINCIPAL_PARSE_MUST_REALM)
 
     if ((flags & RFLAGS) == RFLAGS) {
-       krb5_set_error_string(context, "Can't require both realm and "
-                             "no realm at the same time");
+       krb5_set_error_message(context, KRB5_ERR_NO_SERVICE,
+                              "Can't require both realm and "
+                              "no realm at the same time");
        return KRB5_ERR_NO_SERVICE;
     }
 #undef RFLAGS
@@ -163,7 +164,7 @@ krb5_parse_name_flags(krb5_context context,
        for(p = name; *p; p++){
            if(*p=='\\'){
                if(!p[1]) {
-                   krb5_set_error_string (context,
+                   krb5_set_error_message(context, KRB5_PARSE_MALFORMED,
                                           "trailing \\ in principal name");
                    return KRB5_PARSE_MALFORMED;
                }
@@ -176,7 +177,7 @@ krb5_parse_name_flags(krb5_context context,
     }
     comp = calloc(ncomp, sizeof(*comp));
     if (comp == NULL) {
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
   
@@ -184,7 +185,7 @@ krb5_parse_name_flags(krb5_context context,
     p = start = q = s = strdup(name);
     if (start == NULL) {
        free (comp);
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     while(*p){
@@ -200,9 +201,9 @@ krb5_parse_name_flags(krb5_context context,
            else if(c == '0')
                c = '\0';
            else if(c == '\0') {
-               krb5_set_error_string (context,
-                                      "trailing \\ in principal name");
                ret = KRB5_PARSE_MALFORMED;
+               krb5_set_error_message(context, ret,
+                                      "trailing \\ in principal name");
                goto exit;
            }
        }else if(enterprise && first_at) {
@@ -210,15 +211,15 @@ krb5_parse_name_flags(krb5_context context,
                first_at = 0;
        }else if((c == '/' && !enterprise) || c == '@'){
            if(got_realm){
-               krb5_set_error_string (context,
-                                      "part after realm in principal name");
                ret = KRB5_PARSE_MALFORMED;
+               krb5_set_error_message(context, ret,
+                                      "part after realm in principal name");
                goto exit;
            }else{
                comp[n] = malloc(q - start + 1);
                if (comp[n] == NULL) {
-                   krb5_set_error_string (context, "malloc: out of memory");
                    ret = ENOMEM;
+                   krb5_set_error_message(context, ret, "malloc: out of memory");
                    goto exit;
                }
                memcpy(comp[n], start, q - start);
@@ -231,33 +232,33 @@ krb5_parse_name_flags(krb5_context context,
            continue;
        }
        if(got_realm && (c == ':' || c == '/' || c == '\0')) {
-           krb5_set_error_string (context,
-                                  "part after realm in principal name");
            ret = KRB5_PARSE_MALFORMED;
+           krb5_set_error_message(context, ret,
+                                  "part after realm in principal name");
            goto exit;
        }
        *q++ = c;
     }
     if(got_realm){
        if (flags & KRB5_PRINCIPAL_PARSE_NO_REALM) {
-           krb5_set_error_string (context, "realm found in 'short' principal "
-                                  "expected to be without one");
            ret = KRB5_PARSE_MALFORMED;
+           krb5_set_error_message(context, ret, "realm found in 'short' principal "
+                                  "expected to be without one");
            goto exit;
        }
        realm = malloc(q - start + 1);
        if (realm == NULL) {
-           krb5_set_error_string (context, "malloc: out of memory");
            ret = ENOMEM;
+           krb5_set_error_message(context, ret, "malloc: out of memory");
            goto exit;
        }
        memcpy(realm, start, q - start);
        realm[q - start] = 0;
     }else{
        if (flags & KRB5_PRINCIPAL_PARSE_MUST_REALM) {
-           krb5_set_error_string (context, "realm NOT found in principal "
-                                  "expected to be with one");
            ret = KRB5_PARSE_MALFORMED;
+           krb5_set_error_message(context, ret, "realm NOT found in principal "
+                                  "expected to be with one");
            goto exit;
        } else if (flags & KRB5_PRINCIPAL_PARSE_NO_REALM) {
            realm = NULL;
@@ -269,8 +270,8 @@ krb5_parse_name_flags(krb5_context context,
 
        comp[n] = malloc(q - start + 1);
        if (comp[n] == NULL) {
-           krb5_set_error_string (context, "malloc: out of memory");
            ret = ENOMEM;
+           krb5_set_error_message(context, ret, "malloc: out of memory");
            goto exit;
        }
        memcpy(comp[n], start, q - start);
@@ -279,8 +280,8 @@ krb5_parse_name_flags(krb5_context context,
     }
     *principal = malloc(sizeof(**principal));
     if (*principal == NULL) {
-       krb5_set_error_string (context, "malloc: out of memory");
        ret = ENOMEM;
+       krb5_set_error_message(context, ret, "malloc: out of memory");
        goto exit;
     }
     if (enterprise)
@@ -350,7 +351,8 @@ unparse_name_fixed(krb5_context context,
     int display = (flags & KRB5_PRINCIPAL_UNPARSE_DISPLAY) != 0;
 
     if (!no_realm && princ_realm(principal) == NULL) {
-       krb5_set_error_string(context, "Realm missing from principal, "
+       krb5_set_error_message(context, ERANGE,
+                              "Realm missing from principal, "
                              "can't unparse");
        return ERANGE;
     }
@@ -360,7 +362,7 @@ unparse_name_fixed(krb5_context context,
            add_char(name, idx, len, '/');
        idx = quote_string(princ_ncomp(principal, i), name, idx, len, display);
        if(idx == len) {
-           krb5_set_error_string(context, "Out of space printing principal");
+           krb5_set_error_message(context, ERANGE, "Out of space printing principal");
            return ERANGE;
        }
     } 
@@ -379,8 +381,8 @@ unparse_name_fixed(krb5_context context,
        add_char(name, idx, len, '@');
        idx = quote_string(princ_realm(principal), name, idx, len, display);
        if(idx == len) {
-           krb5_set_error_string(context, 
-                                 "Out of space printing realm of principal");
+           krb5_set_error_message(context, ERANGE,
+                                  "Out of space printing realm of principal");
            return ERANGE;
        }
     }
@@ -446,7 +448,7 @@ unparse_name(krb5_context context,
     len++; /* '\0' */
     *name = malloc(len);
     if(*name == NULL) {
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     ret = unparse_name_fixed(context, principal, *name, len, flags);
@@ -511,6 +513,22 @@ krb5_princ_set_realm(krb5_context context,
     princ_realm(principal) = *realm;
 }
 
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_principal_set_realm(krb5_context context,
+                        krb5_principal principal,
+                        krb5_const_realm realm)
+{
+    if (princ_realm(principal))
+       free(princ_realm(principal));
+
+    princ_realm(principal) = strdup(realm);
+    if (princ_realm(principal) == NULL) {
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
+       return ENOMEM;
+    }
+    return 0;
+}
+
 
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_build_principal(krb5_context context,
@@ -537,13 +555,13 @@ append_component(krb5_context context, krb5_principal p,
 
     tmp = realloc(princ_comp(p), (len + 1) * sizeof(*tmp));
     if(tmp == NULL) {
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     princ_comp(p) = tmp;
     princ_ncomp(p, len) = malloc(comp_len + 1);
     if (princ_ncomp(p, len) == NULL) {
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     memcpy (princ_ncomp(p, len), comp, comp_len);
@@ -591,7 +609,7 @@ build_principal(krb5_context context,
   
     p = calloc(1, sizeof(*p));
     if (p == NULL) {
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     princ_type(p) = KRB5_NT_PRINCIPAL;
@@ -599,7 +617,7 @@ build_principal(krb5_context context,
     princ_realm(p) = strdup(realm);
     if(p->realm == NULL){
        free(p);
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
   
@@ -675,12 +693,12 @@ krb5_copy_principal(krb5_context context,
 {
     krb5_principal p = malloc(sizeof(*p));
     if (p == NULL) {
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     if(copy_Principal(inprinc, p)) {
        free(p);
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     *outprinc = p;
@@ -706,6 +724,22 @@ krb5_principal_compare_any_realm(krb5_context context,
     return TRUE;
 }
 
+krb5_boolean KRB5_LIB_FUNCTION
+_krb5_principal_compare_PrincipalName(krb5_context context,
+                                     krb5_const_principal princ1,
+                                     PrincipalName *princ2)
+{
+    int i;
+    if (princ_num_comp(princ1) != princ2->name_string.len)
+       return FALSE;
+    for(i = 0; i < princ_num_comp(princ1); i++){
+       if(strcmp(princ_ncomp(princ1, i), princ2->name_string.val[i]) != 0)
+           return FALSE;
+    }
+    return TRUE;
+}
+
+
 /*
  * return TRUE iff princ1 == princ2
  */
@@ -909,7 +943,7 @@ krb5_425_conv_principal_ext2(krb5_context context,
 #endif
        if (passed) {
            if (inst == NULL) {
-               krb5_set_error_string (context, "malloc: out of memory");
+               krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
                return ENOMEM;
            }
            strlwr(inst);
@@ -1160,7 +1194,7 @@ krb5_524_conv_principal(krb5_context context,
        i = principal->name.name_string.val[1];
        break;
     default:
-       krb5_set_error_string (context,
+       krb5_set_error_message(context, KRB5_PARSE_MALFORMED,
                               "cannot convert a %d component principal",
                               principal->name.name_string.len);
        return KRB5_PARSE_MALFORMED;
@@ -1186,17 +1220,17 @@ krb5_524_conv_principal(krb5_context context,
     }
     
     if (strlcpy (name, n, aname_sz) >= aname_sz) {
-       krb5_set_error_string (context,
+       krb5_set_error_message(context, KRB5_PARSE_MALFORMED,
                               "too long name component to convert");
        return KRB5_PARSE_MALFORMED;
     }
     if (strlcpy (instance, i, aname_sz) >= aname_sz) {
-       krb5_set_error_string (context,
+       krb5_set_error_message(context, KRB5_PARSE_MALFORMED,
                               "too long instance component to convert");
        return KRB5_PARSE_MALFORMED;
     }
     if (strlcpy (realm, r, aname_sz) >= aname_sz) {
-       krb5_set_error_string (context,
+       krb5_set_error_message(context, KRB5_PARSE_MALFORMED,
                               "too long realm component to convert");
        return KRB5_PARSE_MALFORMED;
     }
@@ -1219,8 +1253,9 @@ krb5_sname_to_principal (krb5_context context,
     char **realms, *host = NULL;
        
     if(type != KRB5_NT_SRV_HST && type != KRB5_NT_UNKNOWN) {
-       krb5_set_error_string (context, "unsupported name type %d",
-                              type);
+       krb5_set_error_message(context, KRB5_SNAME_UNSUPP_NAMETYPE,
+                              "unsupported name type %d",
+                              (int)type);
        return KRB5_SNAME_UNSUPP_NAMETYPE;
     }
     if(hostname == NULL) {
@@ -1280,6 +1315,7 @@ krb5_parse_nametype(krb5_context context, const char *str, int32_t *nametype)
            return 0;
        }
     }
-    krb5_set_error_string(context, "Failed to find name type %s", str);
+    krb5_set_error_message(context, KRB5_PARSE_MALFORMED,
+                          "Failed to find name type %s", str);
     return KRB5_PARSE_MALFORMED;
 }
index c3f732201f3d9b271d5b3d0c3e2719dde3705666..26aa3f2d79e142e5c8e9259776330524af4a17ad 100644 (file)
@@ -33,7 +33,7 @@
 
 #include <krb5_locl.h>
 
-RCSID("$Id: rd_cred.c 20304 2007-04-11 11:15:05Z lha $");
+RCSID("$Id: rd_cred.c 23316 2008-06-23 04:32:32Z lha $");
 
 static krb5_error_code
 compare_addrs(krb5_context context,
@@ -49,7 +49,8 @@ compare_addrs(krb5_context context,
 
     krb5_print_address (a, a_str, sizeof(a_str), &len);
     krb5_print_address (b, b_str, sizeof(b_str), &len);
-    krb5_set_error_string(context, "%s: %s != %s", message, b_str, a_str);
+    krb5_set_error_message(context, KRB5KRB_AP_ERR_BADADDR,
+                          "%s: %s != %s", message, b_str, a_str);
     return KRB5KRB_AP_ERR_BADADDR;
 }
 
@@ -244,7 +245,7 @@ krb5_rd_cred(krb5_context context,
 
     if (*ret_creds == NULL) {
        ret = ENOMEM;
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message(context, ret, "malloc: out of memory");
        goto out;
     }
 
@@ -255,7 +256,7 @@ krb5_rd_cred(krb5_context context,
        creds = calloc(1, sizeof(*creds));
        if(creds == NULL) {
            ret = ENOMEM;
-           krb5_set_error_string (context, "malloc: out of memory");
+           krb5_set_error_message(context, ret, "malloc: out of memory");
            goto out;
        }
 
index e7646467afdb784984314154a7f0185340a9b9e8..9e50af539a19b958f343e3e1712f61a4ab6bd10d 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: rd_error.c 21057 2007-06-12 17:22:31Z lha $");
+RCSID("$Id: rd_error.c 23316 2008-06-23 04:32:32Z lha $");
 
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_rd_error(krb5_context context,
@@ -78,7 +78,7 @@ krb5_error_from_rd_error(krb5_context context,
 
     ret = error->error_code;
     if (error->e_text != NULL) {
-       krb5_set_error_string(context, "%s", *error->e_text);
+       krb5_set_error_message(context, ret, "%s", *error->e_text);
     } else {
        char clientname[256], servername[256];
 
@@ -91,28 +91,28 @@ krb5_error_from_rd_error(krb5_context context,
 
        switch (ret) {
        case KRB5KDC_ERR_NAME_EXP :
-           krb5_set_error_string(context, "Client %s%s%s expired",
-                                 creds ? "(" : "",
-                                 creds ? clientname : "",
-                                 creds ? ")" : "");
+           krb5_set_error_message(context, ret, "Client %s%s%s expired",
+                                  creds ? "(" : "",
+                                  creds ? clientname : "",
+                                  creds ? ")" : "");
            break;
        case KRB5KDC_ERR_SERVICE_EXP :
-           krb5_set_error_string(context, "Server %s%s%s expired",
-                                 creds ? "(" : "",
-                                 creds ? servername : "",
-                                 creds ? ")" : "");
+           krb5_set_error_message(context, ret, "Server %s%s%s expired",
+                                  creds ? "(" : "",
+                                  creds ? servername : "",
+                                  creds ? ")" : "");
            break;
        case KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN :
-           krb5_set_error_string(context, "Client %s%s%s unknown",
-                                 creds ? "(" : "",
-                                 creds ? clientname : "",
-                                 creds ? ")" : "");
+           krb5_set_error_message(context, ret, "Client %s%s%s unknown",
+                                  creds ? "(" : "",
+                                  creds ? clientname : "",
+                                  creds ? ")" : "");
            break;
        case KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN :
-           krb5_set_error_string(context, "Server %s%s%s unknown",
-                                 creds ? "(" : "",
-                                 creds ? servername : "",
-                                 creds ? ")" : "");
+           krb5_set_error_message(context, ret, "Server %s%s%s unknown",
+                                  creds ? "(" : "",
+                                  creds ? servername : "",
+                                  creds ? ")" : "");
            break;
        default :
            krb5_clear_error_string(context);
index 8c9b7bb441d7be3f2937211570f9c5b1d536991c..0e6e3d09afa0849410f89908c7c9789bb5239dd9 100644 (file)
@@ -33,7 +33,7 @@
 
 #include <krb5_locl.h>
 
-RCSID("$Id: rd_rep.c 17890 2006-08-21 09:19:22Z lha $");
+RCSID("$Id: rd_rep.c 23304 2008-06-23 03:29:56Z lha $");
 
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_rd_rep(krb5_context context,
@@ -79,7 +79,7 @@ krb5_rd_rep(krb5_context context,
     *repl = malloc(sizeof(**repl));
     if (*repl == NULL) {
        ret = ENOMEM;
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message(context, ret, "malloc: out of memory");
        goto out;
     }
     ret = krb5_decode_EncAPRepPart(context,
index 0f33b97164544c426797646172ea41ed5764d84b..ddf1f69ae44d02772360b8ec9e18140892e96223 100644 (file)
@@ -33,7 +33,7 @@
 
 #include <krb5_locl.h>
 
-RCSID("$Id: rd_req.c 22235 2007-12-08 21:52:07Z lha $");
+RCSID("$Id: rd_req.c 23415 2008-07-26 18:35:44Z lha $");
 
 static krb5_error_code
 decrypt_tkt_enc_part (krb5_context context,
@@ -133,7 +133,7 @@ static krb5_error_code
 check_transited(krb5_context context, Ticket *ticket, EncTicketPart *enc)
 {
     char **realms;
-    int num_realms;
+    unsigned int num_realms;
     krb5_error_code ret;
            
     /* 
@@ -389,11 +389,6 @@ krb5_verify_ap_req2(krb5_context context,
                                             t->ticket.crealm);
     if (ret) goto out;
 
-    /* save key */
-
-    ret = krb5_copy_keyblock(context, &t->ticket.key, &ac->keyblock);
-    if (ret) goto out;
-
     ret = decrypt_authenticator (context,
                                 &t->ticket.key,
                                 &ap_req->authenticator,
@@ -479,6 +474,10 @@ krb5_verify_ap_req2(krb5_context context,
        }
     }
 
+    /* save key */
+    ret = krb5_copy_keyblock(context, &t->ticket.key, &ac->keyblock);
+    if (ret) goto out;
+
     if (ap_req_options) {
        *ap_req_options = 0;
        if (ac->keytype != ETYPE_NULL)
@@ -533,7 +532,7 @@ krb5_rd_req_in_ctx_alloc(krb5_context context, krb5_rd_req_in_ctx *ctx)
 {
     *ctx = calloc(1, sizeof(**ctx));
     if (*ctx == NULL) {
-       krb5_set_error_string(context, "out of memory");
+       krb5_set_error_message(context, ENOMEM, "out of memory");
        return ENOMEM;
     }
     (*ctx)->check_pac = (context->flags & KRB5_CTX_F_CHECK_PAC) ? 1 : 0;
@@ -616,7 +615,7 @@ _krb5_rd_req_out_ctx_alloc(krb5_context context, krb5_rd_req_out_ctx *ctx)
 {
     *ctx = calloc(1, sizeof(**ctx));
     if (*ctx == NULL) {
-       krb5_set_error_string(context, "out of memory");
+       krb5_set_error_message(context, ENOMEM, "out of memory");
        return ENOMEM;
     }
     return 0;
@@ -805,9 +804,9 @@ krb5_rd_req_ctx(krb5_context context,
     }
     if (ap_req.ap_options.use_session_key &&
        (*auth_context)->keyblock == NULL) {
-       krb5_set_error_string(context, "krb5_rd_req: user to user auth "
-                             "without session key given");
        ret = KRB5KRB_AP_ERR_NOKEY;
+       krb5_set_error_message(context, ret, "krb5_rd_req: user to user auth "
+                              "without session key given");
        goto out;
     }
 
index 12894d96a95ead3cc20a14a584ff49d135c159a5..7639bfa2ce2269c987e4112e65158d159d49416c 100644 (file)
@@ -34,7 +34,7 @@
 #include "krb5_locl.h"
 #include <vis.h>
 
-RCSID("$Id: replay.c 17047 2006-04-10 17:13:49Z lha $");
+RCSID("$Id: replay.c 23467 2008-07-27 12:16:37Z lha $");
 
 struct krb5_rcache_data {
     char *name;
@@ -47,7 +47,7 @@ krb5_rc_resolve(krb5_context context,
 {
     id->name = strdup(name);
     if(id->name == NULL) {
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message(context, KRB5_RC_MALLOC, "malloc: out of memory");
        return KRB5_RC_MALLOC;
     }
     return 0;
@@ -60,13 +60,14 @@ krb5_rc_resolve_type(krb5_context context,
 {
     *id = NULL;
     if(strcmp(type, "FILE")) {
-       krb5_set_error_string (context, "replay cache type %s not supported",
-                              type);
+       krb5_set_error_message (context, KRB5_RC_TYPE_NOTFOUND,
+                               "replay cache type %s not supported",
+                               type);
        return KRB5_RC_TYPE_NOTFOUND;
     }
     *id = calloc(1, sizeof(**id));
     if(*id == NULL) {
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message(context, KRB5_RC_MALLOC, "malloc: out of memory");
        return KRB5_RC_MALLOC;
     }
     return 0;
@@ -82,7 +83,8 @@ krb5_rc_resolve_full(krb5_context context,
     *id = NULL;
 
     if(strncmp(string_name, "FILE:", 5)) {
-       krb5_set_error_string (context, "replay cache type %s not supported",
+       krb5_set_error_message(context, KRB5_RC_TYPE_NOTFOUND,
+                              "replay cache type %s not supported",
                               string_name);
        return KRB5_RC_TYPE_NOTFOUND;
     }
@@ -132,7 +134,7 @@ krb5_rc_initialize(krb5_context context,
 
     if(f == NULL) {
        ret = errno;
-       krb5_set_error_string (context, "open(%s): %s", id->name,
+       krb5_set_error_message(context, ret, "open(%s): %s", id->name,
                               strerror(ret));
        return ret;
     }
@@ -157,7 +159,7 @@ krb5_rc_destroy(krb5_context context,
 
     if(remove(id->name) < 0) {
        ret = errno;
-       krb5_set_error_string (context, "remove(%s): %s", id->name,
+       krb5_set_error_message(context, ret, "remove(%s): %s", id->name,
                               strerror(ret));
        return ret;
     }
@@ -204,10 +206,11 @@ krb5_rc_store(krb5_context context,
     f = fopen(id->name, "r");
     if(f == NULL) {
        ret = errno;
-       krb5_set_error_string (context, "open(%s): %s", id->name,
+       krb5_set_error_message(context, ret, "open(%s): %s", id->name,
                               strerror(ret));
        return ret;
     }
+    rk_cloexec_file(f);
     fread(&tmp, sizeof(ent), 1, f);
     t = ent.stamp - tmp.stamp;
     while(fread(&tmp, sizeof(ent), 1, f)){
@@ -222,13 +225,15 @@ krb5_rc_store(krb5_context context,
     if(ferror(f)){
        ret = errno;
        fclose(f);
-       krb5_set_error_string (context, "%s: %s", id->name, strerror(ret));
+       krb5_set_error_message(context, ret, "%s: %s",
+                              id->name, strerror(ret));
        return ret;
     }
     fclose(f);
     f = fopen(id->name, "a");
     if(f == NULL) {
-       krb5_set_error_string (context, "open(%s): %s", id->name,
+       krb5_set_error_message(context, KRB5_RC_IO_UNKNOWN,
+                              "open(%s): %s", id->name,
                               strerror(errno));
        return KRB5_RC_IO_UNKNOWN;
     }
@@ -288,7 +293,7 @@ krb5_get_server_rcache(krb5_context context,
     char *name;
 
     if(tmp == NULL) {
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     strvisx(tmp, piece->data, piece->length, VIS_WHITE | VIS_OCTAL);
@@ -299,7 +304,7 @@ krb5_get_server_rcache(krb5_context context,
 #endif
     free(tmp);
     if(name == NULL) {
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
 
index 2582a615c052b749f2be94547e137c0c76f3339a..1ddb5afd1f9067c96b47e6bb292cb5ed72271969 100644 (file)
@@ -32,8 +32,9 @@
  */
 
 #include "krb5_locl.h"
+#include "send_to_kdc_plugin.h"
 
-RCSID("$Id: send_to_kdc.c 21934 2007-08-27 14:21:04Z lha $");
+RCSID("$Id: send_to_kdc.c 23448 2008-07-27 12:09:22Z lha $");
 
 struct send_to_kdc {
     krb5_send_to_kdc_func func;
@@ -290,6 +291,7 @@ send_via_proxy (krb5_context context,
        s = socket (a->ai_family, a->ai_socktype, a->ai_protocol);
        if (s < 0)
            continue;
+       rk_cloexec(s);
        if (connect (s, a->ai_addr, a->ai_addrlen) < 0) {
            close (s);
            continue;
@@ -316,6 +318,46 @@ send_via_proxy (krb5_context context,
     return 1;
 }
 
+static krb5_error_code
+send_via_plugin(krb5_context context,
+               krb5_krbhst_info *hi,
+               time_t timeout,
+               const krb5_data *send_data,
+               krb5_data *receive)
+{
+    struct krb5_plugin *list = NULL, *e;
+    krb5_error_code ret;
+
+    ret = _krb5_plugin_find(context, PLUGIN_TYPE_DATA, KRB5_PLUGIN_SEND_TO_KDC, &list);
+    if(ret != 0 || list == NULL)
+       return KRB5_PLUGIN_NO_HANDLE;
+
+    for (e = list; e != NULL; e = _krb5_plugin_get_next(e)) {
+       krb5plugin_send_to_kdc_ftable *service;
+       void *ctx;
+
+       service = _krb5_plugin_get_symbol(e);
+       if (service->minor_version != 0)
+           continue;
+       
+       (*service->init)(context, &ctx);
+       ret = (*service->send_to_kdc)(context, ctx, hi, 
+                                     timeout, send_data, receive);
+       (*service->fini)(ctx);
+       if (ret == 0)
+           break;
+       if (ret != KRB5_PLUGIN_NO_HANDLE) {
+           krb5_set_error_message(context, ret,
+                                  "Plugin %s failed to lookup with error: %d", 
+                                  KRB5_PLUGIN_SEND_TO_KDC, ret);
+           break;
+       }
+    }
+    _krb5_plugin_free(list);
+    return KRB5_PLUGIN_NO_HANDLE;
+}
+
+
 /*
  * Send the data `send' to one host from `handle` and get back the reply
  * in `receive'.
@@ -343,12 +385,19 @@ krb5_sendto (krb5_context context,
                 struct send_to_kdc *s = context->send_to_kdc;
 
                 ret = (*s->func)(context, s->data, 
-                                 hi, send_data, receive);
+                                 hi, context->kdc_timeout, send_data, receive);
                 if (ret == 0 && receive->length != 0)
                     goto out;
                 continue;
             }
 
+            ret = send_via_plugin(context, hi, context->kdc_timeout,
+                                  send_data, receive);
+            if (ret == 0 && receive->length != 0)
+                goto out;
+            else if (ret != KRB5_PLUGIN_NO_HANDLE)
+                continue;
+
             if(hi->proto == KRB5_KRBHST_HTTP && context->http_proxy) {
                 if (send_via_proxy (context, hi, send_data, receive) == 0) {
                     ret = 0;
@@ -365,6 +414,7 @@ krb5_sendto (krb5_context context,
                 fd = socket (a->ai_family, a->ai_socktype, a->ai_protocol);
                 if (fd < 0)
                     continue;
+                rk_cloexec(fd);
                 if (connect (fd, a->ai_addr, a->ai_addrlen) < 0) {
                     close (fd);
                     continue;
@@ -439,7 +489,7 @@ krb5_set_send_to_kdc_func(krb5_context context,
 
     context->send_to_kdc = malloc(sizeof(*context->send_to_kdc));
     if (context->send_to_kdc == NULL) {
-       krb5_set_error_string(context, "Out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
 
@@ -460,7 +510,7 @@ krb5_sendto_ctx_alloc(krb5_context context, krb5_sendto_ctx *ctx)
 {
     *ctx = calloc(1, sizeof(**ctx));
     if (*ctx == NULL) {
-       krb5_set_error_string(context, "out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     return 0;
@@ -566,8 +616,8 @@ krb5_sendto_context(krb5_context context,
     if (handle)
        krb5_krbhst_free(context, handle);
     if (ret == KRB5_KDC_UNREACH)
-       krb5_set_error_string(context, 
-                             "unable to reach any KDC in realm %s", realm);
+       krb5_set_error_message(context, ret,
+                              "unable to reach any KDC in realm %s", realm);
     if (ret)
        krb5_data_free(receive);
     if (freectx)
diff --git a/source4/heimdal/lib/krb5/send_to_kdc_plugin.h b/source4/heimdal/lib/krb5/send_to_kdc_plugin.h
new file mode 100644 (file)
index 0000000..e0c2979
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2008 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden). 
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ *
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ */
+
+/* $Id$ */
+
+#ifndef HEIMDAL_KRB5_SEND_TO_KDC_PLUGIN_H
+#define HEIMDAL_KRB5_SEND_TO_KDC_PLUGIN_H 1
+
+#include <krb5.h>
+
+#define KRB5_PLUGIN_SEND_TO_KDC "send_to_kdc"
+
+typedef krb5_error_code
+(*krb5plugin_send_to_kdc_func)(krb5_context, 
+                              void *, 
+                              krb5_krbhst_info *,
+                              time_t timeout,
+                              const krb5_data *,
+                              krb5_data *);
+
+typedef struct krb5plugin_send_to_kdc_ftable {
+    int                        minor_version;
+    krb5_error_code    (*init)(krb5_context, void **);
+    void               (*fini)(void *);
+    krb5plugin_send_to_kdc_func send_to_kdc;
+} krb5plugin_send_to_kdc_ftable;
+
+#endif /* HEIMDAL_KRB5_SEND_TO_KDC_PLUGIN_H */
index 98040bc2e9d6c73065be182258d33dfb26697e37..55abf2ea7d8af3abc2ec29a131ea49b3af1b94d1 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: set_default_realm.c 13863 2004-05-25 21:46:46Z lha $");
+RCSID("$Id: set_default_realm.c 23309 2008-06-23 03:30:41Z lha $");
 
 /*
  * Convert the simple string `s' into a NULL-terminated and freshly allocated 
@@ -46,13 +46,13 @@ string_to_list (krb5_context context, const char *s, krb5_realm **list)
 
     *list = malloc (2 * sizeof(**list));
     if (*list == NULL) {
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     (*list)[0] = strdup (s);
     if ((*list)[0] == NULL) {
        free (*list);
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     (*list)[1] = NULL;
index 7eb4d32fad57fd75d8403acfdb0f1506de272a25..5eff64e12db1b6929fc42887928bf66630f32f24 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: ticket.c 19544 2006-12-28 20:49:18Z lha $");
+RCSID("$Id: ticket.c 23310 2008-06-23 03:30:49Z lha $");
 
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_free_ticket(krb5_context context,
@@ -57,7 +57,7 @@ krb5_copy_ticket(krb5_context context,
     *to = NULL;
     tmp = malloc(sizeof(*tmp));
     if(tmp == NULL) {
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     if((ret = copy_EncTicketPart(&from->ticket, &tmp->ticket))){
@@ -118,9 +118,10 @@ find_type_in_ad(krb5_context context,
     int i;
 
     if (level > 9) {
-       krb5_set_error_string(context, "Authorization data nested deeper "
-                             "then %d levels, stop searching", level);
        ret = ENOENT; /* XXX */
+       krb5_set_error_message(context, ret, 
+                              "Authorization data nested deeper "
+                              "then %d levels, stop searching", level);
        goto out;
     }
 
@@ -133,7 +134,7 @@ find_type_in_ad(krb5_context context,
        if (!*found && ad->val[i].ad_type == type) {
            ret = der_copy_octet_string(&ad->val[i].ad_data, data);
            if (ret) {
-               krb5_set_error_string(context, "malloc - out of memory");
+               krb5_set_error_message(context, ret, "malloc: out of memory");
                goto out;
            }
            *found = TRUE;
@@ -147,8 +148,8 @@ find_type_in_ad(krb5_context context,
                                           &child,
                                           NULL);
            if (ret) {
-               krb5_set_error_string(context, "Failed to decode "
-                                     "IF_RELEVANT with %d", ret);
+               krb5_set_error_message(context, ret, "Failed to decode "
+                                      "IF_RELEVANT with %d", (int)ret);
                goto out;
            }
            ret = find_type_in_ad(context, type, data, found, FALSE,
@@ -167,8 +168,8 @@ find_type_in_ad(krb5_context context,
                                      &child,
                                      NULL);
            if (ret) {
-               krb5_set_error_string(context, "Failed to decode "
-                                     "AD_KDCIssued with %d", ret);
+               krb5_set_error_message(context, ret, "Failed to decode "
+                                      "AD_KDCIssued with %d", ret);
                goto out;
            }
            if (failp) {
@@ -211,17 +212,17 @@ find_type_in_ad(krb5_context context,
        case KRB5_AUTHDATA_AND_OR:
            if (!failp)
                break;
-           krb5_set_error_string(context, "Authorization data contains "
-                                 "AND-OR element that is unknown to the "
-                                 "application");
            ret = ENOENT; /* XXX */
+           krb5_set_error_message(context, ret, "Authorization data contains "
+                                  "AND-OR element that is unknown to the "
+                                  "application");
            goto out;
        default:
            if (!failp)
                break;
-           krb5_set_error_string(context, "Authorization data contains "
-                                 "unknown type (%d) ", ad->val[i].ad_type);
            ret = ENOENT; /* XXX */
+           krb5_set_error_message(context, ret, "Authorization data contains "
+                                  "unknown type (%d) ", ad->val[i].ad_type);
            goto out;
        }
     }
@@ -255,7 +256,8 @@ krb5_ticket_get_authorization_data_type(krb5_context context,
 
     ad = ticket->ticket.authorization_data;
     if (ticket->ticket.authorization_data == NULL) {
-       krb5_set_error_string(context, "Ticket have not authorization data");
+       krb5_set_error_message(context, ENOENT,
+                              "Ticket have not authorization data");
        return ENOENT; /* XXX */
     }
 
@@ -264,8 +266,8 @@ krb5_ticket_get_authorization_data_type(krb5_context context,
     if (ret)
        return ret;
     if (!found) {
-       krb5_set_error_string(context, "Ticket have not authorization "
-                         "data of type %d", type);
+       krb5_set_error_message(context, ENOENT, "Ticket have not "
+                              "authorization data of type %d", type);
        return ENOENT; /* XXX */
     }
     return 0;
index 4cd992d48f27386f05772b1f280cacd43dc84054..46f88a86cd9474f1337287c31cc35dd9e1bd0151 100644 (file)
 
 #include "krb5_locl.h"
 
-RCSID("$Id: time.c 14308 2004-10-13 17:57:11Z lha $");
+RCSID("$Id: time.c 23260 2008-06-21 15:22:37Z lha $");
 
-/*
+/**
  * Set the absolute time that the caller knows the kdc has so the
  * kerberos library can calculate the relative diffrence beteen the
  * KDC time and local system time.
+ *
+ * @param context Keberos 5 context.
+ * @param sec The applications new of "now" in seconds
+ * @param usec The applications new of "now" in micro seconds
+
+ * @return Kerberos 5 error code, see krb5_get_error_message().
+ *
+ * @ingroup krb5
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
@@ -51,12 +59,21 @@ krb5_set_real_time (krb5_context context,
     gettimeofday(&tv, NULL);
 
     context->kdc_sec_offset = sec - tv.tv_sec;
-    context->kdc_usec_offset = usec - tv.tv_usec;
 
-    if (context->kdc_usec_offset < 0) {
-       context->kdc_sec_offset--;
-       context->kdc_usec_offset += 1000000;
-    }
+    /**
+     * If the caller passes in a negative usec, its assumed to be
+     * unknown and the function will use the current time usec.
+     */
+    if (usec >= 0) {
+       context->kdc_usec_offset = usec - tv.tv_usec;
+
+       if (context->kdc_usec_offset < 0) {
+           context->kdc_sec_offset--;
+           context->kdc_usec_offset += 1000000;
+       }
+    } else 
+       context->kdc_usec_offset = tv.tv_usec;
+
     return 0;
 }
 
index 9b67ecc04f26181e9859a23fd64441b17be9bdd6..58b00a4b7a805c7b7f4c06d89ef53cecf9d2824a 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: transited.c 21745 2007-07-31 16:11:25Z lha $");
+RCSID("$Id: transited.c 23316 2008-06-23 04:32:32Z lha $");
 
 /* this is an attempt at one of the most horrible `compression'
    schemes that has ever been invented; it's so amazingly brain-dead
@@ -88,7 +88,7 @@ make_path(krb5_context context, struct tr_realm *r,
                break;
            tmp = calloc(1, sizeof(*tmp));
            if(tmp == NULL){
-               krb5_set_error_string (context, "malloc: out of memory");
+               krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
                return ENOMEM;
            }
            tmp->next = path;
@@ -96,7 +96,7 @@ make_path(krb5_context context, struct tr_realm *r,
            path->realm = strdup(p);
            if(path->realm == NULL){
                r->next = path; /* XXX */
-               krb5_set_error_string (context, "malloc: out of memory");
+               krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
                return ENOMEM;;
            }
        }
@@ -112,7 +112,7 @@ make_path(krb5_context context, struct tr_realm *r,
                break;
            tmp = calloc(1, sizeof(*tmp));
            if(tmp == NULL){
-               krb5_set_error_string (context, "malloc: out of memory");
+               krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
                return ENOMEM;
            }
            tmp->next = path;
@@ -120,7 +120,7 @@ make_path(krb5_context context, struct tr_realm *r,
            path->realm = malloc(p - from + 1);
            if(path->realm == NULL){
                r->next = path; /* XXX */
-               krb5_set_error_string (context, "malloc: out of memory");
+               krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
                return ENOMEM;
            }
            memcpy(path->realm, from, p - from);
@@ -186,7 +186,7 @@ expand_realms(krb5_context context,
            tmp = realloc(r->realm, len);
            if(tmp == NULL){
                free_realms(realms);
-               krb5_set_error_string (context, "malloc: out of memory");
+               krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
                return ENOMEM;
            }
            r->realm = tmp;
@@ -200,7 +200,7 @@ expand_realms(krb5_context context,
            tmp = malloc(len);
            if(tmp == NULL){
                free_realms(realms);
-               krb5_set_error_string (context, "malloc: out of memory");
+               krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
                return ENOMEM;
            }
            strlcpy(tmp, prev_realm, len);
@@ -286,7 +286,7 @@ decode_realms(krb5_context context,
        if(tr[i] == ','){
            tmp = malloc(tr + i - start + 1);
            if(tmp == NULL){
-               krb5_set_error_string (context, "malloc: out of memory");
+               krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
                return ENOMEM;
            }
            memcpy(tmp, start, tr + i - start);
@@ -294,7 +294,7 @@ decode_realms(krb5_context context,
            r = make_realm(tmp);
            if(r == NULL){
                free_realms(*realms);
-               krb5_set_error_string (context, "malloc: out of memory");
+               krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
                return ENOMEM;
            }
            *realms = append_realm(*realms, r);
@@ -304,7 +304,7 @@ decode_realms(krb5_context context,
     tmp = malloc(tr + i - start + 1);
     if(tmp == NULL){
        free(*realms);
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     memcpy(tmp, start, tr + i - start);
@@ -312,7 +312,7 @@ decode_realms(krb5_context context,
     r = make_realm(tmp);
     if(r == NULL){
        free_realms(*realms);
-       krb5_set_error_string (context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     *realms = append_realm(*realms, r);
@@ -323,7 +323,7 @@ decode_realms(krb5_context context,
 
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_domain_x500_decode(krb5_context context,
-                       krb5_data tr, char ***realms, int *num_realms, 
+                       krb5_data tr, char ***realms, unsigned int *num_realms, 
                        const char *client_realm, const char *server_realm)
 {
     struct tr_realm *r = NULL;
@@ -385,11 +385,12 @@ krb5_domain_x500_decode(krb5_context context,
 }
 
 krb5_error_code KRB5_LIB_FUNCTION
-krb5_domain_x500_encode(char **realms, int num_realms, krb5_data *encoding)
+krb5_domain_x500_encode(char **realms, unsigned int num_realms, 
+                       krb5_data *encoding)
 {
     char *s = NULL;
     int len = 0;
-    int i;
+    unsigned int i;
     krb5_data_zero(encoding);
     if (num_realms == 0)
        return 0;
@@ -420,7 +421,7 @@ krb5_check_transited(krb5_context context,
                     krb5_const_realm client_realm,
                     krb5_const_realm server_realm,
                     krb5_realm *realms,
-                    int num_realms,
+                    unsigned int num_realms,
                     int *bad_realm)
 {
     char **tr_realms;
@@ -442,8 +443,9 @@ krb5_check_transited(krb5_context context,
        }
        if(p == NULL || *p == NULL) {
            krb5_config_free_strings(tr_realms);
-           krb5_set_error_string (context, "no transit through realm %s",
-                                  realms[i]);
+           krb5_set_error_message (context, KRB5KRB_AP_ERR_ILL_CR_TKT,
+                                   "no transit through realm %s",
+                                   realms[i]);
            if(bad_realm)
                *bad_realm = i;
            return KRB5KRB_AP_ERR_ILL_CR_TKT;
@@ -456,7 +458,7 @@ krb5_check_transited(krb5_context context,
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_check_transited_realms(krb5_context context,
                            const char *const *realms, 
-                           int num_realms, 
+                           unsigned int num_realms, 
                            int *bad_realm)
 {
     int i;
@@ -472,9 +474,9 @@ krb5_check_transited_realms(krb5_context context,
        char **p;
        for(p = bad_realms; *p; p++)
            if(strcmp(*p, realms[i]) == 0) {
-               krb5_set_error_string (context, "no transit through realm %s",
-                                      *p);
                ret = KRB5KRB_AP_ERR_ILL_CR_TKT;
+               krb5_set_error_message (context, ret,
+                                       "no transit through realm %s", *p);
                if(bad_realm)
                    *bad_realm = i;
                break;
index 37b1e35dd18833adcce07bcf12dcfe75a58ff29a..55570c44dd35d25b1fe57cdafc621cd1925f8a4b 100644 (file)
@@ -32,7 +32,7 @@
  */
 
 #include "krb5_locl.h"
-RCSID("$Id: v4_glue.c 22071 2007-11-14 20:04:50Z lha $");
+RCSID("$Id: v4_glue.c 23452 2008-07-27 12:10:54Z lha $");
 
 #include "krb5-v4compat.h"
 
@@ -147,7 +147,7 @@ write_v4_cc(krb5_context context, const char *tkfile,
 
     ret = get_krb4_cc_name(tkfile, &path);
     if (ret) {
-       krb5_set_error_string(context, 
+       krb5_set_error_message(context, ret, 
                              "krb5_krb_tf_setup: failed getting "
                              "the krb4 credentials cache name"); 
        return ret;
@@ -156,15 +156,16 @@ write_v4_cc(krb5_context context, const char *tkfile,
     fd = open(path, O_WRONLY|O_CREAT, 0600);
     if (fd < 0) {
        ret = errno;
-       krb5_set_error_string(context, 
+       krb5_set_error_message(context, ret, 
                              "krb5_krb_tf_setup: error opening file %s", 
                              path);
        free(path);
        return ret;
     }
+    rk_cloexec(fd);
 
     if (fstat(fd, &sb) != 0 || !S_ISREG(sb.st_mode)) {
-       krb5_set_error_string(context, 
+       krb5_set_error_message(context, ret, 
                              "krb5_krb_tf_setup: tktfile %s is not a file",
                              path);
        free(path);
@@ -179,9 +180,9 @@ write_v4_cc(krb5_context context, const char *tkfile,
            break;
     }
     if (i == KRB5_TF_LCK_RETRY_COUNT) {
-       krb5_set_error_string(context,
-                             "krb5_krb_tf_setup: failed to lock %s",
-                             path);
+       krb5_set_error_message(context, KRB5_FCC_PERM,
+                              "krb5_krb_tf_setup: failed to lock %s",
+                              path);
        free(path);
        close(fd);
        return KRB5_FCC_PERM;
@@ -191,9 +192,9 @@ write_v4_cc(krb5_context context, const char *tkfile,
        ret = ftruncate(fd, 0);
        if (ret < 0) {
            flock(fd, LOCK_UN);
-           krb5_set_error_string(context,
-                                 "krb5_krb_tf_setup: failed to truncate %s",
-                                 path);
+           krb5_set_error_message(context, KRB5_FCC_PERM,
+                                  "krb5_krb_tf_setup: failed to truncate %s",
+                                  path);
            free(path);
            close(fd);
            return KRB5_FCC_PERM;
@@ -291,7 +292,7 @@ _krb5_krb_dest_tkt(krb5_context context, const char *tkfile)
 
     ret = get_krb4_cc_name(tkfile, &path);
     if (ret) {
-       krb5_set_error_string(context, 
+       krb5_set_error_message(context, ret, 
                              "krb5_krb_tf_setup: failed getting "
                              "the krb4 credentials cache name"); 
        return ret;
@@ -299,7 +300,7 @@ _krb5_krb_dest_tkt(krb5_context context, const char *tkfile)
 
     if (unlink(path) < 0) {
        ret = errno;
-       krb5_set_error_string(context, 
+       krb5_set_error_message(context, ret, 
                              "krb5_krb_dest_tkt failed removing the cache "
                              "with error %s", strerror(ret));
     }
@@ -421,7 +422,7 @@ _krb5_krb_create_ticket(krb5_context context,
 
     sp = krb5_storage_emem();
     if (sp == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_BE);
@@ -448,7 +449,7 @@ _krb5_krb_create_ticket(krb5_context context,
  error:
     krb5_storage_free(sp);
     if (ret)
-       krb5_set_error_string(context, "Failed to encode kerberos 4 ticket");
+       krb5_set_error_message(context, ret, "Failed to encode kerberos 4 ticket");
 
     return ret;
 }
@@ -477,7 +478,7 @@ _krb5_krb_create_ciph(krb5_context context,
 
     sp = krb5_storage_emem();
     if (sp == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_BE);
@@ -507,7 +508,7 @@ _krb5_krb_create_ciph(krb5_context context,
  error:
     krb5_storage_free(sp);
     if (ret)
-       krb5_set_error_string(context, "Failed to encode kerberos 4 ticket");
+       krb5_set_error_message(context, ret, "Failed to encode kerberos 4 ticket");
 
     return ret;
 }
@@ -535,7 +536,7 @@ _krb5_krb_create_auth_reply(krb5_context context,
 
     sp = krb5_storage_emem();
     if (sp == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_BE);
@@ -559,7 +560,7 @@ _krb5_krb_create_auth_reply(krb5_context context,
  error:
     krb5_storage_free(sp);
     if (ret)
-       krb5_set_error_string(context, "Failed to encode kerberos 4 ticket");
+       krb5_set_error_message(context, ret, "Failed to encode kerberos 4 ticket");
        
     return ret;
 }
@@ -590,7 +591,7 @@ _krb5_krb_cr_err_reply(krb5_context context,
 
     sp = krb5_storage_emem();
     if (sp == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
        return ENOMEM;
     }
     krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_BE);
@@ -610,7 +611,7 @@ _krb5_krb_cr_err_reply(krb5_context context,
  error:
     krb5_storage_free(sp);
     if (ret)
-       krb5_set_error_string(context, "Failed to encode kerberos 4 error");
+       krb5_set_error_message(context, ret, "Failed to encode kerberos 4 error");
        
     return 0;
 }
@@ -661,7 +662,7 @@ _krb5_krb_decomp_ticket(krb5_context context,
     sp = krb5_storage_from_data(&ticket);
     if (sp == NULL) {
        krb5_data_free(&ticket);
-       krb5_set_error_string(context, "alloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "alloc: out of memory");
        return ENOMEM;
     }
 
@@ -720,7 +721,7 @@ _krb5_krb_decomp_ticket(krb5_context context,
            *sinstance = NULL;
        }
        _krb5_krb_free_auth_data(context, ad);
-       krb5_set_error_string(context, "Failed to decode v4 ticket");
+       krb5_set_error_message(context, ret, "Failed to decode v4 ticket");
     }
     return ret;
 }
@@ -769,7 +770,7 @@ _krb5_krb_rd_req(krb5_context context,
 
     sp = krb5_storage_from_data(authent);
     if (sp == NULL) {
-       krb5_set_error_string(context, "alloc: out of memory");
+       krb5_set_error_message(context, ENOMEM, "alloc: out of memory");
        return ENOMEM;
     }
 
@@ -777,19 +778,19 @@ _krb5_krb_rd_req(krb5_context context,
 
     ret = krb5_ret_int8(sp, &pvno);
     if (ret) {
-       krb5_set_error_string(context, "Failed reading v4 pvno");
+       krb5_set_error_message(context, ret, "Failed reading v4 pvno");
        goto error;
     }
 
     if (pvno != KRB_PROT_VERSION) {
        ret = KRB4ET_RD_AP_VERSION;
-       krb5_set_error_string(context, "Failed v4 pvno not 4");
+       krb5_set_error_message(context, ret, "Failed v4 pvno not 4");
        goto error;
     }
 
     ret = krb5_ret_int8(sp, &type);
     if (ret) {
-       krb5_set_error_string(context, "Failed readin v4 type");
+       krb5_set_error_message(context, ret, "Failed readin v4 type");
        goto error;
     }
 
@@ -798,7 +799,7 @@ _krb5_krb_rd_req(krb5_context context,
     
     if(type != AUTH_MSG_APPL_REQUEST && type != AUTH_MSG_APPL_REQUEST_MUTUAL) {
        ret = KRB4ET_RD_AP_MSG_TYPE;
-       krb5_set_error_string(context, "Not a valid v4 request type");
+       krb5_set_error_message(context, ret, "Not a valid v4 request type");
        goto error;
     }
 
@@ -811,7 +812,7 @@ _krb5_krb_rd_req(krb5_context context,
     size = krb5_storage_read(sp, ticket.data, ticket.length);
     if (size != ticket.length) {
        ret = KRB4ET_INTK_PROT;
-       krb5_set_error_string(context, "Failed reading v4 ticket");
+       krb5_set_error_message(context, ret, "Failed reading v4 ticket");
        goto error;
     }
 
@@ -826,7 +827,7 @@ _krb5_krb_rd_req(krb5_context context,
     size = krb5_storage_read(sp, eaut.data, eaut.length);
     if (size != eaut.length) {
        ret = KRB4ET_INTK_PROT;
-       krb5_set_error_string(context, "Failed reading v4 authenticator");
+       krb5_set_error_message(context, ret, "Failed reading v4 authenticator");
        goto error;
     }
 
@@ -840,7 +841,7 @@ _krb5_krb_rd_req(krb5_context context,
     sp = krb5_storage_from_data(&aut);
     if (sp == NULL) {
        ret = ENOMEM;
-       krb5_set_error_string(context, "alloc: out of memory");
+       krb5_set_error_message(context, ret, "alloc: out of memory");
        goto error;
     }
 
@@ -860,14 +861,14 @@ _krb5_krb_rd_req(krb5_context context,
     if (strcmp(ad->pname, r_name) != 0 ||
        strcmp(ad->pinst, r_instance) != 0 ||
        strcmp(ad->prealm, r_realm) != 0) {
-       krb5_set_error_string(context, "v4 principal mismatch");
        ret = KRB4ET_RD_AP_INCON;
+       krb5_set_error_message(context, ret, "v4 principal mismatch");
        goto error;
     }
     
     if (from_addr && ad->address && from_addr != ad->address) {
-       krb5_set_error_string(context, "v4 bad address in ticket");
        ret = KRB4ET_RD_AP_BADD;
+       krb5_set_error_message(context, ret, "v4 bad address in ticket");
        goto error;
     }
 
@@ -875,7 +876,7 @@ _krb5_krb_rd_req(krb5_context context,
     delta_t = abs((int)(tv.tv_sec - r_time_sec));
     if (delta_t > CLOCK_SKEW) {
         ret = KRB4ET_RD_AP_TIME;
-       krb5_set_error_string(context, "v4 clock skew");
+       krb5_set_error_message(context, ret, "v4 clock skew");
        goto error;
     }
 
@@ -885,13 +886,13 @@ _krb5_krb_rd_req(krb5_context context,
     
     if ((tkt_age < 0) && (-tkt_age > CLOCK_SKEW)) {
         ret = KRB4ET_RD_AP_NYV;
-       krb5_set_error_string(context, "v4 clock skew for expiration");
+       krb5_set_error_message(context, ret, "v4 clock skew for expiration");
        goto error;
     }
 
     if (tv.tv_sec > _krb5_krb_life_to_time(ad->time_sec, ad->life)) {
        ret = KRB4ET_RD_AP_EXP;
-       krb5_set_error_string(context, "v4 ticket expired");
+       krb5_set_error_message(context, ret, "v4 ticket expired");
        goto error;
     }
 
index 85f143b8b4b6ee5fc29cd1052b09aa36917f57a0..97a6cc9e0a73d15524d9961b328084f57a336ed9 100644 (file)
@@ -34,7 +34,7 @@
 #include "krb5_locl.h"
 #include <err.h>
 
-RCSID("$Id: warn.c 19086 2006-11-21 08:06:40Z lha $");
+RCSID("$Id: warn.c 23206 2008-05-29 02:13:41Z lha $");
 
 static krb5_error_code _warnerr(krb5_context context, int do_errtext, 
         krb5_error_code code, int level, const char *fmt, va_list ap)
@@ -47,7 +47,7 @@ _warnerr(krb5_context context, int do_errtext,
     char xfmt[7] = "";
     const char *args[2], **arg;
     char *msg = NULL;
-    char *err_str = NULL;
+    const char *err_str = NULL;
     
     args[0] = args[1] = NULL;
     arg = args;
@@ -65,7 +65,7 @@ _warnerr(krb5_context context, int do_errtext,
 
        strlcat(xfmt, "%s", sizeof(xfmt));
 
-       err_str = krb5_get_error_string(context);
+       err_str = krb5_get_error_message(context, code);
        if (err_str != NULL) {
            *arg++ = err_str;
        } else {
@@ -82,7 +82,7 @@ _warnerr(krb5_context context, int do_errtext,
     else
        warnx(xfmt, args[0], args[1]);
     free(msg);
-    free(err_str);
+    krb5_free_error_message(context, err_str);
     return 0;
 }
 
index f3dccfaca165886f48f06edb9fa3a34011553a38..d3309824b52c3c2cc3c5ad6bdb80561741da9e77 100644 (file)
@@ -33,7 +33,7 @@
 
 #include <config.h>
 
-RCSID("$Id: ntlm.c 22370 2007-12-28 16:12:01Z lha $");
+RCSID("$Id: ntlm.c 23169 2008-05-22 02:52:07Z lha $");
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -68,7 +68,7 @@ RCSID("$Id: ntlm.c 22370 2007-12-28 16:12:01Z lha $");
  * Heimdal to implement and GSS-API mechanism. There is also support
  * in the KDC to do remote digest authenticiation, this to allow
  * services to authenticate users w/o direct access to the users ntlm
- * hashes (same as Kerberos arcfour enctype hashes).
+ * hashes (same as Kerberos arcfour enctype keys).
  *
  * More information about the NTLM protocol can found here
  * http://davenport.sourceforge.net/ntlm.html .
@@ -876,7 +876,7 @@ splitandenc(unsigned char *hash,
     ((unsigned char*)key)[7] = (hash[6] << 1);
 
     DES_set_odd_parity(&key);
-    DES_set_key(&key, &sched);
+    DES_set_key_unchecked(&key, &sched);
     DES_ecb_encrypt((DES_cblock *)challange, (DES_cblock *)answer, &sched, 1);
     memset(&sched, 0, sizeof(sched));
     memset(key, 0, sizeof(key));
index c445bfa361b260cd01bf5f8a27aaee6ab198e82f..81fd12729695cee5241776d67d46ffc48adfaba9 100644 (file)
@@ -33,7 +33,7 @@
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
-RCSID("$Id: dumpdata.c 21005 2007-06-08 01:54:35Z lha $");
+RCSID("$Id: dumpdata.c 23412 2008-07-26 18:34:23Z lha $");
 #endif
 
 #include <unistd.h>
@@ -55,3 +55,45 @@ rk_dumpdata (const char *filename, const void *buf, size_t size)
     net_write(fd, buf, size);
     close(fd);
 }
+
+/*
+ * Read all data from a filename, care about errors.
+ */
+
+int ROKEN_LIB_FUNCTION
+rk_undumpdata(const char *filename, void **buf, size_t *size)
+{
+    struct stat sb;
+    int fd, ret;
+    ssize_t sret;
+
+    *buf = NULL;
+
+    fd = open(filename, O_RDONLY, 0);
+    if (fd < 0)
+       return errno;
+    if (fstat(fd, &sb) != 0){
+       ret = errno;
+       goto out;
+    }
+    *buf = malloc(sb.st_size);
+    if (*buf == NULL) {
+       ret = ENOMEM;
+       goto out;
+    }
+    *size = sb.st_size;
+
+    sret = net_read(fd, *buf, *size);
+    if (sret < 0)
+       ret = errno;
+    else if (sret != *size) {
+       ret = EINVAL;
+       free(*buf);
+       *buf = NULL;
+    } else
+       ret = 0;
+
+ out:
+    close(fd);
+    return ret;
+}
index fcae879279512a8105f8a78cd650fa0d5c526c4c..2f1232d3e7f866feb618aaa91e4526d2b412bce8 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
-/* $Id: err.hin,v 1.18 2005/04/12 11:28:38 lha Exp $ */
+/* $Id: err.hin 14773 2005-04-12 11:29:18Z lha $ */
 
 #ifndef __ERR_H__
 #define __ERR_H__
index a8778fda57d23e018f9ffe2402969d6e1f20cbfa..bf064e8aae9f76d8dc846f72b0faacede9a3c8b0 100644 (file)
@@ -45,7 +45,7 @@
 
 #include <assert.h>
 
-RCSID("$Id: resolve.c 19869 2007-01-12 16:03:14Z lha $");
+RCSID("$Id: resolve.c 22873 2008-04-07 18:50:39Z lha $");
 
 #ifdef _AIX /* AIX have broken res_nsearch() in 5.1 (5.0 also ?) */
 #undef HAVE_RES_NSEARCH
@@ -128,7 +128,8 @@ parse_record(const unsigned char *data, const unsigned char *end_data,
             const unsigned char **pp, struct resource_record **ret_rr)
 {
     struct resource_record *rr;
-    int type, class, ttl, size;
+    int type, class, ttl;
+    unsigned size;
     int status;
     char host[MAXDNAME];
     const unsigned char *p = *pp;
index b835e880a2498fb1339c5a8a881e284f78ec4f10..f943202c45db6bac15096dd80ba07810dcf83d48 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
-/* $Id: roken-common.h 20867 2007-06-03 21:00:45Z lha $ */
+/* $Id: roken-common.h 23468 2008-07-27 12:16:56Z lha $ */
 
 #ifndef __ROKEN_COMMON_H__
 #define __ROKEN_COMMON_H__
@@ -400,6 +400,19 @@ rk_strpoolfree(struct rk_strpool *);
 void ROKEN_LIB_FUNCTION
 rk_dumpdata (const char *, const void *, size_t);
 
+int ROKEN_LIB_FUNCTION
+rk_undumpdata (const char *, void **, size_t *);
+
+void ROKEN_LIB_FUNCTION
+rk_xfree (void *);
+
+void ROKEN_LIB_FUNCTION
+rk_cloexec(int);
+
+void ROKEN_LIB_FUNCTION
+rk_cloexec_file(FILE *);
+
+
 ROKEN_CPP_END
 
 #endif /* __ROKEN_COMMON_H__ */
index 82473d7053cf7e9b53ca520f59da17ff31b1c001..cf2ee9ed7bdb854363632fdcbbc6679940e0780d 100644 (file)
@@ -32,7 +32,7 @@
  * SUCH DAMAGE.
  */
 
-/* $Id: roken.h.in,v 1.182 2006/10/19 16:35:16 lha Exp $ */
+/* $Id: roken.h.in 18612 2006-10-19 16:35:16Z lha $ */
 
 #include <stdio.h>
 #include <stdlib.h>
index b7a6f3ceff1d7026460cf0c775ba017cf959f108..224870b00af1b656f808f7b32b3e6efb051f1c54 100644 (file)
@@ -1,5 +1,5 @@
 /*     $NetBSD: vis.h,v 1.11 1999/11/25 16:55:50 wennmach Exp $        */
-/*     $Id: vis.hin,v 1.7 2006/12/15 11:53:09 lha Exp $        */
+/*     $Id: vis.hin 19341 2006-12-15 11:53:09Z lha $   */
 
 /*-
  * Copyright (c) 1990, 1993
index 0beba76384000a08217475fbb2520b201d447ea3..7c28fdae1f186e6396ebb38154f7d106aa5bbcda 100644 (file)
 #endif
 #include "windlocl.h"
 #include <stdlib.h>
-#include <strings.h>
+#include <string.h>
 #include <errno.h>
 
-RCSID("$Id: stringprep.c 22593 2008-02-12 11:58:01Z lha $");
+RCSID("$Id: stringprep.c 23063 2008-04-21 11:18:04Z lha $");
 
 /**
  * Process a input UCS4 string according a string-prep profile.
index c49e80522ebff79ab851a9ad5737ebc717bcfe49..544e0fe00d28f504ed5b0041bb90a09c8e62a914 100644 (file)
 #endif
 #include "windlocl.h"
 
-RCSID("$Id: utf8.c 22572 2008-02-05 20:22:39Z lha $");
+RCSID("$Id: utf8.c 23246 2008-06-01 22:29:04Z lha $");
+
+static int
+utf8toutf32(const unsigned char **pp, uint32_t *out)
+{
+    const unsigned char *p = *pp;
+    unsigned c = *p;
+
+    if (c & 0x80) {
+       if ((c & 0xE0) == 0xC0) {
+           const unsigned c2 = *++p;
+           if ((c2 & 0xC0) == 0x80) {
+               *out =  ((c  & 0x1F) << 6)
+                   | (c2 & 0x3F);
+           } else {
+               return WIND_ERR_INVALID_UTF8;
+           }
+       } else if ((c & 0xF0) == 0xE0) {
+           const unsigned c2 = *++p;
+           if ((c2 & 0xC0) == 0x80) {
+               const unsigned c3 = *++p;
+               if ((c3 & 0xC0) == 0x80) {
+                   *out =   ((c  & 0x0F) << 12)
+                       | ((c2 & 0x3F) << 6)
+                       |  (c3 & 0x3F);
+               } else {
+                   return WIND_ERR_INVALID_UTF8;
+               }
+           } else {
+               return WIND_ERR_INVALID_UTF8;
+           }
+       } else if ((c & 0xF8) == 0xF0) {
+           const unsigned c2 = *++p;
+           if ((c2 & 0xC0) == 0x80) {
+               const unsigned c3 = *++p;
+               if ((c3 & 0xC0) == 0x80) {
+                   const unsigned c4 = *++p;
+                   if ((c4 & 0xC0) == 0x80) {
+                       *out =   ((c  & 0x07) << 18)
+                           | ((c2 & 0x3F) << 12)
+                           | ((c3 & 0x3F) <<  6)
+                           |  (c4 & 0x3F);
+                   } else {
+                       return WIND_ERR_INVALID_UTF8;
+                   }
+               } else {
+                   return WIND_ERR_INVALID_UTF8;
+               }
+           } else {
+               return WIND_ERR_INVALID_UTF8;
+           }
+       } else {
+           return WIND_ERR_INVALID_UTF8;
+       }
+    } else {
+       *out = c;
+    }
+
+    *pp = p;
+
+    return 0;
+}
 
 /**
  * Convert an UTF-8 string to an UCS4 string.
@@ -59,60 +120,15 @@ wind_utf8ucs4(const char *in, uint32_t *out, size_t *out_len)
 {
     const unsigned char *p;
     size_t o = 0;
+    int ret;
 
     for (p = (const unsigned char *)in; *p != '\0'; ++p) {
-       unsigned c = *p;
        uint32_t u;
 
-       if (c & 0x80) {
-           if ((c & 0xE0) == 0xC0) {
-               const unsigned c2 = *++p;
-               if ((c2 & 0xC0) == 0x80) {
-                   u =  ((c  & 0x1F) << 6)
-                       | (c2 & 0x3F);
-               } else {
-                   return WIND_ERR_INVALID_UTF8;
-               }
-           } else if ((c & 0xF0) == 0xE0) {
-               const unsigned c2 = *++p;
-               if ((c2 & 0xC0) == 0x80) {
-                   const unsigned c3 = *++p;
-                   if ((c3 & 0xC0) == 0x80) {
-                       u =   ((c  & 0x0F) << 12)
-                           | ((c2 & 0x3F) << 6)
-                           |  (c3 & 0x3F);
-                   } else {
-                       return WIND_ERR_INVALID_UTF8;
-                   }
-               } else {
-                   return WIND_ERR_INVALID_UTF8;
-               }
-           } else if ((c & 0xF8) == 0xF0) {
-               const unsigned c2 = *++p;
-               if ((c2 & 0xC0) == 0x80) {
-                   const unsigned c3 = *++p;
-                   if ((c3 & 0xC0) == 0x80) {
-                       const unsigned c4 = *++p;
-                       if ((c4 & 0xC0) == 0x80) {
-                           u =   ((c  & 0x07) << 18)
-                               | ((c2 & 0x3F) << 12)
-                               | ((c3 & 0x3F) <<  6)
-                               |  (c4 & 0x3F);
-                       } else {
-                           return WIND_ERR_INVALID_UTF8;
-                       }
-                   } else {
-                       return WIND_ERR_INVALID_UTF8;
-                   }
-               } else {
-                   return WIND_ERR_INVALID_UTF8;
-               }
-           } else {
-               return WIND_ERR_INVALID_UTF8;
-           }
-       } else {
-           u = c;
-       }
+       ret = utf8toutf32(&p, &u);
+       if (ret)
+           return ret;
+
        if (out) {
            if (o >= *out_len)
                return WIND_ERR_OVERRUN;
@@ -364,6 +380,67 @@ wind_ucs2write(const uint16_t *in, size_t in_len, unsigned int *flags,
 }
 
 
+/**
+ * Convert an UTF-8 string to an UCS2 string.
+ *
+ * @param in an UTF-8 string to convert.
+ * @param out the resulting UCS2 strint, must be at least
+ * wind_utf8ucs2_length() long.  If out is NULL, the function will
+ * calculate the needed space for the out variable (just like
+ * wind_utf8ucs2_length()).
+ * @param out_len before processing out_len should be the length of
+ * the out variable, after processing it will be the length of the out
+ * string.
+ * 
+ * @return returns 0 on success, an wind error code otherwise
+ * @ingroup wind
+ */
+
+int
+wind_utf8ucs2(const char *in, uint16_t *out, size_t *out_len)
+{
+    const unsigned char *p;
+    size_t o = 0;
+    int ret;
+
+    for (p = (const unsigned char *)in; *p != '\0'; ++p) {
+       uint32_t u;
+
+       ret = utf8toutf32(&p, &u);
+       if (ret)
+           return ret;
+
+       if (u & 0xffff0000)
+           return WIND_ERR_NOT_UTF16;
+
+       if (out) {
+           if (o >= *out_len)
+               return WIND_ERR_OVERRUN;
+           out[o] = u;
+       }
+       o++;
+    }
+    *out_len = o;
+    return 0;
+}
+
+/**
+ * Calculate the length of from converting a UTF-8 string to a UCS2
+ * string.
+ *
+ * @param in an UTF-8 string to convert.
+ * @param out_len the length of the resulting UCS4 string.
+ * 
+ * @return returns 0 on success, an wind error code otherwise
+ * @ingroup wind
+ */
+
+int
+wind_utf8ucs2_length(const char *in, size_t *out_len)
+{
+    return wind_utf8ucs2(in, NULL, out_len);
+}
+
 /**
  * Convert an UCS2 string to a UTF-8 string.
  *
index 6921b619f5341a47745c2347e1d64b8aef513ab4..3120e87da5ceb4ef8c7ab7befb2a10a0a6d3b3e2 100644 (file)
  * SUCH DAMAGE. 
  */
 
-/* $Id: wind.h 22595 2008-02-12 11:59:05Z lha $ */
+/* $Id: wind.h 23233 2008-06-01 22:25:25Z lha $ */
 
 #ifndef _WIND_H_
 #define _WIND_H_
 
 #include <stddef.h>
-#include <stdint.h>
+#include <krb5-types.h>
 
 #include <wind_err.h>
 
@@ -58,9 +58,9 @@ typedef unsigned int wind_profile_flags;
 #define WIND_RW_BE     2
 #define WIND_RW_BOM    4
 
-int wind_stringprep(const unsigned *in, size_t in_len,
-                   unsigned *out, size_t *out_len,
-                   wind_profile_flags flags);
+int wind_stringprep(const uint32_t *, size_t,
+                   uint32_t *, size_t *,
+                   wind_profile_flags);
 int wind_profile(const char *, wind_profile_flags *);
 
 int wind_punycode_label_toascii(const uint32_t *, size_t,
@@ -72,6 +72,9 @@ int wind_utf8ucs4_length(const char *, size_t *);
 int wind_ucs4utf8(const uint32_t *, size_t, char *, size_t *);
 int wind_ucs4utf8_length(const uint32_t *, size_t, size_t *);
 
+int wind_utf8ucs2(const char *, uint16_t *, size_t *);
+int wind_utf8ucs2_length(const char *, size_t *);
+
 int wind_ucs2utf8(const uint16_t *, size_t, char *, size_t *);
 int wind_ucs2utf8_length(const uint16_t *, size_t, size_t *);
 
index 025c402790bfa95698c2bf3a8e232ecb6b909065..65bdff992fb6a7f089b69f16335a1b87328fbb53 100644 (file)
@@ -3,7 +3,7 @@
 #
 # This might look like a com_err file, but is not
 #
-id "$Id: wind_err.et 22559 2008-02-03 16:35:07Z lha $"
+id "$Id: wind_err.et 23233 2008-06-01 22:25:25Z lha $"
 
 error_table wind
 
@@ -18,5 +18,6 @@ error_code INVALID_UTF8,      "Invalid UTF-8 combination in string"
 error_code INVALID_UTF16,      "Invalid UTF-16 combination in string"
 error_code INVALID_UTF32,      "Invalid UTF-32 combination in string"
 error_code NO_BOM,             "No byte order mark (BOM) in string"
+error_code NOT_UTF16,          "Code can't be represented as UTF-16"
 
 end
index 02e8c46481c15377dc58af54015274e55633c3f8..009a4ae94afdecc4c9bc48300d49cc15fc5af771 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE. 
  */
 
-/* $Id: windlocl.h 22582 2008-02-11 20:43:50Z lha $ */
+/* $Id: windlocl.h 23187 2008-05-23 15:04:07Z lha $ */
 
 #ifndef _WINDLOCL_H_
 #define _WINDLOCL_H_
@@ -40,6 +40,8 @@
 #include <config.h>
 #endif
 
+#include <krb5-types.h>
+
 #include "wind.h"
 #include "wind_err.h"