1/*
2 * Copyright (c) 1997-2007 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 *
17 * 3. Neither the name of the Institute nor the names of its contributors
18 *    may be used to endorse or promote products derived from this software
19 *    without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#include "kdc_locl.h"
35
36#define MAX_TIME ((time_t)((1U << 31) - 1))
37
38void
39_kdc_fix_time(time_t **t)
40{
41    if(*t == NULL){
42	ALLOC(*t);
43	**t = MAX_TIME;
44    }
45    if(**t == 0) **t = MAX_TIME; /* fix for old clients */
46}
47
48static int
49realloc_method_data(METHOD_DATA *md)
50{
51    PA_DATA *pa;
52    pa = realloc(md->val, (md->len + 1) * sizeof(*md->val));
53    if(pa == NULL)
54	return ENOMEM;
55    md->val = pa;
56    md->len++;
57    return 0;
58}
59
60static void
61set_salt_padata(METHOD_DATA *md, Salt *salt)
62{
63    if (salt) {
64       realloc_method_data(md);
65       md->val[md->len - 1].padata_type = salt->type;
66       der_copy_octet_string(&salt->salt,
67                             &md->val[md->len - 1].padata_value);
68    }
69}
70
71const PA_DATA*
72_kdc_find_padata(const KDC_REQ *req, int *start, int type)
73{
74    if (req->padata == NULL)
75	return NULL;
76
77    while((size_t)*start < req->padata->len){
78	(*start)++;
79	if(req->padata->val[*start - 1].padata_type == (unsigned)type)
80	    return &req->padata->val[*start - 1];
81    }
82    return NULL;
83}
84
85/*
86 * This is a hack to allow predefined weak services, like afs to
87 * still use weak types
88 */
89
90krb5_boolean
91_kdc_is_weak_exception(krb5_principal principal, krb5_enctype etype)
92{
93    if (principal->name.name_string.len > 0 &&
94	strcmp(principal->name.name_string.val[0], "afs") == 0 &&
95	(etype == ETYPE_DES_CBC_CRC
96	 || etype == ETYPE_DES_CBC_MD4
97	 || etype == ETYPE_DES_CBC_MD5))
98	return TRUE;
99    return FALSE;
100}
101
102
103/*
104 * Detect if `key' is the using the the precomputed `default_salt'.
105 */
106
107static krb5_boolean
108is_default_salt_p(const krb5_salt *default_salt, const Key *key)
109{
110    if (key->salt == NULL)
111	return TRUE;
112    if (default_salt->salttype != key->salt->type)
113	return FALSE;
114    if (krb5_data_cmp(&default_salt->saltvalue, &key->salt->salt))
115	return FALSE;
116    return TRUE;
117}
118
119/*
120 * return the first appropriate key of `princ' in `ret_key'.  Look for
121 * all the etypes in (`etypes', `len'), stopping as soon as we find
122 * one, but preferring one that has default salt
123 */
124
125krb5_error_code
126_kdc_find_etype(krb5_context context, krb5_boolean use_strongest_session_key,
127		krb5_boolean is_preauth, hdb_entry_ex *princ,
128		krb5_enctype *etypes, unsigned len,
129		krb5_enctype *ret_enctype, Key **ret_key)
130{
131    krb5_error_code ret;
132    krb5_salt def_salt;
133    krb5_enctype enctype = ETYPE_NULL;
134    Key *key;
135    int i;
136
137    /* We'll want to avoid keys with v4 salted keys in the pre-auth case... */
138    ret = krb5_get_pw_salt(context, princ->entry.principal, &def_salt);
139    if (ret)
140	return ret;
141
142    ret = KRB5KDC_ERR_ETYPE_NOSUPP;
143
144    if (use_strongest_session_key) {
145	const krb5_enctype *p;
146	krb5_enctype clientbest = ETYPE_NULL;
147	int j;
148
149	/*
150	 * Pick the strongest key that the KDC, target service, and
151	 * client all support, using the local cryptosystem enctype
152	 * list in strongest-to-weakest order to drive the search.
153	 *
154	 * This is not what RFC4120 says to do, but it encourages
155	 * adoption of stronger enctypes.  This doesn't play well with
156	 * clients that have multiple Kerberos client implementations
157	 * available with different supported enctype lists.
158	 */
159
160	/* drive the search with local supported enctypes list */
161	p = krb5_kerberos_enctypes(context);
162	for (i = 0; p[i] != ETYPE_NULL && enctype == ETYPE_NULL; i++) {
163	    if (krb5_enctype_valid(context, p[i]) != 0)
164		continue;
165
166	    /* check that the client supports it too */
167	    for (j = 0; j < len && enctype == ETYPE_NULL; j++) {
168		if (p[i] != etypes[j])
169		    continue;
170		/* save best of union of { client, crypto system } */
171		if (clientbest == ETYPE_NULL)
172		    clientbest = p[i];
173		/* check target princ support */
174		ret = hdb_enctype2key(context, &princ->entry, p[i], &key);
175		if (ret)
176		    continue;
177		if (is_preauth && !is_default_salt_p(&def_salt, key))
178		    continue;
179		enctype = p[i];
180	    }
181	}
182	if (clientbest != ETYPE_NULL && enctype == ETYPE_NULL)
183	    enctype = clientbest;
184	else if (enctype == ETYPE_NULL)
185	    ret = KRB5KDC_ERR_ETYPE_NOSUPP;
186	if (ret == 0 && ret_enctype != NULL)
187	    *ret_enctype = enctype;
188	if (ret == 0 && ret_key != NULL)
189	    *ret_key = key;
190    } else {
191	/*
192	 * Pick the first key from the client's enctype list that is
193	 * supported by the cryptosystem and by the given principal.
194	 *
195	 * RFC4120 says we SHOULD pick the first _strong_ key from the
196	 * client's list... not the first key...  If the admin disallows
197	 * weak enctypes in krb5.conf and selects this key selection
198	 * algorithm, then we get exactly what RFC4120 says.
199	 */
200	for(key = NULL, i = 0; ret != 0 && i < len; i++, key = NULL) {
201
202	    if (krb5_enctype_valid(context, etypes[i]) != 0 &&
203		!_kdc_is_weak_exception(princ->entry.principal, etypes[i]))
204		continue;
205
206	    while (hdb_next_enctype2key(context, &princ->entry, etypes[i], &key) == 0) {
207		if (key->key.keyvalue.length == 0) {
208		    ret = KRB5KDC_ERR_NULL_KEY;
209		    continue;
210		}
211		if (ret_key != NULL)
212		    *ret_key = key;
213		if (ret_enctype != NULL)
214		    *ret_enctype = etypes[i];
215		ret = 0;
216		if (is_preauth && is_default_salt_p(&def_salt, key))
217		    goto out;
218	    }
219	}
220    }
221
222out:
223    krb5_free_salt (context, def_salt);
224    return ret;
225}
226
227krb5_error_code
228_kdc_make_anonymous_principalname (PrincipalName *pn)
229{
230    pn->name_type = KRB5_NT_PRINCIPAL;
231    pn->name_string.len = 1;
232    pn->name_string.val = malloc(sizeof(*pn->name_string.val));
233    if (pn->name_string.val == NULL)
234	return ENOMEM;
235    pn->name_string.val[0] = strdup("anonymous");
236    if (pn->name_string.val[0] == NULL) {
237	free(pn->name_string.val);
238	pn->name_string.val = NULL;
239	return ENOMEM;
240    }
241    return 0;
242}
243
244void
245_kdc_log_timestamp(krb5_context context,
246		   krb5_kdc_configuration *config,
247		   const char *type,
248		   KerberosTime authtime, KerberosTime *starttime,
249		   KerberosTime endtime, KerberosTime *renew_till)
250{
251    char authtime_str[100], starttime_str[100],
252	endtime_str[100], renewtime_str[100];
253
254    krb5_format_time(context, authtime,
255		     authtime_str, sizeof(authtime_str), TRUE);
256    if (starttime)
257	krb5_format_time(context, *starttime,
258			 starttime_str, sizeof(starttime_str), TRUE);
259    else
260	strlcpy(starttime_str, "unset", sizeof(starttime_str));
261    krb5_format_time(context, endtime,
262		     endtime_str, sizeof(endtime_str), TRUE);
263    if (renew_till)
264	krb5_format_time(context, *renew_till,
265			 renewtime_str, sizeof(renewtime_str), TRUE);
266    else
267	strlcpy(renewtime_str, "unset", sizeof(renewtime_str));
268
269    kdc_log(context, config, 5,
270	    "%s authtime: %s starttime: %s endtime: %s renew till: %s",
271	    type, authtime_str, starttime_str, endtime_str, renewtime_str);
272}
273
274static void
275log_patypes(krb5_context context,
276	    krb5_kdc_configuration *config,
277	    METHOD_DATA *padata)
278{
279    struct rk_strpool *p = NULL;
280    char *str;
281    size_t i;
282
283    for (i = 0; i < padata->len; i++) {
284	switch(padata->val[i].padata_type) {
285	case KRB5_PADATA_PK_AS_REQ:
286	    p = rk_strpoolprintf(p, "PK-INIT(ietf)");
287	    break;
288	case KRB5_PADATA_PK_AS_REQ_WIN:
289	    p = rk_strpoolprintf(p, "PK-INIT(win2k)");
290	    break;
291	case KRB5_PADATA_PA_PK_OCSP_RESPONSE:
292	    p = rk_strpoolprintf(p, "OCSP");
293	    break;
294	case KRB5_PADATA_ENC_TIMESTAMP:
295	    p = rk_strpoolprintf(p, "encrypted-timestamp");
296	    break;
297	default:
298	    p = rk_strpoolprintf(p, "%d", padata->val[i].padata_type);
299	    break;
300	}
301	if (p && i + 1 < padata->len)
302	    p = rk_strpoolprintf(p, ", ");
303	if (p == NULL) {
304	    kdc_log(context, config, 0, "out of memory");
305	    return;
306	}
307    }
308    if (p == NULL)
309	p = rk_strpoolprintf(p, "none");
310
311    str = rk_strpoolcollect(p);
312    kdc_log(context, config, 0, "Client sent patypes: %s", str);
313    free(str);
314}
315
316/*
317 *
318 */
319
320
321krb5_error_code
322_kdc_encode_reply(krb5_context context,
323		  krb5_kdc_configuration *config,
324		  KDC_REP *rep, const EncTicketPart *et, EncKDCRepPart *ek,
325		  krb5_enctype etype,
326		  int skvno, const EncryptionKey *skey,
327		  int ckvno, const EncryptionKey *reply_key,
328		  int rk_is_subkey,
329		  const char **e_text,
330		  krb5_data *reply)
331{
332    unsigned char *buf;
333    size_t buf_size;
334    size_t len = 0;
335    krb5_error_code ret;
336    krb5_crypto crypto;
337
338    ASN1_MALLOC_ENCODE(EncTicketPart, buf, buf_size, et, &len, ret);
339    if(ret) {
340	const char *msg = krb5_get_error_message(context, ret);
341	kdc_log(context, config, 0, "Failed to encode ticket: %s", msg);
342	krb5_free_error_message(context, msg);
343	return ret;
344    }
345    if(buf_size != len) {
346	free(buf);
347	kdc_log(context, config, 0, "Internal error in ASN.1 encoder");
348	*e_text = "KDC internal error";
349	return KRB5KRB_ERR_GENERIC;
350    }
351
352    ret = krb5_crypto_init(context, skey, etype, &crypto);
353    if (ret) {
354        const char *msg;
355	free(buf);
356	msg = krb5_get_error_message(context, ret);
357	kdc_log(context, config, 0, "krb5_crypto_init failed: %s", msg);
358	krb5_free_error_message(context, msg);
359	return ret;
360    }
361
362    ret = krb5_encrypt_EncryptedData(context,
363				     crypto,
364				     KRB5_KU_TICKET,
365				     buf,
366				     len,
367				     skvno,
368				     &rep->ticket.enc_part);
369    free(buf);
370    krb5_crypto_destroy(context, crypto);
371    if(ret) {
372	const char *msg = krb5_get_error_message(context, ret);
373	kdc_log(context, config, 0, "Failed to encrypt data: %s", msg);
374	krb5_free_error_message(context, msg);
375	return ret;
376    }
377
378    if(rep->msg_type == krb_as_rep && !config->encode_as_rep_as_tgs_rep)
379	ASN1_MALLOC_ENCODE(EncASRepPart, buf, buf_size, ek, &len, ret);
380    else
381	ASN1_MALLOC_ENCODE(EncTGSRepPart, buf, buf_size, ek, &len, ret);
382    if(ret) {
383	const char *msg = krb5_get_error_message(context, ret);
384	kdc_log(context, config, 0, "Failed to encode KDC-REP: %s", msg);
385	krb5_free_error_message(context, msg);
386	return ret;
387    }
388    if(buf_size != len) {
389	free(buf);
390	kdc_log(context, config, 0, "Internal error in ASN.1 encoder");
391	*e_text = "KDC internal error";
392	return KRB5KRB_ERR_GENERIC;
393    }
394    ret = krb5_crypto_init(context, reply_key, 0, &crypto);
395    if (ret) {
396	const char *msg = krb5_get_error_message(context, ret);
397	free(buf);
398	kdc_log(context, config, 0, "krb5_crypto_init failed: %s", msg);
399	krb5_free_error_message(context, msg);
400	return ret;
401    }
402    if(rep->msg_type == krb_as_rep) {
403	krb5_encrypt_EncryptedData(context,
404				   crypto,
405				   KRB5_KU_AS_REP_ENC_PART,
406				   buf,
407				   len,
408				   ckvno,
409				   &rep->enc_part);
410	free(buf);
411	ASN1_MALLOC_ENCODE(AS_REP, buf, buf_size, rep, &len, ret);
412    } else {
413	krb5_encrypt_EncryptedData(context,
414				   crypto,
415				   rk_is_subkey ? KRB5_KU_TGS_REP_ENC_PART_SUB_KEY : KRB5_KU_TGS_REP_ENC_PART_SESSION,
416				   buf,
417				   len,
418				   ckvno,
419				   &rep->enc_part);
420	free(buf);
421	ASN1_MALLOC_ENCODE(TGS_REP, buf, buf_size, rep, &len, ret);
422    }
423    krb5_crypto_destroy(context, crypto);
424    if(ret) {
425	const char *msg = krb5_get_error_message(context, ret);
426	kdc_log(context, config, 0, "Failed to encode KDC-REP: %s", msg);
427	krb5_free_error_message(context, msg);
428	return ret;
429    }
430    if(buf_size != len) {
431	free(buf);
432	kdc_log(context, config, 0, "Internal error in ASN.1 encoder");
433	*e_text = "KDC internal error";
434	return KRB5KRB_ERR_GENERIC;
435    }
436    reply->data = buf;
437    reply->length = buf_size;
438    return 0;
439}
440
441/*
442 * Return 1 if the client have only older enctypes, this is for
443 * determining if the server should send ETYPE_INFO2 or not.
444 */
445
446static int
447older_enctype(krb5_enctype enctype)
448{
449    switch (enctype) {
450    case ETYPE_DES_CBC_CRC:
451    case ETYPE_DES_CBC_MD4:
452    case ETYPE_DES_CBC_MD5:
453    case ETYPE_DES3_CBC_SHA1:
454    case ETYPE_ARCFOUR_HMAC_MD5:
455    case ETYPE_ARCFOUR_HMAC_MD5_56:
456    /*
457     * The following three is "old" windows enctypes and is needed for
458     * windows 2000 hosts.
459     */
460    case ETYPE_ARCFOUR_MD4:
461    case ETYPE_ARCFOUR_HMAC_OLD:
462    case ETYPE_ARCFOUR_HMAC_OLD_EXP:
463	return 1;
464    default:
465	return 0;
466    }
467}
468
469/*
470 *
471 */
472
473static krb5_error_code
474make_etype_info_entry(krb5_context context, ETYPE_INFO_ENTRY *ent, Key *key)
475{
476    ent->etype = key->key.keytype;
477    if(key->salt){
478#if 0
479	ALLOC(ent->salttype);
480
481	if(key->salt->type == hdb_pw_salt)
482	    *ent->salttype = 0; /* or 1? or NULL? */
483	else if(key->salt->type == hdb_afs3_salt)
484	    *ent->salttype = 2;
485	else {
486	    kdc_log(context, config, 0, "unknown salt-type: %d",
487		    key->salt->type);
488	    return KRB5KRB_ERR_GENERIC;
489	}
490	/* according to `the specs', we can't send a salt if
491	   we have AFS3 salted key, but that requires that you
492	   *know* what cell you are using (e.g by assuming
493	   that the cell is the same as the realm in lower
494	   case) */
495#elif 0
496	ALLOC(ent->salttype);
497	*ent->salttype = key->salt->type;
498#else
499	/*
500	 * We shouldn't sent salttype since it is incompatible with the
501	 * specification and it breaks windows clients.  The afs
502	 * salting problem is solved by using KRB5-PADATA-AFS3-SALT
503	 * implemented in Heimdal 0.7 and later.
504	 */
505	ent->salttype = NULL;
506#endif
507	krb5_copy_data(context, &key->salt->salt,
508		       &ent->salt);
509    } else {
510	/* we return no salt type at all, as that should indicate
511	 * the default salt type and make everybody happy.  some
512	 * systems (like w2k) dislike being told the salt type
513	 * here. */
514
515	ent->salttype = NULL;
516	ent->salt = NULL;
517    }
518    return 0;
519}
520
521static krb5_error_code
522get_pa_etype_info(krb5_context context,
523		  krb5_kdc_configuration *config,
524		  METHOD_DATA *md, Key *ckey)
525{
526    krb5_error_code ret = 0;
527    ETYPE_INFO pa;
528    unsigned char *buf;
529    size_t len;
530
531
532    pa.len = 1;
533    pa.val = calloc(1, sizeof(pa.val[0]));
534    if(pa.val == NULL)
535	return ENOMEM;
536
537    ret = make_etype_info_entry(context, &pa.val[0], ckey);
538    if (ret) {
539	free_ETYPE_INFO(&pa);
540	return ret;
541    }
542
543    ASN1_MALLOC_ENCODE(ETYPE_INFO, buf, len, &pa, &len, ret);
544    free_ETYPE_INFO(&pa);
545    if(ret)
546	return ret;
547    ret = realloc_method_data(md);
548    if(ret) {
549	free(buf);
550	return ret;
551    }
552    md->val[md->len - 1].padata_type = KRB5_PADATA_ETYPE_INFO;
553    md->val[md->len - 1].padata_value.length = len;
554    md->val[md->len - 1].padata_value.data = buf;
555    return 0;
556}
557
558/*
559 *
560 */
561
562extern int _krb5_AES_string_to_default_iterator;
563
564static krb5_error_code
565make_etype_info2_entry(ETYPE_INFO2_ENTRY *ent, Key *key)
566{
567    ent->etype = key->key.keytype;
568    if(key->salt) {
569	ALLOC(ent->salt);
570	if (ent->salt == NULL)
571	    return ENOMEM;
572	*ent->salt = malloc(key->salt->salt.length + 1);
573	if (*ent->salt == NULL) {
574	    free(ent->salt);
575	    ent->salt = NULL;
576	    return ENOMEM;
577	}
578	memcpy(*ent->salt, key->salt->salt.data, key->salt->salt.length);
579	(*ent->salt)[key->salt->salt.length] = '\0';
580    } else
581	ent->salt = NULL;
582
583    ent->s2kparams = NULL;
584
585    switch (key->key.keytype) {
586    case ETYPE_AES128_CTS_HMAC_SHA1_96:
587    case ETYPE_AES256_CTS_HMAC_SHA1_96:
588	ALLOC(ent->s2kparams);
589	if (ent->s2kparams == NULL)
590	    return ENOMEM;
591	ent->s2kparams->length = 4;
592	ent->s2kparams->data = malloc(ent->s2kparams->length);
593	if (ent->s2kparams->data == NULL) {
594	    free(ent->s2kparams);
595	    ent->s2kparams = NULL;
596	    return ENOMEM;
597	}
598	_krb5_put_int(ent->s2kparams->data,
599		      _krb5_AES_string_to_default_iterator,
600		      ent->s2kparams->length);
601	break;
602    case ETYPE_DES_CBC_CRC:
603    case ETYPE_DES_CBC_MD4:
604    case ETYPE_DES_CBC_MD5:
605	/* Check if this was a AFS3 salted key */
606	if(key->salt && key->salt->type == hdb_afs3_salt){
607	    ALLOC(ent->s2kparams);
608	    if (ent->s2kparams == NULL)
609		return ENOMEM;
610	    ent->s2kparams->length = 1;
611	    ent->s2kparams->data = malloc(ent->s2kparams->length);
612	    if (ent->s2kparams->data == NULL) {
613		free(ent->s2kparams);
614		ent->s2kparams = NULL;
615		return ENOMEM;
616	    }
617	    _krb5_put_int(ent->s2kparams->data,
618			  1,
619			  ent->s2kparams->length);
620	}
621	break;
622    default:
623	break;
624    }
625    return 0;
626}
627
628/*
629 * Return an ETYPE-INFO2. Enctypes are storted the same way as in the
630 * database (client supported enctypes first, then the unsupported
631 * enctypes).
632 */
633
634static krb5_error_code
635get_pa_etype_info2(krb5_context context,
636		   krb5_kdc_configuration *config,
637		   METHOD_DATA *md, Key *ckey)
638{
639    krb5_error_code ret = 0;
640    ETYPE_INFO2 pa;
641    unsigned char *buf;
642    size_t len;
643
644    pa.len = 1;
645    pa.val = calloc(1, sizeof(pa.val[0]));
646    if(pa.val == NULL)
647	return ENOMEM;
648
649    ret = make_etype_info2_entry(&pa.val[0], ckey);
650    if (ret) {
651	free_ETYPE_INFO2(&pa);
652	return ret;
653    }
654
655    ASN1_MALLOC_ENCODE(ETYPE_INFO2, buf, len, &pa, &len, ret);
656    free_ETYPE_INFO2(&pa);
657    if(ret)
658	return ret;
659    ret = realloc_method_data(md);
660    if(ret) {
661	free(buf);
662	return ret;
663    }
664    md->val[md->len - 1].padata_type = KRB5_PADATA_ETYPE_INFO2;
665    md->val[md->len - 1].padata_value.length = len;
666    md->val[md->len - 1].padata_value.data = buf;
667    return 0;
668}
669
670/*
671 *
672 */
673
674static void
675log_as_req(krb5_context context,
676	   krb5_kdc_configuration *config,
677	   krb5_enctype cetype,
678	   krb5_enctype setype,
679	   const KDC_REQ_BODY *b)
680{
681    krb5_error_code ret;
682    struct rk_strpool *p;
683    char *str;
684    size_t i;
685
686    p = rk_strpoolprintf(NULL, "%s", "Client supported enctypes: ");
687
688    for (i = 0; i < b->etype.len; i++) {
689	ret = krb5_enctype_to_string(context, b->etype.val[i], &str);
690	if (ret == 0) {
691	    p = rk_strpoolprintf(p, "%s", str);
692	    free(str);
693	} else
694	    p = rk_strpoolprintf(p, "%d", b->etype.val[i]);
695	if (p && i + 1 < b->etype.len)
696	    p = rk_strpoolprintf(p, ", ");
697	if (p == NULL) {
698	    kdc_log(context, config, 0, "out of memory");
699	    return;
700	}
701    }
702    if (p == NULL)
703	p = rk_strpoolprintf(p, "no encryption types");
704
705    {
706	char *cet;
707	char *set;
708
709	ret = krb5_enctype_to_string(context, cetype, &cet);
710	if(ret == 0) {
711	    ret = krb5_enctype_to_string(context, setype, &set);
712	    if (ret == 0) {
713		p = rk_strpoolprintf(p, ", using %s/%s", cet, set);
714		free(set);
715	    }
716	    free(cet);
717	}
718	if (ret != 0)
719	    p = rk_strpoolprintf(p, ", using enctypes %d/%d",
720				 cetype, setype);
721    }
722
723    str = rk_strpoolcollect(p);
724    kdc_log(context, config, 0, "%s", str);
725    free(str);
726
727    {
728	char fixedstr[128];
729	unparse_flags(KDCOptions2int(b->kdc_options), asn1_KDCOptions_units(),
730		      fixedstr, sizeof(fixedstr));
731	if(*fixedstr)
732	    kdc_log(context, config, 0, "Requested flags: %s", fixedstr);
733    }
734}
735
736/*
737 * verify the flags on `client' and `server', returning 0
738 * if they are OK and generating an error messages and returning
739 * and error code otherwise.
740 */
741
742krb5_error_code
743kdc_check_flags(krb5_context context,
744		krb5_kdc_configuration *config,
745		hdb_entry_ex *client_ex, const char *client_name,
746		hdb_entry_ex *server_ex, const char *server_name,
747		krb5_boolean is_as_req)
748{
749    if(client_ex != NULL) {
750	hdb_entry *client = &client_ex->entry;
751
752	/* check client */
753	if (client->flags.locked_out) {
754	    kdc_log(context, config, 0,
755		    "Client (%s) is locked out", client_name);
756	    return KRB5KDC_ERR_POLICY;
757	}
758
759	if (client->flags.invalid) {
760	    kdc_log(context, config, 0,
761		    "Client (%s) has invalid bit set", client_name);
762	    return KRB5KDC_ERR_POLICY;
763	}
764
765	if(!client->flags.client){
766	    kdc_log(context, config, 0,
767		    "Principal may not act as client -- %s", client_name);
768	    return KRB5KDC_ERR_POLICY;
769	}
770
771	if (client->valid_start && *client->valid_start > kdc_time) {
772	    char starttime_str[100];
773	    krb5_format_time(context, *client->valid_start,
774			     starttime_str, sizeof(starttime_str), TRUE);
775	    kdc_log(context, config, 0,
776		    "Client not yet valid until %s -- %s",
777		    starttime_str, client_name);
778	    return KRB5KDC_ERR_CLIENT_NOTYET;
779	}
780
781	if (client->valid_end && *client->valid_end < kdc_time) {
782	    char endtime_str[100];
783	    krb5_format_time(context, *client->valid_end,
784			     endtime_str, sizeof(endtime_str), TRUE);
785	    kdc_log(context, config, 0,
786		    "Client expired at %s -- %s",
787		    endtime_str, client_name);
788	    return KRB5KDC_ERR_NAME_EXP;
789	}
790
791	if (client->pw_end && *client->pw_end < kdc_time
792	    && (server_ex == NULL || !server_ex->entry.flags.change_pw)) {
793	    char pwend_str[100];
794	    krb5_format_time(context, *client->pw_end,
795			     pwend_str, sizeof(pwend_str), TRUE);
796	    kdc_log(context, config, 0,
797		    "Client's key has expired at %s -- %s",
798		    pwend_str, client_name);
799	    return KRB5KDC_ERR_KEY_EXPIRED;
800	}
801    }
802
803    /* check server */
804
805    if (server_ex != NULL) {
806	hdb_entry *server = &server_ex->entry;
807
808	if (server->flags.locked_out) {
809	    kdc_log(context, config, 0,
810		    "Client server locked out -- %s", server_name);
811	    return KRB5KDC_ERR_POLICY;
812	}
813	if (server->flags.invalid) {
814	    kdc_log(context, config, 0,
815		    "Server has invalid flag set -- %s", server_name);
816	    return KRB5KDC_ERR_POLICY;
817	}
818
819	if(!server->flags.server){
820	    kdc_log(context, config, 0,
821		    "Principal may not act as server -- %s", server_name);
822	    return KRB5KDC_ERR_POLICY;
823	}
824
825	if(!is_as_req && server->flags.initial) {
826	    kdc_log(context, config, 0,
827		    "AS-REQ is required for server -- %s", server_name);
828	    return KRB5KDC_ERR_POLICY;
829	}
830
831	if (server->valid_start && *server->valid_start > kdc_time) {
832	    char starttime_str[100];
833	    krb5_format_time(context, *server->valid_start,
834			     starttime_str, sizeof(starttime_str), TRUE);
835	    kdc_log(context, config, 0,
836		    "Server not yet valid until %s -- %s",
837		    starttime_str, server_name);
838	    return KRB5KDC_ERR_SERVICE_NOTYET;
839	}
840
841	if (server->valid_end && *server->valid_end < kdc_time) {
842	    char endtime_str[100];
843	    krb5_format_time(context, *server->valid_end,
844			     endtime_str, sizeof(endtime_str), TRUE);
845	    kdc_log(context, config, 0,
846		    "Server expired at %s -- %s",
847		    endtime_str, server_name);
848	    return KRB5KDC_ERR_SERVICE_EXP;
849	}
850
851	if (server->pw_end && *server->pw_end < kdc_time) {
852	    char pwend_str[100];
853	    krb5_format_time(context, *server->pw_end,
854			     pwend_str, sizeof(pwend_str), TRUE);
855	    kdc_log(context, config, 0,
856		    "Server's key has expired at -- %s",
857		    pwend_str, server_name);
858	    return KRB5KDC_ERR_KEY_EXPIRED;
859	}
860    }
861    return 0;
862}
863
864/*
865 * Return TRUE if `from' is part of `addresses' taking into consideration
866 * the configuration variables that tells us how strict we should be about
867 * these checks
868 */
869
870krb5_boolean
871_kdc_check_addresses(krb5_context context,
872		     krb5_kdc_configuration *config,
873		     HostAddresses *addresses, const struct sockaddr *from)
874{
875    krb5_error_code ret;
876    krb5_address addr;
877    krb5_boolean result;
878    krb5_boolean only_netbios = TRUE;
879    size_t i;
880
881    if(config->check_ticket_addresses == 0)
882	return TRUE;
883
884    if(addresses == NULL)
885	return config->allow_null_ticket_addresses;
886
887    for (i = 0; i < addresses->len; ++i) {
888	if (addresses->val[i].addr_type != KRB5_ADDRESS_NETBIOS) {
889	    only_netbios = FALSE;
890	}
891    }
892
893    /* Windows sends it's netbios name, which I can only assume is
894     * used for the 'allowed workstations' check.  This is painful,
895     * but we still want to check IP addresses if they happen to be
896     * present.
897     */
898
899    if(only_netbios)
900	return config->allow_null_ticket_addresses;
901
902    ret = krb5_sockaddr2address (context, from, &addr);
903    if(ret)
904	return FALSE;
905
906    result = krb5_address_search(context, &addr, addresses);
907    krb5_free_address (context, &addr);
908    return result;
909}
910
911/*
912 *
913 */
914
915static krb5_boolean
916send_pac_p(krb5_context context, KDC_REQ *req)
917{
918    krb5_error_code ret;
919    PA_PAC_REQUEST pacreq;
920    const PA_DATA *pa;
921    int i = 0;
922
923    pa = _kdc_find_padata(req, &i, KRB5_PADATA_PA_PAC_REQUEST);
924    if (pa == NULL)
925	return TRUE;
926
927    ret = decode_PA_PAC_REQUEST(pa->padata_value.data,
928				pa->padata_value.length,
929				&pacreq,
930				NULL);
931    if (ret)
932	return TRUE;
933    i = pacreq.include_pac;
934    free_PA_PAC_REQUEST(&pacreq);
935    if (i == 0)
936	return FALSE;
937    return TRUE;
938}
939
940krb5_boolean
941_kdc_is_anonymous(krb5_context context, krb5_principal principal)
942{
943    if (principal->name.name_type != KRB5_NT_WELLKNOWN ||
944	principal->name.name_string.len != 2 ||
945	strcmp(principal->name.name_string.val[0], KRB5_WELLKNOWN_NAME) != 0 ||
946	strcmp(principal->name.name_string.val[1], KRB5_ANON_NAME) != 0)
947	return 0;
948    return 1;
949}
950
951/*
952 *
953 */
954
955krb5_error_code
956_kdc_as_rep(krb5_context context,
957	    krb5_kdc_configuration *config,
958	    KDC_REQ *req,
959	    const krb5_data *req_buffer,
960	    krb5_data *reply,
961	    const char *from,
962	    struct sockaddr *from_addr,
963	    int datagram_reply)
964{
965    KDC_REQ_BODY *b = &req->req_body;
966    AS_REP rep;
967    KDCOptions f = b->kdc_options;
968    hdb_entry_ex *client = NULL, *server = NULL;
969    HDB *clientdb;
970    krb5_enctype setype, sessionetype;
971    krb5_data e_data;
972    EncTicketPart et;
973    EncKDCRepPart ek;
974    krb5_principal client_princ = NULL, server_princ = NULL;
975    char *client_name = NULL, *server_name = NULL;
976    krb5_error_code ret = 0;
977    const char *e_text = NULL;
978    krb5_crypto crypto;
979    Key *ckey, *skey;
980    EncryptionKey *reply_key = NULL, session_key;
981    int flags = HDB_F_FOR_AS_REQ;
982#ifdef PKINIT
983    pk_client_params *pkp = NULL;
984#endif
985
986    memset(&rep, 0, sizeof(rep));
987    memset(&session_key, 0, sizeof(session_key));
988    krb5_data_zero(&e_data);
989
990    ALLOC(rep.padata);
991    rep.padata->len = 0;
992    rep.padata->val = NULL;
993
994    if (f.canonicalize)
995	flags |= HDB_F_CANON;
996
997    if(b->sname == NULL){
998	ret = KRB5KRB_ERR_GENERIC;
999	e_text = "No server in request";
1000    } else{
1001	ret = _krb5_principalname2krb5_principal (context,
1002						  &server_princ,
1003						  *(b->sname),
1004						  b->realm);
1005	if (ret == 0)
1006	    ret = krb5_unparse_name(context, server_princ, &server_name);
1007    }
1008    if (ret) {
1009	kdc_log(context, config, 0,
1010		"AS-REQ malformed server name from %s", from);
1011	goto out;
1012    }
1013    if(b->cname == NULL){
1014	ret = KRB5KRB_ERR_GENERIC;
1015	e_text = "No client in request";
1016    } else {
1017	ret = _krb5_principalname2krb5_principal (context,
1018						  &client_princ,
1019						  *(b->cname),
1020						  b->realm);
1021	if (ret)
1022	    goto out;
1023
1024	ret = krb5_unparse_name(context, client_princ, &client_name);
1025    }
1026    if (ret) {
1027	kdc_log(context, config, 0,
1028		"AS-REQ malformed client name from %s", from);
1029	goto out;
1030    }
1031
1032    kdc_log(context, config, 0, "AS-REQ %s from %s for %s",
1033	    client_name, from, server_name);
1034
1035    /*
1036     *
1037     */
1038
1039    if (_kdc_is_anonymous(context, client_princ)) {
1040	if (!b->kdc_options.request_anonymous) {
1041	    kdc_log(context, config, 0, "Anonymous ticket w/o anonymous flag");
1042	    ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
1043	    goto out;
1044	}
1045    } else if (b->kdc_options.request_anonymous) {
1046	kdc_log(context, config, 0,
1047		"Request for a anonymous ticket with non "
1048		"anonymous client name: %s", client_name);
1049	ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
1050	goto out;
1051    }
1052
1053    /*
1054     *
1055     */
1056
1057    ret = _kdc_db_fetch(context, config, client_princ,
1058			HDB_F_GET_CLIENT | flags, NULL,
1059			&clientdb, &client);
1060    if(ret == HDB_ERR_NOT_FOUND_HERE) {
1061	kdc_log(context, config, 5, "client %s does not have secrets at this KDC, need to proxy", client_name);
1062	goto out;
1063    } else if(ret){
1064	const char *msg = krb5_get_error_message(context, ret);
1065	kdc_log(context, config, 0, "UNKNOWN -- %s: %s", client_name, msg);
1066	krb5_free_error_message(context, msg);
1067	ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
1068	goto out;
1069    }
1070    ret = _kdc_db_fetch(context, config, server_princ,
1071			HDB_F_GET_SERVER|HDB_F_GET_KRBTGT | flags,
1072			NULL, NULL, &server);
1073    if(ret == HDB_ERR_NOT_FOUND_HERE) {
1074	kdc_log(context, config, 5, "target %s does not have secrets at this KDC, need to proxy", server_name);
1075	goto out;
1076    } else if(ret){
1077	const char *msg = krb5_get_error_message(context, ret);
1078	kdc_log(context, config, 0, "UNKNOWN -- %s: %s", server_name, msg);
1079	krb5_free_error_message(context, msg);
1080	ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
1081	goto out;
1082    }
1083
1084    memset(&et, 0, sizeof(et));
1085    memset(&ek, 0, sizeof(ek));
1086
1087    /*
1088     * Select a session enctype from the list of the crypto system
1089     * supported enctypes that is supported by the client and is one of
1090     * the enctype of the enctype of the service (likely krbtgt).
1091     *
1092     * The latter is used as a hint of what enctypes all KDC support,
1093     * to make sure a newer version of KDC won't generate a session
1094     * enctype that an older version of a KDC in the same realm can't
1095     * decrypt.
1096     */
1097    ret = _kdc_find_etype(context,
1098			  krb5_principal_is_krbtgt(context, server_princ) ?
1099			  config->tgt_use_strongest_session_key :
1100			  config->svc_use_strongest_session_key, FALSE,
1101			  client, b->etype.val, b->etype.len, &sessionetype,
1102			  NULL);
1103    if (ret) {
1104	kdc_log(context, config, 0,
1105		"Client (%s) from %s has no common enctypes with KDC "
1106		"to use for the session key",
1107		client_name, from);
1108	goto out;
1109    }
1110    /*
1111     * But if the KDC admin is paranoid and doesn't want to have "not
1112     * the best" enctypes on the krbtgt, lets save the best pick from
1113     * the client list and hope that that will work for any other
1114     * KDCs.
1115     */
1116
1117    /*
1118     * Pre-auth processing
1119     */
1120
1121    if(req->padata){
1122	int i;
1123	const PA_DATA *pa;
1124	int found_pa = 0;
1125
1126	log_patypes(context, config, req->padata);
1127
1128#ifdef PKINIT
1129	kdc_log(context, config, 5,
1130		"Looking for PKINIT pa-data -- %s", client_name);
1131
1132	e_text = "No PKINIT PA found";
1133
1134	i = 0;
1135	pa = _kdc_find_padata(req, &i, KRB5_PADATA_PK_AS_REQ);
1136	if (pa == NULL) {
1137	    i = 0;
1138	    pa = _kdc_find_padata(req, &i, KRB5_PADATA_PK_AS_REQ_WIN);
1139	}
1140	if (pa) {
1141	    char *client_cert = NULL;
1142
1143	    ret = _kdc_pk_rd_padata(context, config, req, pa, client, &pkp);
1144	    if (ret) {
1145		ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
1146		kdc_log(context, config, 5,
1147			"Failed to decode PKINIT PA-DATA -- %s",
1148			client_name);
1149		goto ts_enc;
1150	    }
1151	    if (ret == 0 && pkp == NULL)
1152		goto ts_enc;
1153
1154	    ret = _kdc_pk_check_client(context,
1155				       config,
1156				       clientdb,
1157				       client,
1158				       pkp,
1159				       &client_cert);
1160	    if (ret) {
1161		e_text = "PKINIT certificate not allowed to "
1162		    "impersonate principal";
1163		_kdc_pk_free_client_param(context, pkp);
1164
1165		kdc_log(context, config, 0, "%s", e_text);
1166		pkp = NULL;
1167		goto out;
1168	    }
1169
1170	    found_pa = 1;
1171	    et.flags.pre_authent = 1;
1172	    kdc_log(context, config, 0,
1173		    "PKINIT pre-authentication succeeded -- %s using %s",
1174		    client_name, client_cert);
1175	    free(client_cert);
1176	    if (pkp)
1177		goto preauth_done;
1178	}
1179    ts_enc:
1180#endif
1181	kdc_log(context, config, 5, "Looking for ENC-TS pa-data -- %s",
1182		client_name);
1183
1184	i = 0;
1185	e_text = "No ENC-TS found";
1186	while((pa = _kdc_find_padata(req, &i, KRB5_PADATA_ENC_TIMESTAMP))){
1187	    krb5_data ts_data;
1188	    PA_ENC_TS_ENC p;
1189	    size_t len;
1190	    EncryptedData enc_data;
1191	    Key *pa_key;
1192	    char *str;
1193
1194	    found_pa = 1;
1195
1196	    if (b->kdc_options.request_anonymous) {
1197		ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
1198		kdc_log(context, config, 0, "ENC-TS doesn't support anon");
1199		goto out;
1200	    }
1201
1202	    ret = decode_EncryptedData(pa->padata_value.data,
1203				       pa->padata_value.length,
1204				       &enc_data,
1205				       &len);
1206	    if (ret) {
1207		ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
1208		kdc_log(context, config, 5, "Failed to decode PA-DATA -- %s",
1209			client_name);
1210		goto out;
1211	    }
1212
1213	    ret = hdb_enctype2key(context, &client->entry,
1214				  enc_data.etype, &pa_key);
1215	    if(ret){
1216		char *estr;
1217		e_text = "No key matches pa-data";
1218		ret = KRB5KDC_ERR_ETYPE_NOSUPP;
1219		if(krb5_enctype_to_string(context, enc_data.etype, &estr))
1220		    estr = NULL;
1221		if(estr == NULL)
1222		    kdc_log(context, config, 5,
1223			    "No client key matching pa-data (%d) -- %s",
1224			    enc_data.etype, client_name);
1225		else
1226		    kdc_log(context, config, 5,
1227			    "No client key matching pa-data (%s) -- %s",
1228			    estr, client_name);
1229		free(estr);
1230		free_EncryptedData(&enc_data);
1231
1232		continue;
1233	    }
1234
1235	try_next_key:
1236	    ret = krb5_crypto_init(context, &pa_key->key, 0, &crypto);
1237	    if (ret) {
1238		const char *msg = krb5_get_error_message(context, ret);
1239		kdc_log(context, config, 0, "krb5_crypto_init failed: %s", msg);
1240		krb5_free_error_message(context, msg);
1241		free_EncryptedData(&enc_data);
1242		continue;
1243	    }
1244
1245	    ret = krb5_decrypt_EncryptedData (context,
1246					      crypto,
1247					      KRB5_KU_PA_ENC_TIMESTAMP,
1248					      &enc_data,
1249					      &ts_data);
1250	    krb5_crypto_destroy(context, crypto);
1251	    /*
1252	     * Since the user might have several keys with the same
1253	     * enctype but with diffrent salting, we need to try all
1254	     * the keys with the same enctype.
1255	     */
1256	    if(ret){
1257		krb5_error_code ret2;
1258		const char *msg = krb5_get_error_message(context, ret);
1259
1260		ret2 = krb5_enctype_to_string(context,
1261					      pa_key->key.keytype, &str);
1262		if (ret2)
1263		    str = NULL;
1264		kdc_log(context, config, 5,
1265			"Failed to decrypt PA-DATA -- %s "
1266			"(enctype %s) error %s",
1267			client_name, str ? str : "unknown enctype", msg);
1268		krb5_free_error_message(context, msg);
1269		free(str);
1270
1271		if(hdb_next_enctype2key(context, &client->entry,
1272					enc_data.etype, &pa_key) == 0)
1273		    goto try_next_key;
1274		e_text = "Failed to decrypt PA-DATA";
1275
1276		free_EncryptedData(&enc_data);
1277
1278		if (clientdb->hdb_auth_status)
1279		    (clientdb->hdb_auth_status)(context, clientdb, client, HDB_AUTH_WRONG_PASSWORD);
1280
1281		ret = KRB5KDC_ERR_PREAUTH_FAILED;
1282		continue;
1283	    }
1284	    free_EncryptedData(&enc_data);
1285	    ret = decode_PA_ENC_TS_ENC(ts_data.data,
1286				       ts_data.length,
1287				       &p,
1288				       &len);
1289	    krb5_data_free(&ts_data);
1290	    if(ret){
1291		e_text = "Failed to decode PA-ENC-TS-ENC";
1292		ret = KRB5KDC_ERR_PREAUTH_FAILED;
1293		kdc_log(context, config,
1294			5, "Failed to decode PA-ENC-TS_ENC -- %s",
1295			client_name);
1296		continue;
1297	    }
1298	    free_PA_ENC_TS_ENC(&p);
1299	    if (abs(kdc_time - p.patimestamp) > context->max_skew) {
1300		char client_time[100];
1301
1302		krb5_format_time(context, p.patimestamp,
1303				 client_time, sizeof(client_time), TRUE);
1304
1305 		ret = KRB5KRB_AP_ERR_SKEW;
1306 		kdc_log(context, config, 0,
1307			"Too large time skew, "
1308			"client time %s is out by %u > %u seconds -- %s",
1309			client_time,
1310			(unsigned)abs(kdc_time - p.patimestamp),
1311			context->max_skew,
1312			client_name);
1313
1314		/*
1315		 * The following is needed to make windows clients to
1316		 * retry using the timestamp in the error message, if
1317		 * there is a e_text, they become unhappy.
1318		 */
1319		e_text = NULL;
1320		goto out;
1321	    }
1322	    et.flags.pre_authent = 1;
1323
1324	    set_salt_padata(rep.padata, pa_key->salt);
1325
1326	    reply_key = &pa_key->key;
1327
1328	    ret = krb5_enctype_to_string(context, pa_key->key.keytype, &str);
1329	    if (ret)
1330		str = NULL;
1331
1332	    kdc_log(context, config, 2,
1333		    "ENC-TS Pre-authentication succeeded -- %s using %s",
1334		    client_name, str ? str : "unknown enctype");
1335	    free(str);
1336	    break;
1337	}
1338#ifdef PKINIT
1339    preauth_done:
1340#endif
1341	if(found_pa == 0 && config->require_preauth)
1342	    goto use_pa;
1343	/* We come here if we found a pa-enc-timestamp, but if there
1344           was some problem with it, other than too large skew */
1345	if(found_pa && et.flags.pre_authent == 0){
1346	    kdc_log(context, config, 0, "%s -- %s", e_text, client_name);
1347	    e_text = NULL;
1348	    goto out;
1349	}
1350    }else if (config->require_preauth
1351	      || b->kdc_options.request_anonymous /* hack to force anon */
1352	      || client->entry.flags.require_preauth
1353	      || server->entry.flags.require_preauth) {
1354	METHOD_DATA method_data;
1355	PA_DATA *pa;
1356	unsigned char *buf;
1357	size_t len;
1358
1359    use_pa:
1360	method_data.len = 0;
1361	method_data.val = NULL;
1362
1363	ret = realloc_method_data(&method_data);
1364	if (ret) {
1365	    free_METHOD_DATA(&method_data);
1366	    goto out;
1367	}
1368	pa = &method_data.val[method_data.len-1];
1369	pa->padata_type		= KRB5_PADATA_ENC_TIMESTAMP;
1370	pa->padata_value.length	= 0;
1371	pa->padata_value.data	= NULL;
1372
1373#ifdef PKINIT
1374	ret = realloc_method_data(&method_data);
1375	if (ret) {
1376	    free_METHOD_DATA(&method_data);
1377	    goto out;
1378	}
1379	pa = &method_data.val[method_data.len-1];
1380	pa->padata_type		= KRB5_PADATA_PK_AS_REQ;
1381	pa->padata_value.length	= 0;
1382	pa->padata_value.data	= NULL;
1383
1384	ret = realloc_method_data(&method_data);
1385	if (ret) {
1386	    free_METHOD_DATA(&method_data);
1387	    goto out;
1388	}
1389	pa = &method_data.val[method_data.len-1];
1390	pa->padata_type		= KRB5_PADATA_PK_AS_REQ_WIN;
1391	pa->padata_value.length	= 0;
1392	pa->padata_value.data	= NULL;
1393#endif
1394
1395	/*
1396	 * If there is a client key, send ETYPE_INFO{,2}
1397	 */
1398	ret = _kdc_find_etype(context,
1399			      config->preauth_use_strongest_session_key, TRUE,
1400			      client, b->etype.val, b->etype.len, NULL, &ckey);
1401	if (ret == 0) {
1402
1403	    /*
1404	     * RFC4120 requires:
1405	     * - If the client only knows about old enctypes, then send
1406	     *   both info replies (we send 'info' first in the list).
1407	     * - If the client is 'modern', because it knows about 'new'
1408	     *   enctype types, then only send the 'info2' reply.
1409	     *
1410	     * Before we send the full list of etype-info data, we pick
1411	     * the client key we would have used anyway below, just pick
1412	     * that instead.
1413	     */
1414
1415	    if (older_enctype(ckey->key.keytype)) {
1416		ret = get_pa_etype_info(context, config,
1417					&method_data, ckey);
1418		if (ret) {
1419		    free_METHOD_DATA(&method_data);
1420		    goto out;
1421		}
1422	    }
1423	    ret = get_pa_etype_info2(context, config,
1424				     &method_data, ckey);
1425	    if (ret) {
1426		free_METHOD_DATA(&method_data);
1427		goto out;
1428	    }
1429	}
1430
1431	ASN1_MALLOC_ENCODE(METHOD_DATA, buf, len, &method_data, &len, ret);
1432	free_METHOD_DATA(&method_data);
1433
1434	e_data.data   = buf;
1435	e_data.length = len;
1436	e_text ="Need to use PA-ENC-TIMESTAMP/PA-PK-AS-REQ",
1437
1438	ret = KRB5KDC_ERR_PREAUTH_REQUIRED;
1439
1440	kdc_log(context, config, 0,
1441		"No preauth found, returning PREAUTH-REQUIRED -- %s",
1442		client_name);
1443	goto out;
1444    }
1445
1446    if (clientdb->hdb_auth_status)
1447	(clientdb->hdb_auth_status)(context, clientdb, client,
1448				    HDB_AUTH_SUCCESS);
1449
1450    /*
1451     * Verify flags after the user been required to prove its identity
1452     * with in a preauth mech.
1453     */
1454
1455    ret = _kdc_check_access(context, config, client, client_name,
1456			    server, server_name,
1457			    req, &e_data);
1458    if(ret)
1459	goto out;
1460
1461    /*
1462     * Selelct the best encryption type for the KDC with out regard to
1463     * the client since the client never needs to read that data.
1464     */
1465
1466    ret = _kdc_get_preferred_key(context, config,
1467				 server, server_name,
1468				 &setype, &skey);
1469    if(ret)
1470	goto out;
1471
1472    if(f.renew || f.validate || f.proxy || f.forwarded || f.enc_tkt_in_skey
1473       || (f.request_anonymous && !config->allow_anonymous)) {
1474	ret = KRB5KDC_ERR_BADOPTION;
1475	e_text = "Bad KDC options";
1476	kdc_log(context, config, 0, "Bad KDC options -- %s", client_name);
1477	goto out;
1478    }
1479
1480    rep.pvno = 5;
1481    rep.msg_type = krb_as_rep;
1482
1483    ret = copy_Realm(&client->entry.principal->realm, &rep.crealm);
1484    if (ret)
1485	goto out;
1486    ret = _krb5_principal2principalname(&rep.cname, client->entry.principal);
1487    if (ret)
1488	goto out;
1489
1490    rep.ticket.tkt_vno = 5;
1491    copy_Realm(&server->entry.principal->realm, &rep.ticket.realm);
1492    _krb5_principal2principalname(&rep.ticket.sname,
1493				  server->entry.principal);
1494    /* java 1.6 expects the name to be the same type, lets allow that
1495     * uncomplicated name-types. */
1496#define CNT(sp,t) (((sp)->sname->name_type) == KRB5_NT_##t)
1497    if (CNT(b, UNKNOWN) || CNT(b, PRINCIPAL) || CNT(b, SRV_INST) || CNT(b, SRV_HST) || CNT(b, SRV_XHST))
1498	rep.ticket.sname.name_type = b->sname->name_type;
1499#undef CNT
1500
1501    et.flags.initial = 1;
1502    if(client->entry.flags.forwardable && server->entry.flags.forwardable)
1503	et.flags.forwardable = f.forwardable;
1504    else if (f.forwardable) {
1505	e_text = "Ticket may not be forwardable";
1506	ret = KRB5KDC_ERR_POLICY;
1507	kdc_log(context, config, 0,
1508		"Ticket may not be forwardable -- %s", client_name);
1509	goto out;
1510    }
1511    if(client->entry.flags.proxiable && server->entry.flags.proxiable)
1512	et.flags.proxiable = f.proxiable;
1513    else if (f.proxiable) {
1514	e_text = "Ticket may not be proxiable";
1515	ret = KRB5KDC_ERR_POLICY;
1516	kdc_log(context, config, 0,
1517		"Ticket may not be proxiable -- %s", client_name);
1518	goto out;
1519    }
1520    if(client->entry.flags.postdate && server->entry.flags.postdate)
1521	et.flags.may_postdate = f.allow_postdate;
1522    else if (f.allow_postdate){
1523	e_text = "Ticket may not be postdate";
1524	ret = KRB5KDC_ERR_POLICY;
1525	kdc_log(context, config, 0,
1526		"Ticket may not be postdatable -- %s", client_name);
1527	goto out;
1528    }
1529
1530    /* check for valid set of addresses */
1531    if(!_kdc_check_addresses(context, config, b->addresses, from_addr)) {
1532	e_text = "Bad address list in requested";
1533	ret = KRB5KRB_AP_ERR_BADADDR;
1534	kdc_log(context, config, 0,
1535		"Bad address list requested -- %s", client_name);
1536	goto out;
1537    }
1538
1539    ret = copy_PrincipalName(&rep.cname, &et.cname);
1540    if (ret)
1541	goto out;
1542    ret = copy_Realm(&rep.crealm, &et.crealm);
1543    if (ret)
1544	goto out;
1545
1546    {
1547	time_t start;
1548	time_t t;
1549
1550	start = et.authtime = kdc_time;
1551
1552	if(f.postdated && req->req_body.from){
1553	    ALLOC(et.starttime);
1554	    start = *et.starttime = *req->req_body.from;
1555	    et.flags.invalid = 1;
1556	    et.flags.postdated = 1; /* XXX ??? */
1557	}
1558	_kdc_fix_time(&b->till);
1559	t = *b->till;
1560
1561	/* be careful not overflowing */
1562
1563	if(client->entry.max_life)
1564	    t = start + min(t - start, *client->entry.max_life);
1565	if(server->entry.max_life)
1566	    t = start + min(t - start, *server->entry.max_life);
1567#if 0
1568	t = min(t, start + realm->max_life);
1569#endif
1570	et.endtime = t;
1571	if(f.renewable_ok && et.endtime < *b->till){
1572	    f.renewable = 1;
1573	    if(b->rtime == NULL){
1574		ALLOC(b->rtime);
1575		*b->rtime = 0;
1576	    }
1577	    if(*b->rtime < *b->till)
1578		*b->rtime = *b->till;
1579	}
1580	if(f.renewable && b->rtime){
1581	    t = *b->rtime;
1582	    if(t == 0)
1583		t = MAX_TIME;
1584	    if(client->entry.max_renew)
1585		t = start + min(t - start, *client->entry.max_renew);
1586	    if(server->entry.max_renew)
1587		t = start + min(t - start, *server->entry.max_renew);
1588#if 0
1589	    t = min(t, start + realm->max_renew);
1590#endif
1591	    ALLOC(et.renew_till);
1592	    *et.renew_till = t;
1593	    et.flags.renewable = 1;
1594	}
1595    }
1596
1597    if (f.request_anonymous)
1598	et.flags.anonymous = 1;
1599
1600    if(b->addresses){
1601	ALLOC(et.caddr);
1602	copy_HostAddresses(b->addresses, et.caddr);
1603    }
1604
1605    et.transited.tr_type = DOMAIN_X500_COMPRESS;
1606    krb5_data_zero(&et.transited.contents);
1607
1608    /* The MIT ASN.1 library (obviously) doesn't tell lengths encoded
1609     * as 0 and as 0x80 (meaning indefinite length) apart, and is thus
1610     * incapable of correctly decoding SEQUENCE OF's of zero length.
1611     *
1612     * To fix this, always send at least one no-op last_req
1613     *
1614     * If there's a pw_end or valid_end we will use that,
1615     * otherwise just a dummy lr.
1616     */
1617    ek.last_req.val = malloc(2 * sizeof(*ek.last_req.val));
1618    if (ek.last_req.val == NULL) {
1619	ret = ENOMEM;
1620	goto out;
1621    }
1622    ek.last_req.len = 0;
1623    if (client->entry.pw_end
1624	&& (config->kdc_warn_pwexpire == 0
1625	    || kdc_time + config->kdc_warn_pwexpire >= *client->entry.pw_end)) {
1626	ek.last_req.val[ek.last_req.len].lr_type  = LR_PW_EXPTIME;
1627	ek.last_req.val[ek.last_req.len].lr_value = *client->entry.pw_end;
1628	++ek.last_req.len;
1629    }
1630    if (client->entry.valid_end) {
1631	ek.last_req.val[ek.last_req.len].lr_type  = LR_ACCT_EXPTIME;
1632	ek.last_req.val[ek.last_req.len].lr_value = *client->entry.valid_end;
1633	++ek.last_req.len;
1634    }
1635    if (ek.last_req.len == 0) {
1636	ek.last_req.val[ek.last_req.len].lr_type  = LR_NONE;
1637	ek.last_req.val[ek.last_req.len].lr_value = 0;
1638	++ek.last_req.len;
1639    }
1640    ek.nonce = b->nonce;
1641    if (client->entry.valid_end || client->entry.pw_end) {
1642	ALLOC(ek.key_expiration);
1643	if (client->entry.valid_end) {
1644	    if (client->entry.pw_end)
1645		*ek.key_expiration = min(*client->entry.valid_end,
1646					 *client->entry.pw_end);
1647	    else
1648		*ek.key_expiration = *client->entry.valid_end;
1649	} else
1650	    *ek.key_expiration = *client->entry.pw_end;
1651    } else
1652	ek.key_expiration = NULL;
1653    ek.flags = et.flags;
1654    ek.authtime = et.authtime;
1655    if (et.starttime) {
1656	ALLOC(ek.starttime);
1657	*ek.starttime = *et.starttime;
1658    }
1659    ek.endtime = et.endtime;
1660    if (et.renew_till) {
1661	ALLOC(ek.renew_till);
1662	*ek.renew_till = *et.renew_till;
1663    }
1664    copy_Realm(&rep.ticket.realm, &ek.srealm);
1665    copy_PrincipalName(&rep.ticket.sname, &ek.sname);
1666    if(et.caddr){
1667	ALLOC(ek.caddr);
1668	copy_HostAddresses(et.caddr, ek.caddr);
1669    }
1670
1671#if PKINIT
1672    if (pkp) {
1673        e_text = "Failed to build PK-INIT reply";
1674	ret = _kdc_pk_mk_pa_reply(context, config, pkp, client,
1675				  sessionetype, req, req_buffer,
1676				  &reply_key, &et.key, rep.padata);
1677	if (ret)
1678	    goto out;
1679	ret = _kdc_add_inital_verified_cas(context,
1680					   config,
1681					   pkp,
1682					   &et);
1683	if (ret)
1684	    goto out;
1685
1686    } else
1687#endif
1688    {
1689	ret = krb5_generate_random_keyblock(context, sessionetype, &et.key);
1690	if (ret)
1691	    goto out;
1692    }
1693
1694    if (reply_key == NULL) {
1695	e_text = "Client have no reply key";
1696	ret = KRB5KDC_ERR_CLIENT_NOTYET;
1697	goto out;
1698    }
1699
1700    ret = copy_EncryptionKey(&et.key, &ek.key);
1701    if (ret)
1702	goto out;
1703
1704    /* Add signing of alias referral */
1705    if (f.canonicalize) {
1706	PA_ClientCanonicalized canon;
1707	krb5_data data;
1708	PA_DATA pa;
1709	krb5_crypto cryptox;
1710	size_t len = 0;
1711
1712	memset(&canon, 0, sizeof(canon));
1713
1714	canon.names.requested_name = *b->cname;
1715	canon.names.mapped_name = client->entry.principal->name;
1716
1717	ASN1_MALLOC_ENCODE(PA_ClientCanonicalizedNames, data.data, data.length,
1718			   &canon.names, &len, ret);
1719	if (ret)
1720	    goto out;
1721	if (data.length != len)
1722	    krb5_abortx(context, "internal asn.1 error");
1723
1724	/* sign using "returned session key" */
1725	ret = krb5_crypto_init(context, &et.key, 0, &cryptox);
1726	if (ret) {
1727	    free(data.data);
1728	    goto out;
1729	}
1730
1731	ret = krb5_create_checksum(context, cryptox,
1732				   KRB5_KU_CANONICALIZED_NAMES, 0,
1733				   data.data, data.length,
1734				   &canon.canon_checksum);
1735	free(data.data);
1736	krb5_crypto_destroy(context, cryptox);
1737	if (ret)
1738	    goto out;
1739
1740	ASN1_MALLOC_ENCODE(PA_ClientCanonicalized, data.data, data.length,
1741			   &canon, &len, ret);
1742	free_Checksum(&canon.canon_checksum);
1743	if (ret)
1744	    goto out;
1745	if (data.length != len)
1746	    krb5_abortx(context, "internal asn.1 error");
1747
1748	pa.padata_type = KRB5_PADATA_CLIENT_CANONICALIZED;
1749	pa.padata_value = data;
1750	ret = add_METHOD_DATA(rep.padata, &pa);
1751	free(data.data);
1752	if (ret)
1753	    goto out;
1754    }
1755
1756    if (rep.padata->len == 0) {
1757	free(rep.padata);
1758	rep.padata = NULL;
1759    }
1760
1761    /* Add the PAC */
1762    if (send_pac_p(context, req)) {
1763	krb5_pac p = NULL;
1764	krb5_data data;
1765
1766	ret = _kdc_pac_generate(context, client, &p);
1767	if (ret) {
1768	    kdc_log(context, config, 0, "PAC generation failed for -- %s",
1769		    client_name);
1770	    goto out;
1771	}
1772	if (p != NULL) {
1773	    ret = _krb5_pac_sign(context, p, et.authtime,
1774				 client->entry.principal,
1775				 &skey->key, /* Server key */
1776				 &skey->key, /* FIXME: should be krbtgt key */
1777				 &data);
1778	    krb5_pac_free(context, p);
1779	    if (ret) {
1780		kdc_log(context, config, 0, "PAC signing failed for -- %s",
1781			client_name);
1782		goto out;
1783	    }
1784
1785	    ret = _kdc_tkt_add_if_relevant_ad(context, &et,
1786					      KRB5_AUTHDATA_WIN2K_PAC,
1787					      &data);
1788	    krb5_data_free(&data);
1789	    if (ret)
1790		goto out;
1791	}
1792    }
1793
1794    _kdc_log_timestamp(context, config, "AS-REQ", et.authtime, et.starttime,
1795		       et.endtime, et.renew_till);
1796
1797    /* do this as the last thing since this signs the EncTicketPart */
1798    ret = _kdc_add_KRB5SignedPath(context,
1799				  config,
1800				  server,
1801				  setype,
1802				  client->entry.principal,
1803				  NULL,
1804				  NULL,
1805				  &et);
1806    if (ret)
1807	goto out;
1808
1809    log_as_req(context, config, reply_key->keytype, setype, b);
1810
1811    ret = _kdc_encode_reply(context, config,
1812			    &rep, &et, &ek, setype, server->entry.kvno,
1813			    &skey->key, client->entry.kvno,
1814			    reply_key, 0, &e_text, reply);
1815    free_EncTicketPart(&et);
1816    free_EncKDCRepPart(&ek);
1817    if (ret)
1818	goto out;
1819
1820    /* */
1821    if (datagram_reply && reply->length > config->max_datagram_reply_length) {
1822	krb5_data_free(reply);
1823	ret = KRB5KRB_ERR_RESPONSE_TOO_BIG;
1824	e_text = "Reply packet too large";
1825    }
1826
1827out:
1828    free_AS_REP(&rep);
1829    if(ret != 0 && ret != HDB_ERR_NOT_FOUND_HERE){
1830	krb5_mk_error(context,
1831		      ret,
1832		      e_text,
1833		      (e_data.data ? &e_data : NULL),
1834		      client_princ,
1835		      server_princ,
1836		      NULL,
1837		      NULL,
1838		      reply);
1839	ret = 0;
1840    }
1841#ifdef PKINIT
1842    if (pkp)
1843	_kdc_pk_free_client_param(context, pkp);
1844#endif
1845    if (e_data.data)
1846        free(e_data.data);
1847    if (client_princ)
1848	krb5_free_principal(context, client_princ);
1849    free(client_name);
1850    if (server_princ)
1851	krb5_free_principal(context, server_princ);
1852    free(server_name);
1853    if(client)
1854	_kdc_free_ent(context, client);
1855    if(server)
1856	_kdc_free_ent(context, server);
1857    return ret;
1858}
1859
1860/*
1861 * Add the AuthorizationData `data´ of `type´ to the last element in
1862 * the sequence of authorization_data in `tkt´ wrapped in an IF_RELEVANT
1863 */
1864
1865krb5_error_code
1866_kdc_tkt_add_if_relevant_ad(krb5_context context,
1867			    EncTicketPart *tkt,
1868			    int type,
1869			    const krb5_data *data)
1870{
1871    krb5_error_code ret;
1872    size_t size = 0;
1873
1874    if (tkt->authorization_data == NULL) {
1875	tkt->authorization_data = calloc(1, sizeof(*tkt->authorization_data));
1876	if (tkt->authorization_data == NULL) {
1877	    krb5_set_error_message(context, ENOMEM, "out of memory");
1878	    return ENOMEM;
1879	}
1880    }
1881
1882    /* add the entry to the last element */
1883    {
1884	AuthorizationData ad = { 0, NULL };
1885	AuthorizationDataElement ade;
1886
1887	ade.ad_type = type;
1888	ade.ad_data = *data;
1889
1890	ret = add_AuthorizationData(&ad, &ade);
1891	if (ret) {
1892	    krb5_set_error_message(context, ret, "add AuthorizationData failed");
1893	    return ret;
1894	}
1895
1896	ade.ad_type = KRB5_AUTHDATA_IF_RELEVANT;
1897
1898	ASN1_MALLOC_ENCODE(AuthorizationData,
1899			   ade.ad_data.data, ade.ad_data.length,
1900			   &ad, &size, ret);
1901	free_AuthorizationData(&ad);
1902	if (ret) {
1903	    krb5_set_error_message(context, ret, "ASN.1 encode of "
1904				   "AuthorizationData failed");
1905	    return ret;
1906	}
1907	if (ade.ad_data.length != size)
1908	    krb5_abortx(context, "internal asn.1 encoder error");
1909
1910	ret = add_AuthorizationData(tkt->authorization_data, &ade);
1911	der_free_octet_string(&ade.ad_data);
1912	if (ret) {
1913	    krb5_set_error_message(context, ret, "add AuthorizationData failed");
1914	    return ret;
1915	}
1916    }
1917
1918    return 0;
1919}
1920