s4:heimdal: import lorikeet-heimdal-200911122202 (commit 9291fd2d101f3eecec550178634f...
authorAndrew Bartlett <abartlet@samba.org>
Thu, 12 Nov 2009 23:51:14 +0000 (10:51 +1100)
committerAndrew Bartlett <abartlet@samba.org>
Fri, 13 Nov 2009 12:19:05 +0000 (23:19 +1100)
59 files changed:
source4/heimdal/README
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/windc.c
source4/heimdal/kdc/windc_plugin.h
source4/heimdal/kuser/kinit.c
source4/heimdal/lib/asn1/asn1parse.y
source4/heimdal/lib/asn1/der_get.c
source4/heimdal/lib/asn1/gen.c
source4/heimdal/lib/asn1/gen_copy.c
source4/heimdal/lib/asn1/gen_decode.c
source4/heimdal/lib/asn1/gen_encode.c
source4/heimdal/lib/asn1/gen_free.c
source4/heimdal/lib/asn1/gen_length.c
source4/heimdal/lib/asn1/rfc2459.asn1
source4/heimdal/lib/asn1/symbol.h
source4/heimdal/lib/com_err/com_right.h
source4/heimdal/lib/com_err/error.c
source4/heimdal/lib/gssapi/krb5/init_sec_context.c
source4/heimdal/lib/hcrypto/evp-cc.c
source4/heimdal/lib/hcrypto/hmac.c
source4/heimdal/lib/hcrypto/rand-unix.c
source4/heimdal/lib/hdb/ext.c
source4/heimdal/lib/hdb/hdb.c
source4/heimdal/lib/hdb/hdb.h
source4/heimdal/lib/hx509/ca.c
source4/heimdal/lib/hx509/cert.c
source4/heimdal/lib/hx509/error.c
source4/heimdal/lib/hx509/file.c
source4/heimdal/lib/hx509/keyset.c
source4/heimdal/lib/hx509/ks_file.c
source4/heimdal/lib/hx509/lock.c
source4/heimdal/lib/hx509/name.c
source4/heimdal/lib/hx509/revoke.c
source4/heimdal/lib/hx509/sel.c
source4/heimdal/lib/krb5/auth_context.c
source4/heimdal/lib/krb5/build_auth.c
source4/heimdal/lib/krb5/context.c
source4/heimdal/lib/krb5/crypto.c
source4/heimdal/lib/krb5/error_string.c
source4/heimdal/lib/krb5/fcache.c
source4/heimdal/lib/krb5/generate_seq_number.c
source4/heimdal/lib/krb5/generate_subkey.c
source4/heimdal/lib/krb5/get_cred.c
source4/heimdal/lib/krb5/get_for_creds.c
source4/heimdal/lib/krb5/krb5_locl.h
source4/heimdal/lib/krb5/mk_error.c
source4/heimdal/lib/krb5/mk_req_ext.c
source4/heimdal/lib/krb5/pkinit.c
source4/heimdal/lib/krb5/principal.c
source4/heimdal/lib/krb5/replay.c
source4/heimdal/lib/krb5/warn.c
source4/heimdal/lib/roken/rkpty.c
source4/heimdal/lib/roken/roken.h.in
source4/heimdal/lib/wind/normalize.c
source4/heimdal/lib/wind/stringprep.c

index f130698597c86861fce9d59cf180d2a553377f8e..d2c4eba8ce67fe7fd347524c1fe9b4c29240746e 100644 (file)
@@ -1,12 +1,12 @@
 
 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.
+For information how to install see <http://www.h5l.org/compile.html>.
+
+There are 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.
+the manual on how we prefer them: <heimdal-bugs@h5l.org>.
 
 For more information see the web-page at
 <http://www.h5l.org/> or the mailing lists:
index 0a9d4a5ca4c6b8353a2dbfaa807472238963cfe3..fb88aa9f8fbf526ef00374b0d66ce5d0bfb0d5e7 100644 (file)
@@ -261,6 +261,7 @@ _kdc_encode_reply(krb5_context context,
                  krb5_enctype etype,
                  int skvno, const EncryptionKey *skey,
                  int ckvno, const EncryptionKey *reply_key,
+                 int rk_is_subkey,
                  const char **e_text,
                  krb5_data *reply)
 {
@@ -272,8 +273,9 @@ _kdc_encode_reply(krb5_context context,
 
     ASN1_MALLOC_ENCODE(EncTicketPart, buf, buf_size, et, &len, ret);
     if(ret) {
-       kdc_log(context, config, 0, "Failed to encode ticket: %s",
-               krb5_get_err_text(context, ret));
+       const char *msg = krb5_get_error_message(context, ret);
+       kdc_log(context, config, 0, "Failed to encode ticket: %s", msg);
+       krb5_free_error_message(context, msg);
        return ret;
     }
     if(buf_size != len) {
@@ -286,8 +288,9 @@ _kdc_encode_reply(krb5_context context,
     ret = krb5_crypto_init(context, skey, etype, &crypto);
     if (ret) {
        free(buf);
-       kdc_log(context, config, 0, "krb5_crypto_init failed: %s",
-               krb5_get_err_text(context, ret));
+       const char *msg = krb5_get_error_message(context, ret);
+       kdc_log(context, config, 0, "krb5_crypto_init failed: %s", msg);
+       krb5_free_error_message(context, msg);
        return ret;
     }
 
@@ -301,8 +304,9 @@ _kdc_encode_reply(krb5_context context,
     free(buf);
     krb5_crypto_destroy(context, crypto);
     if(ret) {
-       kdc_log(context, config, 0, "Failed to encrypt data: %s",
-               krb5_get_err_text(context, ret));
+       const char *msg = krb5_get_error_message(context, ret);
+       kdc_log(context, config, 0, "Failed to encrypt data: %s", msg);
+       krb5_free_error_message(context, msg);
        return ret;
     }
 
@@ -311,8 +315,9 @@ _kdc_encode_reply(krb5_context context,
     else
        ASN1_MALLOC_ENCODE(EncTGSRepPart, buf, buf_size, ek, &len, ret);
     if(ret) {
-       kdc_log(context, config, 0, "Failed to encode KDC-REP: %s",
-               krb5_get_err_text(context, ret));
+       const char *msg = krb5_get_error_message(context, ret);
+       kdc_log(context, config, 0, "Failed to encode KDC-REP: %s", msg);
+       krb5_free_error_message(context, msg);
        return ret;
     }
     if(buf_size != len) {
@@ -323,9 +328,10 @@ _kdc_encode_reply(krb5_context context,
     }
     ret = krb5_crypto_init(context, reply_key, 0, &crypto);
     if (ret) {
+       const char *msg = krb5_get_error_message(context, ret);
        free(buf);
-       kdc_log(context, config, 0, "krb5_crypto_init failed: %s",
-               krb5_get_err_text(context, ret));
+       kdc_log(context, config, 0, "krb5_crypto_init failed: %s", msg);
+       krb5_free_error_message(context, msg);
        return ret;
     }
     if(rep->msg_type == krb_as_rep) {
@@ -341,7 +347,7 @@ _kdc_encode_reply(krb5_context context,
     } else {
        krb5_encrypt_EncryptedData(context,
                                   crypto,
-                                  KRB5_KU_TGS_REP_ENC_PART_SESSION,
+                                  rk_is_subkey ? KRB5_KU_TGS_REP_ENC_PART_SUB_KEY : KRB5_KU_TGS_REP_ENC_PART_SESSION,
                                   buf,
                                   len,
                                   ckvno,
@@ -351,8 +357,9 @@ _kdc_encode_reply(krb5_context context,
     }
     krb5_crypto_destroy(context, crypto);
     if(ret) {
-       kdc_log(context, config, 0, "Failed to encode KDC-REP: %s",
-               krb5_get_err_text(context, ret));
+       const char *msg = krb5_get_error_message(context, ret);
+       kdc_log(context, config, 0, "Failed to encode KDC-REP: %s", msg);
+       krb5_free_error_message(context, msg);
        return ret;
     }
     if(buf_size != len) {
@@ -980,8 +987,9 @@ _kdc_as_rep(krb5_context context,
     ret = _kdc_db_fetch(context, config, client_princ,
                        HDB_F_GET_CLIENT | flags, &clientdb, &client);
     if(ret){
-       kdc_log(context, config, 0, "UNKNOWN -- %s: %s", client_name,
-               krb5_get_err_text(context, ret));
+       const char *msg = krb5_get_error_message(context, ret);
+       kdc_log(context, config, 0, "UNKNOWN -- %s: %s", client_name, msg);
+       krb5_free_error_message(context, msg);
        ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
        goto out;
     }
@@ -990,8 +998,9 @@ _kdc_as_rep(krb5_context context,
                        HDB_F_GET_SERVER|HDB_F_GET_KRBTGT,
                        NULL, &server);
     if(ret){
-       kdc_log(context, config, 0, "UNKNOWN -- %s: %s", server_name,
-               krb5_get_err_text(context, ret));
+       const char *msg = krb5_get_error_message(context, ret);
+       kdc_log(context, config, 0, "UNKNOWN -- %s: %s", server_name, msg);
+       krb5_free_error_message(context, msg);
        ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
        goto out;
     }
@@ -1135,8 +1144,9 @@ _kdc_as_rep(krb5_context context,
        try_next_key:
            ret = krb5_crypto_init(context, &pa_key->key, 0, &crypto);
            if (ret) {
-               kdc_log(context, config, 0, "krb5_crypto_init failed: %s",
-                       krb5_get_err_text(context, ret));
+               const char *msg = krb5_get_error_message(context, ret);
+               kdc_log(context, config, 0, "krb5_crypto_init failed: %s", msg);
+               krb5_free_error_message(context, msg);
                free_EncryptedData(&enc_data);
                continue;
            }
@@ -1154,6 +1164,8 @@ _kdc_as_rep(krb5_context context,
             */
            if(ret){
                krb5_error_code ret2;
+               const char *msg = krb5_get_error_message(context, ret);
+
                ret2 = krb5_enctype_to_string(context,
                                              pa_key->key.keytype, &str);
                if (ret2)
@@ -1161,9 +1173,8 @@ _kdc_as_rep(krb5_context context,
                kdc_log(context, config, 5,
                        "Failed to decrypt PA-DATA -- %s "
                        "(enctype %s) error %s",
-                       client_name,
-                       str ? str : "unknown enctype",
-                       krb5_get_err_text(context, ret));
+                       client_name, str ? str : "unknown enctype", msg);
+               krb5_free_error_message(context, msg);
                free(str);
 
                if(hdb_next_enctype2key(context, &client->entry,
@@ -1757,7 +1768,7 @@ _kdc_as_rep(krb5_context context,
     ret = _kdc_encode_reply(context, config,
                            &rep, &et, &ek, setype, server->entry.kvno,
                            &skey->key, client->entry.kvno,
-                           reply_key, &e_text, reply);
+                           reply_key, 0, &e_text, reply);
     free_EncTicketPart(&et);
     free_EncKDCRepPart(&ek);
     if (ret)
index c3b0aaa89e23cc88998938b65aaca1f0a9a793af..4f587cf1b631230fb2a042975aa8d30af855134a 100644 (file)
@@ -671,6 +671,8 @@ tgs_make_reply(krb5_context context,
               KDC_REQ_BODY *b,
               krb5_const_principal tgt_name,
               const EncTicketPart *tgt,
+              const krb5_keyblock *replykey,
+              int rk_is_subkey,
               const EncryptionKey *serverkey,
               const krb5_keyblock *sessionkey,
               krb5_kvno kvno,
@@ -823,10 +825,14 @@ tgs_make_reply(krb5_context context,
        unsigned int i = 0;
 
        /* XXX check authdata */
+
        if (et.authorization_data == NULL) {
-           ret = ENOMEM;
-           krb5_set_error_message(context, ret, "malloc: out of memory");
-           goto out;
+           et.authorization_data = calloc(1, sizeof(*et.authorization_data));
+           if (et.authorization_data == NULL) {
+               ret = ENOMEM;
+               krb5_set_error_message(context, ret, "malloc: out of memory");
+               goto out;
+           }
        }
        for(i = 0; i < auth_data->len ; i++) {
            ret = add_AuthorizationData(et.authorization_data, &auth_data->val[i]);
@@ -927,7 +933,8 @@ tgs_make_reply(krb5_context context,
     ret = _kdc_encode_reply(context, config,
                            &rep, &et, &ek, et.key.keytype,
                            kvno,
-                           serverkey, 0, &tgt->key, e_text, reply);
+                           serverkey, 0, replykey, rk_is_subkey,
+                           e_text, reply);
     if (is_weak)
        krb5_enctype_disable(context, et.key.keytype);
 
@@ -988,8 +995,9 @@ 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",
-               krb5_get_err_text(context, ret));
+       const char *msg = krb5_get_error_message(context, ret);
+       kdc_log(context, config, 0, "Failed to encode KDC-REQ-BODY: %s", msg);
+       krb5_free_error_message(context, msg);
        goto out;
     }
     if(buf_size != len) {
@@ -1001,9 +1009,10 @@ tgs_check_authenticator(krb5_context context,
     }
     ret = krb5_crypto_init(context, key, 0, &crypto);
     if (ret) {
+       const char *msg = krb5_get_error_message(context, ret);
        free(buf);
-       kdc_log(context, config, 0, "krb5_crypto_init failed: %s",
-               krb5_get_err_text(context, ret));
+       kdc_log(context, config, 0, "krb5_crypto_init failed: %s", msg);
+       krb5_free_error_message(context, msg);
        goto out;
     }
     ret = krb5_verify_checksum(context,
@@ -1015,9 +1024,10 @@ tgs_check_authenticator(krb5_context context,
     free(buf);
     krb5_crypto_destroy(context, crypto);
     if(ret){
+       const char *msg = krb5_get_error_message(context, ret);
        kdc_log(context, config, 0,
-               "Failed to verify authenticator checksum: %s",
-               krb5_get_err_text(context, ret));
+               "Failed to verify authenticator checksum: %s", msg);
+       krb5_free_error_message(context, msg);
     }
 out:
     free_Authenticator(auth);
@@ -1077,7 +1087,9 @@ tgs_parse_request(krb5_context context,
                  const struct sockaddr *from_addr,
                  time_t **csec,
                  int **cusec,
-                 AuthorizationData **auth_data)
+                 AuthorizationData **auth_data,
+                 krb5_keyblock **replykey,
+                 int *rk_is_subkey)
 {
     krb5_ap_req ap_req;
     krb5_error_code ret;
@@ -1087,16 +1099,20 @@ tgs_parse_request(krb5_context context,
     krb5_flags verify_ap_req_flags;
     krb5_crypto crypto;
     Key *tkey;
+    krb5_keyblock *subkey = NULL;
+    unsigned usage;
 
     *auth_data = NULL;
     *csec  = NULL;
     *cusec = NULL;
+    *replykey = NULL;
 
     memset(&ap_req, 0, sizeof(ap_req));
     ret = krb5_decode_ap_req(context, &tgs_req->padata_value, &ap_req);
     if(ret){
-       kdc_log(context, config, 0, "Failed to decode AP-REQ: %s",
-               krb5_get_err_text(context, ret));
+       const char *msg = krb5_get_error_message(context, ret);
+       kdc_log(context, config, 0, "Failed to decode AP-REQ: %s", msg);
+       krb5_free_error_message(context, msg);
        goto out;
     }
 
@@ -1115,14 +1131,15 @@ tgs_parse_request(krb5_context context,
     ret = _kdc_db_fetch(context, config, princ, HDB_F_GET_KRBTGT, NULL, krbtgt);
 
     if(ret) {
+       const char *msg = krb5_get_error_message(context, ret);
        char *p;
        ret = krb5_unparse_name(context, princ, &p);
        if (ret != 0)
            p = "<unparse_name failed>";
        krb5_free_principal(context, princ);
        kdc_log(context, config, 0,
-               "Ticket-granting ticket not found in database: %s: %s",
-               p, krb5_get_err_text(context, ret));
+               "Ticket-granting ticket not found in database: %s: %s", msg);
+       krb5_free_error_message(context, msg);
        if (ret == 0)
            free(p);
        ret = KRB5KRB_AP_ERR_NOT_US;
@@ -1184,8 +1201,9 @@ tgs_parse_request(krb5_context context,
                        
     krb5_free_principal(context, princ);
     if(ret) {
-       kdc_log(context, config, 0, "Failed to verify AP-REQ: %s",
-               krb5_get_err_text(context, ret));
+       const char *msg = krb5_get_error_message(context, ret);
+       kdc_log(context, config, 0, "Failed to verify AP-REQ: %s", msg);
+       krb5_free_error_message(context, msg);
        goto out;
     }
 
@@ -1219,41 +1237,49 @@ tgs_parse_request(krb5_context context,
        goto out;
     }
 
-    if (b->enc_authorization_data) {
-       unsigned usage = KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY;
-       krb5_keyblock *subkey;
-       krb5_data ad;
+    usage = KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY;
+    *rk_is_subkey = 1;
 
-       ret = krb5_auth_con_getremotesubkey(context, ac, &subkey);
-       if(ret){
-           krb5_auth_con_free(context, ac);
-           kdc_log(context, config, 0, "Failed to get remote subkey: %s",
-                   krb5_get_err_text(context, ret));
-           goto out;
-       }
-       if(subkey == NULL){
-           usage = KRB5_KU_TGS_REQ_AUTH_DAT_SESSION;
-           ret = krb5_auth_con_getkey(context, ac, &subkey);
-           if(ret) {
-               krb5_auth_con_free(context, ac);
-               kdc_log(context, config, 0, "Failed to get session key: %s",
-                       krb5_get_err_text(context, ret));
-               goto out;
-           }
-       }
-       if(subkey == NULL){
+    ret = krb5_auth_con_getremotesubkey(context, ac, &subkey);
+    if(ret){
+       const char *msg = krb5_get_error_message(context, ret);
+       krb5_auth_con_free(context, ac);
+       kdc_log(context, config, 0, "Failed to get remote subkey: %s", msg);
+       krb5_free_error_message(context, msg);
+       goto out;
+    }
+    if(subkey == NULL){
+       usage = KRB5_KU_TGS_REQ_AUTH_DAT_SESSION;
+       *rk_is_subkey = 0;
+
+       ret = krb5_auth_con_getkey(context, ac, &subkey);
+       if(ret) {
+           const char *msg = krb5_get_error_message(context, ret);
            krb5_auth_con_free(context, ac);
-           kdc_log(context, config, 0,
-                   "Failed to get key for enc-authorization-data");
-           ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */
+           kdc_log(context, config, 0, "Failed to get session key: %s", msg);
+           krb5_free_error_message(context, msg);
            goto out;
        }
+    }
+    if(subkey == NULL){
+       krb5_auth_con_free(context, ac);
+       kdc_log(context, config, 0,
+               "Failed to get key for enc-authorization-data");
+       ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */
+       goto out;
+    }
+
+    *replykey = subkey;
+
+    if (b->enc_authorization_data) {
+       krb5_data ad;
+
        ret = krb5_crypto_init(context, subkey, 0, &crypto);
-       krb5_free_keyblock(context, subkey);
        if (ret) {
+           const char *msg = krb5_get_error_message(context, ret);
            krb5_auth_con_free(context, ac);
-           kdc_log(context, config, 0, "krb5_crypto_init failed: %s",
-                   krb5_get_err_text(context, ret));
+           kdc_log(context, config, 0, "krb5_crypto_init failed: %s", msg);
+           krb5_free_error_message(context, msg);
            goto out;
        }
        ret = krb5_decrypt_EncryptedData (context,
@@ -1377,6 +1403,8 @@ tgs_build_reply(krb5_context context,
                KDC_REQ_BODY *b,
                hdb_entry_ex *krbtgt,
                krb5_enctype krbtgt_etype,
+               const krb5_keyblock *replykey,
+               int rk_is_subkey,
                krb5_ticket *ticket,
                krb5_data *reply,
                const char *from,
@@ -1495,7 +1523,7 @@ server_lookup:
                        NULL, &server);
 
     if(ret){
-       const char *new_rlm;
+       const char *new_rlm, *msg;
        Realm req_rlm;
        krb5_realm *realms;
 
@@ -1543,9 +1571,10 @@ server_lookup:
            }
            krb5_free_host_realm(context, realms);
        }
+       msg = krb5_get_error_message(context, ret);
        kdc_log(context, config, 0,
-               "Server not found in database: %s: %s", spn,
-               krb5_get_err_text(context, ret));
+               "Server not found in database: %s: %s", spn, msg);
+       krb5_free_error_message(context, msg);
        if (ret == HDB_ERR_NOENTRY)
            ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
        goto out;
@@ -1554,7 +1583,7 @@ server_lookup:
     ret = _kdc_db_fetch(context, config, cp, HDB_F_GET_CLIENT | HDB_F_CANON,
                        &clientdb, &client);
     if(ret) {
-       const char *krbtgt_realm;
+       const char *krbtgt_realm, *msg;
 
        /*
         * If the client belongs to the same realm as our krbtgt, it
@@ -1574,8 +1603,9 @@ server_lookup:
            goto out;
        }
        
-       kdc_log(context, config, 1, "Client not found in database: %s: %s",
-               cpn, krb5_get_err_text(context, ret));
+       msg = krb5_get_error_message(context, ret);
+       kdc_log(context, config, 1, "Client not found in database: %s", msg);
+       krb5_free_error_message(context, msg);
     }
 
     /*
@@ -1656,9 +1686,11 @@ server_lookup:
                    client, server, ekey, &tkey->key,
                    tgt, &rspac, &signedpath);
     if (ret) {
+       const char *msg = krb5_get_error_message(context, 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));
+               spn, cpn, from, msg);
+       krb5_free_error_message(context, msg);
        goto out;
     }
 
@@ -1671,9 +1703,11 @@ server_lookup:
                               &spp,
                               &signedpath);
     if (ret) {
+       const char *msg = krb5_get_error_message(context, 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));
+               spn, cpn, from, msg);
+       krb5_free_error_message(context, msg);
        goto out;
     }
 
@@ -1709,10 +1743,11 @@ server_lookup:
 
            ret = krb5_crypto_init(context, &tgt->key, 0, &crypto);
            if (ret) {
+               const char *msg = krb5_get_error_message(context, ret);
                free_PA_S4U2Self(&self);
                krb5_data_free(&datack);
-               kdc_log(context, config, 0, "krb5_crypto_init failed: %s",
-                       krb5_get_err_text(context, ret));
+               kdc_log(context, config, 0, "krb5_crypto_init failed: %s", msg);
+               krb5_free_error_message(context, msg);
                goto out;
            }
 
@@ -1725,10 +1760,11 @@ server_lookup:
            krb5_data_free(&datack);
            krb5_crypto_destroy(context, crypto);
            if (ret) {
+               const char *msg = krb5_get_error_message(context, ret);
                free_PA_S4U2Self(&self);
                kdc_log(context, config, 0,
-                       "krb5_verify_checksum failed for S4U2Self: %s",
-                       krb5_get_err_text(context, ret));
+                       "krb5_verify_checksum failed for S4U2Self: %s", msg);
+               krb5_free_error_message(context, msg);
                goto out;
            }
 
@@ -1866,11 +1902,13 @@ server_lookup:
        if (ret == 0 && !ad_signedpath)
            ret = KRB5KDC_ERR_BADOPTION;
        if (ret) {
+           const char *msg = krb5_get_error_message(context, ret);
            kdc_log(context, config, 0,
                    "KRB5SignedPath check from service %s failed "
                    "for delegation to %s for client %s "
                    "from %s failed with %s",
-                   spn, str, cpn, from, krb5_get_err_text(context, ret));
+                   spn, str, cpn, from, msg);
+           krb5_free_error_message(context, msg);
            free(str);
            goto out;
        }
@@ -1950,6 +1988,8 @@ server_lookup:
                         b,
                         client_principal,
                         tgt,
+                        replykey,
+                        rk_is_subkey,
                         ekey,
                         &sessionkey,
                         kvno,
@@ -2016,6 +2056,8 @@ _kdc_tgs_rep(krb5_context context,
     const char *e_text = NULL;
     krb5_enctype krbtgt_etype = ETYPE_NULL;
 
+    krb5_keyblock *replykey = NULL;
+    int rk_is_subkey = 0;
     time_t *csec = NULL;
     int *cusec = NULL;
 
@@ -2043,7 +2085,9 @@ _kdc_tgs_rep(krb5_context context,
                            &e_text,
                            from, from_addr,
                            &csec, &cusec,
-                           &auth_data);
+                           &auth_data,
+                           &replykey,
+                           &rk_is_subkey);
     if (ret) {
        kdc_log(context, config, 0,
                "Failed parsing TGS-REQ from %s", from);
@@ -2056,6 +2100,8 @@ _kdc_tgs_rep(krb5_context context,
                          &req->req_body,
                          krbtgt,
                          krbtgt_etype,
+                         replykey,
+                         rk_is_subkey,
                          ticket,
                          data,
                          from,
@@ -2076,6 +2122,8 @@ _kdc_tgs_rep(krb5_context context,
     }
 
 out:
+    if (replykey)
+       krb5_free_keyblock(context, replykey);
     if(ret && data->data == NULL){
        krb5_mk_error(context,
                      ret,
index 8f7f3a27fb0d71c46dab9eb30727496a7b807b87..eb757bb5786bcdc4876f10ca80ee6b17fc373af7 100644 (file)
@@ -143,7 +143,6 @@ build_certificate(krb5_context context,
                  krb5_principal principal,
                  krb5_data *certificate)
 {
-    hx509_context hxctx = NULL;
     hx509_ca_tbs tbs = NULL;
     hx509_env env = NULL;
     hx509_cert cert = NULL;
@@ -155,11 +154,7 @@ build_certificate(krb5_context context,
        return EINVAL;
     }
 
-    ret = hx509_context_init(&hxctx);
-    if (ret)
-       goto out;
-
-    ret = hx509_env_add(hxctx, &env, "principal-name",
+    ret = hx509_env_add(context->hx509ctx, &env, "principal-name",
                        krb5_principal_get_comp_string(context, principal, 0));
     if (ret)
        goto out;
@@ -168,14 +163,14 @@ build_certificate(krb5_context context,
        hx509_certs certs;
        hx509_query *q;
 
-       ret = hx509_certs_init(hxctx, config->kx509_ca, 0,
+       ret = hx509_certs_init(context->hx509ctx, config->kx509_ca, 0,
                               NULL, &certs);
        if (ret) {
            kdc_log(context, config, 0, "Failed to load CA %s",
                    config->kx509_ca);
            goto out;
        }
-       ret = hx509_query_alloc(hxctx, &q);
+       ret = hx509_query_alloc(context->hx509ctx, &q);
        if (ret) {
            hx509_certs_free(&certs);
            goto out;
@@ -184,8 +179,8 @@ build_certificate(krb5_context context,
        hx509_query_match_option(q, HX509_QUERY_OPTION_PRIVATE_KEY);
        hx509_query_match_option(q, HX509_QUERY_OPTION_KU_KEYCERTSIGN);
 
-       ret = hx509_certs_find(hxctx, certs, q, &signer);
-       hx509_query_free(hxctx, q);
+       ret = hx509_certs_find(context->hx509ctx, certs, q, &signer);
+       hx509_query_free(context->hx509ctx, q);
        hx509_certs_free(&certs);
        if (ret) {
            kdc_log(context, config, 0, "Failed to find a CA in %s",
@@ -194,7 +189,7 @@ build_certificate(krb5_context context,
        }
     }
 
-    ret = hx509_ca_tbs_init(hxctx, &tbs);
+    ret = hx509_ca_tbs_init(context->hx509ctx, &tbs);
     if (ret)
        goto out;
 
@@ -214,7 +209,7 @@ build_certificate(krb5_context context,
        any.length = 2;
        spki.algorithm.parameters = &any;
 
-       ret = hx509_ca_tbs_set_spki(hxctx, tbs, &spki);
+       ret = hx509_ca_tbs_set_spki(context->hx509ctx, tbs, &spki);
        der_free_oid(&spki.algorithm.algorithm);
        if (ret)
            goto out;
@@ -224,21 +219,21 @@ build_certificate(krb5_context context,
        hx509_certs certs;
        hx509_cert template;
 
-       ret = hx509_certs_init(hxctx, config->kx509_template, 0,
+       ret = hx509_certs_init(context->hx509ctx, config->kx509_template, 0,
                               NULL, &certs);
        if (ret) {
            kdc_log(context, config, 0, "Failed to load template %s",
                    config->kx509_template);
            goto out;
        }
-       ret = hx509_get_one_cert(hxctx, certs, &template);
+       ret = hx509_get_one_cert(context->hx509ctx, certs, &template);
        hx509_certs_free(&certs);
        if (ret) {
            kdc_log(context, config, 0, "Failed to find template in %s",
                    config->kx509_template);
            goto out;
        }
-       ret = hx509_ca_tbs_set_template(hxctx, tbs,
+       ret = hx509_ca_tbs_set_template(context->hx509ctx, tbs,
                                        HX509_CA_TEMPLATE_SUBJECT|
                                        HX509_CA_TEMPLATE_KU|
                                        HX509_CA_TEMPLATE_EKU,
@@ -248,25 +243,23 @@ build_certificate(krb5_context context,
            goto out;
     }
 
-    hx509_ca_tbs_set_notAfter(hxctx, tbs, endtime);
+    hx509_ca_tbs_set_notAfter(context->hx509ctx, tbs, endtime);
 
-    hx509_ca_tbs_subject_expand(hxctx, tbs, env);
+    hx509_ca_tbs_subject_expand(context->hx509ctx, tbs, env);
     hx509_env_free(&env);
 
-    ret = hx509_ca_sign(hxctx, tbs, signer, &cert);
+    ret = hx509_ca_sign(context->hx509ctx, tbs, signer, &cert);
     hx509_cert_free(signer);
     if (ret)
        goto out;
 
     hx509_ca_tbs_free(&tbs);
 
-    ret = hx509_cert_binary(hxctx, cert, certificate);
+    ret = hx509_cert_binary(context->hx509ctx, cert, certificate);
     hx509_cert_free(cert);
     if (ret)
        goto out;
                
-    hx509_context_free(&hxctx);
-
     return 0;
 out:
     if (env)
@@ -275,8 +268,6 @@ out:
        hx509_ca_tbs_free(&tbs);
     if (signer)
        hx509_cert_free(signer);
-    if (hxctx)
-       hx509_context_free(&hxctx);
     krb5_set_error_message(context, ret, "cert creation failed");
     return ret;
 }
index e016183615612eecf0de11d04c1c639e19bd5559..9a3f25464030208acefde5a29c65ec70ff436afb 100644 (file)
@@ -80,8 +80,9 @@ _kdc_db_fetch(krb5_context context,
 
        ret = config->db[i]->hdb_open(context, config->db[i], O_RDONLY, 0);
        if (ret) {
-           kdc_log(context, config, 0, "Failed to open database: %s",
-                   krb5_get_err_text(context, ret));
+           const char *msg = krb5_get_error_message(context, ret);
+           kdc_log(context, config, 0, "Failed to open database: %s", msg);
+           krb5_free_error_message(context, msg);
            continue;
        }
 
index 0d00ef21732c384bc140ca2f233ec835cb2aa00f..7bb32eb577094f82304935c5e2ae20f98228886a 100644 (file)
@@ -517,7 +517,7 @@ _kdc_pk_rd_padata(krb5_context context,
        goto out;
     }
 
-    ret = hx509_certs_init(kdc_identity->hx509ctx,
+    ret = hx509_certs_init(context->hx509ctx,
                           "MEMORY:trust-anchors",
                           0, NULL, &trust_anchors);
     if (ret) {
@@ -525,7 +525,7 @@ _kdc_pk_rd_padata(krb5_context context,
        goto out;
     }
 
-    ret = hx509_certs_merge(kdc_identity->hx509ctx, trust_anchors, 
+    ret = hx509_certs_merge(context->hx509ctx, trust_anchors, 
                            kdc_identity->anchors);
     if (ret) {
        hx509_certs_free(&trust_anchors);
@@ -540,18 +540,18 @@ _kdc_pk_rd_padata(krb5_context context,
        unsigned int i;
        
        for (i = 0; i < pc->len; i++) {
-           ret = hx509_cert_init_data(kdc_identity->hx509ctx,
+           ret = hx509_cert_init_data(context->hx509ctx,
                                       pc->val[i].cert.data,
                                       pc->val[i].cert.length,
                                       &cert);
            if (ret)
                continue;
-           hx509_certs_add(kdc_identity->hx509ctx, trust_anchors, cert);
+           hx509_certs_add(context->hx509ctx, trust_anchors, cert);
            hx509_cert_free(cert);
        }
     }
 
-    ret = hx509_verify_init_ctx(kdc_identity->hx509ctx, &cp->verify_ctx);
+    ret = hx509_verify_init_ctx(context->hx509ctx, &cp->verify_ctx);
     if (ret) {
        hx509_certs_free(&trust_anchors);
        krb5_set_error_message(context, ret, "failed to create verify context");
@@ -618,7 +618,7 @@ _kdc_pk_rd_padata(krb5_context context,
            ExternalPrincipalIdentifiers *edi = r.trustedCertifiers;
            unsigned int i, maxedi;
 
-           ret = hx509_certs_init(kdc_identity->hx509ctx,
+           ret = hx509_certs_init(context->hx509ctx,
                                   "MEMORY:client-anchors",
                                   0, NULL,
                                   &cp->client_anchors);
@@ -645,7 +645,7 @@ _kdc_pk_rd_padata(krb5_context context,
                if (edi->val[i].issuerAndSerialNumber == NULL)
                    continue;
 
-               ret = hx509_query_alloc(kdc_identity->hx509ctx, &q);
+               ret = hx509_query_alloc(context->hx509ctx, &q);
                if (ret) {
                    krb5_set_error_message(context, ret,
                                          "Failed to allocate hx509_query");
@@ -657,24 +657,24 @@ _kdc_pk_rd_padata(krb5_context context,
                                                   &iasn,
                                                   &size);
                if (ret) {
-                   hx509_query_free(kdc_identity->hx509ctx, q);
+                   hx509_query_free(context->hx509ctx, q);
                    continue;
                }
                ret = hx509_query_match_issuer_serial(q, &iasn.issuer, &iasn.serialNumber);
                free_IssuerAndSerialNumber(&iasn);
                if (ret) {
-                   hx509_query_free(kdc_identity->hx509ctx, q);
+                   hx509_query_free(context->hx509ctx, q);
                    continue;
                }
 
-               ret = hx509_certs_find(kdc_identity->hx509ctx,
+               ret = hx509_certs_find(context->hx509ctx,
                                       kdc_identity->certs,
                                       q,
                                       &cert);
-               hx509_query_free(kdc_identity->hx509ctx, q);
+               hx509_query_free(context->hx509ctx, q);
                if (ret)
                    continue;
-               hx509_certs_add(kdc_identity->hx509ctx,
+               hx509_certs_add(context->hx509ctx,
                                cp->client_anchors, cert);
                hx509_cert_free(cert);
            }
@@ -719,7 +719,7 @@ _kdc_pk_rd_padata(krb5_context context,
        if (req->req_body.kdc_options.request_anonymous)
            flags |= HX509_CMS_VS_ALLOW_ZERO_SIGNER;
 
-       ret = hx509_cms_verify_signed(kdc_identity->hx509ctx,
+       ret = hx509_cms_verify_signed(context->hx509ctx,
                                      cp->verify_ctx,
                                      flags,
                                      signed_content.data,
@@ -730,7 +730,7 @@ _kdc_pk_rd_padata(krb5_context context,
                                      &eContent,
                                      &signer_certs);
        if (ret) {
-           char *s = hx509_get_error_string(kdc_identity->hx509ctx, ret);
+           char *s = hx509_get_error_string(context->hx509ctx, ret);
            krb5_warnx(context, "PKINIT: failed to verify signature: %s: %d",
                       s, ret);
            free(s);
@@ -738,7 +738,7 @@ _kdc_pk_rd_padata(krb5_context context,
        }
 
        if (signer_certs) {
-           ret = hx509_get_one_cert(kdc_identity->hx509ctx, signer_certs,
+           ret = hx509_get_one_cert(context->hx509ctx, signer_certs,
                                     &cp->cert);
            hx509_certs_free(&signer_certs);
        }
@@ -843,7 +843,7 @@ _kdc_pk_rd_padata(krb5_context context,
        } else
            cp->keyex = USE_RSA;
 
-       ret = hx509_peer_info_alloc(kdc_identity->hx509ctx,
+       ret = hx509_peer_info_alloc(context->hx509ctx,
                                        &cp->peer);
        if (ret) {
            free_AuthPack(&ap);
@@ -851,7 +851,7 @@ _kdc_pk_rd_padata(krb5_context context,
        }
        
        if (ap.supportedCMSTypes) {
-           ret = hx509_peer_info_set_cms_algs(kdc_identity->hx509ctx,
+           ret = hx509_peer_info_set_cms_algs(context->hx509ctx,
                                               cp->peer,
                                               ap.supportedCMSTypes->val,
                                               ap.supportedCMSTypes->len);
@@ -861,11 +861,11 @@ _kdc_pk_rd_padata(krb5_context context,
            }
        } else {
            /* assume old client */
-           hx509_peer_info_add_cms_alg(kdc_identity->hx509ctx, cp->peer,
+           hx509_peer_info_add_cms_alg(context->hx509ctx, cp->peer,
                                        hx509_crypto_des_rsdi_ede3_cbc());
-           hx509_peer_info_add_cms_alg(kdc_identity->hx509ctx, cp->peer,
+           hx509_peer_info_add_cms_alg(context->hx509ctx, cp->peer,
                                        hx509_signature_rsa_with_sha1());
-           hx509_peer_info_add_cms_alg(kdc_identity->hx509ctx, cp->peer,
+           hx509_peer_info_add_cms_alg(context->hx509ctx, cp->peer,
                                        hx509_signature_sha1());
        }
        free_AuthPack(&ap);
@@ -1016,7 +1016,7 @@ pk_mk_pa_reply_enckey(krb5_context context,
        hx509_query *q;
        hx509_cert cert;
        
-       ret = hx509_query_alloc(kdc_identity->hx509ctx, &q);
+       ret = hx509_query_alloc(context->hx509ctx, &q);
        if (ret)
            goto out;
        
@@ -1024,15 +1024,15 @@ pk_mk_pa_reply_enckey(krb5_context context,
        if (config->pkinit_kdc_friendly_name)
            hx509_query_match_friendly_name(q, config->pkinit_kdc_friendly_name);
        
-       ret = hx509_certs_find(kdc_identity->hx509ctx,
+       ret = hx509_certs_find(context->hx509ctx,
                               kdc_identity->certs,
                               q,
                               &cert);
-       hx509_query_free(kdc_identity->hx509ctx, q);
+       hx509_query_free(context->hx509ctx, q);
        if (ret)
            goto out;
        
-       ret = hx509_cms_create_signed_1(kdc_identity->hx509ctx,
+       ret = hx509_cms_create_signed_1(context->hx509ctx,
                                        0,
                                        sdAlg,
                                        buf.data,
@@ -1060,7 +1060,7 @@ pk_mk_pa_reply_enckey(krb5_context context,
        signed_data = buf;
     }
 
-    ret = hx509_cms_envelope_1(kdc_identity->hx509ctx,
+    ret = hx509_cms_envelope_1(context->hx509ctx,
                               HX509_CMS_EV_NO_KU_CHECK,
                               cp->cert,
                               signed_data.data, signed_data.length,
@@ -1172,7 +1172,7 @@ pk_mk_pa_reply_dh(krb5_context context,
      * filled in above
      */
 
-    ret = hx509_query_alloc(kdc_identity->hx509ctx, &q);
+    ret = hx509_query_alloc(context->hx509ctx, &q);
     if (ret)
        goto out;
     
@@ -1180,15 +1180,15 @@ pk_mk_pa_reply_dh(krb5_context context,
     if (config->pkinit_kdc_friendly_name)
        hx509_query_match_friendly_name(q, config->pkinit_kdc_friendly_name);
     
-    ret = hx509_certs_find(kdc_identity->hx509ctx,
+    ret = hx509_certs_find(context->hx509ctx,
                           kdc_identity->certs,
                           q,
                           &cert);
-    hx509_query_free(kdc_identity->hx509ctx, q);
+    hx509_query_free(context->hx509ctx, q);
     if (ret)
        goto out;
     
-    ret = hx509_cms_create_signed_1(kdc_identity->hx509ctx,
+    ret = hx509_cms_create_signed_1(context->hx509ctx,
                                    0,
                                    &asn1_oid_id_pkdhkeydata,
                                    buf.data,
@@ -1509,7 +1509,7 @@ _kdc_pk_mk_pa_reply(krb5_context context,
                goto out_ocsp;
            }
 
-           ret = hx509_ocsp_verify(kdc_identity->hx509ctx,
+           ret = hx509_ocsp_verify(context->hx509ctx,
                                    kdc_time,
                                    kdc_cert,
                                    0,
@@ -1580,9 +1580,10 @@ match_rfc_san(krb5_context context,
                                       list.val[i].length,
                                       &kn, &size);
        if (ret) {
+           const char *msg = krb5_get_error_message(context, ret);
            kdc_log(context, config, 0,
-                   "Decoding kerberos name in certificate failed: %s",
-                   krb5_get_err_text(context, ret));
+                   "Decoding kerberos name in certificate failed: %s", msg);
+           krb5_free_error_message(context, msg);
            break;
        }
        if (size != list.val[i].length) {
@@ -1644,6 +1645,12 @@ match_ms_upn_san(krb5_context context,
        kdc_log(context, config, 0, "Decode of MS-UPN-SAN failed");
        goto out;
     }
+    if (size != list.val[0].length) {
+       free_MS_UPN_SAN(&upn);
+       kdc_log(context, config, 0, "Trailing data in ");
+       ret = KRB5_KDC_ERR_CLIENT_NAME_MISMATCH;
+       goto out;
+    }
 
     kdc_log(context, config, 0, "found MS UPN SAN: %s", upn);
 
@@ -1697,7 +1704,7 @@ _kdc_pk_check_client(krb5_context context,
        return 0;
     }
 
-    ret = hx509_cert_get_base_subject(kdc_identity->hx509ctx,
+    ret = hx509_cert_get_base_subject(context->hx509ctx,
                                      cp->cert,
                                      &name);
     if (ret)
@@ -1718,7 +1725,7 @@ _kdc_pk_check_client(krb5_context context,
        unsigned int i;
        
        for (i = 0; i < pc->len; i++) {
-           ret = hx509_cert_init_data(kdc_identity->hx509ctx,
+           ret = hx509_cert_init_data(context->hx509ctx,
                                       pc->val[i].cert.data,
                                       pc->val[i].cert.length,
                                       &cert);
@@ -1737,7 +1744,7 @@ _kdc_pk_check_client(krb5_context context,
 
     if (config->pkinit_princ_in_cert) {
        ret = match_rfc_san(context, config,
-                           kdc_identity->hx509ctx,
+                           context->hx509ctx,
                            cp->cert,
                            client->entry.principal);
        if (ret == 0) {
@@ -1746,7 +1753,7 @@ _kdc_pk_check_client(krb5_context context,
            return 0;
        }
        ret = match_ms_upn_san(context, config,
-                              kdc_identity->hx509ctx,
+                              context->hx509ctx,
                               cp->cert,
                               clientdb, 
                               client);
@@ -1944,7 +1951,6 @@ _kdc_pk_initialize(krb5_context context,
 
     ret = _krb5_pk_load_id(context,
                           &kdc_identity,
-                          0,
                           user_id,
                           anchors,
                           pool,
@@ -1962,7 +1968,7 @@ _kdc_pk_initialize(krb5_context context,
        hx509_query *q;
        hx509_cert cert;
        
-       ret = hx509_query_alloc(kdc_identity->hx509ctx, &q);
+       ret = hx509_query_alloc(context->hx509ctx, &q);
        if (ret) {
            krb5_warnx(context, "PKINIT: out of memory");
            return ENOMEM;
@@ -1972,13 +1978,13 @@ _kdc_pk_initialize(krb5_context context,
        if (config->pkinit_kdc_friendly_name)
            hx509_query_match_friendly_name(q, config->pkinit_kdc_friendly_name);
        
-       ret = hx509_certs_find(kdc_identity->hx509ctx,
+       ret = hx509_certs_find(context->hx509ctx,
                               kdc_identity->certs,
                               q,
                               &cert);
-       hx509_query_free(kdc_identity->hx509ctx, q);
+       hx509_query_free(context->hx509ctx, q);
        if (ret == 0) {
-           if (hx509_cert_check_eku(kdc_identity->hx509ctx, cert,
+           if (hx509_cert_check_eku(context->hx509ctx, cert,
                                     &asn1_oid_id_pkkdcekuoid, 0)) {
                hx509_name name;
                char *str;
index ab844e346cf53fc6d7afe3bab7f146c5c37d6faf..0ef9cdb7abac0a5f6015148f189e90d68fc2e06f 100644 (file)
@@ -55,7 +55,7 @@ krb5_kdc_windc_init(krb5_context context)
     for (e = list; e != NULL; e = _krb5_plugin_get_next(e)) {
 
        windcft = _krb5_plugin_get_symbol(e);
-       if (windcft->minor_version < KRB5_WINDC_PLUGING_MINOR)
+       if (windcft->minor_version < KRB5_WINDC_PLUGIN_MINOR)
            continue;
        
        (*windcft->init)(context, &windcctx);
index c7efb7b852478978e46ef23390fa1222429f4c50..0ec8e066c7395292d7ed7cbf25a8cdbcd03bba2a 100644 (file)
@@ -72,6 +72,7 @@ typedef krb5_error_code
 
 
 #define KRB5_WINDC_PLUGING_MINOR               4
+#define KRB5_WINDC_PLUGIN_MINOR                        4
 
 typedef struct krb5plugin_windc_ftable {
     int                        minor_version;
index dd122b5ce73c4f0ec50fa973b1d8f15971be22e5..809d3993367abe7fa632fc043de6e65c450c12da 100644 (file)
@@ -40,6 +40,7 @@
 struct krb5_dh_moduli;
 struct AlgorithmIdentifier;
 struct _krb5_krb_auth_data;
+struct hx509_certs_data;
 #include <krb5-private.h>
 
 #ifndef NO_NTLM
@@ -76,6 +77,7 @@ int fcache_version;
 char *password_file    = NULL;
 char *pk_user_id       = NULL;
 int pk_enterprise_flag = 0;
+struct hx509_certs_data *ent_user_id = NULL;
 char *pk_x509_anchors  = NULL;
 int pk_use_enckey      = 0;
 static int canonicalize_flag = 0;
@@ -246,10 +248,15 @@ do_524init(krb5_context context, krb5_ccache ccache,
        real_creds = creds;
     else {
        krb5_principal client;
-       krb5_cc_get_principal(context, ccache, &client);
+       ret = krb5_cc_get_principal(context, ccache, &client);
+       if (ret) {
+           krb5_warn(context, ret, "524init: can't get client principal");
+           return ret;
+       }
        memset(&in_creds, 0, sizeof(in_creds));
        ret = get_server(context, client, server, &in_creds.server);
        if(ret) {
+           krb5_warn(context, ret, "524init: can't get server principal");
            krb5_free_principal(context, client);
            return ret;
        }
@@ -415,7 +422,7 @@ get_new_tickets(krb5_context context,
     char passwd[256];
     krb5_deltat start_time = 0;
     krb5_deltat renew = 0;
-    char *renewstr = NULL;
+    const char *renewstr = NULL;
     krb5_enctype *enctype = NULL;
     krb5_ccache tempccache;
 #ifndef NO_NTLM
@@ -467,7 +474,7 @@ get_new_tickets(krb5_context context,
        krb5_get_init_creds_opt_set_canonicalize(context, opt, TRUE);
     if (pk_enterprise_flag && windows_flag)
        krb5_get_init_creds_opt_set_win2k(context, opt, TRUE);
-    if (pk_user_id || anonymous_flag) {
+    if (pk_user_id || ent_user_id || anonymous_flag) {
        ret = krb5_get_init_creds_opt_set_pkinit(context, opt,
                                                 principal,
                                                 pk_user_id,
@@ -481,6 +488,8 @@ get_new_tickets(krb5_context context,
                                                 passwd);
        if (ret)
            krb5_err(context, 1, ret, "krb5_get_init_creds_opt_set_pkinit");
+       if (ent_user_id)
+           _krb5_get_init_creds_opt_set_pkinit_user_certs(context, opt, ent_user_id);
     }
 
     if (addrs_flag != -1)
@@ -488,14 +497,14 @@ get_new_tickets(krb5_context context,
                                                addrs_flag ? FALSE : TRUE);
 
     if (renew_life == NULL && renewable_flag)
-       asprintf(&renewstr, "1 month");
+       renewstr = "1 month";
     if (renew_life)
-       asprintf(&renewstr, "%s", renew_life);
+       renewstr = renew_life;
     if (renewstr) {
        renew = parse_time (renewstr, "s");
        if (renew < 0)
            errx (1, "unparsable time: %s", renewstr);
-       free(renewstr);
+       
        krb5_get_init_creds_opt_set_renew_life (opt, renew);
     }
 
@@ -543,7 +552,7 @@ get_new_tickets(krb5_context context,
                                          server_str,
                                          opt);
        krb5_kt_close(context, kt);
-    } else if (pk_user_id || anonymous_flag) {
+    } else if (pk_user_id || ent_user_id || anonymous_flag) {
        ret = krb5_get_init_creds_password (context,
                                            &cred,
                                            principal,
@@ -796,17 +805,20 @@ main (int argc, char **argv)
 
     if (pk_enterprise_flag) {
        ret = _krb5_pk_enterprise_cert(context, pk_user_id,
-                                      argv[0], &principal);
+                                      argv[0], &principal,
+                                      &ent_user_id);
        if (ret)
            krb5_err(context, 1, ret, "krb5_pk_enterprise_certs");
 
+       pk_user_id = NULL;
+
     } else if (anonymous_flag) {
 
        ret = krb5_make_principal(context, &principal, argv[0],
                                  KRB5_WELLKNOWN_NAME, KRB5_ANON_NAME, 
                                  NULL);
        if (ret)
-           krb5_err(context, 1, ret, "krb5_build_principal");
+           krb5_err(context, 1, ret, "krb5_make_principal");
        krb5_principal_set_type(context, principal, KRB5_NT_WELLKNOWN);
 
     } else {
index 7975fe4f6ba003fd51c1dfd2074f2c68b0cad6ac..3835744bbd33657ff9875083de5781625be9173a 100644 (file)
@@ -687,6 +687,11 @@ RestrictedCharactedStringType: kw_GeneralString
                        $$ = new_tag(ASN1_C_UNIV, UT_GeneralString,
                                     TE_EXPLICIT, new_type(TGeneralString));
                }
+               | kw_TeletexString
+               {
+                       $$ = new_tag(ASN1_C_UNIV, UT_TeletexString,
+                                    TE_EXPLICIT, new_type(TTeletexString));
+               }
                | kw_UTF8String
                {
                        $$ = new_tag(ASN1_C_UNIV, UT_UTF8String,
index aee565040fd61168d76b9b17249f7244502c5aee..5a062fb339e8a4676287a15318ea85e69c1b73b1 100644 (file)
@@ -305,7 +305,7 @@ der_get_octet_string_ber (const unsigned char *p, size_t len,
            void *ptr;
 
            ptr = realloc(data->data, data->length + datalen);
-           if (ptr == NULL) {
+           if (ptr == NULL && data->length + datalen != 0) {
                e = ENOMEM;
                goto out;
            }
@@ -354,21 +354,23 @@ der_get_heim_integer (const unsigned char *p, size_t len,
            p++;
            data->length--;
        }
-       data->data = malloc(data->length);
-       if (data->data == NULL) {
-           data->length = 0;
-           if (size)
-               *size = 0;
-           return ENOMEM;
-       }
-       q = &((unsigned char*)data->data)[data->length - 1];
-       p += data->length - 1;
-       while (q >= (unsigned char*)data->data) {
-           *q = *p ^ 0xff;
-           if (carry)
-               carry = !++*q;
-           p--;
-           q--;
+       if (data->length) {
+           data->data = malloc(data->length);
+           if (data->data == NULL) {
+               data->length = 0;
+               if (size)
+                   *size = 0;
+               return ENOMEM;
+           }
+           q = &((unsigned char*)data->data)[data->length - 1];
+           p += data->length - 1;
+           while (q >= (unsigned char*)data->data) {
+               *q = *p ^ 0xff;
+               if (carry)
+                   carry = !++*q;
+               p--;
+               q--;
+           }
        }
     } else {
        data->negative = 0;
index e156c7cefb4809fa1facd6c01b6f2f4fe9ea90c9..780c18b36ff19e5130c9ca82deeb42b02537a865 100644 (file)
@@ -494,6 +494,9 @@ define_asn1 (int level, Type *t)
     case TGeneralString:
        fprintf (headerfile, "GeneralString");
        break;
+    case TTeletexString:
+       fprintf (headerfile, "TeletexString");
+       break;
     case TTag: {
        const char *classnames[] = { "UNIVERSAL ", "APPLICATION ",
                                     "" /* CONTEXT */, "PRIVATE " };
@@ -685,6 +688,10 @@ define_type (int level, const char *name, Type *t, int typedefp, int preservep)
        space(level);
        fprintf (headerfile, "heim_general_string %s;\n", name);
        break;
+    case TTeletexString:
+       space(level);
+       fprintf (headerfile, "heim_general_string %s;\n", name);
+       break;
     case TTag:
        define_type (level, name, t->subtype, typedefp, preservep);
        break;
index 5042ed64ed27bd17ccf3e6a443f8c238a847666b..f28647d19a479ec9152a98adc15a34786244e9fd 100644 (file)
@@ -184,6 +184,9 @@ copy_type (const char *from, const char *to, const Type *t, int preserve)
     case TGeneralString:
        copy_primitive ("general_string", from, to);
        break;
+    case TTeletexString:
+       copy_primitive ("general_string", from, to);
+       break;
     case TUTCTime:
        fprintf(codefile, "*(%s) = *(%s);\n", to, from);
        break;
index cf7f0b05dc06f47fe781563d99a0a85dc584e5ce..327de4c98ca02a1c5d27b78f8b601571cb01d06a 100644 (file)
@@ -67,6 +67,7 @@ is_primitive_type(int type)
     case TEnumerated:
     case TGeneralizedTime:
     case TGeneralString:
+    case TTeletexString:
     case TOID:
     case TUTCTime:
     case TUTF8String:
@@ -109,6 +110,11 @@ find_tag (const Type *t,
        *ty  = PRIM;
        *tag = UT_GeneralString;
        break;
+    case TTeletexString:
+       *cl  = ASN1_C_UNIV;
+       *ty  = PRIM;
+       *tag = UT_TeletexString;
+       break;
     case TGeneralizedTime:
        *cl  = ASN1_C_UNIV;
        *ty  = PRIM;
@@ -489,6 +495,9 @@ decode_type (const char *name, const Type *t, int optional,
     case TGeneralString:
        decode_primitive ("general_string", name, forwstr);
        break;
+    case TTeletexString:
+       decode_primitive ("general_string", name, forwstr);
+       break;
     case TTag:{
        char *tname, *typestring;
        char *ide = NULL;
@@ -621,7 +630,7 @@ decode_type (const char *name, const Type *t, int optional,
            fprintf(codefile,
                    "else {\n"
                    "(%s)->u.%s.data = calloc(1, len);\n"
-                   "if ((%s)->u.%s.data == NULL) {\n"
+                   "if ((%s)->u.%s.data == NULL && len != 0) {\n"
                    "e = ENOMEM; %s;\n"
                    "}\n"
                    "(%s)->u.%s.length = len;\n"
@@ -703,6 +712,7 @@ generate_type_decode (const Symbol *s)
     case TOID:
     case TGeneralizedTime:
     case TGeneralString:
+    case TTeletexString:
     case TUTF8String:
     case TPrintableString:
     case TIA5String:
@@ -734,7 +744,7 @@ generate_type_decode (const Symbol *s)
        if (preserve)
            fprintf (codefile,
                     "data->_save.data = calloc(1, ret);\n"
-                    "if (data->_save.data == NULL) { \n"
+                    "if (data->_save.data == NULL && ret != 0) { \n"
                     "e = ENOMEM; goto fail; \n"
                     "}\n"
                     "data->_save.length = ret;\n"
index 1f8078a0ee4261a0f6eda2efb53ecb8b43c3c052..012d4677f4a39dc2fe8965553309ad759aed8dee 100644 (file)
@@ -383,6 +383,10 @@ encode_type (const char *name, const Type *t, const char *tmpstr)
        encode_primitive ("general_string", name);
        constructed = 0;
        break;
+    case TTeletexString:
+       encode_primitive ("general_string", name);
+       constructed = 0;
+       break;
     case TTag: {
        char *tname;
        int c;
@@ -521,6 +525,7 @@ generate_type_encode (const Symbol *s)
     case TOctetString:
     case TGeneralizedTime:
     case TGeneralString:
+    case TTeletexString:
     case TUTCTime:
     case TUTF8String:
     case TPrintableString:
index fac1f6da5d5df3deff955a3f0a70594734fb5e0f..48fe8cd787d4a2b9d0b8692a91152d3a85675991 100644 (file)
@@ -145,6 +145,9 @@ free_type (const char *name, const Type *t, int preserve)
     case TGeneralString:
        free_primitive ("general_string", name);
        break;
+    case TTeletexString:
+       free_primitive ("general_string", name);
+       break;
     case TUTF8String:
        free_primitive ("utf8string", name);
        break;
index 7f9755e2da3ed88816bfb745b3272a99feb411e5..e1f045c4c5932791684c162615d7aec300194fe7 100644 (file)
@@ -219,6 +219,9 @@ length_type (const char *name, const Type *t,
     case TGeneralString:
        length_primitive ("general_string", name, variable);
        break;
+    case TTeletexString:
+       length_primitive ("general_string", name, variable);
+       break;
     case TUTCTime:
        length_primitive ("utctime", name, variable);
        break;
index 51cac55cc032906ac76c7472420b77daa8aec9e1..9794ca1514f5d7ee2be313cea25e52a962acb79a 100644 (file)
@@ -150,11 +150,9 @@ AttributeType ::=   OBJECT IDENTIFIER
 
 AttributeValue ::=   heim_any
 
-TeletexStringx ::= [UNIVERSAL 20] IMPLICIT OCTET STRING
-
 DirectoryString ::= CHOICE {
        ia5String       IA5String,
-       teletexString   TeletexStringx,
+       teletexString   TeletexString,
        printableString PrintableString,
        universalString UniversalString,
        utf8String      UTF8String,
index 3a0f8079800c885144bb3162412f105f5badf2a7..a39c8f46512d4073d886ad592eb2aad18f605c6a 100644 (file)
@@ -44,6 +44,7 @@ enum typetype {
     TChoice,
     TEnumerated,
     TGeneralString,
+    TTeletexString,
     TGeneralizedTime,
     TIA5String,
     TInteger,
index 46aec001ada0230b31364d15a8473dbff48e6dd2..e13855abad07270ac471e7a795aec306dd02d17a 100644 (file)
@@ -52,6 +52,7 @@ struct et_list {
 extern struct et_list *_et_list;
 
 const char *com_right (struct et_list *list, long code);
+const char *com_right_r (struct et_list *list, long code, char *, size_t);
 void initialize_error_table_r (struct et_list **, const char **, int, long);
 void free_error_table (struct et_list *);
 
index 6b12c00c7a22434a7b7e9f15f38417d7ae3909d9..d4a42ac5dea2ba0aaa60b53f2139e9ca37241afc 100644 (file)
 
 const char *
 com_right(struct et_list *list, long code)
+{
+    struct et_list *p;
+    for (p = list; p; p = p->next)
+       if (code >= p->table->base && code < p->table->base + p->table->n_msgs)
+           return p->table->msgs[code - p->table->base];
+    return NULL;
+}
+
+const char *
+com_right_r(struct et_list *list, long code, char *str, size_t len)
 {
     struct et_list *p;
     for (p = list; p; p = p->next) {
        if (code >= p->table->base && code < p->table->base + p->table->n_msgs) {
-           const char *str = p->table->msgs[code - p->table->base];
+           const char *msg = p->table->msgs[code - p->table->base];
 #ifdef LIBINTL
            char domain[12 + 20];
            snprintf(domain, sizeof(domain), "heim_com_err%d", p->table->base);
 #endif
-           return dgettext(domain, str);
+           strlcpy(str, dgettext(domain, msg), len);
+           return str;
        }
-
     }
     return NULL;
 }
index 1954c101c78f1198acade036598bae2b15765acd..7f84efe35408a1ae169dad3af24411a24a952dea 100644 (file)
@@ -297,13 +297,12 @@ do_delegation (krb5_context context,
     if (kret)
        goto out;
 
-    kret = krb5_build_principal(context,
-                               &creds.server,
-                               strlen(creds.client->realm),
-                               creds.client->realm,
-                               KRB5_TGS_NAME,
-                               creds.client->realm,
-                               NULL);
+    kret = krb5_make_principal(context,
+                              &creds.server,
+                              creds.client->realm,
+                              KRB5_TGS_NAME,
+                              creds.client->realm,
+                              NULL);
     if (kret)
        goto out;
 
@@ -610,12 +609,11 @@ init_auth_restart
        krb5_set_kdc_sec_offset (context, offset, -1);
     }
 
-    kret = krb5_build_authenticator (context,
+    kret = _krb5_build_authenticator(context,
                                     ctx->auth_context,
                                     enctype,
                                     ctx->kcred,
                                     &cksum,
-                                    NULL,
                                     &authenticator,
                                     KRB5_KU_AP_REQ_AUTH);
 
index 1bf8ca8af98ace3a368b197074d93040c98087a1..15b3479f8ed7fc81a48d8d3726030c079fe347f9 100644 (file)
@@ -296,6 +296,7 @@ EVP_cc_aes_256_cbc(void)
  *
  */
 
+#ifdef COMMONCRYPTO_SUPPORTS_RC2
 static int
 cc_rc2_cbc_init(EVP_CIPHER_CTX *ctx,
                const unsigned char * key,
@@ -305,6 +306,7 @@ cc_rc2_cbc_init(EVP_CIPHER_CTX *ctx,
     struct cc_key *cc = ctx->cipher_data;
     return init_cc_key(encp, kCCAlgorithmRC2, key, ctx->cipher->key_len, iv, &cc->href);
 }
+#endif
 
 /**
  * The RC2 cipher type - common crypto
@@ -318,6 +320,7 @@ cc_rc2_cbc_init(EVP_CIPHER_CTX *ctx,
 const EVP_CIPHER *
 EVP_cc_rc2_cbc(void)
 {
+#ifdef COMMONCRYPTO_SUPPORTS_RC2
     static const EVP_CIPHER rc2_cbc = {
        0,
        kCCBlockSizeRC2,
@@ -334,6 +337,9 @@ EVP_cc_rc2_cbc(void)
        NULL
     };
     return &rc2_cbc;
+#else
+    return NULL;
+#endif
 }
 
 /**
@@ -348,6 +354,7 @@ EVP_cc_rc2_cbc(void)
 const EVP_CIPHER *
 EVP_cc_rc2_40_cbc(void)
 {
+#ifdef COMMONCRYPTO_SUPPORTS_RC2
     static const EVP_CIPHER rc2_40_cbc = {
        0,
        kCCBlockSizeRC2,
@@ -364,6 +371,9 @@ EVP_cc_rc2_40_cbc(void)
        NULL
     };
     return &rc2_40_cbc;
+#else
+    return NULL;
+#endif
 }
 
 
@@ -379,6 +389,7 @@ EVP_cc_rc2_40_cbc(void)
 const EVP_CIPHER *
 EVP_cc_rc2_64_cbc(void)
 {
+#ifdef COMMONCRYPTO_SUPPORTS_RC2
     static const EVP_CIPHER rc2_64_cbc = {
        0,
        kCCBlockSizeRC2,
@@ -395,6 +406,9 @@ EVP_cc_rc2_64_cbc(void)
        NULL
     };
     return &rc2_64_cbc;
+#else
+    return NULL;
+#endif
 }
 
 /**
index 282dc38113683e04edfd2ee2bcd09ffe13a29761..dcd836d0be3b9c861089c6ca311dfd0b12fbdcb1 100644 (file)
@@ -121,7 +121,8 @@ HMAC_Init_ex(HMAC_CTX *ctx,
     for (i = 0, p = ctx->opad; i < keylen; i++)
        p[i] ^= ((const unsigned char *)key)[i];
 
-    ctx->ctx = EVP_MD_CTX_create();
+    if (ctx->ctx == NULL)
+       ctx->ctx = EVP_MD_CTX_create();
 
     EVP_DigestInit_ex(ctx->ctx, ctx->md, ctx->engine);
     EVP_DigestUpdate(ctx->ctx, ctx->ipad, EVP_MD_block_size(ctx->md));
index 2bfa265fa48450da78202f2d2a1f9448cad40a0c..fcad39f1de7c5c354038875f9ec57746a8824cfd 100644 (file)
@@ -95,8 +95,10 @@ unix_bytes(unsigned char *outdata, int size)
     ssize_t count;
     int once = 0;
 
-    if (size <= 0)
+    if (size < 0)
        return 0;
+    else if (size == 0)
+       return 1;
 
     HEIMDAL_MUTEX_lock(&random_mutex);
     if (random_fd == -1) {
index 8248098dc5412c23ff4dd7392fdd14b7dc161cb8..a8a882c6b257d1fc3d633bf21a3029e508499367 100644 (file)
@@ -281,12 +281,11 @@ hdb_entry_get_password(krb5_context context, HDB *db,
                       const hdb_entry *entry, char **p)
 {
     HDB_extension *ext;
-    char *str;
     int ret;
 
     ext = hdb_find_extension(entry, choice_HDB_extension_data_password);
     if (ext) {
-       heim_utf8_string str2;
+       heim_utf8_string str;
        heim_octet_string pw;
 
        if (db->hdb_master_key_set && ext->data.u.password.mkvno) {
@@ -314,13 +313,13 @@ hdb_entry_get_password(krb5_context context, HDB *db,
            return ret;
        }
 
-       str2 = pw.data;
-       if (str2[pw.length - 1] != '\0') {
+       str = pw.data;
+       if (str[pw.length - 1] != '\0') {
            krb5_set_error_message(context, EINVAL, "password malformated");
            return EINVAL;
        }
 
-       *p = strdup(str2);
+       *p = strdup(str);
 
        der_free_octet_string(&pw);
        if (*p == NULL) {
@@ -330,14 +329,17 @@ hdb_entry_get_password(krb5_context context, HDB *db,
        return 0;
     }
 
-    ret = krb5_unparse_name(context, entry->principal, &str);
-    if (ret == 0) {
-       krb5_set_error_message(context, ENOENT, "no password attributefor %s", str);
-       free(str);
-    } else
-       krb5_clear_error_message(context);
-
-    return ENOENT;
+    {
+       char *name;
+       ret = krb5_unparse_name(context, entry->principal, &name);
+       if (ret == 0) {
+           krb5_set_error_message(context, ENOENT, "no password attributefor %s", name);
+           free(name);
+       } else
+           krb5_clear_error_message(context);
+       
+       return ENOENT;
+    }
 }
 
 int
index c5d91b8f9d0e5b75cb4075ac7d4dceedf41dd567..fa70c7778dc987327f2bfc674bba5e63bf8d2ee2 100644 (file)
@@ -59,7 +59,7 @@
  *
  */
 
-
+const int hdb_interface_version = HDB_INTERFACE_VERSION;
 
 static struct hdb_method methods[] = {
 #if HAVE_DB1 || HAVE_DB3
index 8eba864fd39f438802cf326206a06fa07760cb46..f34c9fb36e38f592a3160da56957594f0982bba4 100644 (file)
@@ -53,6 +53,7 @@ enum hdb_lockop{ HDB_RLOCK, HDB_WLOCK };
 #define HDB_F_GET_KRBTGT       16      /* fetch krbtgt */
 #define HDB_F_GET_ANY          28      /* fetch any of client,server,krbtgt */
 #define HDB_F_CANON            32      /* want canonicalition */
+#define HDB_F_ADMIN_DATA       64      /* want data that kdc don't use  */
 
 /* hdb_capability_flags */
 #define HDB_CAP_F_HANDLE_ENTERPRISE_PRINCIPAL 1
@@ -245,6 +246,8 @@ struct hdb_method {
     krb5_error_code (*create)(krb5_context, HDB **, const char *filename);
 };
 
+extern const int hdb_interface_version;
+
 #include <hdb-protos.h>
 
 #endif /* __HDB_H__ */
index 552a869809f35dbae4ef9bc4945fa63018e62266..8ec6eae22a6398b46243ba426b66206edd363d23 100644 (file)
@@ -692,7 +692,7 @@ add_utf8_san(hx509_context context,
             const heim_oid *oid,
             const char *string)
 {
-    const PKIXXmppAddr ustring = string;
+    const PKIXXmppAddr ustring = (const PKIXXmppAddr)string;
     heim_octet_string os;
     size_t size;
     int ret;
index 7eaf6eb3c843f38c146816fc76d4cc6d75991691..ebf02a99e34ced6df2ada3690c4e71ffdfd65c93 100644 (file)
@@ -283,6 +283,7 @@ hx509_cert_init_data(hx509_context context,
        return ret;
     }
     if (size != len) {
+       free_Certificate(&t);
        hx509_set_error_string(context, 0, HX509_EXTRA_DATA_AFTER_STRUCTURE,
                               "Extra data after certificate");
        return HX509_EXTRA_DATA_AFTER_STRUCTURE;
@@ -445,7 +446,7 @@ hx509_verify_attach_anchors(hx509_verify_ctx ctx, hx509_certs set)
 {
     if (ctx->trust_anchors)
        hx509_certs_free(&ctx->trust_anchors);
-    ctx->trust_anchors = _hx509_certs_ref(set);
+    ctx->trust_anchors = hx509_certs_ref(set);
 }
 
 /**
@@ -1926,9 +1927,9 @@ hx509_verify_path(hx509_context context,
      *
      */
     if (ctx->trust_anchors)
-       anchors = _hx509_certs_ref(ctx->trust_anchors);
+       anchors = hx509_certs_ref(ctx->trust_anchors);
     else if (context->default_trust_anchors && ALLOW_DEF_TA(ctx))
-       anchors = _hx509_certs_ref(context->default_trust_anchors);
+       anchors = hx509_certs_ref(context->default_trust_anchors);
     else {
        ret = hx509_certs_init(context, "MEMORY:no-TA", 0, NULL, &anchors);
        if (ret)
@@ -3451,3 +3452,66 @@ out:
     hx509_env_free(&envcert);
     return ret;
 }
+
+/**
+ * Print a simple representation of a certificate
+ *
+ * @param context A hx509 context, can be NULL
+ * @param cert certificate to print
+ * @param out the stdio output stream, if NULL, stdout is used
+ *
+ * @return An hx509 error code
+ *
+ * @ingroup hx509_cert
+ */
+
+int
+hx509_print_cert(hx509_context context, hx509_cert cert, FILE *out)
+{
+    hx509_name name;
+    char *str;
+    int ret;
+
+    if (out == NULL)
+       out = stderr;
+
+    ret = hx509_cert_get_issuer(cert, &name);
+    if (ret)
+       return ret;
+    hx509_name_to_string(name, &str);
+    hx509_name_free(&name);
+    fprintf(out, "    issuer:  \"%s\"\n", str);
+    free(str);
+
+    ret = hx509_cert_get_subject(cert, &name);
+    if (ret)
+       return ret;
+    hx509_name_to_string(name, &str);
+    hx509_name_free(&name);
+    fprintf(out, "    subject: \"%s\"\n", str);
+    free(str);
+
+    {
+       heim_integer serialNumber;
+
+       ret = hx509_cert_get_serialnumber(cert, &serialNumber);
+       if (ret)
+           return ret;
+       ret = der_print_hex_heim_integer(&serialNumber, &str);
+       if (ret)
+           return ret;
+       der_free_heim_integer(&serialNumber);
+       fprintf(out, "    serial: %s\n", str);
+       free(str);
+    }
+
+    printf("    keyusage: ");
+    ret = hx509_cert_keyusage_print(context, cert, &str);
+    if (ret == 0) {
+       fprintf(out, "%s\n", str);
+       free(str);
+    } else
+       fprintf(out, "no");
+
+    return 0;
+}
index 45813efb38b15e931af287ac340e8569f23ff0ec..fc3cf90b3255849b6ebb71e2513fcc8631814099 100644 (file)
@@ -67,8 +67,10 @@ free_error_string(hx509_error msg)
 void
 hx509_clear_error_string(hx509_context context)
 {
-    free_error_string(context->error);
-    context->error = NULL;
+    if (context) {
+       free_error_string(context->error);
+       context->error = NULL;
+    }
 }
 
 /**
@@ -91,6 +93,9 @@ hx509_set_error_stringv(hx509_context context, int flags, int code,
 {
     hx509_error msg;
 
+    if (context == NULL)
+       return;
+
     msg = calloc(1, sizeof(*msg));
     if (msg == NULL) {
        hx509_clear_error_string(context);
index 674d2706ce0c3d9c0919b392515ce613755db709..56e25766ef953232968508bf7c407e6503220df7 100644 (file)
@@ -66,7 +66,7 @@ _hx509_write_file(const char *fn, const void *data, size_t length)
  */
 
 static void
-header(FILE *f, const char *type, const char *str)
+print_pem_stamp(FILE *f, const char *type, const char *str)
 {
     fprintf(f, "-----%s %s-----\n", type, str);
 }
@@ -82,7 +82,7 @@ hx509_pem_write(hx509_context context, const char *type,
 
 #define ENCODE_LINE_LENGTH     54
 
-    header(f, "BEGIN", type);
+    print_pem_stamp(f, "BEGIN", type);
 
     while (headers) {
        fprintf(f, "%s: %s\n%s",
@@ -110,7 +110,7 @@ hx509_pem_write(hx509_context context, const char *type,
        free(line);
     }
 
-    header(f, "END", type);
+    print_pem_stamp(f, "END", type);
 
     return 0;
 }
@@ -121,14 +121,14 @@ hx509_pem_write(hx509_context context, const char *type,
 
 int
 hx509_pem_add_header(hx509_pem_header **headers,
-                    const char *hdr, const char *value)
+                    const char *header, const char *value)
 {
     hx509_pem_header *h;
 
     h = calloc(1, sizeof(*h));
     if (h == NULL)
        return ENOMEM;
-    h->header = strdup(hdr);
+    h->header = strdup(header);
     if (h->header == NULL) {
        free(h);
        return ENOMEM;
@@ -164,10 +164,10 @@ hx509_pem_free_header(hx509_pem_header *headers)
  */
 
 const char *
-hx509_pem_find_header(const hx509_pem_header *h, const char *hdr)
+hx509_pem_find_header(const hx509_pem_header *h, const char *header)
 {
     while(h) {
-       if (strcmp(hdr, h->header) == 0)
+       if (strcmp(header, h->header) == 0)
            return h->value;
        h = h->next;
     }
index c4f035ab87ee51ec9b149b0f3185bb63fba3548c..4a96cff530598051c51bdba79ee41f3ece4d1bc4 100644 (file)
@@ -198,7 +198,7 @@ hx509_certs_store(hx509_context context,
 
 
 hx509_certs
-_hx509_certs_ref(hx509_certs certs)
+hx509_certs_ref(hx509_certs certs)
 {
     if (certs == NULL)
        return NULL;
index 3955820aef213c624c71f18bfa13cfe7b20656db..f137b846410c13e4ddfeaeeeae1b2d4a67a00577 100644 (file)
@@ -367,7 +367,7 @@ file_init_common(hx509_context context,
                 const char *residue, hx509_lock lock, outformat format)
 {
     char *p, *pnext;
-    struct ks_file *f = NULL;
+    struct ks_file *ksf = NULL;
     hx509_private_key *keys = NULL;
     int ret;
     struct pem_ctx pem_ctx;
@@ -380,15 +380,15 @@ file_init_common(hx509_context context,
     if (lock == NULL)
        lock = _hx509_empty_lock;
 
-    f = calloc(1, sizeof(*f));
-    if (f == NULL) {
+    ksf = calloc(1, sizeof(*ksf));
+    if (ksf == NULL) {
        hx509_clear_error_string(context);
        return ENOMEM;
     }
-    f->format = format;
+    ksf->format = format;
 
-    f->fn = strdup(residue);
-    if (f->fn == NULL) {
+    ksf->fn = strdup(residue);
+    if (ksf->fn == NULL) {
        hx509_clear_error_string(context);
        ret = ENOMEM;
        goto out;
@@ -401,10 +401,10 @@ file_init_common(hx509_context context,
 
     if (flags & HX509_CERTS_CREATE) {
        ret = hx509_certs_init(context, "MEMORY:ks-file-create",
-                              0, lock, &f->certs);
+                              0, lock, &ksf->certs);
        if (ret)
            goto out;
-       *data = f;
+       *data = ksf;
        return 0;
     }
 
@@ -412,25 +412,25 @@ file_init_common(hx509_context context,
     if (ret)
        goto out;
 
-    for (p = f->fn; p != NULL; p = pnext) {
-       FILE *f2;
+    for (p = ksf->fn; p != NULL; p = pnext) {
+       FILE *f;
 
        pnext = strchr(p, ',');
        if (pnext)
            *pnext++ = '\0';
        
 
-       if ((f2 = fopen(p, "r")) == NULL) {
+       if ((f = fopen(p, "r")) == NULL) {
            ret = ENOENT;
            hx509_set_error_string(context, 0, ret,
                                   "Failed to open PEM file \"%s\": %s",
                                   p, strerror(errno));
            goto out;
        }
-       rk_cloexec_file(f2);
+       rk_cloexec_file(f);
 
-       ret = hx509_pem_read(context, f2, pem_func, &pem_ctx);
-       fclose(f2);
+       ret = hx509_pem_read(context, f, pem_func, &pem_ctx);
+       fclose(f);              
        if (ret != 0 && ret != HX509_PARSING_KEY_FAILED)
            goto out;
        else if (ret == HX509_PARSING_KEY_FAILED) {
@@ -461,7 +461,7 @@ file_init_common(hx509_context context,
        }
     }
 
-    ret = _hx509_collector_collect_certs(context, pem_ctx.c, &f->certs);
+    ret = _hx509_collector_collect_certs(context, pem_ctx.c, &ksf->certs);
     if (ret)
        goto out;
 
@@ -470,17 +470,17 @@ file_init_common(hx509_context context,
        int i;
 
        for (i = 0; keys[i]; i++)
-           _hx509_certs_keys_add(context, f->certs, keys[i]);
+           _hx509_certs_keys_add(context, ksf->certs, keys[i]);
        _hx509_certs_keys_free(context, keys);
     }
 
 out:
     if (ret == 0)
-       *data = f;
+       *data = ksf;
     else {
-       if (f->fn)
-           free(f->fn);
-       free(f);
+       if (ksf->fn)
+           free(ksf->fn);
+       free(ksf);
     }
     if (pem_ctx.c)
        _hx509_collector_free(pem_ctx.c);
@@ -507,10 +507,10 @@ file_init_der(hx509_context context,
 static int
 file_free(hx509_certs certs, void *data)
 {
-    struct ks_file *f = data;
-    hx509_certs_free(&f->certs);
-    free(f->fn);
-    free(f);
+    struct ks_file *ksf = data;
+    hx509_certs_free(&ksf->certs);
+    free(ksf->fn);
+    free(ksf);
     return 0;
 }
 
@@ -558,20 +558,20 @@ static int
 file_store(hx509_context context,
           hx509_certs certs, void *data, int flags, hx509_lock lock)
 {
-    struct ks_file *f = data;
+    struct ks_file *ksf = data;
     struct store_ctx sc;
     int ret;
 
-    sc.f = fopen(f->fn, "w");
+    sc.f = fopen(ksf->fn, "w");
     if (sc.f == NULL) {
        hx509_set_error_string(context, 0, ENOENT,
                               "Failed to open file %s for writing");
        return ENOENT;
     }
     rk_cloexec_file(sc.f);
-    sc.format = f->format;
+    sc.format = ksf->format;
 
-    ret = hx509_certs_iter(context, f->certs, store_func, &sc);
+    ret = hx509_certs_iter(context, ksf->certs, store_func, &sc);
     fclose(sc.f);
     return ret;
 }
@@ -579,24 +579,24 @@ file_store(hx509_context context,
 static int
 file_add(hx509_context context, hx509_certs certs, void *data, hx509_cert c)
 {
-    struct ks_file *f = data;
-    return hx509_certs_add(context, f->certs, c);
+    struct ks_file *ksf = data;
+    return hx509_certs_add(context, ksf->certs, c);
 }
 
 static int
 file_iter_start(hx509_context context,
                hx509_certs certs, void *data, void **cursor)
 {
-    struct ks_file *f = data;
-    return hx509_certs_start_seq(context, f->certs, cursor);
+    struct ks_file *ksf = data;
+    return hx509_certs_start_seq(context, ksf->certs, cursor);
 }
 
 static int
 file_iter(hx509_context context,
          hx509_certs certs, void *data, void *iter, hx509_cert *cert)
 {
-    struct ks_file *f = data;
-    return hx509_certs_next_cert(context, f->certs, iter, cert);
+    struct ks_file *ksf = data;
+    return hx509_certs_next_cert(context, ksf->certs, iter, cert);
 }
 
 static int
@@ -605,8 +605,8 @@ file_iter_end(hx509_context context,
              void *data,
              void *cursor)
 {
-    struct ks_file *f = data;
-    return hx509_certs_end_seq(context, f->certs, cursor);
+    struct ks_file *ksf = data;
+    return hx509_certs_end_seq(context, ksf->certs, cursor);
 }
 
 static int
@@ -615,8 +615,8 @@ file_getkeys(hx509_context context,
             void *data,
             hx509_private_key **keys)
 {
-    struct ks_file *f = data;
-    return _hx509_certs_keys_get(context, f->certs, keys);
+    struct ks_file *ksf = data;
+    return _hx509_certs_keys_get(context, ksf->certs, keys);
 }
 
 static int
@@ -625,8 +625,8 @@ file_addkey(hx509_context context,
             void *data,
             hx509_private_key key)
 {
-    struct ks_file *f = data;
-    return _hx509_certs_keys_add(context, f->certs, key);
+    struct ks_file *ksf = data;
+    return _hx509_certs_keys_add(context, ksf->certs, key);
 }
 
 static struct hx509_keyset_ops keyset_file = {
index 219a301928c6296a8f276063c53932d30c85e601..07e9d36125587f0e7501159563a9f05ddb8155f7 100644 (file)
@@ -214,10 +214,12 @@ hx509_lock_prompt(hx509_lock lock, hx509_prompt *prompt)
 void
 hx509_lock_free(hx509_lock lock)
 {
-    hx509_certs_free(&lock->certs);
-    hx509_lock_reset_passwords(lock);
-    memset(lock, 0, sizeof(*lock));
-    free(lock);
+    if (lock) {
+       hx509_certs_free(&lock->certs);
+       hx509_lock_reset_passwords(lock);
+       memset(lock, 0, sizeof(*lock));
+       free(lock);
+    }
 }
 
 int
index c5844f98cc25cadf1888177dfb1be860c8154400..b544ecb7ffd69c099613f0684f8683bd7d9685d1 100644 (file)
@@ -243,11 +243,7 @@ _hx509_Name_to_string(const Name *n, char **str)
                break;
            }
            case choice_DirectoryString_teletexString:
-               ss = malloc(ds->u.teletexString.length + 1);
-               if (ss == NULL)
-                   _hx509_abort("allocation failure"); /* XXX */
-               memcpy(ss, ds->u.teletexString.data, ds->u.teletexString.length);
-               ss[ds->u.teletexString.length] = '\0';
+               ss = ds->u.teletexString;
                break;
            case choice_DirectoryString_universalString: {
                const uint32_t *uni = ds->u.universalString.data;
@@ -279,8 +275,7 @@ _hx509_Name_to_string(const Name *n, char **str)
            len = strlen(ss);
            append_string(str, &total_len, ss, len, 1);
            if (ds->element == choice_DirectoryString_universalString ||
-               ds->element == choice_DirectoryString_bmpString ||
-               ds->element == choice_DirectoryString_teletexString)
+               ds->element == choice_DirectoryString_bmpString)
            {
                free(ss);
            }
@@ -341,7 +336,7 @@ dsstringprep(const DirectoryString *ds, uint32_t **rname, size_t *rlen)
        COPYCHARARRAY(ds, printableString, len, name);
        break;
     case choice_DirectoryString_teletexString:
-       COPYVOIDARRAY(ds, teletexString, len, name);
+       COPYCHARARRAY(ds, teletexString, len, name);
        break;
     case choice_DirectoryString_bmpString:
        COPYVALARRAY(ds, bmpString, len, name);
@@ -930,12 +925,12 @@ hx509_general_name_unparse(GeneralName *name, char **str)
 
     switch (name->element) {
     case choice_GeneralName_otherName: {
-       char *str2;
-       hx509_oid_sprint(&name->u.otherName.type_id, &str2);
-       if (str2 == NULL)
+       char *oid;
+       hx509_oid_sprint(&name->u.otherName.type_id, &oid);
+       if (oid == NULL)
            return ENOMEM;
-       strpool = rk_strpoolprintf(strpool, "otherName: %s", str2);
-       free(str2);
+       strpool = rk_strpoolprintf(strpool, "otherName: %s", oid);
+       free(oid);
        break;
     }
     case choice_GeneralName_rfc822Name:
@@ -990,12 +985,12 @@ hx509_general_name_unparse(GeneralName *name, char **str)
        break;
     }
     case choice_GeneralName_registeredID: {
-       char *str2;
-       hx509_oid_sprint(&name->u.registeredID, &str2);
-       if (str2 == NULL)
+       char *oid;
+       hx509_oid_sprint(&name->u.registeredID, &oid);
+       if (oid == NULL)
            return ENOMEM;
-       strpool = rk_strpoolprintf(strpool, "registeredID: %s", str2);
-       free(str2);
+       strpool = rk_strpoolprintf(strpool, "registeredID: %s", oid);
+       free(oid);
        break;
     }
     default:
index 74f2d7467903766d68ad4e551d935da7257346bd..21140b3c7e0c7a982130c0769d332fcfd3b10aed 100644 (file)
@@ -1004,17 +1004,17 @@ hx509_ocsp_request(hx509_context context,
 
        es = req.tbsRequest.requestExtensions;
        
-       es->val = calloc(es->len, sizeof(es->val[0]));
+       es->val = calloc(1, sizeof(es->val[0]));
        if (es->val == NULL) {
            ret = ENOMEM;
            goto out;
        }
-       es->len = 1;
        ret = der_copy_oid(&asn1_oid_id_pkix_ocsp_nonce, &es->val[0].extnID);
        if (ret) {
            free_OCSPRequest(&req);
            return ret;
        }
+       es->len = 1;
 
        es->val[0].extnValue.data = malloc(10);
        if (es->val[0].extnValue.data == NULL) {
index c5e760569a9b318aa96b64b9a516cf6f09f5233b..5932ce84c3d4020c24987365221ceca131a48e7c 100644 (file)
@@ -176,7 +176,6 @@ _hx509_expr_eval(hx509_context context, hx509_env env, struct hx_expr *expr)
     default:
        _hx509_abort("hx509 eval expr with unknown op: %d", (int)expr->op);
     }
-    return 0;
 }
 
 void
index bfc183d168a7dddde2f2c1182a006be7f3464cd0..dfb9f6a0e3a39097e75f58894ab5fbd620ae6d69 100644 (file)
@@ -171,10 +171,10 @@ krb5_auth_con_genaddrs(krb5_context context,
        if (auth_context->local_address == NULL) {
            len = sizeof(ss_local);
            if(getsockname(fd, local, &len) < 0) {
+               char buf[128];
                ret = errno;
-               krb5_set_error_message(context, ret,
-                                      "getsockname: %s",
-                                      strerror(ret));
+               strerror_r(ret, buf, sizeof(buf));
+               krb5_set_error_message(context, ret, "getsockname: %s", buf);
                goto out;
            }
            ret = krb5_sockaddr2address (context, local, &local_k_address);
@@ -189,9 +189,10 @@ krb5_auth_con_genaddrs(krb5_context context,
     if(flags & KRB5_AUTH_CONTEXT_GENERATE_REMOTE_ADDR) {
        len = sizeof(ss_remote);
        if(getpeername(fd, remote, &len) < 0) {
+           char buf[128];
            ret = errno;
-           krb5_set_error_message(context, ret,
-                                  "getpeername: %s", strerror(ret));
+           strerror_r(ret, buf, sizeof(buf));
+           krb5_set_error_message(context, ret, "getpeername: %s", buf);
            goto out;
        }
        ret = krb5_sockaddr2address (context, remote, &remote_k_address);
index bf77fd4e77ea01e5ab0d5d1274d66f878df8e3bd..a845e0ac3337a5b0975be08e38ad0689af9c0563 100644 (file)
@@ -100,35 +100,30 @@ make_etypelist(krb5_context context,
 }
 
 krb5_error_code KRB5_LIB_FUNCTION
-krb5_build_authenticator (krb5_context context,
+_krb5_build_authenticator(krb5_context context,
                          krb5_auth_context auth_context,
                          krb5_enctype enctype,
                          krb5_creds *cred,
                          Checksum *cksum,
-                         Authenticator **auth_result,
                          krb5_data *result,
                          krb5_key_usage usage)
 {
-    Authenticator *auth;
+    Authenticator auth;
     u_char *buf = NULL;
     size_t buf_size;
     size_t len;
     krb5_error_code ret;
     krb5_crypto crypto;
 
-    auth = calloc(1, sizeof(*auth));
-    if (auth == NULL) {
-       krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
-       return ENOMEM;
-    }
+    memset(&auth, 0, sizeof(auth));
 
-    auth->authenticator_vno = 5;
-    copy_Realm(&cred->client->realm, &auth->crealm);
-    copy_PrincipalName(&cred->client->name, &auth->cname);
+    auth.authenticator_vno = 5;
+    copy_Realm(&cred->client->realm, &auth.crealm);
+    copy_PrincipalName(&cred->client->name, &auth.cname);
 
-    krb5_us_timeofday (context, &auth->ctime, &auth->cusec);
+    krb5_us_timeofday (context, &auth.ctime, &auth.cusec);
 
-    ret = krb5_auth_con_getlocalsubkey(context, auth_context, &auth->subkey);
+    ret = krb5_auth_con_getlocalsubkey(context, auth_context, &auth.subkey);
     if(ret)
        goto fail;
 
@@ -137,33 +132,43 @@ krb5_build_authenticator (krb5_context context,
            krb5_generate_seq_number (context,
                                      &cred->session,
                                      &auth_context->local_seqnumber);
-       ALLOC(auth->seq_number, 1);
-       if(auth->seq_number == NULL) {
+       ALLOC(auth.seq_number, 1);
+       if(auth.seq_number == NULL) {
            ret = ENOMEM;
            goto fail;
        }
-       *auth->seq_number = auth_context->local_seqnumber;
+       *auth.seq_number = auth_context->local_seqnumber;
     } else
-       auth->seq_number = NULL;
-    auth->authorization_data = NULL;
-    auth->cksum = cksum;
-
-    if (cksum != NULL && cksum->cksumtype == CKSUMTYPE_GSSAPI) {
-       /*
-        * This is not GSS-API specific, we only enable it for
-        * GSS for now
-        */
-       ret = make_etypelist(context, &auth->authorization_data);
+       auth.seq_number = NULL;
+    auth.authorization_data = NULL;
+
+    if (cksum) {
+       ALLOC(auth.cksum, 1);
+       if (auth.cksum == NULL) {
+           ret = ENOMEM;
+           goto fail;
+       }
+       ret = copy_Checksum(cksum, auth.cksum);
        if (ret)
            goto fail;
+
+       if (auth.cksum->cksumtype == CKSUMTYPE_GSSAPI) {
+           /*
+            * This is not GSS-API specific, we only enable it for
+            * GSS for now
+            */
+           ret = make_etypelist(context, &auth.authorization_data);
+           if (ret)
+               goto fail;
+       }
     }
 
     /* XXX - Copy more to auth_context? */
 
-    auth_context->authenticator->ctime = auth->ctime;
-    auth_context->authenticator->cusec = auth->cusec;
+    auth_context->authenticator->ctime = auth.ctime;
+    auth_context->authenticator->cusec = auth.cusec;
 
-    ASN1_MALLOC_ENCODE(Authenticator, buf, buf_size, auth, &len, ret);
+    ASN1_MALLOC_ENCODE(Authenticator, buf, buf_size, &auth, &len, ret);
     if (ret)
        goto fail;
     if(buf_size != len)
@@ -175,7 +180,7 @@ krb5_build_authenticator (krb5_context context,
     ret = krb5_encrypt (context,
                        crypto,
                        usage /* KRB5_KU_AP_REQ_AUTH */,
-                       buf + buf_size - len,
+                       buf,
                        len,
                        result);
     krb5_crypto_destroy(context, crypto);
@@ -183,20 +188,9 @@ krb5_build_authenticator (krb5_context context,
     if (ret)
        goto fail;
 
+ fail:
+    free_Authenticator (&auth);
     free (buf);
 
-    if (auth_result)
-       *auth_result = auth;
-    else {
-       /* Don't free the `cksum', it's allocated by the caller */
-       auth->cksum = NULL;
-       free_Authenticator (auth);
-       free (auth);
-    }
-    return ret;
-  fail:
-    free_Authenticator (auth);
-    free (auth);
-    free (buf);
     return ret;
 }
index 8bf8b79022646466bf95cc48cd23efcf63264b7c..79e1000fd0982a02b537419982ef71cf8abce427 100644 (file)
@@ -304,6 +304,12 @@ krb5_init_context(krb5_context *context)
     cc_ops_register(p);
     kt_ops_register(p);
 
+#ifdef PKINIT
+    ret = hx509_context_init(&p->hx509ctx);
+    if (ret)
+       goto out;
+#endif 
+
 out:
     if(ret) {
        krb5_free_context(p);
@@ -815,31 +821,6 @@ krb5_get_default_in_tkt_etypes(krb5_context context,
     return 0;
 }
 
-/**
- * Return the error string for the error code. The caller must not
- * free the string.
- *
- * @param context Kerberos 5 context.
- * @param code Kerberos error code.
- *
- * @return the error message matching code
- *
- * @ingroup krb5
- */
-
-const char* KRB5_LIB_FUNCTION
-krb5_get_err_text(krb5_context context, krb5_error_code code)
-{
-    const char *p = NULL;
-    if(context != NULL)
-       p = com_right(context->et_list, code);
-    if(p == NULL)
-       p = strerror(code);
-    if (p == NULL)
-       p = "Unknown error";
-    return p;
-}
-
 /**
  * Init the built-in ets in the Kerberos library.
  *
index bdcdb2ea0a13d75207d6faa58bb1ec75b6008da7..68233c290d7b2d7b3e7259863415611fcbc02524 100644 (file)
@@ -2058,7 +2058,7 @@ evp_encrypt(krb5_context context,
     return 0;
 }
 
-static const char zero_ivec[EVP_MAX_BLOCK_LENGTH] = { 0 };
+static const unsigned char zero_ivec[EVP_MAX_BLOCK_LENGTH] = { 0 };
 
 static krb5_error_code
 evp_encrypt_cts(krb5_context context,
index 829c080a555478cc49bb342691dac9abf33dbb95..d2661dcaf5c6ded8c8f0fc37c317f55060add3e0 100644 (file)
@@ -104,6 +104,68 @@ krb5_vset_error_message (krb5_context context, krb5_error_code ret,
     HEIMDAL_MUTEX_unlock(context->mutex);
 }
 
+/**
+ * Prepend the context full error string for a specific error code.
+ * The error that is stored should be internationalized.
+ *
+ * @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_prepend_error_message(krb5_context context, krb5_error_code ret,
+                          const char *fmt, ...)
+    __attribute__ ((format (printf, 3, 4)))
+{
+    va_list ap;
+
+    va_start(ap, fmt);
+    krb5_vset_error_message (context, ret, fmt, ap);
+    va_end(ap);
+}
+
+/**
+ * Prepend the contexts's 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_vprepend_error_message (krb5_context context, krb5_error_code ret,
+                            const char *fmt, va_list args)
+    __attribute__ ((format (printf, 3, 0)))
+{
+    char *str, *str2;
+    HEIMDAL_MUTEX_lock(context->mutex);
+    if (context->error_code != ret) {
+       HEIMDAL_MUTEX_unlock(context->mutex);
+       return;
+    }
+    vasprintf(&str, fmt, args);
+    if (context->error_string) {
+       int e;
+
+       e = asprintf(&str2, "%s: %s", str, context->error_string);
+       free(context->error_string);
+       if (e < 0)
+           context->error_string = NULL;
+       else
+           context->error_string = str2;
+       free(str);
+    } else
+       context->error_string = str;
+    HEIMDAL_MUTEX_unlock(context->mutex);
+}
+
 
 /**
  * Return the error message in context. On error or no error string,
@@ -155,7 +217,6 @@ krb5_have_error_string(krb5_context context)
 const char * KRB5_LIB_FUNCTION
 krb5_get_error_message(krb5_context context, krb5_error_code code)
 {
-    const char *cstr;
     char *str;
 
     HEIMDAL_MUTEX_lock(context->mutex);
@@ -172,10 +233,13 @@ krb5_get_error_message(krb5_context context, krb5_error_code code)
 
     if (code == 0)
        return strdup("Success");
-
-    cstr = krb5_get_err_text(context, code);
-    if (cstr)
-       return strdup(cstr);
+    {
+       const char *msg;
+       char buf[128];
+       msg = com_right_r(context->et_list, code, buf, sizeof(buf));
+       if (msg)
+           return strdup(msg);
+    }
 
     if (asprintf(&str, "<unknown error: %d>", (int)code) == -1)
        return NULL;
@@ -199,3 +263,31 @@ krb5_free_error_message(krb5_context context, const char *msg)
 {
     free(rk_UNCONST(msg));
 }
+
+
+/**
+ * Return the error string for the error code. The caller must not
+ * free the string.
+ *
+ * This function is deprecated since its not threadsafe.
+ *
+ * @param context Kerberos 5 context.
+ * @param code Kerberos error code.
+ *
+ * @return the error message matching code
+ *
+ * @ingroup krb5
+ */
+
+const char* KRB5_LIB_FUNCTION
+krb5_get_err_text(krb5_context context, krb5_error_code code) KRB5_DEPRECATED
+{
+    const char *p = NULL;
+    if(context != NULL)
+       p = com_right(context->et_list, code);
+    if(p == NULL)
+       p = strerror(code);
+    if (p == NULL)
+       p = "Unknown error";
+    return p;
+}
index f8e74f1ddc1c1964a1290fe717b388f1098dab76..cda15e483bf7ae563a2388a6bf7dc2a1e3dd48dd 100644 (file)
@@ -95,13 +95,15 @@ _krb5_xlock(krb5_context context, int fd, krb5_boolean exclusive,
                               N_("timed out locking cache file %s", "file"),
                               filename);
        break;
-    default:
+    default: {
+       char buf[128];
+       strerror_r(ret, buf, sizeof(buf));
        krb5_set_error_message(context, ret,
                               N_("error locking cache file %s: %s",
-                                 "file, error"),
-                              filename, strerror(ret));
+                                 "file, error"), filename, buf);
        break;
     }
+    }
     return ret;
 }
 
@@ -127,12 +129,14 @@ _krb5_xunlock(krb5_context context, int fd)
     case EINVAL: /* filesystem doesn't support locking, let the user have it */
        ret = 0;
        break;
-    default:
+    default: {
+       char buf[128];
+       strerror_r(ret, buf, sizeof(buf));
        krb5_set_error_message(context, ret,
-                              N_("Failed to unlock file: %s", ""),
-                              strerror(ret));
+                              N_("Failed to unlock file: %s", ""), buf);
        break;
     }
+    }
     return ret;
 }
 
@@ -369,9 +373,11 @@ fcc_open(krb5_context context,
     int fd;
     fd = open(filename, flags, mode);
     if(fd < 0) {
+       char buf[128];
        ret = errno;
+       strerror_r(ret, buf, sizeof(buf));
        krb5_set_error_message(context, ret, N_("open(%s): %s", "file, error"),
-                              filename, strerror(ret));
+                              filename, buf);
        return ret;
     }
     rk_cloexec(fd);
@@ -431,9 +437,11 @@ fcc_initialize(krb5_context context,
     fcc_unlock(context, fd);
     if (close(fd) < 0)
        if (ret == 0) {
+           char buf[128];
            ret = errno;
+           strerror_r(ret, buf, sizeof(buf));
            krb5_set_error_message (context, ret, N_("close %s: %s", ""),
-                                   FILENAME(id), strerror(ret));
+                                   FILENAME(id), buf);
        }
     return ret;
 }
@@ -485,9 +493,11 @@ fcc_store_cred(krb5_context context,
     fcc_unlock(context, fd);
     if (close(fd) < 0) {
        if (ret == 0) {
+           char buf[128];
+           strerror_r(ret, buf, sizeof(buf));
            ret = errno;
            krb5_set_error_message (context, ret, N_("close %s: %s", ""),
-                                   FILENAME(id), strerror(ret));
+                                   FILENAME(id), buf);
        }
     }
     return ret;
@@ -875,12 +885,13 @@ fcc_move(krb5_context context, krb5_ccache from, krb5_ccache to)
 
     ret = rename(FILENAME(from), FILENAME(to));
     if (ret && errno != EXDEV) {
+       char buf[128];
        ret = errno;
+       strerror_r(ret, buf, sizeof(buf));
        krb5_set_error_message(context, ret,
                               N_("Rename of file from %s "
                                  "to %s failed: %s", ""),
-                              FILENAME(from), FILENAME(to),
-                              strerror(ret));
+                              FILENAME(from), FILENAME(to), buf);
        return ret;
     } else if (ret && errno == EXDEV) {
        /* make a copy and delete the orignal */
index 2764f1a9144fa29c1f1104bf23dcda90610c1300..b7bd8b99f8f9c2fea22dbb2b3d0d0a1aa536919e 100644 (file)
@@ -38,23 +38,11 @@ krb5_generate_seq_number(krb5_context context,
                         const krb5_keyblock *key,
                         uint32_t *seqno)
 {
-    krb5_error_code ret;
-    krb5_keyblock *subkey;
-    uint32_t q;
-    u_char *p;
-    int i;
-
-    ret = krb5_generate_subkey (context, key, &subkey);
-    if (ret)
-       return ret;
-
-    q = 0;
-    for (p = (u_char *)subkey->keyvalue.data, i = 0;
-        i < subkey->keyvalue.length;
-        ++i, ++p)
-       q = (q << 8) | *p;
-    q &= 0xffffffff;
-    *seqno = q;
-    krb5_free_keyblock (context, subkey);
+    if (RAND_bytes((void *)seqno, sizeof(*seqno)) != 1)
+       krb5_abortx(context, "Failed to generate random block");
+    /* MIT used signed numbers, lets not stomp into that space directly */
+    *seqno &= 0x3fffffff;
+    if (*seqno == 0)
+       *seqno = 1;
     return 0;
 }
index efb6cce28848ae8f4bffd8d8d2c47bf7e949ce7f..003a66ac0169a60ac98d855029b9b5b69b9d92f3 100644 (file)
 
 #include <krb5_locl.h>
 
-krb5_error_code KRB5_LIB_FUNCTION
-krb5_generate_subkey(krb5_context context,
-                    const krb5_keyblock *key,
-                    krb5_keyblock **subkey)
-{
-    return krb5_generate_subkey_extended(context, key, key->keytype, subkey);
-}
+/**
+ * Generate subkey, from keyblock
+ *
+ * @param context kerberos context
+ * @param key session key
+ * @param etype encryption type of subkey, if ETYPE_NULL, use key's enctype
+ * @param subkey returned new, free with krb5_free_keyblock().
+ *
+ * @return 0 on success or a Kerberos 5 error code
+ *
+* @ingroup krb5_crypto
+ */
 
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_generate_subkey_extended(krb5_context context,
index 10417f1a529f1bcb309a3cf4b995cc2787b46ca7..63152bbfa6567903e4651c1b37e665965dc089b4 100644 (file)
@@ -32,6 +32,7 @@
  */
 
 #include <krb5_locl.h>
+#include <assert.h>
 
 /*
  * Take the `body' and encode it into `padata' using the credentials
@@ -79,7 +80,7 @@ static krb5_error_code
 set_auth_data (krb5_context context,
               KDC_REQ_BODY *req_body,
               krb5_authdata *authdata,
-              krb5_keyblock *key)
+              krb5_keyblock *subkey)
 {
     if(authdata->len) {
        size_t len, buf_size;
@@ -101,7 +102,7 @@ set_auth_data (krb5_context context,
                                   N_("malloc: out of memory", ""));
            return ENOMEM;
        }
-       ret = krb5_crypto_init(context, key, 0, &crypto);
+       ret = krb5_crypto_init(context, subkey, 0, &crypto);
        if (ret) {
            free (buf);
            free (req_body->enc_authorization_data);
@@ -111,7 +112,6 @@ set_auth_data (krb5_context context,
        krb5_encrypt_EncryptedData(context,
                                   crypto,
                                   KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY,
-                                  /* KRB5_KU_TGS_REQ_AUTH_DAT_SESSION? */
                                   buf,
                                   len,
                                   0,
@@ -143,7 +143,9 @@ init_tgs_req (krb5_context context,
              krb5_keyblock **subkey,
              TGS_REQ *t)
 {
+    krb5_auth_context ac = NULL;
     krb5_error_code ret = 0;
+    krb5_keyblock *key = NULL;
 
     memset(t, 0, sizeof(*t));
     t->pvno = 5;
@@ -238,60 +240,39 @@ init_tgs_req (krb5_context context,
        }
     }
 
-    {
-       krb5_auth_context ac;
-       krb5_keyblock *key = NULL;
-
-       ret = krb5_auth_con_init(context, &ac);
-       if(ret)
-           goto fail;
-
-       if (krb5_config_get_bool_default(context, NULL, FALSE,
-                                        "realms",
-                                        krbtgt->server->realm,
-                                        "tgs_require_subkey",
-                                        NULL))
-       {
-           ret = krb5_generate_subkey (context, &krbtgt->session, &key);
-           if (ret) {
-               krb5_auth_con_free (context, ac);
-               goto fail;
-           }
-
-           ret = krb5_auth_con_setlocalsubkey(context, ac, key);
-           if (ret) {
-               if (key)
-                   krb5_free_keyblock (context, key);
-               krb5_auth_con_free (context, ac);
-               goto fail;
-           }
-       }
-
-       ret = set_auth_data (context, &t->req_body, &in_creds->authdata,
-                            key ? key : &krbtgt->session);
-       if (ret) {
-           if (key)
-               krb5_free_keyblock (context, key);
-           krb5_auth_con_free (context, ac);
-           goto fail;
-       }
+    ret = krb5_auth_con_init(context, &ac);
+    if(ret)
+       goto fail;
+    
+    ret = krb5_generate_subkey_extended(context, &krbtgt->session, 
+                                       ETYPE_NULL, &key);
+    if (ret)
+       goto fail;
+    
+    ret = krb5_auth_con_setlocalsubkey(context, ac, key);
+    if (ret)
+       goto fail;
+    
+    ret = set_auth_data (context, &t->req_body, &in_creds->authdata, key);
+    if (ret)
+       goto fail;
+    
+    ret = make_pa_tgs_req(context,
+                         ac,
+                         &t->req_body,
+                         &t->padata->val[0],
+                         krbtgt);
+    if(ret)
+       goto fail;
 
-       ret = make_pa_tgs_req(context,
-                             ac,
-                             &t->req_body,
-                             &t->padata->val[0],
-                             krbtgt);
-       if(ret) {
-           if (key)
-               krb5_free_keyblock (context, key);
-           krb5_auth_con_free(context, ac);
-           goto fail;
-       }
-       *subkey = key;
-       
-       krb5_auth_con_free(context, ac);
-    }
+    *subkey = key;
+    key = NULL;
+    
 fail:
+    if (key)
+       krb5_free_keyblock (context, key);
+    if (ac)
+       krb5_auth_con_free(context, ac);
     if (ret) {
        t->req_body.addresses = NULL;
        free_TGS_REQ (t);
@@ -349,17 +330,12 @@ decrypt_tkt_with_subkey (krb5_context context,
     size_t size;
     krb5_crypto crypto;
 
-    ret = krb5_crypto_init(context, key, 0, &crypto);
-    if (ret)
-       return ret;
-    ret = krb5_decrypt_EncryptedData (context,
-                                     crypto,
-                                     usage,
-                                     &dec_rep->kdc_rep.enc_part,
-                                     &data);
-    krb5_crypto_destroy(context, crypto);
-    if(ret && subkey){
-       /* DCE compat -- try to decrypt with subkey */
+    assert(usage == 0);
+
+    /*
+     * start out with trying with subkey if we have one
+     */
+    if (subkey) {
        ret = krb5_crypto_init(context, subkey, 0, &crypto);
        if (ret)
            return ret;
@@ -370,6 +346,17 @@ decrypt_tkt_with_subkey (krb5_context context,
                                          &data);
        krb5_crypto_destroy(context, crypto);
     }
+    if (subkey == NULL || ret) {
+       ret = krb5_crypto_init(context, key, 0, &crypto);
+       if (ret)
+           return ret;
+       ret = krb5_decrypt_EncryptedData (context,
+                                         crypto,
+                                         KRB5_KU_TGS_REP_ENC_PART_SESSION,
+                                         &dec_rep->kdc_rep.enc_part,
+                                         &data);
+       krb5_crypto_destroy(context, crypto);
+    }
     if (ret)
        return ret;
 
@@ -549,7 +536,7 @@ get_cred_kdc(krb5_context context,
                                   out_creds,
                                   &krbtgt->session,
                                   NULL,
-                                  KRB5_KU_TGS_REP_ENC_PART_SESSION,
+                                  0,
                                   &krbtgt->addresses,
                                   nonce,
                                   eflags,
@@ -574,10 +561,8 @@ out:
     free_METHOD_DATA(&padata);
     krb5_data_free(&resp);
     krb5_data_free(&enc);
-    if(subkey){
-       krb5_free_keyblock_contents(context, subkey);
-       free(subkey);
-    }
+    if(subkey)
+       krb5_free_keyblock(context, subkey);
     return ret;
 
 }
@@ -898,6 +883,12 @@ get_cred_kdc_referral(krb5_context context,
     int loop = 0;
     int ok_as_delegate = 1;
 
+    if (in_creds->server->name.name_string.len < 2 && !flags.b.canonicalize) {
+       krb5_set_error_message(context, KRB5KDC_ERR_PATH_NOT_ACCEPTED,
+                              N_("Name too short to do referals, skipping", ""));
+       return KRB5KDC_ERR_PATH_NOT_ACCEPTED;
+    }
+
     memset(&tgt, 0, sizeof(tgt));
     memset(&ticket, 0, sizeof(ticket));
 
@@ -1087,6 +1078,12 @@ krb5_get_credentials_with_flags(krb5_context context,
     krb5_creds *res_creds;
     int i;
 
+    if (in_creds->session.keytype) {
+       ret = krb5_enctype_valid(context, in_creds->session.keytype);
+       if (ret)
+           return ret;
+    }
+
     *out_creds = NULL;
     res_creds = calloc(1, sizeof(*res_creds));
     if (res_creds == NULL) {
@@ -1282,6 +1279,12 @@ krb5_get_creds(krb5_context context,
     krb5_creds *res_creds;
     int i;
 
+    if (opt && opt->enctype) {
+       ret = krb5_enctype_valid(context, opt->enctype);
+       if (ret)
+           return ret;
+    }
+
     memset(&in_creds, 0, sizeof(in_creds));
     in_creds.server = rk_UNCONST(inprinc);
 
@@ -1289,7 +1292,10 @@ krb5_get_creds(krb5_context context,
     if (ret)
        return ret;
 
-    options = opt->options;
+    if (opt)
+       options = opt->options;
+    else
+       options = 0;
     flags.i = 0;
 
     *out_creds = NULL;
@@ -1301,7 +1307,7 @@ krb5_get_creds(krb5_context context,
        return ENOMEM;
     }
 
-    if (opt->enctype) {
+    if (opt && opt->enctype) {
        in_creds.session.keytype = opt->enctype;
        options |= KRB5_TC_MATCH_KEYTYPE;
     }
@@ -1312,7 +1318,7 @@ krb5_get_creds(krb5_context context,
      */
     ret = krb5_cc_retrieve_cred(context,
                                 ccache,
-                               opt->enctype ? KRB5_TC_MATCH_KEYTYPE : 0,
+                               options & KRB5_TC_MATCH_KEYTYPE,
                                 &in_creds, res_creds);
     /*
      * If we got a credential, check if credential is expired before
index 19e48173df92b0d17873c406286257033504c76e..8c58dae1878cc3683c9fcd93636c5a3325d955a6 100644 (file)
@@ -137,13 +137,12 @@ krb5_fwd_tgt_creds (krb5_context  context,
     memset (&creds, 0, sizeof(creds));
     creds.client = client;
 
-    ret = krb5_build_principal(context,
-                              &creds.server,
-                              strlen(client_realm),
-                              client_realm,
-                              KRB5_TGS_NAME,
-                              client_realm,
-                              NULL);
+    ret = krb5_make_principal(context,
+                             &creds.server,
+                             client_realm,
+                             KRB5_TGS_NAME,
+                             client_realm,
+                             NULL);
     if (ret)
        return ret;
 
index 71dc1327c6f81a88dd22235859c9f3427cb89948..d436215769ef53491d96363ac65d2d100804950e 100644 (file)
@@ -136,6 +136,8 @@ struct sockaddr_dl;
 #include <door.h>
 #endif
 
+#include <com_err.h>
+
 #include <roken.h>
 #include <parse_time.h>
 #include <base64.h>
@@ -151,6 +153,7 @@ struct sockaddr_dl;
 struct send_to_kdc;
 
 /* XXX glue for pkinit */
+struct hx509_certs_data;
 struct krb5_pk_identity;
 struct krb5_pk_cert;
 struct ContentInfo;
@@ -265,6 +268,9 @@ typedef struct krb5_context_data {
 #define KRB5_CTX_F_CHECK_PAC                   2
 #define KRB5_CTX_F_HOMEDIR_ACCESS              4
     struct send_to_kdc *send_to_kdc;
+#ifdef PKINIT
+    hx509_context hx509ctx;
+#endif
 } krb5_context_data;
 
 #define KRB5_DEFAULT_CCNAME_FILE "FILE:/tmp/krb5cc_%{uid}"
@@ -295,7 +301,6 @@ typedef struct krb5_context_data {
 #ifdef PKINIT
 
 struct krb5_pk_identity {
-    hx509_context hx509ctx;
     hx509_verify_ctx verify_ctx;
     hx509_certs certs;
     hx509_cert cert;
index f623fc495b1d8e2c2f75438324c049646369f62d..0de30e4ddbfb5bb33e07d5c9b4d770722786acf7 100644 (file)
@@ -44,6 +44,7 @@ krb5_mk_error(krb5_context context,
              int *client_usec,
              krb5_data *reply)
 {
+    const char *e_text2 = NULL;
     KRB_ERROR msg;
     krb5_timestamp sec;
     int32_t usec;
@@ -62,7 +63,7 @@ krb5_mk_error(krb5_context context,
     /* Make sure we only send `protocol' error codes */
     if(error_code < KRB5KDC_ERR_NONE || error_code >= KRB5_ERR_RCSID) {
        if(e_text == NULL)
-           e_text = krb5_get_err_text(context, error_code);
+           e_text = e_text2 = krb5_get_error_message(context, error_code);
        error_code = KRB5KRB_ERR_GENERIC;
     }
     msg.error_code = error_code - KRB5KDC_ERR_NONE;
@@ -82,6 +83,8 @@ krb5_mk_error(krb5_context context,
     }
 
     ASN1_MALLOC_ENCODE(KRB_ERROR, reply->data, reply->length, &msg, &len, ret);
+    if (e_text2)
+       krb5_free_error_message(context, e_text2);
     if (ret)
        return ret;
     if(reply->length != len)
index d130272aa1641bb2fff8bb96f878b0549489efde..03fc93b02f1362274e4a0f7699805e88602ff22f 100644 (file)
@@ -123,12 +123,11 @@ _krb5_mk_req_internal(krb5_context context,
     if (ret)
        goto out;
 
-    ret = krb5_build_authenticator (context,
+    ret = _krb5_build_authenticator(context,
                                    ac,
                                    ac->keyblock->keytype,
                                    in_creds,
                                    c_opt,
-                                   NULL,
                                    &authenticator,
                                    encrypt_usage);
     if (c_opt)
index 2f6d7854a542fbf8eee997dac754cd6292fb2a5c..f6457aa5c9712680f41b02e2841dde8df7e56389 100644 (file)
@@ -74,6 +74,7 @@ struct krb5_pk_init_ctx_data {
     unsigned int require_krbtgt_otherName:1;
     unsigned int require_hostname_match:1;
     unsigned int trustedCertifiers:1;
+    unsigned int anonymous:1;
 };
 
 static void
@@ -193,15 +194,15 @@ 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) {
-           pk_copy_error(context, id->hx509ctx, ret,
+           pk_copy_error(context, context->hx509ctx, ret,
                          "Failed setting %s OID", cf[i].type);
            return ret;
        }
 
-       ret = hx509_certs_find(id->hx509ctx, id->certs, q, cert);
+       ret = hx509_certs_find(context->hx509ctx, id->certs, q, cert);
        if (ret == 0)
            break;
-       pk_copy_error(context, id->hx509ctx, ret,
+       pk_copy_error(context, context->hx509ctx, ret,
                      "Failed finding certificate with %s OID", cf[i].type);
     }
     return ret;
@@ -221,7 +222,7 @@ create_signature(krb5_context context,
     if (id->cert == NULL)
        flags |= HX509_CMS_SIGNATURE_NO_SIGNER;
 
-    ret = hx509_cms_create_signed_1(id->hx509ctx,
+    ret = hx509_cms_create_signed_1(context->hx509ctx,
                                    flags,
                                    eContentType,
                                    eContent->data,
@@ -233,7 +234,7 @@ create_signature(krb5_context context,
                                    id->certs,
                                    sd_data);
     if (ret) {
-       pk_copy_error(context, id->hx509ctx, ret,
+       pk_copy_error(context, context->hx509ctx, ret,
                      "Create CMS signedData");
        return ret;
     }
@@ -596,7 +597,7 @@ build_auth_pack(krb5_context context,
        if (a->supportedCMSTypes == NULL)
            return ENOMEM;
 
-       ret = hx509_crypto_available(ctx->id->hx509ctx, HX509_SELECT_ALL, NULL,
+       ret = hx509_crypto_available(context->hx509ctx, HX509_SELECT_ALL, NULL,
                                     &a->supportedCMSTypes->val,
                                     &a->supportedCMSTypes->len);
        if (ret)
@@ -756,7 +757,7 @@ pk_mk_padata(krb5_context context,
                free_PA_PK_AS_REQ(&req);
                goto out;
            }
-           ret = build_edi(context, ctx->id->hx509ctx,
+           ret = build_edi(context, context->hx509ctx,
                            ctx->id->anchors, req.trustedCertifiers);
            if (ret) {
                krb5_set_error_message(context, ret,
@@ -806,6 +807,12 @@ _krb5_pk_mk_padata(krb5_context context,
     krb5_pk_init_ctx ctx = c;
     int win2k_compat;
 
+    if (ctx->id->certs == NULL && ctx->anonymous == 0) {
+       krb5_set_error_message(context, HEIM_PKINIT_NO_PRIVATE_KEY,
+                              N_("PKINIT: No user certificate given", ""));
+       return HEIM_PKINIT_NO_PRIVATE_KEY;
+    }
+
     win2k_compat = krb5_config_get_bool_default(context, NULL,
                                                FALSE,
                                                "realms",
@@ -873,7 +880,7 @@ pk_verify_sign(krb5_context context,
 
     *signer = NULL;
 
-    ret = hx509_cms_verify_signed(id->hx509ctx,
+    ret = hx509_cms_verify_signed(context->hx509ctx,
                                  id->verify_ctx,
                                  HX509_CMS_VS_ALLOW_DATA_OID_MISMATCH|HX509_CMS_VS_NO_KU_CHECK,
                                  data,
@@ -884,7 +891,7 @@ pk_verify_sign(krb5_context context,
                                  content,
                                  &signer_certs);
     if (ret) {
-       pk_copy_error(context, id->hx509ctx, ret,
+       pk_copy_error(context, context->hx509ctx, ret,
                      "CMS verify signed failed");
        return ret;
     }
@@ -896,9 +903,9 @@ pk_verify_sign(krb5_context context,
        goto out;
     }
        
-    ret = hx509_get_one_cert(id->hx509ctx, signer_certs, &(*signer)->cert);
+    ret = hx509_get_one_cert(context->hx509ctx, signer_certs, &(*signer)->cert);
     if (ret) {
-       pk_copy_error(context, id->hx509ctx, ret,
+       pk_copy_error(context, context->hx509ctx, ret,
                      "Failed to get on of the signer certs");
        goto out;
     }
@@ -1040,7 +1047,7 @@ pk_verify_host(krb5_context context,
     krb5_error_code ret = 0;
 
     if (ctx->require_eku) {
-       ret = hx509_cert_check_eku(ctx->id->hx509ctx, host->cert,
+       ret = hx509_cert_check_eku(context->hx509ctx, host->cert,
                                   &asn1_oid_id_pkkdcekuoid, 0);
        if (ret) {
            krb5_set_error_message(context, ret,
@@ -1052,7 +1059,7 @@ pk_verify_host(krb5_context context,
        hx509_octet_string_list list;
        int i;
 
-       ret = hx509_cert_find_subjectAltName_otherName(ctx->id->hx509ctx,
+       ret = hx509_cert_find_subjectAltName_otherName(context->hx509ctx,
                                                       host->cert,
                                                       &asn1_oid_id_pkinit_san,
                                                       &list);
@@ -1102,7 +1109,7 @@ pk_verify_host(krb5_context context,
        return ret;
 
     if (hi) {
-       ret = hx509_verify_hostname(ctx->id->hx509ctx, host->cert,
+       ret = hx509_verify_hostname(context->hx509ctx, host->cert,
                                    ctx->require_hostname_match,
                                    HX509_HN_HOSTNAME,
                                    hi->hostname,
@@ -1145,7 +1152,7 @@ pk_rd_pa_reply_enckey(krb5_context context,
     if (ctx->type == PKINIT_WIN2K)
        flags |= HX509_CMS_UE_ALLOW_WEAK;
 
-    ret = hx509_cms_unenvelope(ctx->id->hx509ctx,
+    ret = hx509_cms_unenvelope(context->hx509ctx,
                               ctx->id->certs,
                               flags,
                               indata->data,
@@ -1155,7 +1162,7 @@ pk_rd_pa_reply_enckey(krb5_context context,
                               &contentType,
                               &content);
     if (ret) {
-       pk_copy_error(context, ctx->id->hx509ctx, ret,
+       pk_copy_error(context, context->hx509ctx, ret,
                      "Failed to unenvelope CMS data in PK-INIT reply");
        return ret;
     }
@@ -1167,8 +1174,26 @@ pk_rd_pa_reply_enckey(krb5_context context,
        heim_octet_string out;
 
        ret = hx509_cms_unwrap_ContentInfo(&content, &type, &out, NULL);
-       if (ret)
-           goto out;
+       if (ret) {
+           /* windows LH with interesting CMS packets */
+           size_t ph = 1 + der_length_len(content.length);
+           unsigned char *ptr = malloc(content.length + ph);
+           size_t l;
+           
+           memcpy(ptr + ph, content.data, content.length);
+           
+           ret = der_put_length_and_tag (ptr + ph - 1, ph, content.length,
+                                         ASN1_C_UNIV, CONS, UT_Sequence, &l);
+           if (ret)
+               return ret;
+           free(content.data);
+           content.data = ptr;
+           content.length += ph;
+
+           ret = hx509_cms_unwrap_ContentInfo(&content, &type, &out, NULL);
+           if (ret)
+               goto out;
+       }
        if (der_heim_oid_cmp(&type, &asn1_oid_id_pkcs7_signedData)) {
            ret = EINVAL; /* XXX */
            krb5_set_error_message(context, ret,
@@ -1700,10 +1725,44 @@ hx_pass_prompter(void *data, const hx509_prompt *prompter)
     return 0;
 }
 
+static krb5_error_code
+_krb5_pk_set_user_id(krb5_context context,
+                    krb5_pk_init_ctx ctx,
+                    struct hx509_certs_data *certs)
+{
+    hx509_certs c = hx509_certs_ref(certs);
+    hx509_query *q = NULL;
+    int ret;
+
+    if (ctx->id->certs)
+       hx509_certs_free(&ctx->id->certs);
+    if (ctx->id->cert) {
+       hx509_cert_free(ctx->id->cert);
+       ctx->id->cert = NULL;
+    }
+
+    ctx->id->certs = c;
+    ctx->anonymous = 0;
+
+    ret = hx509_query_alloc(context->hx509ctx, &q);
+    if (ret) {
+       pk_copy_error(context, context->hx509ctx, ret,
+                     "Allocate query to find signing certificate");
+       return ret;
+    }
+       
+    hx509_query_match_option(q, HX509_QUERY_OPTION_PRIVATE_KEY);
+    hx509_query_match_option(q, HX509_QUERY_OPTION_KU_DIGITALSIGNATURE);
+       
+    ret = find_cert(context, ctx->id, q, &ctx->id->cert);
+    hx509_query_free(context->hx509ctx, q);
+
+    return ret;
+}
+
 krb5_error_code KRB5_LIB_FUNCTION
 _krb5_pk_load_id(krb5_context context,
                 struct krb5_pk_identity **ret_id,
-                int flags,
                 const char *user_id,
                 const char *anchor_id,
                 char * const *chain_list,
@@ -1713,7 +1772,6 @@ _krb5_pk_load_id(krb5_context context,
                 char *password)
 {
     struct krb5_pk_identity *id = NULL;
-    hx509_lock lock = NULL;
     struct prompter p;
     int ret;
 
@@ -1725,12 +1783,6 @@ _krb5_pk_load_id(krb5_context context,
        return HEIM_PKINIT_NO_VALID_CA;
     }
 
-    if (user_id == NULL && (flags & 4) == 0) {
-       krb5_set_error_message(context, HEIM_PKINIT_NO_PRIVATE_KEY,
-                              N_("PKINIT: No user certificate given", ""));
-       return HEIM_PKINIT_NO_PRIVATE_KEY;
-    }
-
     /* load cert */
 
     id = calloc(1, sizeof(*id));
@@ -1740,33 +1792,34 @@ _krb5_pk_load_id(krb5_context context,
        return ENOMEM;
     }  
 
-    ret = hx509_context_init(&id->hx509ctx);
-    if (ret)
-       goto out;
-
-    ret = hx509_lock_init(id->hx509ctx, &lock);
-    if (ret) {
-       pk_copy_error(context, id->hx509ctx, ret, "Failed init lock");
-       goto out;
-    }
-
-    if (password && password[0])
-       hx509_lock_add_password(lock, password);
-
-    if (prompter) {
-       p.context = context;
-       p.prompter = prompter;
-       p.prompter_data = prompter_data;
+    if (user_id) {
+       hx509_lock lock;
 
-       ret = hx509_lock_set_prompter(lock, hx_pass_prompter, &p);
-       if (ret)
+       ret = hx509_lock_init(context->hx509ctx, &lock);
+       if (ret) {
+           pk_copy_error(context, context->hx509ctx, ret, "Failed init lock");
            goto out;
-    }
+       }
+       
+       if (password && password[0])
+           hx509_lock_add_password(lock, password);
+       
+       if (prompter) {
+           p.context = context;
+           p.prompter = prompter;
+           p.prompter_data = prompter_data;
+           
+           ret = hx509_lock_set_prompter(lock, hx_pass_prompter, &p);
+           if (ret) {
+               hx509_lock_free(lock);
+               goto out;
+           }
+       }
 
-    if (user_id) {
-       ret = hx509_certs_init(id->hx509ctx, user_id, 0, lock, &id->certs);
+       ret = hx509_certs_init(context->hx509ctx, user_id, 0, lock, &id->certs);
+        hx509_lock_free(lock);
        if (ret) {
-           pk_copy_error(context, id->hx509ctx, ret,
+           pk_copy_error(context, context->hx509ctx, ret,
                          "Failed to init cert certs");
            goto out;
        }
@@ -1774,26 +1827,26 @@ _krb5_pk_load_id(krb5_context context,
        id->certs = NULL;
     }
 
-    ret = hx509_certs_init(id->hx509ctx, anchor_id, 0, NULL, &id->anchors);
+    ret = hx509_certs_init(context->hx509ctx, anchor_id, 0, NULL, &id->anchors);
     if (ret) {
-       pk_copy_error(context, id->hx509ctx, ret,
+       pk_copy_error(context, context->hx509ctx, ret,
                      "Failed to init anchors");
        goto out;
     }
 
-    ret = hx509_certs_init(id->hx509ctx, "MEMORY:pkinit-cert-chain",
+    ret = hx509_certs_init(context->hx509ctx, "MEMORY:pkinit-cert-chain",
                           0, NULL, &id->certpool);
     if (ret) {
-       pk_copy_error(context, id->hx509ctx, ret,
+       pk_copy_error(context, context->hx509ctx, ret,
                      "Failed to init chain");
        goto out;
     }
 
     while (chain_list && *chain_list) {
-       ret = hx509_certs_append(id->hx509ctx, id->certpool,
+       ret = hx509_certs_append(context->hx509ctx, id->certpool,
                                 NULL, *chain_list);
        if (ret) {
-           pk_copy_error(context, id->hx509ctx, ret,
+           pk_copy_error(context, context->hx509ctx, ret,
                          "Failed to laod chain %s",
                          *chain_list);
            goto out;
@@ -1802,30 +1855,30 @@ _krb5_pk_load_id(krb5_context context,
     }
 
     if (revoke_list) {
-       ret = hx509_revoke_init(id->hx509ctx, &id->revokectx);
+       ret = hx509_revoke_init(context->hx509ctx, &id->revokectx);
        if (ret) {
-           pk_copy_error(context, id->hx509ctx, ret,
+           pk_copy_error(context, context->hx509ctx, ret,
                          "Failed init revoke list");
            goto out;
        }
 
        while (*revoke_list) {
-           ret = hx509_revoke_add_crl(id->hx509ctx,
+           ret = hx509_revoke_add_crl(context->hx509ctx,
                                       id->revokectx,
                                       *revoke_list);
            if (ret) {
-               pk_copy_error(context, id->hx509ctx, ret,
+               pk_copy_error(context, context->hx509ctx, ret,
                              "Failed load revoke list");
                goto out;
            }
            revoke_list++;
        }
     } else
-       hx509_context_set_missing_revoke(id->hx509ctx, 1);
+       hx509_context_set_missing_revoke(context->hx509ctx, 1);
 
-    ret = hx509_verify_init_ctx(id->hx509ctx, &id->verify_ctx);
+    ret = hx509_verify_init_ctx(context->hx509ctx, &id->verify_ctx);
     if (ret) {
-       pk_copy_error(context, id->hx509ctx, ret,
+       pk_copy_error(context, context->hx509ctx, ret,
                      "Failed init verify context");
        goto out;
     }
@@ -1840,14 +1893,11 @@ _krb5_pk_load_id(krb5_context context,
        hx509_certs_free(&id->anchors);
        hx509_certs_free(&id->certpool);
        hx509_revoke_free(&id->revokectx);
-       hx509_context_free(&id->hx509ctx);
+       hx509_context_free(&context->hx509ctx);
        free(id);
     } else
        *ret_id = id;
 
-    if (lock)
-        hx509_lock_free(lock);
-
     return ret;
 }
 
@@ -2204,7 +2254,6 @@ _krb5_get_init_creds_opt_free_pkinit(krb5_get_init_creds_opt *opt)
        hx509_cert_free(ctx->id->cert);
        hx509_certs_free(&ctx->id->anchors);
        hx509_certs_free(&ctx->id->certpool);
-       hx509_context_free(&ctx->id->hx509ctx);
 
        if (ctx->clientDHNonce) {
            krb5_free_data(NULL, ctx->clientDHNonce);
@@ -2275,9 +2324,11 @@ krb5_get_init_creds_opt_set_pkinit(krb5_context context,
        x509_anchors = anchors;
     }
 
+    if (flags & 4)
+       opt->opt_private->pk_init_ctx->anonymous = 1;
+
     ret = _krb5_pk_load_id(context,
                           &opt->opt_private->pk_init_ctx->id,
-                          flags,
                           user_id,
                           x509_anchors,
                           pool,
@@ -2292,31 +2343,14 @@ krb5_get_init_creds_opt_set_pkinit(krb5_context context,
     }
 
     if (opt->opt_private->pk_init_ctx->id->certs) {
-       hx509_query *q = NULL;
-       hx509_cert cert = NULL;
-       hx509_context hx509ctx = opt->opt_private->pk_init_ctx->id->hx509ctx;
-
-       ret = hx509_query_alloc(hx509ctx, &q);
-       if (ret) {
-           pk_copy_error(context, hx509ctx, ret,
-                         "Allocate query to find signing certificate");
-           return ret;
-       }
-       
-       hx509_query_match_option(q, HX509_QUERY_OPTION_PRIVATE_KEY);
-       hx509_query_match_option(q, HX509_QUERY_OPTION_KU_DIGITALSIGNATURE);
-       
-       ret = find_cert(context, opt->opt_private->pk_init_ctx->id, q, &cert);
-       hx509_query_free(hx509ctx, q);
-       if (ret)
-           return ret;
-
-       opt->opt_private->pk_init_ctx->id->cert = cert;
+       _krb5_pk_set_user_id(context,
+                            opt->opt_private->pk_init_ctx,
+                            opt->opt_private->pk_init_ctx->id->certs);
     } else
        opt->opt_private->pk_init_ctx->id->cert = NULL;
 
     if ((flags & 2) == 0) {
-       hx509_context hx509ctx = opt->opt_private->pk_init_ctx->id->hx509ctx;
+       hx509_context hx509ctx = context->hx509ctx;
        hx509_cert cert = opt->opt_private->pk_init_ctx->id->cert;
 
        opt->opt_private->pk_init_ctx->keyex = USE_DH;
@@ -2353,6 +2387,33 @@ krb5_get_init_creds_opt_set_pkinit(krb5_context context,
 #endif
 }
 
+krb5_error_code KRB5_LIB_FUNCTION
+_krb5_get_init_creds_opt_set_pkinit_user_certs(krb5_context context,
+                                              krb5_get_init_creds_opt *opt,
+                                              struct hx509_certs_data *certs)
+{
+#ifdef PKINIT
+    if (opt->opt_private == NULL) {
+       krb5_set_error_message(context, EINVAL,
+                              N_("PKINIT: on non extendable opt", ""));
+       return EINVAL;
+    }
+    if (opt->opt_private->pk_init_ctx == NULL) {
+       krb5_set_error_message(context, EINVAL,
+                              N_("PKINIT: on pkinit context", ""));
+       return EINVAL;
+    }
+    
+    _krb5_pk_set_user_id(context, opt->opt_private->pk_init_ctx, certs);
+
+    return 0;
+#else
+    krb5_set_error_message(context, EINVAL,
+                          N_("no support for PKINIT compiled in", ""));
+    return EINVAL;
+#endif
+}
+
 #ifdef PKINIT
 
 static int
@@ -2404,34 +2465,35 @@ krb5_error_code  KRB5_LIB_FUNCTION
 _krb5_pk_enterprise_cert(krb5_context context,
                         const char *user_id,
                         krb5_const_realm realm,
-                        krb5_principal *principal)
+                        krb5_principal *principal,
+                        struct hx509_certs_data **res)
 {
 #ifdef PKINIT
     krb5_error_code ret;
-    hx509_context hx509ctx;
     hx509_certs certs, result;
     hx509_cert cert;
     hx509_query *q;
     char *name;
 
     *principal = NULL;
+    if (res)
+       *res = NULL;
     
-    if (user_id == NULL)
+    if (user_id == NULL) {
+       krb5_clear_error_message(context);
        return ENOENT;
+    }
 
-    ret = hx509_context_init(&hx509ctx);
-    if (ret)
-       return ret;
-
-    ret = hx509_certs_init(hx509ctx, user_id, 0, NULL, &certs);
+    ret = hx509_certs_init(context->hx509ctx, user_id, 0, NULL, &certs);
     if (ret) {
-       pk_copy_error(context, hx509ctx, ret,
+       pk_copy_error(context, context->hx509ctx, ret,
                      "Failed to init cert certs");
        return ret;
     }
 
-    ret = hx509_query_alloc(hx509ctx, &q);
+    ret = hx509_query_alloc(context->hx509ctx, &q);
     if (ret) {
+       krb5_set_error_message(context, ret, "out of memory");
        hx509_certs_free(&certs);
        return ret;
     }
@@ -2441,29 +2503,54 @@ _krb5_pk_enterprise_cert(krb5_context context,
     hx509_query_match_eku(q, &asn1_oid_id_pkinit_ms_eku);
     hx509_query_match_cmp_func(q, find_ms_san, NULL);
 
-    ret = hx509_certs_filter(hx509ctx, certs, q, &result);
-    hx509_query_free(hx509ctx, q);
+    ret = hx509_certs_filter(context->hx509ctx, certs, q, &result);
+    hx509_query_free(context->hx509ctx, q);
     hx509_certs_free(&certs);
-    if (ret)
+    if (ret) {
+       pk_copy_error(context, context->hx509ctx, ret,
+                     "Failed to find PKINIT certificate");
        return ret;
+    }
     
-    ret = hx509_get_one_cert(hx509ctx, result, &cert);
+    ret = hx509_get_one_cert(context->hx509ctx, result, &cert);
     hx509_certs_free(&result);
-    if (ret)
-       return ret;
+    if (ret) {
+       pk_copy_error(context, context->hx509ctx, ret,
+                     "Failed to get one cert");
+       goto out;
+    }
 
-    ret = get_ms_san(hx509ctx, cert, &name);
-    if (ret)
-       return ret;
+    ret = get_ms_san(context->hx509ctx, cert, &name);
+    if (ret) {
+       pk_copy_error(context, context->hx509ctx, ret,
+                     "Failed to get MS SAN");
+       goto out;
+    }
 
     ret = krb5_make_principal(context, principal, realm, name, NULL);
     free(name);
-    hx509_context_free(&hx509ctx);
     if (ret)
-       return ret;
+       goto out;
 
     krb5_principal_set_type(context, *principal, KRB5_NT_ENTERPRISE_PRINCIPAL);
-    
+
+    if (res) {
+       ret = hx509_certs_init(context->hx509ctx, "MEMORY:", 0, NULL, res);
+       if (ret) {
+           hx509_cert_free(cert);
+           goto out;
+       }
+       
+       ret = hx509_certs_add(context->hx509ctx, *res, cert);
+       if (ret) {
+           hx509_certs_free(res);
+           goto out;
+       }
+    }
+
+ out:
+    hx509_cert_free(cert);
+
     return ret;
 #else
     krb5_set_error_message(context, EINVAL,
index 1483d59f9dc03b11582de4c0fcc3c25ed7644c11..d854113a43f97d3667ffc300859eb2683396a907 100644 (file)
@@ -106,6 +106,17 @@ krb5_principal_set_type(krb5_context context,
     princ_type(principal) = type;
 }
 
+/**
+ * Get the type of the principal
+ *
+ * @param context A Kerberos context.
+ * @param principal principal to get the type for
+ *
+ * @return the type of principal
+ *
+ * @ingroup krb5_principal
+ */
+
 int KRB5_LIB_FUNCTION
 krb5_principal_get_type(krb5_context context,
                        krb5_const_principal principal)
@@ -113,6 +124,17 @@ krb5_principal_get_type(krb5_context context,
     return princ_type(principal);
 }
 
+/**
+ * Get the realm of the principal
+ *
+ * @param context A Kerberos context.
+ * @param principal principal to get the realm for
+ *
+ * @return realm of the principal, don't free or use after krb5_principal is freed
+ *
+ * @ingroup krb5_principal
+ */
+
 const char* KRB5_LIB_FUNCTION
 krb5_principal_get_realm(krb5_context context,
                         krb5_const_principal principal)
@@ -148,6 +170,19 @@ krb5_principal_get_num_comp(krb5_context context,
     return princ_num_comp(principal);
 }
 
+/**
+ * Parse a name into a krb5_principal structure, flags controls the behavior.
+ *
+ * @param context Kerberos 5 context
+ * @param name name to parse into a Kerberos principal
+ * @param flags flags to control the behavior
+ * @param principal returned principal, free with krb5_free_principal().
+ *
+ * @return An krb5 error code, see krb5_get_error_message().
+ *
+ * @ingroup krb5_principal
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_parse_name_flags(krb5_context context,
                      const char *name,
@@ -337,6 +372,18 @@ exit:
     return ret;
 }
 
+/**
+ * Parse a name into a krb5_principal structure
+ *
+ * @param context Kerberos 5 context
+ * @param name name to parse into a Kerberos principal
+ * @param principal returned principal, free with krb5_free_principal().
+ *
+ * @return An krb5 error code, see krb5_get_error_message().
+ *
+ * @ingroup krb5_principal
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_parse_name(krb5_context context,
                const char *name,
@@ -630,6 +677,20 @@ krb5_principal_set_realm(krb5_context context,
     return 0;
 }
 
+#ifndef HEIMDAL_SMALLER
+/**
+ * Build a principal using vararg style building
+ *
+ * @param context A Kerberos context.
+ * @param principal returned principal
+ * @param rlen length of realm
+ * @param realm realm name
+ * @param ... a list of components ended with NULL.
+ *
+ * @return An krb5 error code, see krb5_get_error_message().
+ *
+ * @ingroup krb5_principal
+ */
 
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_build_principal(krb5_context context,
@@ -645,6 +706,43 @@ krb5_build_principal(krb5_context context,
     va_end(ap);
     return ret;
 }
+#endif
+
+/**
+ * Build a principal using vararg style building
+ *
+ * @param context A Kerberos context.
+ * @param principal returned principal
+ * @param realm realm name
+ * @param ... a list of components ended with NULL.
+ *
+ * @return An krb5 error code, see krb5_get_error_message().
+ *
+ * @ingroup krb5_principal
+ */
+
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_make_principal(krb5_context context,
+                   krb5_principal *principal,
+                   krb5_const_realm realm,
+                   ...)
+{
+    krb5_error_code ret;
+    krb5_realm r = NULL;
+    va_list ap;
+    if(realm == NULL) {
+       ret = krb5_get_default_realm(context, &r);
+       if(ret)
+           return ret;
+       realm = r;
+    }
+    va_start(ap, realm);
+    ret = krb5_build_principal_va(context, principal, strlen(realm), realm, ap);
+    va_end(ap);
+    if(r)
+       free(r);
+    return ret;
+}
 
 static krb5_error_code
 append_component(krb5_context context, krb5_principal p,
@@ -730,28 +828,6 @@ build_principal(krb5_context context,
     return 0;
 }
 
-krb5_error_code KRB5_LIB_FUNCTION
-krb5_make_principal(krb5_context context,
-                   krb5_principal *principal,
-                   krb5_const_realm realm,
-                   ...)
-{
-    krb5_error_code ret;
-    krb5_realm r = NULL;
-    va_list ap;
-    if(realm == NULL) {
-       ret = krb5_get_default_realm(context, &r);
-       if(ret)
-           return ret;
-       realm = r;
-    }
-    va_start(ap, realm);
-    ret = krb5_build_principal_va(context, principal, strlen(realm), realm, ap);
-    va_end(ap);
-    if(r)
-       free(r);
-    return ret;
-}
 
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_build_principal_va(krb5_context context,
@@ -789,6 +865,18 @@ krb5_build_principal_ext(krb5_context context,
     return ret;
 }
 
+/**
+ * Copy a principal
+ *
+ * @param context A Kerberos context.
+ * @param inprinc principal to copy
+ * @param outprinc copied principal, free with krb5_free_principal()
+ *
+ * @return An krb5 error code, see krb5_get_error_message().
+ *
+ * @ingroup krb5_principal
+ */
+
 
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_copy_principal(krb5_context context,
@@ -821,6 +909,8 @@ krb5_copy_principal(krb5_context context,
  * @return non zero if equal, 0 if not
  *
  * @ingroup krb5_principal
+ * @see krb5_principal_compare()
+ * @see krb5_realm_compare()
  */
 
 krb5_boolean KRB5_LIB_FUNCTION
@@ -854,6 +944,19 @@ _krb5_principal_compare_PrincipalName(krb5_context context,
 }
 
 
+/**
+ * Compares the two principals, including realm of the principals and returns
+ * TRUE if they are the same and FALSE if not.
+ *
+ * @param context Kerberos 5 context
+ * @param princ1 first principal to compare
+ * @param princ2 second principal to compare
+ *
+ * @ingroup krb5_principal
+ * @see krb5_principal_compare_any_realm()
+ * @see krb5_realm_compare()
+ */
+
 /*
  * return TRUE iff princ1 == princ2
  */
@@ -868,8 +971,16 @@ krb5_principal_compare(krb5_context context,
     return krb5_principal_compare_any_realm(context, princ1, princ2);
 }
 
-/*
+/**
  * return TRUE iff realm(princ1) == realm(princ2)
+ *
+ * @param context Kerberos 5 context
+ * @param princ1 first principal to compare
+ * @param princ2 second principal to compare
+ *
+ * @ingroup krb5_principal
+ * @see krb5_principal_compare_any_realm()
+ * @see krb5_principal_compare()
  */
 
 krb5_boolean KRB5_LIB_FUNCTION
@@ -880,8 +991,10 @@ krb5_realm_compare(krb5_context context,
     return strcmp(princ_realm(princ1), princ_realm(princ2)) == 0;
 }
 
-/*
+/**
  * return TRUE iff princ matches pattern
+ *
+ * @ingroup krb5_principal
  */
 
 krb5_boolean KRB5_LIB_FUNCTION
@@ -1418,6 +1531,12 @@ static const struct {
     { NULL }
 };
 
+/**
+ * Parse nametype string and return a nametype integer
+ *
+ * @ingroup krb5_principal
+ */
+
 krb5_error_code
 krb5_parse_nametype(krb5_context context, const char *str, int32_t *nametype)
 {
index be484c29dc49d34fb2ba67d4d1f101b91e689e72..0cad91e43724a8de8f9e5d12f7fde759a467c50f 100644 (file)
@@ -133,9 +133,10 @@ krb5_rc_initialize(krb5_context context,
     int ret;
 
     if(f == NULL) {
+       char buf[128];
        ret = errno;
-       krb5_set_error_message(context, ret, "open(%s): %s", id->name,
-                              strerror(ret));
+       strerror_r(ret, buf, sizeof(buf));
+       krb5_set_error_message(context, ret, "open(%s): %s", id->name, buf);
        return ret;
     }
     tmp.stamp = auth_lifespan;
@@ -158,9 +159,10 @@ krb5_rc_destroy(krb5_context context,
     int ret;
 
     if(remove(id->name) < 0) {
+       char buf[128];
        ret = errno;
-       krb5_set_error_message(context, ret, "remove(%s): %s", id->name,
-                              strerror(ret));
+       strerror_r(ret, buf, sizeof(buf));
+       krb5_set_error_message(context, ret, "remove(%s): %s", id->name, buf);
        return ret;
     }
     return krb5_rc_close(context, id);
@@ -208,9 +210,10 @@ krb5_rc_store(krb5_context context,
     checksum_authenticator(rep, ent.data);
     f = fopen(id->name, "r");
     if(f == NULL) {
+       char buf[128];
        ret = errno;
-       krb5_set_error_message(context, ret, "open(%s): %s", id->name,
-                              strerror(ret));
+       strerror_r(ret, buf, sizeof(buf));
+       krb5_set_error_message(context, ret, "open(%s): %s", id->name, buf);
        return ret;
     }
     rk_cloexec_file(f);
@@ -226,18 +229,21 @@ krb5_rc_store(krb5_context context,
        }
     }
     if(ferror(f)){
+       char buf[128];
        ret = errno;
        fclose(f);
+       strerror_r(ret, buf, sizeof(buf));
        krb5_set_error_message(context, ret, "%s: %s",
-                              id->name, strerror(ret));
+                              id->name, buf);
        return ret;
     }
     fclose(f);
     f = fopen(id->name, "a");
     if(f == NULL) {
+       char buf[128];
+       strerror_r(errno, buf, sizeof(buf));
        krb5_set_error_message(context, KRB5_RC_IO_UNKNOWN,
-                              "open(%s): %s", id->name,
-                              strerror(errno));
+                              "open(%s): %s", id->name, buf);
        return KRB5_RC_IO_UNKNOWN;
     }
     fwrite(&ent, 1, sizeof(ent), f);
index 05239186ec86d7903acaa3ede2b0d1e748a7aa31..886a1fe981bb898b28ac8d685fb10bb8de04ffcd 100644 (file)
@@ -59,19 +59,13 @@ _warnerr(krb5_context context, int do_errtext,
        *arg++ = msg;
     }
     if(context && do_errtext){
-       const char *err_msg;
-
        strlcat(xfmt, "%s", sizeof(xfmt));
 
        err_str = krb5_get_error_message(context, code);
        if (err_str != NULL) {
            *arg = err_str;
        } else {
-           err_msg = krb5_get_err_text(context, code);
-           if (err_msg)
-               *arg = err_msg;
-           else
-               *arg= "<unknown error>";
+           *arg= "<unknown error>";
        }
     }
        
index 2776c1318b15d4f541d715436979ee7b6c545bf6..6043e2b81564bcf553385da93f50d59b3df8f1d1 100644 (file)
@@ -93,6 +93,10 @@ caught_signal(int signo)
 static void
 open_pty(void)
 {
+#ifdef _AIX
+    printf("implement open_pty\n");
+    exit(77);
+#endif
 #if defined(HAVE_OPENPTY) || defined(__linux) || defined(__osf__) /* XXX */
     if(openpty(&master, &slave, line, 0, 0) == 0)
        return;
index 2bd471736cc86ee6f6036ce5c41872ec26cc6273..6fc533c697f075ee4cefe685cdfcf81712c769a8 100644 (file)
@@ -306,6 +306,12 @@ int ROKEN_LIB_FUNCTION getdtablesize(void);
 char * ROKEN_LIB_FUNCTION strerror(int);
 #endif
 
+#if !defined(HAVE_STRERROR) && !defined(strerror)
+#define strerror_r rk_strerror_r
+int ROKEN_LIB_FUNCTION strerror_r(int, char *, size_t);
+#endif
+
+
 #if !defined(HAVE_HSTRERROR) || defined(NEED_HSTRERROR_PROTO)
 #ifndef HAVE_HSTRERROR
 #define hstrerror rk_hstrerror
@@ -476,7 +482,7 @@ unsigned short ROKEN_LIB_FUNCTION bswap16(unsigned short);
 int rk_flock(int fd, int operation);
 #endif /* HAVE_FLOCK */
 
-#ifdef SunOS
+#if defined(SunOS) || defined(_AIX)
 #define dirfd(x) ((x)->dd_fd)
 #endif
 
@@ -799,6 +805,12 @@ time_t ROKEN_LIB_FUNCTION
 rk_timegm(struct tm *tm);
 #endif
 
+#ifdef NEED_QSORT
+#define qsort rk_qsort
+void
+rk_qsort(void *, size_t, size_t, int (*)(const void *, const void *));
+#endif
+
 #ifdef SOCKET_WRAPPER_REPLACE
 #include <socket_wrapper.h>
 #endif
index 4c70a52932bc2a568541bb25b0a867e509904b4e..102c577e66455c993c5753024e4c24faadd2e4e2 100644 (file)
@@ -39,6 +39,9 @@
 #include <assert.h>
 #include <stdlib.h>
 #include <errno.h>
+#include <stdio.h>
+
+#include "roken.h"
 
 #include "normalize_table.h"
 
@@ -173,7 +176,7 @@ cc_cmp(const void *a, const void *b)
 static void
 canonical_reorder(uint32_t *tmp, size_t tmp_len)
 {
-    unsigned i;
+    size_t i;
 
     for (i = 0; i < tmp_len; ++i) {
        int cc = _wind_combining_class(tmp[i]);
@@ -183,8 +186,7 @@ canonical_reorder(uint32_t *tmp, size_t tmp_len)
                 j < tmp_len && _wind_combining_class(tmp[j]);
                 ++j)
                ;
-           qsort(&tmp[i], j - i, sizeof(unsigned),
-                 cc_cmp);
+           qsort(&tmp[i], j - i, sizeof(tmp[0]), cc_cmp);
            i = j;
        }
     }
@@ -280,6 +282,11 @@ _wind_stringprep_normalize(const uint32_t *in, size_t in_len,
     uint32_t *tmp;
     int ret;
 
+    if (in_len == 0) {
+       *out_len = 0;
+       return 0;
+    }
+
     tmp_len = in_len * 4;
     if (tmp_len < MAX_LENGTH_CANON)
        tmp_len = MAX_LENGTH_CANON;
index a991f20cfb7a6a8a55e9338d5658375365a008ad..ec4657665e501bca7a3bd47a71c810d81af85535 100644 (file)
@@ -58,10 +58,16 @@ wind_stringprep(const uint32_t *in, size_t in_len,
                wind_profile_flags flags)
 {
     size_t tmp_len = in_len * 3;
-    uint32_t *tmp = malloc(tmp_len * sizeof(uint32_t));
+    uint32_t *tmp;
     int ret;
     size_t olen;
 
+    if (in_len == 0) {
+       *out_len = 0;
+       return 0;
+    }
+
+    tmp = malloc(tmp_len * sizeof(uint32_t));
     if (tmp == NULL)
        return ENOMEM;