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:
parent
5bc87c14a1
commit
4f8ba5ad6a
@ -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:
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -44,6 +44,7 @@ enum typetype {
|
||||
TChoice,
|
||||
TEnumerated,
|
||||
TGeneralString,
|
||||
TTeletexString,
|
||||
TGeneralizedTime,
|
||||
TIA5String,
|
||||
TInteger,
|
||||
|
@ -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 *);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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));
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -59,7 +59,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
const int hdb_interface_version = HDB_INTERFACE_VERSION;
|
||||
|
||||
static struct hdb_method methods[] = {
|
||||
#if HAVE_DB1 || HAVE_DB3
|
||||
|
@ -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__ */
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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 = {
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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>";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user