aboutsummaryrefslogtreecommitdiff
path: root/lib/krb5/ticket.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/krb5/ticket.c')
-rw-r--r--lib/krb5/ticket.c182
1 files changed, 87 insertions, 95 deletions
diff --git a/lib/krb5/ticket.c b/lib/krb5/ticket.c
index 5b6eabe2b0e0..b8d81c6ad53a 100644
--- a/lib/krb5/ticket.c
+++ b/lib/krb5/ticket.c
@@ -81,11 +81,8 @@ krb5_copy_ticket(krb5_context context,
*to = NULL;
tmp = malloc(sizeof(*tmp));
- if(tmp == NULL) {
- krb5_set_error_message(context, ENOMEM,
- N_("malloc: out of memory", ""));
- return ENOMEM;
- }
+ if (tmp == NULL)
+ return krb5_enomem(context);
if((ret = copy_EncTicketPart(&from->ticket, &tmp->ticket))){
free(tmp);
return ret;
@@ -325,6 +322,37 @@ out:
return ret;
}
+KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
+_krb5_get_ad(krb5_context context,
+ const AuthorizationData *ad,
+ krb5_keyblock *sessionkey,
+ int type,
+ krb5_data *data)
+{
+ krb5_boolean found = FALSE;
+ krb5_error_code ret;
+
+ krb5_data_zero(data);
+
+ if (ad == NULL) {
+ krb5_set_error_message(context, ENOENT,
+ N_("No authorization data", ""));
+ return ENOENT; /* XXX */
+ }
+
+ ret = find_type_in_ad(context, type, data, &found, TRUE, sessionkey, ad, 0);
+ if (ret)
+ return ret;
+ if (!found) {
+ krb5_set_error_message(context, ENOENT,
+ N_("Have no authorization data of type %d", ""),
+ type);
+ return ENOENT; /* XXX */
+ }
+ return 0;
+}
+
+
/**
* Extract the authorization data type of type from the ticket. Store
* the field in data. This function is to use for kerberos
@@ -511,88 +539,9 @@ check_client_referral(krb5_context context,
krb5_const_principal mapped,
krb5_keyblock const * key)
{
- krb5_error_code ret;
- PA_ClientCanonicalized canon;
- krb5_crypto crypto;
- krb5_data data;
- PA_DATA *pa;
- size_t len;
- int i = 0;
-
- if (rep->kdc_rep.padata == NULL)
- goto noreferral;
-
- pa = krb5_find_padata(rep->kdc_rep.padata->val,
- rep->kdc_rep.padata->len,
- KRB5_PADATA_CLIENT_CANONICALIZED, &i);
- if (pa == NULL)
- goto noreferral;
-
- ret = decode_PA_ClientCanonicalized(pa->padata_value.data,
- pa->padata_value.length,
- &canon, &len);
- if (ret) {
- krb5_set_error_message(context, ret,
- N_("Failed to decode ClientCanonicalized "
- "from realm %s", ""), requested->realm);
- return ret;
- }
-
- ASN1_MALLOC_ENCODE(PA_ClientCanonicalizedNames, data.data, data.length,
- &canon.names, &len, ret);
- if (ret) {
- free_PA_ClientCanonicalized(&canon);
- return ret;
- }
- if (data.length != len)
- krb5_abortx(context, "internal asn.1 error");
-
- ret = krb5_crypto_init(context, key, 0, &crypto);
- if (ret) {
- free(data.data);
- free_PA_ClientCanonicalized(&canon);
- return ret;
- }
-
- ret = krb5_verify_checksum(context, crypto, KRB5_KU_CANONICALIZED_NAMES,
- data.data, data.length,
- &canon.canon_checksum);
- krb5_crypto_destroy(context, crypto);
- free(data.data);
- if (ret) {
- krb5_set_error_message(context, ret,
- N_("Failed to verify client canonicalized "
- "data from realm %s", ""),
- requested->realm);
- free_PA_ClientCanonicalized(&canon);
- return ret;
- }
-
- if (!_krb5_principal_compare_PrincipalName(context,
- requested,
- &canon.names.requested_name))
+ if (krb5_principal_compare(context, requested, mapped) == FALSE &&
+ !rep->enc_part.flags.enc_pa_rep)
{
- free_PA_ClientCanonicalized(&canon);
- krb5_set_error_message(context, KRB5_PRINC_NOMATCH,
- N_("Requested name doesn't match"
- " in client referral", ""));
- return KRB5_PRINC_NOMATCH;
- }
- if (!_krb5_principal_compare_PrincipalName(context,
- mapped,
- &canon.names.mapped_name))
- {
- free_PA_ClientCanonicalized(&canon);
- krb5_set_error_message(context, KRB5_PRINC_NOMATCH,
- N_("Mapped name doesn't match"
- " in client referral", ""));
- return KRB5_PRINC_NOMATCH;
- }
-
- return 0;
-
-noreferral:
- if (krb5_principal_compare(context, requested, mapped) == FALSE) {
krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED,
N_("Not same client principal returned "
"as requested", ""));
@@ -646,7 +595,7 @@ decrypt_tkt (krb5_context context,
return 0;
}
-int
+KRB5_LIB_FUNCTION int KRB5_LIB_CALL
_krb5_extract_ticket(krb5_context context,
krb5_kdc_rep *rep,
krb5_creds *creds,
@@ -656,6 +605,7 @@ _krb5_extract_ticket(krb5_context context,
krb5_addresses *addrs,
unsigned nonce,
unsigned flags,
+ krb5_data *request,
krb5_decrypt_proc decrypt_proc,
krb5_const_pointer decryptarg)
{
@@ -674,6 +624,48 @@ _krb5_extract_ticket(krb5_context context,
if (ret)
goto out;
+ if (rep->enc_part.flags.enc_pa_rep && request) {
+ krb5_crypto crypto = NULL;
+ Checksum cksum;
+ PA_DATA *pa = NULL;
+ int idx = 0;
+
+ _krb5_debug(context, 5, "processing enc-ap-rep");
+
+ if (rep->enc_part.encrypted_pa_data == NULL ||
+ (pa = krb5_find_padata(rep->enc_part.encrypted_pa_data->val,
+ rep->enc_part.encrypted_pa_data->len,
+ KRB5_PADATA_REQ_ENC_PA_REP,
+ &idx)) == NULL)
+ {
+ _krb5_debug(context, 5, "KRB5_PADATA_REQ_ENC_PA_REP missing");
+ ret = KRB5KRB_AP_ERR_MODIFIED;
+ goto out;
+ }
+
+ ret = krb5_crypto_init(context, key, 0, &crypto);
+ if (ret)
+ goto out;
+
+ ret = decode_Checksum(pa->padata_value.data,
+ pa->padata_value.length,
+ &cksum, NULL);
+ if (ret) {
+ krb5_crypto_destroy(context, crypto);
+ goto out;
+ }
+
+ ret = krb5_verify_checksum(context, crypto,
+ KRB5_KU_AS_REQ,
+ request->data, request->length,
+ &cksum);
+ krb5_crypto_destroy(context, crypto);
+ free_Checksum(&cksum);
+ _krb5_debug(context, 5, "enc-ap-rep: %svalid", (ret == 0) ? "" : "in");
+ if (ret)
+ goto out;
+ }
+
/* save session key */
creds->session.keyvalue.length = 0;
@@ -688,10 +680,10 @@ _krb5_extract_ticket(krb5_context context,
}
/* compare client and save */
- ret = _krb5_principalname2krb5_principal (context,
- &tmp_principal,
- rep->kdc_rep.cname,
- rep->kdc_rep.crealm);
+ ret = _krb5_principalname2krb5_principal(context,
+ &tmp_principal,
+ rep->kdc_rep.cname,
+ rep->kdc_rep.crealm);
if (ret)
goto out;
@@ -776,12 +768,12 @@ _krb5_extract_ticket(krb5_context context,
tmp_time = rep->enc_part.authtime;
if (creds->times.starttime == 0
- && abs(tmp_time - sec_now) > context->max_skew) {
+ && labs(tmp_time - sec_now) > context->max_skew) {
ret = KRB5KRB_AP_ERR_SKEW;
krb5_set_error_message (context, ret,
- N_("time skew (%d) larger than max (%d)", ""),
- abs(tmp_time - sec_now),
- (int)context->max_skew);
+ N_("time skew (%ld) larger than max (%ld)", ""),
+ labs(tmp_time - sec_now),
+ (long)context->max_skew);
goto out;
}