1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-24 10:50:22 +03:00

s4:heimdal: import lorikeet-heimdal-200911122202 (commit 9291fd2d101f3eecec550178634faa94ead3e9a1)

This commit is contained in:
Andrew Bartlett 2009-11-13 10:51:14 +11:00
parent 5bc87c14a1
commit 4f8ba5ad6a
59 changed files with 1170 additions and 648 deletions

View 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:

View 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)

View 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;
}
usage = KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY;
*rk_is_subkey = 1;
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 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) {
unsigned usage = KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY;
krb5_keyblock *subkey;
krb5_data ad;
ret = krb5_auth_con_getremotesubkey(context, ac, &subkey);
if(ret){
krb5_auth_con_free(context, ac);
kdc_log(context, config, 0, "Failed to get remote subkey: %s",
krb5_get_err_text(context, ret));
goto out;
}
if(subkey == NULL){
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){
krb5_auth_con_free(context, ac);
kdc_log(context, config, 0,
"Failed to get key for enc-authorization-data");
ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */
goto out;
}
ret = krb5_crypto_init(context, subkey, 0, &crypto);
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,

View 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;
}

View 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;
}

View 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;

View 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);

View 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;

View 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 {

View 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,

View 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;

View 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;

View 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;

View 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"

View 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:

View 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;

View 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;

View 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,

View File

@ -44,6 +44,7 @@ enum typetype {
TChoice,
TEnumerated,
TGeneralString,
TTeletexString,
TGeneralizedTime,
TIA5String,
TInteger,

View 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 *);

View File

@ -47,18 +47,28 @@
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;
}

View 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);

View 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
}
/**

View 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));

View 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) {

View 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

View File

@ -59,7 +59,7 @@
*
*/
const int hdb_interface_version = HDB_INTERFACE_VERSION;
static struct hdb_method methods[] = {
#if HAVE_DB1 || HAVE_DB3

View 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__ */

View 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;

View 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;
}

View 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);

View 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;
}

View 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;

View 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 = {

View 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

View 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:

View 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) {

View 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

View 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);

View 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;
auth.seq_number = NULL;
auth.authorization_data = NULL;
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);
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;
}

View 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.
*

View 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,

View 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;
}

View 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 */

View 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;
}

View File

@ -33,13 +33,18 @@
#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,

View 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;
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 = 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 = 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

View 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;

View 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;

View 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)

View 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)

View 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;
ret = hx509_lock_set_prompter(lock, hx_pass_prompter, &p);
if (ret)
goto out;
}
if (user_id) {
ret = hx509_certs_init(id->hx509ctx, user_id, 0, lock, &id->certs);
hx509_lock lock;
ret = hx509_lock_init(context->hx509ctx, &lock);
if (ret) {
pk_copy_error(context, id->hx509ctx, 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;
}
}
ret = hx509_certs_init(context->hx509ctx, user_id, 0, lock, &id->certs);
hx509_lock_free(lock);
if (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,

View 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)
{

View 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);

View 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>";
}
}

View 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;

View 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

View 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;

View 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;