155682Smarkm/*
2233294Sstas * Copyright (c) 1997 - 2008 Kungliga Tekniska H��gskolan
3233294Sstas * (Royal Institute of Technology, Stockholm, Sweden).
4233294Sstas * All rights reserved.
555682Smarkm *
6233294Sstas * Redistribution and use in source and binary forms, with or without
7233294Sstas * modification, are permitted provided that the following conditions
8233294Sstas * are met:
955682Smarkm *
10233294Sstas * 1. Redistributions of source code must retain the above copyright
11233294Sstas *    notice, this list of conditions and the following disclaimer.
1255682Smarkm *
13233294Sstas * 2. Redistributions in binary form must reproduce the above copyright
14233294Sstas *    notice, this list of conditions and the following disclaimer in the
15233294Sstas *    documentation and/or other materials provided with the distribution.
1655682Smarkm *
17233294Sstas * 3. Neither the name of the Institute nor the names of its contributors
18233294Sstas *    may be used to endorse or promote products derived from this software
19233294Sstas *    without specific prior written permission.
2055682Smarkm *
21233294Sstas * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22233294Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23233294Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24233294Sstas * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25233294Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26233294Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27233294Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28233294Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29233294Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30233294Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31233294Sstas * SUCH DAMAGE.
3255682Smarkm */
3355682Smarkm
3455682Smarkm#include "krb5_locl.h"
3555682Smarkm
36233294Sstas#ifndef HEIMDAL_SMALLER
3755682Smarkm
3855682Smarkmstatic krb5_error_code
39233294Sstasmake_pa_enc_timestamp(krb5_context context, PA_DATA *pa,
4055682Smarkm		      krb5_enctype etype, krb5_keyblock *key)
4155682Smarkm{
4255682Smarkm    PA_ENC_TS_ENC p;
43103423Snectar    unsigned char *buf;
44103423Snectar    size_t buf_size;
45233294Sstas    size_t len = 0;
4655682Smarkm    EncryptedData encdata;
4755682Smarkm    krb5_error_code ret;
48178825Sdfr    int32_t usec;
4955682Smarkm    int usec2;
5055682Smarkm    krb5_crypto crypto;
51233294Sstas
52178825Sdfr    krb5_us_timeofday (context, &p.patimestamp, &usec);
5355682Smarkm    usec2         = usec;
5455682Smarkm    p.pausec      = &usec2;
5555682Smarkm
56103423Snectar    ASN1_MALLOC_ENCODE(PA_ENC_TS_ENC, buf, buf_size, &p, &len, ret);
5755682Smarkm    if (ret)
5855682Smarkm	return ret;
59103423Snectar    if(buf_size != len)
60103423Snectar	krb5_abortx(context, "internal error in ASN.1 encoder");
6172445Sassar    ret = krb5_crypto_init(context, key, 0, &crypto);
62103423Snectar    if (ret) {
63103423Snectar	free(buf);
6472445Sassar	return ret;
65103423Snectar    }
66233294Sstas    ret = krb5_encrypt_EncryptedData(context,
6755682Smarkm				     crypto,
6855682Smarkm				     KRB5_KU_PA_ENC_TIMESTAMP,
69103423Snectar				     buf,
7055682Smarkm				     len,
7155682Smarkm				     0,
7255682Smarkm				     &encdata);
73103423Snectar    free(buf);
7455682Smarkm    krb5_crypto_destroy(context, crypto);
7555682Smarkm    if (ret)
7655682Smarkm	return ret;
77233294Sstas
78103423Snectar    ASN1_MALLOC_ENCODE(EncryptedData, buf, buf_size, &encdata, &len, ret);
7955682Smarkm    free_EncryptedData(&encdata);
8055682Smarkm    if (ret)
8155682Smarkm	return ret;
82103423Snectar    if(buf_size != len)
83103423Snectar	krb5_abortx(context, "internal error in ASN.1 encoder");
8472445Sassar    pa->padata_type = KRB5_PADATA_ENC_TIMESTAMP;
85103423Snectar    pa->padata_value.length = len;
86103423Snectar    pa->padata_value.data = buf;
8755682Smarkm    return 0;
8855682Smarkm}
8955682Smarkm
9055682Smarkmstatic krb5_error_code
9155682Smarkmadd_padata(krb5_context context,
92233294Sstas	   METHOD_DATA *md,
9355682Smarkm	   krb5_principal client,
9455682Smarkm	   krb5_key_proc key_proc,
9555682Smarkm	   krb5_const_pointer keyseed,
9690926Snectar	   krb5_enctype *enctypes,
9755682Smarkm	   unsigned netypes,
9855682Smarkm	   krb5_salt *salt)
9955682Smarkm{
10055682Smarkm    krb5_error_code ret;
10155682Smarkm    PA_DATA *pa2;
10255682Smarkm    krb5_salt salt2;
10390926Snectar    krb5_enctype *ep;
104233294Sstas    size_t i;
105233294Sstas
10655682Smarkm    if(salt == NULL) {
10755682Smarkm	/* default to standard salt */
10855682Smarkm	ret = krb5_get_pw_salt (context, client, &salt2);
109233294Sstas	if (ret)
110233294Sstas	    return ret;
11155682Smarkm	salt = &salt2;
11255682Smarkm    }
11355682Smarkm    if (!enctypes) {
11490926Snectar	enctypes = context->etypes;
11555682Smarkm	netypes = 0;
11655682Smarkm	for (ep = enctypes; *ep != ETYPE_NULL; ep++)
11755682Smarkm	    netypes++;
11855682Smarkm    }
11955682Smarkm    pa2 = realloc (md->val, (md->len + netypes) * sizeof(*md->val));
12078527Sassar    if (pa2 == NULL) {
121233294Sstas	krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
12255682Smarkm	return ENOMEM;
12378527Sassar    }
12455682Smarkm    md->val = pa2;
12555682Smarkm
12655682Smarkm    for (i = 0; i < netypes; ++i) {
12755682Smarkm	krb5_keyblock *key;
12855682Smarkm
12955682Smarkm	ret = (*key_proc)(context, enctypes[i], *salt, keyseed, &key);
13055682Smarkm	if (ret)
13155682Smarkm	    continue;
13255682Smarkm	ret = make_pa_enc_timestamp (context, &md->val[md->len],
13355682Smarkm				     enctypes[i], key);
13455682Smarkm	krb5_free_keyblock (context, key);
13555682Smarkm	if (ret)
13655682Smarkm	    return ret;
13755682Smarkm	++md->len;
13855682Smarkm    }
13955682Smarkm    if(salt == &salt2)
14055682Smarkm	krb5_free_salt(context, salt2);
14155682Smarkm    return 0;
14255682Smarkm}
14355682Smarkm
14455682Smarkmstatic krb5_error_code
14555682Smarkminit_as_req (krb5_context context,
146178825Sdfr	     KDCOptions opts,
14755682Smarkm	     krb5_creds *creds,
14855682Smarkm	     const krb5_addresses *addrs,
14955682Smarkm	     const krb5_enctype *etypes,
15055682Smarkm	     const krb5_preauthtype *ptypes,
15155682Smarkm	     const krb5_preauthdata *preauth,
15255682Smarkm	     krb5_key_proc key_proc,
15355682Smarkm	     krb5_const_pointer keyseed,
15455682Smarkm	     unsigned nonce,
15555682Smarkm	     AS_REQ *a)
15655682Smarkm{
15755682Smarkm    krb5_error_code ret;
15855682Smarkm    krb5_salt salt;
15955682Smarkm
16055682Smarkm    memset(a, 0, sizeof(*a));
16155682Smarkm
16255682Smarkm    a->pvno = 5;
16355682Smarkm    a->msg_type = krb_as_req;
164178825Sdfr    a->req_body.kdc_options = opts;
16555682Smarkm    a->req_body.cname = malloc(sizeof(*a->req_body.cname));
16655682Smarkm    if (a->req_body.cname == NULL) {
16755682Smarkm	ret = ENOMEM;
168233294Sstas	krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
16955682Smarkm	goto fail;
17055682Smarkm    }
17155682Smarkm    a->req_body.sname = malloc(sizeof(*a->req_body.sname));
17255682Smarkm    if (a->req_body.sname == NULL) {
17355682Smarkm	ret = ENOMEM;
174233294Sstas	krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
17555682Smarkm	goto fail;
17655682Smarkm    }
177178825Sdfr    ret = _krb5_principal2principalname (a->req_body.cname, creds->client);
17855682Smarkm    if (ret)
17955682Smarkm	goto fail;
180178825Sdfr    ret = _krb5_principal2principalname (a->req_body.sname, creds->server);
18155682Smarkm    if (ret)
18255682Smarkm	goto fail;
18355682Smarkm    ret = copy_Realm(&creds->client->realm, &a->req_body.realm);
18455682Smarkm    if (ret)
18555682Smarkm	goto fail;
18655682Smarkm
18755682Smarkm    if(creds->times.starttime) {
18855682Smarkm	a->req_body.from = malloc(sizeof(*a->req_body.from));
18955682Smarkm	if (a->req_body.from == NULL) {
19055682Smarkm	    ret = ENOMEM;
191233294Sstas	    krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
19255682Smarkm	    goto fail;
19355682Smarkm	}
19455682Smarkm	*a->req_body.from = creds->times.starttime;
19555682Smarkm    }
19655682Smarkm    if(creds->times.endtime){
19755682Smarkm	ALLOC(a->req_body.till, 1);
19855682Smarkm	*a->req_body.till = creds->times.endtime;
19955682Smarkm    }
20055682Smarkm    if(creds->times.renew_till){
20155682Smarkm	a->req_body.rtime = malloc(sizeof(*a->req_body.rtime));
20255682Smarkm	if (a->req_body.rtime == NULL) {
20355682Smarkm	    ret = ENOMEM;
204233294Sstas	    krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
20555682Smarkm	    goto fail;
20655682Smarkm	}
20755682Smarkm	*a->req_body.rtime = creds->times.renew_till;
20855682Smarkm    }
20955682Smarkm    a->req_body.nonce = nonce;
210233294Sstas    ret = _krb5_init_etype(context,
211233294Sstas			   KRB5_PDU_AS_REQUEST,
21255682Smarkm			   &a->req_body.etype.len,
21355682Smarkm			   &a->req_body.etype.val,
21455682Smarkm			   etypes);
21555682Smarkm    if (ret)
21655682Smarkm	goto fail;
21755682Smarkm
21855682Smarkm    /*
21955682Smarkm     * This means no addresses
22055682Smarkm     */
22155682Smarkm
22255682Smarkm    if (addrs && addrs->len == 0) {
22355682Smarkm	a->req_body.addresses = NULL;
22455682Smarkm    } else {
22555682Smarkm	a->req_body.addresses = malloc(sizeof(*a->req_body.addresses));
22655682Smarkm	if (a->req_body.addresses == NULL) {
22755682Smarkm	    ret = ENOMEM;
228233294Sstas	    krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
22955682Smarkm	    goto fail;
23055682Smarkm	}
23155682Smarkm
23255682Smarkm	if (addrs)
23355682Smarkm	    ret = krb5_copy_addresses(context, addrs, a->req_body.addresses);
23490926Snectar	else {
23555682Smarkm	    ret = krb5_get_all_client_addrs (context, a->req_body.addresses);
23690926Snectar	    if(ret == 0 && a->req_body.addresses->len == 0) {
23790926Snectar		free(a->req_body.addresses);
23890926Snectar		a->req_body.addresses = NULL;
23990926Snectar	    }
24090926Snectar	}
24155682Smarkm	if (ret)
24255682Smarkm	    return ret;
24355682Smarkm    }
24455682Smarkm
24555682Smarkm    a->req_body.enc_authorization_data = NULL;
24655682Smarkm    a->req_body.additional_tickets = NULL;
24755682Smarkm
24855682Smarkm    if(preauth != NULL) {
249233294Sstas	size_t i;
25055682Smarkm	ALLOC(a->padata, 1);
25155682Smarkm	if(a->padata == NULL) {
25255682Smarkm	    ret = ENOMEM;
253233294Sstas	    krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
25455682Smarkm	    goto fail;
25555682Smarkm	}
256178825Sdfr	a->padata->val = NULL;
257178825Sdfr	a->padata->len = 0;
25855682Smarkm	for(i = 0; i < preauth->len; i++) {
25955682Smarkm	    if(preauth->val[i].type == KRB5_PADATA_ENC_TIMESTAMP){
260233294Sstas		size_t j;
261178825Sdfr
26255682Smarkm		for(j = 0; j < preauth->val[i].info.len; j++) {
26355682Smarkm		    krb5_salt *sp = &salt;
26455682Smarkm		    if(preauth->val[i].info.val[j].salttype)
26555682Smarkm			salt.salttype = *preauth->val[i].info.val[j].salttype;
26655682Smarkm		    else
26755682Smarkm			salt.salttype = KRB5_PW_SALT;
26855682Smarkm		    if(preauth->val[i].info.val[j].salt)
26955682Smarkm			salt.saltvalue = *preauth->val[i].info.val[j].salt;
27055682Smarkm		    else
27155682Smarkm			if(salt.salttype == KRB5_PW_SALT)
27255682Smarkm			    sp = NULL;
27355682Smarkm			else
27455682Smarkm			    krb5_data_zero(&salt.saltvalue);
275233294Sstas		    ret = add_padata(context, a->padata, creds->client,
276233294Sstas				     key_proc, keyseed,
277127808Snectar				     &preauth->val[i].info.val[j].etype, 1,
278127808Snectar				     sp);
279120945Snectar		    if (ret == 0)
280120945Snectar			break;
28155682Smarkm		}
28255682Smarkm	    }
28355682Smarkm	}
284233294Sstas    } else
28555682Smarkm    /* not sure this is the way to use `ptypes' */
28655682Smarkm    if (ptypes == NULL || *ptypes == KRB5_PADATA_NONE)
28755682Smarkm	a->padata = NULL;
28855682Smarkm    else if (*ptypes ==  KRB5_PADATA_ENC_TIMESTAMP) {
28955682Smarkm	ALLOC(a->padata, 1);
29055682Smarkm	if (a->padata == NULL) {
29155682Smarkm	    ret = ENOMEM;
292233294Sstas	    krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
29355682Smarkm	    goto fail;
29455682Smarkm	}
29555682Smarkm	a->padata->len = 0;
29655682Smarkm	a->padata->val = NULL;
29755682Smarkm
29855682Smarkm	/* make a v5 salted pa-data */
299233294Sstas	add_padata(context, a->padata, creds->client,
30055682Smarkm		   key_proc, keyseed, a->req_body.etype.val,
30155682Smarkm		   a->req_body.etype.len, NULL);
302233294Sstas
30355682Smarkm	/* make a v4 salted pa-data */
30455682Smarkm	salt.salttype = KRB5_PW_SALT;
30555682Smarkm	krb5_data_zero(&salt.saltvalue);
306233294Sstas	add_padata(context, a->padata, creds->client,
30755682Smarkm		   key_proc, keyseed, a->req_body.etype.val,
30855682Smarkm		   a->req_body.etype.len, &salt);
30955682Smarkm    } else {
310233294Sstas	ret = KRB5_PREAUTH_BAD_TYPE;
311233294Sstas	krb5_set_error_message (context, ret,
312233294Sstas				N_("pre-auth type %d not supported", ""),
31378527Sassar			       *ptypes);
31455682Smarkm	goto fail;
31555682Smarkm    }
31655682Smarkm    return 0;
31755682Smarkmfail:
31855682Smarkm    free_AS_REQ(a);
31955682Smarkm    return ret;
32055682Smarkm}
32155682Smarkm
32255682Smarkmstatic int
32355682Smarkmset_ptypes(krb5_context context,
324233294Sstas	   KRB_ERROR *error,
325178825Sdfr	   const krb5_preauthtype **ptypes,
32655682Smarkm	   krb5_preauthdata **preauth)
32755682Smarkm{
32855682Smarkm    static krb5_preauthdata preauth2;
32955682Smarkm    static krb5_preauthtype ptypes2[] = { KRB5_PADATA_ENC_TIMESTAMP, KRB5_PADATA_NONE };
33055682Smarkm
33155682Smarkm    if(error->e_data) {
33255682Smarkm	METHOD_DATA md;
333233294Sstas	size_t i;
334233294Sstas	decode_METHOD_DATA(error->e_data->data,
335233294Sstas			   error->e_data->length,
336233294Sstas			   &md,
33755682Smarkm			   NULL);
33855682Smarkm	for(i = 0; i < md.len; i++){
33955682Smarkm	    switch(md.val[i].padata_type){
34072445Sassar	    case KRB5_PADATA_ENC_TIMESTAMP:
34155682Smarkm		*ptypes = ptypes2;
34255682Smarkm		break;
34372445Sassar	    case KRB5_PADATA_ETYPE_INFO:
34455682Smarkm		*preauth = &preauth2;
34555682Smarkm		ALLOC_SEQ(*preauth, 1);
34655682Smarkm		(*preauth)->val[0].type = KRB5_PADATA_ENC_TIMESTAMP;
347233294Sstas		decode_ETYPE_INFO(md.val[i].padata_value.data,
348233294Sstas				  md.val[i].padata_value.length,
349233294Sstas				  &(*preauth)->val[0].info,
350233294Sstas				  NULL);
35155682Smarkm		break;
35272445Sassar	    default:
35372445Sassar		break;
35455682Smarkm	    }
35555682Smarkm	}
35655682Smarkm	free_METHOD_DATA(&md);
35755682Smarkm    } else {
35855682Smarkm	*ptypes = ptypes2;
35955682Smarkm    }
36055682Smarkm    return(1);
36155682Smarkm}
36255682Smarkm
363233294SstasKRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
36455682Smarkmkrb5_get_in_cred(krb5_context context,
36555682Smarkm		 krb5_flags options,
36655682Smarkm		 const krb5_addresses *addrs,
36755682Smarkm		 const krb5_enctype *etypes,
36855682Smarkm		 const krb5_preauthtype *ptypes,
36955682Smarkm		 const krb5_preauthdata *preauth,
37055682Smarkm		 krb5_key_proc key_proc,
37155682Smarkm		 krb5_const_pointer keyseed,
37255682Smarkm		 krb5_decrypt_proc decrypt_proc,
37355682Smarkm		 krb5_const_pointer decryptarg,
37455682Smarkm		 krb5_creds *creds,
37555682Smarkm		 krb5_kdc_rep *ret_as_reply)
376233294Sstas    KRB5_DEPRECATED_FUNCTION("Use X instead")
37755682Smarkm{
37855682Smarkm    krb5_error_code ret;
37955682Smarkm    AS_REQ a;
38055682Smarkm    krb5_kdc_rep rep;
38155682Smarkm    krb5_data req, resp;
382233294Sstas    size_t len = 0;
38355682Smarkm    krb5_salt salt;
38455682Smarkm    krb5_keyblock *key;
38555682Smarkm    size_t size;
386178825Sdfr    KDCOptions opts;
38755682Smarkm    PA_DATA *pa;
38855682Smarkm    krb5_enctype etype;
38955682Smarkm    krb5_preauthdata *my_preauth = NULL;
39055682Smarkm    unsigned nonce;
39155682Smarkm    int done;
39255682Smarkm
393178825Sdfr    opts = int2KDCOptions(options);
39455682Smarkm
39555682Smarkm    krb5_generate_random_block (&nonce, sizeof(nonce));
39655682Smarkm    nonce &= 0xffffffff;
39755682Smarkm
39855682Smarkm    do {
39955682Smarkm	done = 1;
40055682Smarkm	ret = init_as_req (context,
40155682Smarkm			   opts,
40255682Smarkm			   creds,
40355682Smarkm			   addrs,
40455682Smarkm			   etypes,
40555682Smarkm			   ptypes,
40655682Smarkm			   preauth,
40755682Smarkm			   key_proc,
40855682Smarkm			   keyseed,
40955682Smarkm			   nonce,
41055682Smarkm			   &a);
41155682Smarkm	if (my_preauth) {
41255682Smarkm	    free_ETYPE_INFO(&my_preauth->val[0].info);
41355682Smarkm	    free (my_preauth->val);
414178825Sdfr	    my_preauth = NULL;
41555682Smarkm	}
41655682Smarkm	if (ret)
41755682Smarkm	    return ret;
41855682Smarkm
419103423Snectar	ASN1_MALLOC_ENCODE(AS_REQ, req.data, req.length, &a, &len, ret);
42055682Smarkm	free_AS_REQ(&a);
42155682Smarkm	if (ret)
42255682Smarkm	    return ret;
423103423Snectar	if(len != req.length)
424103423Snectar	    krb5_abortx(context, "internal error in ASN.1 encoder");
42555682Smarkm
42655682Smarkm	ret = krb5_sendto_kdc (context, &req, &creds->client->realm, &resp);
427103423Snectar	krb5_data_free(&req);
42855682Smarkm	if (ret)
42955682Smarkm	    return ret;
43055682Smarkm
43155682Smarkm	memset (&rep, 0, sizeof(rep));
43255682Smarkm	ret = decode_AS_REP(resp.data, resp.length, &rep.kdc_rep, &size);
43355682Smarkm	if(ret) {
43455682Smarkm	    /* let's try to parse it as a KRB-ERROR */
43555682Smarkm	    KRB_ERROR error;
43655682Smarkm	    int ret2;
43755682Smarkm
43855682Smarkm	    ret2 = krb5_rd_error(context, &resp, &error);
43955682Smarkm	    if(ret2 && resp.data && ((char*)resp.data)[0] == 4)
44055682Smarkm		ret = KRB5KRB_AP_ERR_V4_REPLY;
44155682Smarkm	    krb5_data_free(&resp);
44255682Smarkm	    if (ret2 == 0) {
44378527Sassar		ret = krb5_error_from_rd_error(context, &error, creds);
44455682Smarkm		/* if no preauth was set and KDC requires it, give it
44555682Smarkm                   one more try */
44655682Smarkm		if (!ptypes && !preauth
44755682Smarkm		    && ret == KRB5KDC_ERR_PREAUTH_REQUIRED
44855682Smarkm#if 0
44955682Smarkm			|| ret == KRB5KDC_ERR_BADOPTION
45055682Smarkm#endif
45155682Smarkm		    && set_ptypes(context, &error, &ptypes, &my_preauth)) {
45255682Smarkm		    done = 0;
45355682Smarkm		    preauth = my_preauth;
45478527Sassar		    krb5_free_error_contents(context, &error);
455233294Sstas		    krb5_clear_error_message(context);
45655682Smarkm		    continue;
45755682Smarkm		}
45855682Smarkm		if(ret_as_reply)
45955682Smarkm		    ret_as_reply->error = error;
46055682Smarkm		else
46155682Smarkm		    free_KRB_ERROR (&error);
46255682Smarkm		return ret;
46355682Smarkm	    }
46455682Smarkm	    return ret;
46555682Smarkm	}
46655682Smarkm	krb5_data_free(&resp);
46755682Smarkm    } while(!done);
468233294Sstas
46955682Smarkm    pa = NULL;
47055682Smarkm    etype = rep.kdc_rep.enc_part.etype;
47155682Smarkm    if(rep.kdc_rep.padata){
472178825Sdfr	int i = 0;
473233294Sstas	pa = krb5_find_padata(rep.kdc_rep.padata->val, rep.kdc_rep.padata->len,
474178825Sdfr			      KRB5_PADATA_PW_SALT, &i);
47555682Smarkm	if(pa == NULL) {
476178825Sdfr	    i = 0;
477233294Sstas	    pa = krb5_find_padata(rep.kdc_rep.padata->val,
478233294Sstas				  rep.kdc_rep.padata->len,
479178825Sdfr				  KRB5_PADATA_AFS3_SALT, &i);
48055682Smarkm	}
48155682Smarkm    }
48255682Smarkm    if(pa) {
483233294Sstas	salt.salttype = (krb5_salttype)pa->padata_type;
48455682Smarkm	salt.saltvalue = pa->padata_value;
485233294Sstas
48655682Smarkm	ret = (*key_proc)(context, etype, salt, keyseed, &key);
48755682Smarkm    } else {
48855682Smarkm	/* make a v5 salted pa-data */
48955682Smarkm	ret = krb5_get_pw_salt (context, creds->client, &salt);
490233294Sstas
49155682Smarkm	if (ret)
49255682Smarkm	    goto out;
49355682Smarkm	ret = (*key_proc)(context, etype, salt, keyseed, &key);
49455682Smarkm	krb5_free_salt(context, salt);
49555682Smarkm    }
49655682Smarkm    if (ret)
49755682Smarkm	goto out;
498233294Sstas
499178825Sdfr    {
500233294Sstas	unsigned flags = EXTRACT_TICKET_TIMESYNC;
501178825Sdfr	if (opts.request_anonymous)
502178825Sdfr	    flags |= EXTRACT_TICKET_ALLOW_SERVER_MISMATCH;
503178825Sdfr
504233294Sstas	ret = _krb5_extract_ticket(context,
505233294Sstas				   &rep,
506233294Sstas				   creds,
507233294Sstas				   key,
508233294Sstas				   keyseed,
509178825Sdfr				   KRB5_KU_AS_REP_ENC_PART,
510233294Sstas				   NULL,
511233294Sstas				   nonce,
512178825Sdfr				   flags,
513233294Sstas				   decrypt_proc,
514178825Sdfr				   decryptarg);
515178825Sdfr    }
51655682Smarkm    memset (key->keyvalue.data, 0, key->keyvalue.length);
51755682Smarkm    krb5_free_keyblock_contents (context, key);
51855682Smarkm    free (key);
51955682Smarkm
52055682Smarkmout:
52155682Smarkm    if (ret == 0 && ret_as_reply)
52255682Smarkm	*ret_as_reply = rep;
52355682Smarkm    else
52455682Smarkm	krb5_free_kdc_rep (context, &rep);
52555682Smarkm    return ret;
52655682Smarkm}
52755682Smarkm
528233294SstasKRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
52955682Smarkmkrb5_get_in_tkt(krb5_context context,
53055682Smarkm		krb5_flags options,
53155682Smarkm		const krb5_addresses *addrs,
53255682Smarkm		const krb5_enctype *etypes,
53355682Smarkm		const krb5_preauthtype *ptypes,
53455682Smarkm		krb5_key_proc key_proc,
53555682Smarkm		krb5_const_pointer keyseed,
53655682Smarkm		krb5_decrypt_proc decrypt_proc,
53755682Smarkm		krb5_const_pointer decryptarg,
53855682Smarkm		krb5_creds *creds,
53955682Smarkm		krb5_ccache ccache,
54055682Smarkm		krb5_kdc_rep *ret_as_reply)
541233294Sstas    KRB5_DEPRECATED_FUNCTION("Use X instead")
54255682Smarkm{
54355682Smarkm    krb5_error_code ret;
544233294Sstas
54555682Smarkm    ret = krb5_get_in_cred (context,
546178825Sdfr			    options,
54755682Smarkm			    addrs,
54855682Smarkm			    etypes,
54955682Smarkm			    ptypes,
55055682Smarkm			    NULL,
55155682Smarkm			    key_proc,
55255682Smarkm			    keyseed,
55355682Smarkm			    decrypt_proc,
55455682Smarkm			    decryptarg,
55555682Smarkm			    creds,
55655682Smarkm			    ret_as_reply);
557233294Sstas    if(ret)
55855682Smarkm	return ret;
559127808Snectar    if (ccache)
560127808Snectar	ret = krb5_cc_store_cred (context, ccache, creds);
56155682Smarkm    return ret;
56255682Smarkm}
563233294Sstas
564233294Sstas#endif /* HEIMDAL_SMALLER */
565