1*0a6a1f1dSLionel Sambuc /* $NetBSD: get_in_tkt.c,v 1.1.1.2 2014/04/24 12:45:50 pettai Exp $ */
2ebfedea0SLionel Sambuc
3ebfedea0SLionel Sambuc /*
4ebfedea0SLionel Sambuc * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan
5ebfedea0SLionel Sambuc * (Royal Institute of Technology, Stockholm, Sweden).
6ebfedea0SLionel Sambuc * All rights reserved.
7ebfedea0SLionel Sambuc *
8ebfedea0SLionel Sambuc * Redistribution and use in source and binary forms, with or without
9ebfedea0SLionel Sambuc * modification, are permitted provided that the following conditions
10ebfedea0SLionel Sambuc * are met:
11ebfedea0SLionel Sambuc *
12ebfedea0SLionel Sambuc * 1. Redistributions of source code must retain the above copyright
13ebfedea0SLionel Sambuc * notice, this list of conditions and the following disclaimer.
14ebfedea0SLionel Sambuc *
15ebfedea0SLionel Sambuc * 2. Redistributions in binary form must reproduce the above copyright
16ebfedea0SLionel Sambuc * notice, this list of conditions and the following disclaimer in the
17ebfedea0SLionel Sambuc * documentation and/or other materials provided with the distribution.
18ebfedea0SLionel Sambuc *
19ebfedea0SLionel Sambuc * 3. Neither the name of the Institute nor the names of its contributors
20ebfedea0SLionel Sambuc * may be used to endorse or promote products derived from this software
21ebfedea0SLionel Sambuc * without specific prior written permission.
22ebfedea0SLionel Sambuc *
23ebfedea0SLionel Sambuc * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24ebfedea0SLionel Sambuc * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25ebfedea0SLionel Sambuc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26ebfedea0SLionel Sambuc * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27ebfedea0SLionel Sambuc * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28ebfedea0SLionel Sambuc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29ebfedea0SLionel Sambuc * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30ebfedea0SLionel Sambuc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31ebfedea0SLionel Sambuc * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32ebfedea0SLionel Sambuc * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33ebfedea0SLionel Sambuc * SUCH DAMAGE.
34ebfedea0SLionel Sambuc */
35ebfedea0SLionel Sambuc
36*0a6a1f1dSLionel Sambuc #define KRB5_DEPRECATED_FUNCTION(x)
37ebfedea0SLionel Sambuc
38ebfedea0SLionel Sambuc #include "krb5_locl.h"
39ebfedea0SLionel Sambuc
40ebfedea0SLionel Sambuc #ifndef HEIMDAL_SMALLER
41ebfedea0SLionel Sambuc
42ebfedea0SLionel Sambuc static krb5_error_code
make_pa_enc_timestamp(krb5_context context,PA_DATA * pa,krb5_enctype etype,krb5_keyblock * key)43ebfedea0SLionel Sambuc make_pa_enc_timestamp(krb5_context context, PA_DATA *pa,
44ebfedea0SLionel Sambuc krb5_enctype etype, krb5_keyblock *key)
45ebfedea0SLionel Sambuc {
46ebfedea0SLionel Sambuc PA_ENC_TS_ENC p;
47ebfedea0SLionel Sambuc unsigned char *buf;
48ebfedea0SLionel Sambuc size_t buf_size;
49*0a6a1f1dSLionel Sambuc size_t len = 0;
50ebfedea0SLionel Sambuc EncryptedData encdata;
51ebfedea0SLionel Sambuc krb5_error_code ret;
52ebfedea0SLionel Sambuc int32_t usec;
53ebfedea0SLionel Sambuc int usec2;
54ebfedea0SLionel Sambuc krb5_crypto crypto;
55ebfedea0SLionel Sambuc
56ebfedea0SLionel Sambuc krb5_us_timeofday (context, &p.patimestamp, &usec);
57ebfedea0SLionel Sambuc usec2 = usec;
58ebfedea0SLionel Sambuc p.pausec = &usec2;
59ebfedea0SLionel Sambuc
60ebfedea0SLionel Sambuc ASN1_MALLOC_ENCODE(PA_ENC_TS_ENC, buf, buf_size, &p, &len, ret);
61ebfedea0SLionel Sambuc if (ret)
62ebfedea0SLionel Sambuc return ret;
63ebfedea0SLionel Sambuc if(buf_size != len)
64ebfedea0SLionel Sambuc krb5_abortx(context, "internal error in ASN.1 encoder");
65ebfedea0SLionel Sambuc ret = krb5_crypto_init(context, key, 0, &crypto);
66ebfedea0SLionel Sambuc if (ret) {
67ebfedea0SLionel Sambuc free(buf);
68ebfedea0SLionel Sambuc return ret;
69ebfedea0SLionel Sambuc }
70ebfedea0SLionel Sambuc ret = krb5_encrypt_EncryptedData(context,
71ebfedea0SLionel Sambuc crypto,
72ebfedea0SLionel Sambuc KRB5_KU_PA_ENC_TIMESTAMP,
73ebfedea0SLionel Sambuc buf,
74ebfedea0SLionel Sambuc len,
75ebfedea0SLionel Sambuc 0,
76ebfedea0SLionel Sambuc &encdata);
77ebfedea0SLionel Sambuc free(buf);
78ebfedea0SLionel Sambuc krb5_crypto_destroy(context, crypto);
79ebfedea0SLionel Sambuc if (ret)
80ebfedea0SLionel Sambuc return ret;
81ebfedea0SLionel Sambuc
82ebfedea0SLionel Sambuc ASN1_MALLOC_ENCODE(EncryptedData, buf, buf_size, &encdata, &len, ret);
83ebfedea0SLionel Sambuc free_EncryptedData(&encdata);
84ebfedea0SLionel Sambuc if (ret)
85ebfedea0SLionel Sambuc return ret;
86ebfedea0SLionel Sambuc if(buf_size != len)
87ebfedea0SLionel Sambuc krb5_abortx(context, "internal error in ASN.1 encoder");
88ebfedea0SLionel Sambuc pa->padata_type = KRB5_PADATA_ENC_TIMESTAMP;
89ebfedea0SLionel Sambuc pa->padata_value.length = len;
90ebfedea0SLionel Sambuc pa->padata_value.data = buf;
91ebfedea0SLionel Sambuc return 0;
92ebfedea0SLionel Sambuc }
93ebfedea0SLionel Sambuc
94ebfedea0SLionel Sambuc static krb5_error_code
add_padata(krb5_context context,METHOD_DATA * md,krb5_principal client,krb5_key_proc key_proc,krb5_const_pointer keyseed,krb5_enctype * enctypes,unsigned netypes,krb5_salt * salt)95ebfedea0SLionel Sambuc add_padata(krb5_context context,
96ebfedea0SLionel Sambuc METHOD_DATA *md,
97ebfedea0SLionel Sambuc krb5_principal client,
98ebfedea0SLionel Sambuc krb5_key_proc key_proc,
99ebfedea0SLionel Sambuc krb5_const_pointer keyseed,
100ebfedea0SLionel Sambuc krb5_enctype *enctypes,
101ebfedea0SLionel Sambuc unsigned netypes,
102ebfedea0SLionel Sambuc krb5_salt *salt)
103ebfedea0SLionel Sambuc {
104ebfedea0SLionel Sambuc krb5_error_code ret;
105ebfedea0SLionel Sambuc PA_DATA *pa2;
106ebfedea0SLionel Sambuc krb5_salt salt2;
107ebfedea0SLionel Sambuc krb5_enctype *ep;
108*0a6a1f1dSLionel Sambuc size_t i;
109ebfedea0SLionel Sambuc
110ebfedea0SLionel Sambuc if(salt == NULL) {
111ebfedea0SLionel Sambuc /* default to standard salt */
112ebfedea0SLionel Sambuc ret = krb5_get_pw_salt (context, client, &salt2);
113ebfedea0SLionel Sambuc if (ret)
114ebfedea0SLionel Sambuc return ret;
115ebfedea0SLionel Sambuc salt = &salt2;
116ebfedea0SLionel Sambuc }
117ebfedea0SLionel Sambuc if (!enctypes) {
118ebfedea0SLionel Sambuc enctypes = context->etypes;
119ebfedea0SLionel Sambuc netypes = 0;
120ebfedea0SLionel Sambuc for (ep = enctypes; *ep != ETYPE_NULL; ep++)
121ebfedea0SLionel Sambuc netypes++;
122ebfedea0SLionel Sambuc }
123ebfedea0SLionel Sambuc pa2 = realloc (md->val, (md->len + netypes) * sizeof(*md->val));
124ebfedea0SLionel Sambuc if (pa2 == NULL) {
125ebfedea0SLionel Sambuc krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
126ebfedea0SLionel Sambuc return ENOMEM;
127ebfedea0SLionel Sambuc }
128ebfedea0SLionel Sambuc md->val = pa2;
129ebfedea0SLionel Sambuc
130ebfedea0SLionel Sambuc for (i = 0; i < netypes; ++i) {
131ebfedea0SLionel Sambuc krb5_keyblock *key;
132ebfedea0SLionel Sambuc
133ebfedea0SLionel Sambuc ret = (*key_proc)(context, enctypes[i], *salt, keyseed, &key);
134ebfedea0SLionel Sambuc if (ret)
135ebfedea0SLionel Sambuc continue;
136ebfedea0SLionel Sambuc ret = make_pa_enc_timestamp (context, &md->val[md->len],
137ebfedea0SLionel Sambuc enctypes[i], key);
138ebfedea0SLionel Sambuc krb5_free_keyblock (context, key);
139ebfedea0SLionel Sambuc if (ret)
140ebfedea0SLionel Sambuc return ret;
141ebfedea0SLionel Sambuc ++md->len;
142ebfedea0SLionel Sambuc }
143ebfedea0SLionel Sambuc if(salt == &salt2)
144ebfedea0SLionel Sambuc krb5_free_salt(context, salt2);
145ebfedea0SLionel Sambuc return 0;
146ebfedea0SLionel Sambuc }
147ebfedea0SLionel Sambuc
148ebfedea0SLionel Sambuc static krb5_error_code
init_as_req(krb5_context context,KDCOptions opts,krb5_creds * creds,const krb5_addresses * addrs,const krb5_enctype * etypes,const krb5_preauthtype * ptypes,const krb5_preauthdata * preauth,krb5_key_proc key_proc,krb5_const_pointer keyseed,unsigned nonce,AS_REQ * a)149ebfedea0SLionel Sambuc init_as_req (krb5_context context,
150ebfedea0SLionel Sambuc KDCOptions opts,
151ebfedea0SLionel Sambuc krb5_creds *creds,
152ebfedea0SLionel Sambuc const krb5_addresses *addrs,
153ebfedea0SLionel Sambuc const krb5_enctype *etypes,
154ebfedea0SLionel Sambuc const krb5_preauthtype *ptypes,
155ebfedea0SLionel Sambuc const krb5_preauthdata *preauth,
156ebfedea0SLionel Sambuc krb5_key_proc key_proc,
157ebfedea0SLionel Sambuc krb5_const_pointer keyseed,
158ebfedea0SLionel Sambuc unsigned nonce,
159ebfedea0SLionel Sambuc AS_REQ *a)
160ebfedea0SLionel Sambuc {
161ebfedea0SLionel Sambuc krb5_error_code ret;
162ebfedea0SLionel Sambuc krb5_salt salt;
163ebfedea0SLionel Sambuc
164ebfedea0SLionel Sambuc memset(a, 0, sizeof(*a));
165ebfedea0SLionel Sambuc
166ebfedea0SLionel Sambuc a->pvno = 5;
167ebfedea0SLionel Sambuc a->msg_type = krb_as_req;
168ebfedea0SLionel Sambuc a->req_body.kdc_options = opts;
169ebfedea0SLionel Sambuc a->req_body.cname = malloc(sizeof(*a->req_body.cname));
170ebfedea0SLionel Sambuc if (a->req_body.cname == NULL) {
171ebfedea0SLionel Sambuc ret = ENOMEM;
172ebfedea0SLionel Sambuc krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
173ebfedea0SLionel Sambuc goto fail;
174ebfedea0SLionel Sambuc }
175ebfedea0SLionel Sambuc a->req_body.sname = malloc(sizeof(*a->req_body.sname));
176ebfedea0SLionel Sambuc if (a->req_body.sname == NULL) {
177ebfedea0SLionel Sambuc ret = ENOMEM;
178ebfedea0SLionel Sambuc krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
179ebfedea0SLionel Sambuc goto fail;
180ebfedea0SLionel Sambuc }
181ebfedea0SLionel Sambuc ret = _krb5_principal2principalname (a->req_body.cname, creds->client);
182ebfedea0SLionel Sambuc if (ret)
183ebfedea0SLionel Sambuc goto fail;
184ebfedea0SLionel Sambuc ret = _krb5_principal2principalname (a->req_body.sname, creds->server);
185ebfedea0SLionel Sambuc if (ret)
186ebfedea0SLionel Sambuc goto fail;
187ebfedea0SLionel Sambuc ret = copy_Realm(&creds->client->realm, &a->req_body.realm);
188ebfedea0SLionel Sambuc if (ret)
189ebfedea0SLionel Sambuc goto fail;
190ebfedea0SLionel Sambuc
191ebfedea0SLionel Sambuc if(creds->times.starttime) {
192ebfedea0SLionel Sambuc a->req_body.from = malloc(sizeof(*a->req_body.from));
193ebfedea0SLionel Sambuc if (a->req_body.from == NULL) {
194ebfedea0SLionel Sambuc ret = ENOMEM;
195ebfedea0SLionel Sambuc krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
196ebfedea0SLionel Sambuc goto fail;
197ebfedea0SLionel Sambuc }
198ebfedea0SLionel Sambuc *a->req_body.from = creds->times.starttime;
199ebfedea0SLionel Sambuc }
200ebfedea0SLionel Sambuc if(creds->times.endtime){
201ebfedea0SLionel Sambuc ALLOC(a->req_body.till, 1);
202ebfedea0SLionel Sambuc *a->req_body.till = creds->times.endtime;
203ebfedea0SLionel Sambuc }
204ebfedea0SLionel Sambuc if(creds->times.renew_till){
205ebfedea0SLionel Sambuc a->req_body.rtime = malloc(sizeof(*a->req_body.rtime));
206ebfedea0SLionel Sambuc if (a->req_body.rtime == NULL) {
207ebfedea0SLionel Sambuc ret = ENOMEM;
208ebfedea0SLionel Sambuc krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
209ebfedea0SLionel Sambuc goto fail;
210ebfedea0SLionel Sambuc }
211ebfedea0SLionel Sambuc *a->req_body.rtime = creds->times.renew_till;
212ebfedea0SLionel Sambuc }
213ebfedea0SLionel Sambuc a->req_body.nonce = nonce;
214*0a6a1f1dSLionel Sambuc ret = _krb5_init_etype(context,
215*0a6a1f1dSLionel Sambuc KRB5_PDU_AS_REQUEST,
216ebfedea0SLionel Sambuc &a->req_body.etype.len,
217ebfedea0SLionel Sambuc &a->req_body.etype.val,
218ebfedea0SLionel Sambuc etypes);
219ebfedea0SLionel Sambuc if (ret)
220ebfedea0SLionel Sambuc goto fail;
221ebfedea0SLionel Sambuc
222ebfedea0SLionel Sambuc /*
223ebfedea0SLionel Sambuc * This means no addresses
224ebfedea0SLionel Sambuc */
225ebfedea0SLionel Sambuc
226ebfedea0SLionel Sambuc if (addrs && addrs->len == 0) {
227ebfedea0SLionel Sambuc a->req_body.addresses = NULL;
228ebfedea0SLionel Sambuc } else {
229ebfedea0SLionel Sambuc a->req_body.addresses = malloc(sizeof(*a->req_body.addresses));
230ebfedea0SLionel Sambuc if (a->req_body.addresses == NULL) {
231ebfedea0SLionel Sambuc ret = ENOMEM;
232ebfedea0SLionel Sambuc krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
233ebfedea0SLionel Sambuc goto fail;
234ebfedea0SLionel Sambuc }
235ebfedea0SLionel Sambuc
236ebfedea0SLionel Sambuc if (addrs)
237ebfedea0SLionel Sambuc ret = krb5_copy_addresses(context, addrs, a->req_body.addresses);
238ebfedea0SLionel Sambuc else {
239ebfedea0SLionel Sambuc ret = krb5_get_all_client_addrs (context, a->req_body.addresses);
240ebfedea0SLionel Sambuc if(ret == 0 && a->req_body.addresses->len == 0) {
241ebfedea0SLionel Sambuc free(a->req_body.addresses);
242ebfedea0SLionel Sambuc a->req_body.addresses = NULL;
243ebfedea0SLionel Sambuc }
244ebfedea0SLionel Sambuc }
245ebfedea0SLionel Sambuc if (ret)
246ebfedea0SLionel Sambuc return ret;
247ebfedea0SLionel Sambuc }
248ebfedea0SLionel Sambuc
249ebfedea0SLionel Sambuc a->req_body.enc_authorization_data = NULL;
250ebfedea0SLionel Sambuc a->req_body.additional_tickets = NULL;
251ebfedea0SLionel Sambuc
252ebfedea0SLionel Sambuc if(preauth != NULL) {
253*0a6a1f1dSLionel Sambuc size_t i;
254ebfedea0SLionel Sambuc ALLOC(a->padata, 1);
255ebfedea0SLionel Sambuc if(a->padata == NULL) {
256ebfedea0SLionel Sambuc ret = ENOMEM;
257ebfedea0SLionel Sambuc krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
258ebfedea0SLionel Sambuc goto fail;
259ebfedea0SLionel Sambuc }
260ebfedea0SLionel Sambuc a->padata->val = NULL;
261ebfedea0SLionel Sambuc a->padata->len = 0;
262ebfedea0SLionel Sambuc for(i = 0; i < preauth->len; i++) {
263ebfedea0SLionel Sambuc if(preauth->val[i].type == KRB5_PADATA_ENC_TIMESTAMP){
264*0a6a1f1dSLionel Sambuc size_t j;
265ebfedea0SLionel Sambuc
266ebfedea0SLionel Sambuc for(j = 0; j < preauth->val[i].info.len; j++) {
267ebfedea0SLionel Sambuc krb5_salt *sp = &salt;
268ebfedea0SLionel Sambuc if(preauth->val[i].info.val[j].salttype)
269ebfedea0SLionel Sambuc salt.salttype = *preauth->val[i].info.val[j].salttype;
270ebfedea0SLionel Sambuc else
271ebfedea0SLionel Sambuc salt.salttype = KRB5_PW_SALT;
272ebfedea0SLionel Sambuc if(preauth->val[i].info.val[j].salt)
273ebfedea0SLionel Sambuc salt.saltvalue = *preauth->val[i].info.val[j].salt;
274ebfedea0SLionel Sambuc else
275ebfedea0SLionel Sambuc if(salt.salttype == KRB5_PW_SALT)
276ebfedea0SLionel Sambuc sp = NULL;
277ebfedea0SLionel Sambuc else
278ebfedea0SLionel Sambuc krb5_data_zero(&salt.saltvalue);
279ebfedea0SLionel Sambuc ret = add_padata(context, a->padata, creds->client,
280ebfedea0SLionel Sambuc key_proc, keyseed,
281ebfedea0SLionel Sambuc &preauth->val[i].info.val[j].etype, 1,
282ebfedea0SLionel Sambuc sp);
283ebfedea0SLionel Sambuc if (ret == 0)
284ebfedea0SLionel Sambuc break;
285ebfedea0SLionel Sambuc }
286ebfedea0SLionel Sambuc }
287ebfedea0SLionel Sambuc }
288ebfedea0SLionel Sambuc } else
289ebfedea0SLionel Sambuc /* not sure this is the way to use `ptypes' */
290ebfedea0SLionel Sambuc if (ptypes == NULL || *ptypes == KRB5_PADATA_NONE)
291ebfedea0SLionel Sambuc a->padata = NULL;
292ebfedea0SLionel Sambuc else if (*ptypes == KRB5_PADATA_ENC_TIMESTAMP) {
293ebfedea0SLionel Sambuc ALLOC(a->padata, 1);
294ebfedea0SLionel Sambuc if (a->padata == NULL) {
295ebfedea0SLionel Sambuc ret = ENOMEM;
296ebfedea0SLionel Sambuc krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
297ebfedea0SLionel Sambuc goto fail;
298ebfedea0SLionel Sambuc }
299ebfedea0SLionel Sambuc a->padata->len = 0;
300ebfedea0SLionel Sambuc a->padata->val = NULL;
301ebfedea0SLionel Sambuc
302ebfedea0SLionel Sambuc /* make a v5 salted pa-data */
303ebfedea0SLionel Sambuc add_padata(context, a->padata, creds->client,
304ebfedea0SLionel Sambuc key_proc, keyseed, a->req_body.etype.val,
305ebfedea0SLionel Sambuc a->req_body.etype.len, NULL);
306ebfedea0SLionel Sambuc
307ebfedea0SLionel Sambuc /* make a v4 salted pa-data */
308ebfedea0SLionel Sambuc salt.salttype = KRB5_PW_SALT;
309ebfedea0SLionel Sambuc krb5_data_zero(&salt.saltvalue);
310ebfedea0SLionel Sambuc add_padata(context, a->padata, creds->client,
311ebfedea0SLionel Sambuc key_proc, keyseed, a->req_body.etype.val,
312ebfedea0SLionel Sambuc a->req_body.etype.len, &salt);
313ebfedea0SLionel Sambuc } else {
314ebfedea0SLionel Sambuc ret = KRB5_PREAUTH_BAD_TYPE;
315ebfedea0SLionel Sambuc krb5_set_error_message (context, ret,
316ebfedea0SLionel Sambuc N_("pre-auth type %d not supported", ""),
317ebfedea0SLionel Sambuc *ptypes);
318ebfedea0SLionel Sambuc goto fail;
319ebfedea0SLionel Sambuc }
320ebfedea0SLionel Sambuc return 0;
321ebfedea0SLionel Sambuc fail:
322ebfedea0SLionel Sambuc free_AS_REQ(a);
323ebfedea0SLionel Sambuc return ret;
324ebfedea0SLionel Sambuc }
325ebfedea0SLionel Sambuc
326ebfedea0SLionel Sambuc static int
set_ptypes(krb5_context context,KRB_ERROR * error,const krb5_preauthtype ** ptypes,krb5_preauthdata ** preauth)327ebfedea0SLionel Sambuc set_ptypes(krb5_context context,
328ebfedea0SLionel Sambuc KRB_ERROR *error,
329ebfedea0SLionel Sambuc const krb5_preauthtype **ptypes,
330ebfedea0SLionel Sambuc krb5_preauthdata **preauth)
331ebfedea0SLionel Sambuc {
332ebfedea0SLionel Sambuc static krb5_preauthdata preauth2;
333ebfedea0SLionel Sambuc static krb5_preauthtype ptypes2[] = { KRB5_PADATA_ENC_TIMESTAMP, KRB5_PADATA_NONE };
334ebfedea0SLionel Sambuc
335ebfedea0SLionel Sambuc if(error->e_data) {
336ebfedea0SLionel Sambuc METHOD_DATA md;
337*0a6a1f1dSLionel Sambuc size_t i;
338ebfedea0SLionel Sambuc decode_METHOD_DATA(error->e_data->data,
339ebfedea0SLionel Sambuc error->e_data->length,
340ebfedea0SLionel Sambuc &md,
341ebfedea0SLionel Sambuc NULL);
342ebfedea0SLionel Sambuc for(i = 0; i < md.len; i++){
343ebfedea0SLionel Sambuc switch(md.val[i].padata_type){
344ebfedea0SLionel Sambuc case KRB5_PADATA_ENC_TIMESTAMP:
345ebfedea0SLionel Sambuc *ptypes = ptypes2;
346ebfedea0SLionel Sambuc break;
347ebfedea0SLionel Sambuc case KRB5_PADATA_ETYPE_INFO:
348ebfedea0SLionel Sambuc *preauth = &preauth2;
349ebfedea0SLionel Sambuc ALLOC_SEQ(*preauth, 1);
350ebfedea0SLionel Sambuc (*preauth)->val[0].type = KRB5_PADATA_ENC_TIMESTAMP;
351ebfedea0SLionel Sambuc decode_ETYPE_INFO(md.val[i].padata_value.data,
352ebfedea0SLionel Sambuc md.val[i].padata_value.length,
353ebfedea0SLionel Sambuc &(*preauth)->val[0].info,
354ebfedea0SLionel Sambuc NULL);
355ebfedea0SLionel Sambuc break;
356ebfedea0SLionel Sambuc default:
357ebfedea0SLionel Sambuc break;
358ebfedea0SLionel Sambuc }
359ebfedea0SLionel Sambuc }
360ebfedea0SLionel Sambuc free_METHOD_DATA(&md);
361ebfedea0SLionel Sambuc } else {
362ebfedea0SLionel Sambuc *ptypes = ptypes2;
363ebfedea0SLionel Sambuc }
364ebfedea0SLionel Sambuc return(1);
365ebfedea0SLionel Sambuc }
366ebfedea0SLionel Sambuc
367ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_get_in_cred(krb5_context context,krb5_flags options,const krb5_addresses * addrs,const krb5_enctype * etypes,const krb5_preauthtype * ptypes,const krb5_preauthdata * preauth,krb5_key_proc key_proc,krb5_const_pointer keyseed,krb5_decrypt_proc decrypt_proc,krb5_const_pointer decryptarg,krb5_creds * creds,krb5_kdc_rep * ret_as_reply)368ebfedea0SLionel Sambuc krb5_get_in_cred(krb5_context context,
369ebfedea0SLionel Sambuc krb5_flags options,
370ebfedea0SLionel Sambuc const krb5_addresses *addrs,
371ebfedea0SLionel Sambuc const krb5_enctype *etypes,
372ebfedea0SLionel Sambuc const krb5_preauthtype *ptypes,
373ebfedea0SLionel Sambuc const krb5_preauthdata *preauth,
374ebfedea0SLionel Sambuc krb5_key_proc key_proc,
375ebfedea0SLionel Sambuc krb5_const_pointer keyseed,
376ebfedea0SLionel Sambuc krb5_decrypt_proc decrypt_proc,
377ebfedea0SLionel Sambuc krb5_const_pointer decryptarg,
378ebfedea0SLionel Sambuc krb5_creds *creds,
379ebfedea0SLionel Sambuc krb5_kdc_rep *ret_as_reply)
380*0a6a1f1dSLionel Sambuc KRB5_DEPRECATED_FUNCTION("Use X instead")
381ebfedea0SLionel Sambuc {
382ebfedea0SLionel Sambuc krb5_error_code ret;
383ebfedea0SLionel Sambuc AS_REQ a;
384ebfedea0SLionel Sambuc krb5_kdc_rep rep;
385ebfedea0SLionel Sambuc krb5_data req, resp;
386*0a6a1f1dSLionel Sambuc size_t len = 0;
387ebfedea0SLionel Sambuc krb5_salt salt;
388ebfedea0SLionel Sambuc krb5_keyblock *key;
389ebfedea0SLionel Sambuc size_t size;
390ebfedea0SLionel Sambuc KDCOptions opts;
391ebfedea0SLionel Sambuc PA_DATA *pa;
392ebfedea0SLionel Sambuc krb5_enctype etype;
393ebfedea0SLionel Sambuc krb5_preauthdata *my_preauth = NULL;
394ebfedea0SLionel Sambuc unsigned nonce;
395ebfedea0SLionel Sambuc int done;
396ebfedea0SLionel Sambuc
397ebfedea0SLionel Sambuc opts = int2KDCOptions(options);
398ebfedea0SLionel Sambuc
399ebfedea0SLionel Sambuc krb5_generate_random_block (&nonce, sizeof(nonce));
400ebfedea0SLionel Sambuc nonce &= 0xffffffff;
401ebfedea0SLionel Sambuc
402ebfedea0SLionel Sambuc do {
403ebfedea0SLionel Sambuc done = 1;
404ebfedea0SLionel Sambuc ret = init_as_req (context,
405ebfedea0SLionel Sambuc opts,
406ebfedea0SLionel Sambuc creds,
407ebfedea0SLionel Sambuc addrs,
408ebfedea0SLionel Sambuc etypes,
409ebfedea0SLionel Sambuc ptypes,
410ebfedea0SLionel Sambuc preauth,
411ebfedea0SLionel Sambuc key_proc,
412ebfedea0SLionel Sambuc keyseed,
413ebfedea0SLionel Sambuc nonce,
414ebfedea0SLionel Sambuc &a);
415ebfedea0SLionel Sambuc if (my_preauth) {
416ebfedea0SLionel Sambuc free_ETYPE_INFO(&my_preauth->val[0].info);
417ebfedea0SLionel Sambuc free (my_preauth->val);
418ebfedea0SLionel Sambuc my_preauth = NULL;
419ebfedea0SLionel Sambuc }
420ebfedea0SLionel Sambuc if (ret)
421ebfedea0SLionel Sambuc return ret;
422ebfedea0SLionel Sambuc
423ebfedea0SLionel Sambuc ASN1_MALLOC_ENCODE(AS_REQ, req.data, req.length, &a, &len, ret);
424ebfedea0SLionel Sambuc free_AS_REQ(&a);
425ebfedea0SLionel Sambuc if (ret)
426ebfedea0SLionel Sambuc return ret;
427ebfedea0SLionel Sambuc if(len != req.length)
428ebfedea0SLionel Sambuc krb5_abortx(context, "internal error in ASN.1 encoder");
429ebfedea0SLionel Sambuc
430ebfedea0SLionel Sambuc ret = krb5_sendto_kdc (context, &req, &creds->client->realm, &resp);
431ebfedea0SLionel Sambuc krb5_data_free(&req);
432ebfedea0SLionel Sambuc if (ret)
433ebfedea0SLionel Sambuc return ret;
434ebfedea0SLionel Sambuc
435ebfedea0SLionel Sambuc memset (&rep, 0, sizeof(rep));
436ebfedea0SLionel Sambuc ret = decode_AS_REP(resp.data, resp.length, &rep.kdc_rep, &size);
437ebfedea0SLionel Sambuc if(ret) {
438ebfedea0SLionel Sambuc /* let's try to parse it as a KRB-ERROR */
439ebfedea0SLionel Sambuc KRB_ERROR error;
440ebfedea0SLionel Sambuc int ret2;
441ebfedea0SLionel Sambuc
442ebfedea0SLionel Sambuc ret2 = krb5_rd_error(context, &resp, &error);
443ebfedea0SLionel Sambuc if(ret2 && resp.data && ((char*)resp.data)[0] == 4)
444ebfedea0SLionel Sambuc ret = KRB5KRB_AP_ERR_V4_REPLY;
445ebfedea0SLionel Sambuc krb5_data_free(&resp);
446ebfedea0SLionel Sambuc if (ret2 == 0) {
447ebfedea0SLionel Sambuc ret = krb5_error_from_rd_error(context, &error, creds);
448ebfedea0SLionel Sambuc /* if no preauth was set and KDC requires it, give it
449ebfedea0SLionel Sambuc one more try */
450ebfedea0SLionel Sambuc if (!ptypes && !preauth
451ebfedea0SLionel Sambuc && ret == KRB5KDC_ERR_PREAUTH_REQUIRED
452ebfedea0SLionel Sambuc #if 0
453ebfedea0SLionel Sambuc || ret == KRB5KDC_ERR_BADOPTION
454ebfedea0SLionel Sambuc #endif
455ebfedea0SLionel Sambuc && set_ptypes(context, &error, &ptypes, &my_preauth)) {
456ebfedea0SLionel Sambuc done = 0;
457ebfedea0SLionel Sambuc preauth = my_preauth;
458ebfedea0SLionel Sambuc krb5_free_error_contents(context, &error);
459ebfedea0SLionel Sambuc krb5_clear_error_message(context);
460ebfedea0SLionel Sambuc continue;
461ebfedea0SLionel Sambuc }
462ebfedea0SLionel Sambuc if(ret_as_reply)
463ebfedea0SLionel Sambuc ret_as_reply->error = error;
464ebfedea0SLionel Sambuc else
465ebfedea0SLionel Sambuc free_KRB_ERROR (&error);
466ebfedea0SLionel Sambuc return ret;
467ebfedea0SLionel Sambuc }
468ebfedea0SLionel Sambuc return ret;
469ebfedea0SLionel Sambuc }
470ebfedea0SLionel Sambuc krb5_data_free(&resp);
471ebfedea0SLionel Sambuc } while(!done);
472ebfedea0SLionel Sambuc
473ebfedea0SLionel Sambuc pa = NULL;
474ebfedea0SLionel Sambuc etype = rep.kdc_rep.enc_part.etype;
475ebfedea0SLionel Sambuc if(rep.kdc_rep.padata){
476ebfedea0SLionel Sambuc int i = 0;
477ebfedea0SLionel Sambuc pa = krb5_find_padata(rep.kdc_rep.padata->val, rep.kdc_rep.padata->len,
478ebfedea0SLionel Sambuc KRB5_PADATA_PW_SALT, &i);
479ebfedea0SLionel Sambuc if(pa == NULL) {
480ebfedea0SLionel Sambuc i = 0;
481ebfedea0SLionel Sambuc pa = krb5_find_padata(rep.kdc_rep.padata->val,
482ebfedea0SLionel Sambuc rep.kdc_rep.padata->len,
483ebfedea0SLionel Sambuc KRB5_PADATA_AFS3_SALT, &i);
484ebfedea0SLionel Sambuc }
485ebfedea0SLionel Sambuc }
486ebfedea0SLionel Sambuc if(pa) {
487*0a6a1f1dSLionel Sambuc salt.salttype = (krb5_salttype)pa->padata_type;
488ebfedea0SLionel Sambuc salt.saltvalue = pa->padata_value;
489ebfedea0SLionel Sambuc
490ebfedea0SLionel Sambuc ret = (*key_proc)(context, etype, salt, keyseed, &key);
491ebfedea0SLionel Sambuc } else {
492ebfedea0SLionel Sambuc /* make a v5 salted pa-data */
493ebfedea0SLionel Sambuc ret = krb5_get_pw_salt (context, creds->client, &salt);
494ebfedea0SLionel Sambuc
495ebfedea0SLionel Sambuc if (ret)
496ebfedea0SLionel Sambuc goto out;
497ebfedea0SLionel Sambuc ret = (*key_proc)(context, etype, salt, keyseed, &key);
498ebfedea0SLionel Sambuc krb5_free_salt(context, salt);
499ebfedea0SLionel Sambuc }
500ebfedea0SLionel Sambuc if (ret)
501ebfedea0SLionel Sambuc goto out;
502ebfedea0SLionel Sambuc
503ebfedea0SLionel Sambuc {
504ebfedea0SLionel Sambuc unsigned flags = EXTRACT_TICKET_TIMESYNC;
505ebfedea0SLionel Sambuc if (opts.request_anonymous)
506ebfedea0SLionel Sambuc flags |= EXTRACT_TICKET_ALLOW_SERVER_MISMATCH;
507ebfedea0SLionel Sambuc
508ebfedea0SLionel Sambuc ret = _krb5_extract_ticket(context,
509ebfedea0SLionel Sambuc &rep,
510ebfedea0SLionel Sambuc creds,
511ebfedea0SLionel Sambuc key,
512ebfedea0SLionel Sambuc keyseed,
513ebfedea0SLionel Sambuc KRB5_KU_AS_REP_ENC_PART,
514ebfedea0SLionel Sambuc NULL,
515ebfedea0SLionel Sambuc nonce,
516ebfedea0SLionel Sambuc flags,
517ebfedea0SLionel Sambuc decrypt_proc,
518ebfedea0SLionel Sambuc decryptarg);
519ebfedea0SLionel Sambuc }
520ebfedea0SLionel Sambuc memset (key->keyvalue.data, 0, key->keyvalue.length);
521ebfedea0SLionel Sambuc krb5_free_keyblock_contents (context, key);
522ebfedea0SLionel Sambuc free (key);
523ebfedea0SLionel Sambuc
524ebfedea0SLionel Sambuc out:
525ebfedea0SLionel Sambuc if (ret == 0 && ret_as_reply)
526ebfedea0SLionel Sambuc *ret_as_reply = rep;
527ebfedea0SLionel Sambuc else
528ebfedea0SLionel Sambuc krb5_free_kdc_rep (context, &rep);
529ebfedea0SLionel Sambuc return ret;
530ebfedea0SLionel Sambuc }
531ebfedea0SLionel Sambuc
532ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_get_in_tkt(krb5_context context,krb5_flags options,const krb5_addresses * addrs,const krb5_enctype * etypes,const krb5_preauthtype * ptypes,krb5_key_proc key_proc,krb5_const_pointer keyseed,krb5_decrypt_proc decrypt_proc,krb5_const_pointer decryptarg,krb5_creds * creds,krb5_ccache ccache,krb5_kdc_rep * ret_as_reply)533ebfedea0SLionel Sambuc krb5_get_in_tkt(krb5_context context,
534ebfedea0SLionel Sambuc krb5_flags options,
535ebfedea0SLionel Sambuc const krb5_addresses *addrs,
536ebfedea0SLionel Sambuc const krb5_enctype *etypes,
537ebfedea0SLionel Sambuc const krb5_preauthtype *ptypes,
538ebfedea0SLionel Sambuc krb5_key_proc key_proc,
539ebfedea0SLionel Sambuc krb5_const_pointer keyseed,
540ebfedea0SLionel Sambuc krb5_decrypt_proc decrypt_proc,
541ebfedea0SLionel Sambuc krb5_const_pointer decryptarg,
542ebfedea0SLionel Sambuc krb5_creds *creds,
543ebfedea0SLionel Sambuc krb5_ccache ccache,
544ebfedea0SLionel Sambuc krb5_kdc_rep *ret_as_reply)
545*0a6a1f1dSLionel Sambuc KRB5_DEPRECATED_FUNCTION("Use X instead")
546ebfedea0SLionel Sambuc {
547ebfedea0SLionel Sambuc krb5_error_code ret;
548ebfedea0SLionel Sambuc
549ebfedea0SLionel Sambuc ret = krb5_get_in_cred (context,
550ebfedea0SLionel Sambuc options,
551ebfedea0SLionel Sambuc addrs,
552ebfedea0SLionel Sambuc etypes,
553ebfedea0SLionel Sambuc ptypes,
554ebfedea0SLionel Sambuc NULL,
555ebfedea0SLionel Sambuc key_proc,
556ebfedea0SLionel Sambuc keyseed,
557ebfedea0SLionel Sambuc decrypt_proc,
558ebfedea0SLionel Sambuc decryptarg,
559ebfedea0SLionel Sambuc creds,
560ebfedea0SLionel Sambuc ret_as_reply);
561ebfedea0SLionel Sambuc if(ret)
562ebfedea0SLionel Sambuc return ret;
563ebfedea0SLionel Sambuc if (ccache)
564ebfedea0SLionel Sambuc ret = krb5_cc_store_cred (context, ccache, creds);
565ebfedea0SLionel Sambuc return ret;
566ebfedea0SLionel Sambuc }
567ebfedea0SLionel Sambuc
568ebfedea0SLionel Sambuc #endif /* HEIMDAL_SMALLER */
569