s4:heimdal: import lorikeet-heimdal-200906080040 (commit 904d0124b46eed7a8ad6e5b73e89...
[ira/wip.git] / source4 / heimdal / lib / krb5 / get_in_tkt.c
index cc49e16030cbb4f78d50770dcba47dceb615ff3e..84b1ffb71f581d0f5d70f90c667ae31920c66553 100644 (file)
  * 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 */