summaryrefslogtreecommitdiff
path: root/source4/heimdal/lib/krb5/get_in_tkt.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/heimdal/lib/krb5/get_in_tkt.c')
-rw-r--r--source4/heimdal/lib/krb5/get_in_tkt.c539
1 files changed, 13 insertions, 526 deletions
diff --git a/source4/heimdal/lib/krb5/get_in_tkt.c b/source4/heimdal/lib/krb5/get_in_tkt.c
index cc49e16030..84b1ffb71f 100644
--- a/source4/heimdal/lib/krb5/get_in_tkt.c
+++ b/source4/heimdal/lib/krb5/get_in_tkt.c
@@ -31,529 +31,11 @@
* SUCH DAMAGE.
*/
-#include "krb5_locl.h"
-
-RCSID("$Id$");
-
-krb5_error_code KRB5_LIB_FUNCTION
-krb5_init_etype (krb5_context context,
- unsigned *len,
- krb5_enctype **val,
- const krb5_enctype *etypes)
-{
- unsigned int i;
- krb5_error_code ret;
- krb5_enctype *tmp = NULL;
-
- ret = 0;
- if (etypes == NULL) {
- ret = krb5_get_default_in_tkt_etypes(context,
- &tmp);
- if (ret)
- return ret;
- etypes = tmp;
- }
-
- for (i = 0; etypes[i]; ++i)
- ;
- *len = i;
- *val = malloc(i * sizeof(**val));
- if (i != 0 && *val == NULL) {
- ret = ENOMEM;
- krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
- goto cleanup;
- }
- memmove (*val,
- etypes,
- i * sizeof(*tmp));
-cleanup:
- if (tmp != NULL)
- free (tmp);
- return ret;
-}
-
-static krb5_error_code
-check_server_referral(krb5_context context,
- krb5_kdc_rep *rep,
- unsigned flags,
- krb5_const_principal requested,
- krb5_const_principal returned,
- const krb5_keyblock const * key)
-{
- krb5_error_code ret;
- PA_ServerReferralData ref;
- krb5_crypto session;
- EncryptedData ed;
- size_t len;
- krb5_data data;
- PA_DATA *pa;
- int i = 0, cmp;
-
- if (rep->kdc_rep.padata == NULL)
- goto noreferral;
-
- pa = krb5_find_padata(rep->kdc_rep.padata->val,
- rep->kdc_rep.padata->len,
- KRB5_PADATA_SERVER_REFERRAL, &i);
- if (pa == NULL)
- goto noreferral;
-
- memset(&ed, 0, sizeof(ed));
- memset(&ref, 0, sizeof(ref));
-
- ret = decode_EncryptedData(pa->padata_value.data,
- pa->padata_value.length,
- &ed, &len);
- if (ret)
- return ret;
- if (len != pa->padata_value.length) {
- free_EncryptedData(&ed);
- krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED,
- N_("Referral EncryptedData wrong for realm %s",
- "realm"), requested->realm);
- return KRB5KRB_AP_ERR_MODIFIED;
- }
-
- ret = krb5_crypto_init(context, key, 0, &session);
- if (ret) {
- free_EncryptedData(&ed);
- return ret;
- }
-
- ret = krb5_decrypt_EncryptedData(context, session,
- KRB5_KU_PA_SERVER_REFERRAL,
- &ed, &data);
- free_EncryptedData(&ed);
- krb5_crypto_destroy(context, session);
- if (ret)
- return ret;
-
- ret = decode_PA_ServerReferralData(data.data, data.length, &ref, &len);
- if (ret) {
- krb5_data_free(&data);
- return ret;
- }
- krb5_data_free(&data);
-
- if (strcmp(requested->realm, returned->realm) != 0) {
- free_PA_ServerReferralData(&ref);
- krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED,
- N_("server ref realm mismatch, "
- "requested realm %s got back %s", ""),
- requested->realm, returned->realm);
- return KRB5KRB_AP_ERR_MODIFIED;
- }
-
- if (returned->name.name_string.len == 2 &&
- strcmp(returned->name.name_string.val[0], KRB5_TGS_NAME) == 0)
- {
- const char *realm = returned->name.name_string.val[1];
-
- if (ref.referred_realm == NULL
- || strcmp(*ref.referred_realm, realm) != 0)
- {
- free_PA_ServerReferralData(&ref);
- krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED,
- N_("tgt returned with wrong ref", ""));
- return KRB5KRB_AP_ERR_MODIFIED;
- }
- } else if (krb5_principal_compare(context, returned, requested) == 0) {
- free_PA_ServerReferralData(&ref);
- krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED,
- N_("req princ no same as returned", ""));
- return KRB5KRB_AP_ERR_MODIFIED;
- }
-
- if (ref.requested_principal_name) {
- cmp = _krb5_principal_compare_PrincipalName(context,
- requested,
- ref.requested_principal_name);
- if (!cmp) {
- free_PA_ServerReferralData(&ref);
- krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED,
- N_("referred principal not same "
- "as requested", ""));
- return KRB5KRB_AP_ERR_MODIFIED;
- }
- } else if (flags & EXTRACT_TICKET_AS_REQ) {
- free_PA_ServerReferralData(&ref);
- krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED,
- N_("Requested principal missing on AS-REQ", ""));
- return KRB5KRB_AP_ERR_MODIFIED;
- }
-
- free_PA_ServerReferralData(&ref);
-
- return ret;
-noreferral:
- if (krb5_principal_compare(context, requested, returned) == FALSE) {
- krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED,
- N_("Not same server principal returned "
- "as requested", ""));
- return KRB5KRB_AP_ERR_MODIFIED;
- }
- return 0;
-}
-
-
-/*
- * Verify referral data
- */
-
-
-static krb5_error_code
-check_client_referral(krb5_context context,
- krb5_kdc_rep *rep,
- krb5_const_principal requested,
- krb5_const_principal mapped,
- krb5_keyblock const * key)
-{
- krb5_error_code ret;
- PA_ClientCanonicalized canon;
- krb5_crypto crypto;
- krb5_data data;
- PA_DATA *pa;
- size_t len;
- int i = 0;
-
- if (rep->kdc_rep.padata == NULL)
- goto noreferral;
-
- pa = krb5_find_padata(rep->kdc_rep.padata->val,
- rep->kdc_rep.padata->len,
- KRB5_PADATA_CLIENT_CANONICALIZED, &i);
- if (pa == NULL)
- goto noreferral;
-
- ret = decode_PA_ClientCanonicalized(pa->padata_value.data,
- pa->padata_value.length,
- &canon, &len);
- if (ret) {
- krb5_set_error_message(context, ret,
- 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))
- {
- 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", ""));
- return KRB5KRB_AP_ERR_MODIFIED;
- }
- return 0;
-}
-
-
+#define KRB5_DEPRECATED
-static krb5_error_code
-decrypt_tkt (krb5_context context,
- krb5_keyblock *key,
- krb5_key_usage usage,
- krb5_const_pointer decrypt_arg,
- krb5_kdc_rep *dec_rep)
-{
- krb5_error_code ret;
- krb5_data data;
- 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)
- return ret;
-
- ret = krb5_decode_EncASRepPart(context,
- data.data,
- data.length,
- &dec_rep->enc_part,
- &size);
- if (ret)
- ret = krb5_decode_EncTGSRepPart(context,
- data.data,
- data.length,
- &dec_rep->enc_part,
- &size);
- krb5_data_free (&data);
- if (ret)
- return ret;
- return 0;
-}
-
-int
-_krb5_extract_ticket(krb5_context context,
- krb5_kdc_rep *rep,
- krb5_creds *creds,
- krb5_keyblock *key,
- krb5_const_pointer keyseed,
- krb5_key_usage key_usage,
- krb5_addresses *addrs,
- unsigned nonce,
- unsigned flags,
- krb5_decrypt_proc decrypt_proc,
- krb5_const_pointer decryptarg)
-{
- krb5_error_code ret;
- krb5_principal tmp_principal;
- size_t len;
- time_t tmp_time;
- krb5_timestamp sec_now;
-
- /* decrypt */
-
- if (decrypt_proc == NULL)
- decrypt_proc = decrypt_tkt;
-
- ret = (*decrypt_proc)(context, key, key_usage, decryptarg, rep);
- if (ret)
- goto out;
-
- /* save session key */
-
- creds->session.keyvalue.length = 0;
- creds->session.keyvalue.data = NULL;
- creds->session.keytype = rep->enc_part.key.keytype;
- ret = krb5_data_copy (&creds->session.keyvalue,
- rep->enc_part.key.keyvalue.data,
- rep->enc_part.key.keyvalue.length);
- if (ret) {
- krb5_clear_error_message(context);
- goto out;
- }
-
- /*
- * HACK:
- * this is really a ugly hack, to support using the Netbios Domain Name
- * as realm against windows KDC's, they always return the full realm
- * based on the DNS Name.
- */
- flags |= EXTRACT_TICKET_ALLOW_SERVER_MISMATCH;
- flags |= EXTRACT_TICKET_ALLOW_CNAME_MISMATCH;
-
- /* compare client and save */
- ret = _krb5_principalname2krb5_principal (context,
- &tmp_principal,
- rep->kdc_rep.cname,
- rep->kdc_rep.crealm);
- if (ret)
- goto out;
-
- /* check client referral and save principal */
- /* anonymous here ? */
- if((flags & EXTRACT_TICKET_ALLOW_CNAME_MISMATCH) == 0) {
- ret = check_client_referral(context, rep,
- creds->client,
- tmp_principal,
- &creds->session);
- if (ret) {
- krb5_free_principal (context, tmp_principal);
- goto out;
- }
- }
- krb5_free_principal (context, creds->client);
- creds->client = tmp_principal;
-
- /* check server referral and save principal */
- ret = _krb5_principalname2krb5_principal (context,
- &tmp_principal,
- rep->kdc_rep.ticket.sname,
- rep->kdc_rep.ticket.realm);
- if (ret)
- goto out;
- if((flags & EXTRACT_TICKET_ALLOW_SERVER_MISMATCH) == 0){
- ret = check_server_referral(context,
- rep,
- flags,
- creds->server,
- tmp_principal,
- &creds->session);
- if (ret) {
- krb5_free_principal (context, tmp_principal);
- goto out;
- }
- }
- krb5_free_principal(context, creds->server);
- creds->server = tmp_principal;
-
- /* verify names */
- if(flags & EXTRACT_TICKET_MATCH_REALM){
- const char *srealm = krb5_principal_get_realm(context, creds->server);
- const char *crealm = krb5_principal_get_realm(context, creds->client);
-
- if (strcmp(rep->enc_part.srealm, srealm) != 0 ||
- strcmp(rep->enc_part.srealm, crealm) != 0)
- {
- ret = KRB5KRB_AP_ERR_MODIFIED;
- krb5_clear_error_message(context);
- goto out;
- }
- }
-
- /* compare nonces */
-
- if (nonce != rep->enc_part.nonce) {
- ret = KRB5KRB_AP_ERR_MODIFIED;
- krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
- goto out;
- }
-
- /* set kdc-offset */
-
- krb5_timeofday (context, &sec_now);
- if (rep->enc_part.flags.initial
- && context->kdc_sec_offset == 0
- && krb5_config_get_bool (context, NULL,
- "libdefaults",
- "kdc_timesync",
- NULL)) {
- context->kdc_sec_offset = rep->enc_part.authtime - sec_now;
- krb5_timeofday (context, &sec_now);
- }
-
- /* check all times */
-
- if (rep->enc_part.starttime) {
- tmp_time = *rep->enc_part.starttime;
- } else
- tmp_time = rep->enc_part.authtime;
-
- if (creds->times.starttime == 0
- && abs(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);
- goto out;
- }
-
- if (creds->times.starttime != 0
- && tmp_time != creds->times.starttime) {
- krb5_clear_error_message (context);
- ret = KRB5KRB_AP_ERR_MODIFIED;
- goto out;
- }
-
- creds->times.starttime = tmp_time;
-
- if (rep->enc_part.renew_till) {
- tmp_time = *rep->enc_part.renew_till;
- } else
- tmp_time = 0;
-
- if (creds->times.renew_till != 0
- && tmp_time > creds->times.renew_till) {
- krb5_clear_error_message (context);
- ret = KRB5KRB_AP_ERR_MODIFIED;
- goto out;
- }
-
- creds->times.renew_till = tmp_time;
-
- creds->times.authtime = rep->enc_part.authtime;
-
- if (creds->times.endtime != 0
- && rep->enc_part.endtime > creds->times.endtime) {
- krb5_clear_error_message (context);
- ret = KRB5KRB_AP_ERR_MODIFIED;
- goto out;
- }
-
- creds->times.endtime = rep->enc_part.endtime;
-
- if(rep->enc_part.caddr)
- krb5_copy_addresses (context, rep->enc_part.caddr, &creds->addresses);
- else if(addrs)
- krb5_copy_addresses (context, addrs, &creds->addresses);
- else {
- creds->addresses.len = 0;
- creds->addresses.val = NULL;
- }
- creds->flags.b = rep->enc_part.flags;
-
- creds->authdata.len = 0;
- creds->authdata.val = NULL;
-
- /* extract ticket */
- ASN1_MALLOC_ENCODE(Ticket, creds->ticket.data, creds->ticket.length,
- &rep->kdc_rep.ticket, &len, ret);
- if(ret)
- goto out;
- if (creds->ticket.length != len)
- krb5_abortx(context, "internal error in ASN.1 encoder");
- creds->second_ticket.length = 0;
- creds->second_ticket.data = NULL;
-
-
-out:
- memset (rep->enc_part.key.keyvalue.data, 0,
- rep->enc_part.key.keyvalue.length);
- return ret;
-}
+#include "krb5_locl.h"
+#ifndef HEIMDAL_SMALLER
static krb5_error_code
make_pa_enc_timestamp(krb5_context context, PA_DATA *pa,
@@ -626,6 +108,8 @@ add_padata(krb5_context context,
if(salt == NULL) {
/* default to standard salt */
ret = krb5_get_pw_salt (context, client, &salt2);
+ if (ret)
+ return ret;
salt = &salt2;
}
if (!enctypes) {
@@ -861,11 +345,10 @@ set_ptypes(krb5_context context,
*preauth = &preauth2;
ALLOC_SEQ(*preauth, 1);
(*preauth)->val[0].type = KRB5_PADATA_ENC_TIMESTAMP;
- krb5_decode_ETYPE_INFO(context,
- md.val[i].padata_value.data,
- md.val[i].padata_value.length,
- &(*preauth)->val[0].info,
- NULL);
+ decode_ETYPE_INFO(md.val[i].padata_value.data,
+ md.val[i].padata_value.length,
+ &(*preauth)->val[0].info,
+ NULL);
break;
default:
break;
@@ -891,6 +374,7 @@ krb5_get_in_cred(krb5_context context,
krb5_const_pointer decryptarg,
krb5_creds *creds,
krb5_kdc_rep *ret_as_reply)
+ KRB5_DEPRECATED
{
krb5_error_code ret;
AS_REQ a;
@@ -1055,6 +539,7 @@ krb5_get_in_tkt(krb5_context context,
krb5_creds *creds,
krb5_ccache ccache,
krb5_kdc_rep *ret_as_reply)
+ KRB5_DEPRECATED
{
krb5_error_code ret;
@@ -1076,3 +561,5 @@ krb5_get_in_tkt(krb5_context context,
ret = krb5_cc_store_cred (context, ccache, creds);
return ret;
}
+
+#endif /* HEIMDAL_SMALLER */