kdc: principals of type NT-UNKNOWN can be anonymous
[metze/heimdal/wip.git] / kdc / kerberos5.c
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
38 void
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
48 static int
49 realloc_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
60 static void
61 set_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
71 const 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
90 krb5_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 == (krb5_enctype)ETYPE_DES_CBC_CRC
96          || etype == (krb5_enctype)ETYPE_DES_CBC_MD4
97          || etype == (krb5_enctype)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
107 static krb5_boolean
108 is_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
125 krb5_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 = (krb5_enctype)ETYPE_NULL;
134     const krb5_enctype *p;
135     Key *key = NULL;
136     int i, k;
137
138     /* We'll want to avoid keys with v4 salted keys in the pre-auth case... */
139     ret = krb5_get_pw_salt(context, princ->entry.principal, &def_salt);
140     if (ret)
141         return ret;
142
143     ret = KRB5KDC_ERR_ETYPE_NOSUPP;
144
145     if (use_strongest_session_key) {
146
147         /*
148          * Pick the strongest key that the KDC, target service, and
149          * client all support, using the local cryptosystem enctype
150          * list in strongest-to-weakest order to drive the search.
151          *
152          * This is not what RFC4120 says to do, but it encourages
153          * adoption of stronger enctypes.  This doesn't play well with
154          * clients that have multiple Kerberos client implementations
155          * available with different supported enctype lists.
156          */
157
158         /* drive the search with local supported enctypes list */
159         p = krb5_kerberos_enctypes(context);
160         for (i = 0;
161             p[i] != (krb5_enctype)ETYPE_NULL && enctype == (krb5_enctype)ETYPE_NULL;
162             i++) {
163             if (krb5_enctype_valid(context, p[i]) != 0 &&
164                 !_kdc_is_weak_exception(princ->entry.principal, p[i]))
165                 continue;
166
167             /* check that the client supports it too */
168             for (k = 0; k < len && enctype == (krb5_enctype)ETYPE_NULL; k++) {
169
170                 if (p[i] != etypes[k])
171                     continue;
172
173                 /* check target princ support */
174                 key = NULL;
175                 while (hdb_next_enctype2key(context, &princ->entry, NULL,
176                                              p[i], &key) == 0) {
177                     if (key->key.keyvalue.length == 0) {
178                         ret = KRB5KDC_ERR_NULL_KEY;
179                         continue;
180                     }
181                     enctype = p[i];
182                     ret = 0;
183                     if (is_preauth && ret_key != NULL &&
184                         !is_default_salt_p(&def_salt, key))
185                         continue;
186                 }
187             }
188         }
189     } else {
190         /*
191          * Pick the first key from the client's enctype list that is
192          * supported by the cryptosystem and by the given principal.
193          *
194          * RFC4120 says we SHOULD pick the first _strong_ key from the
195          * client's list... not the first key...  If the admin disallows
196          * weak enctypes in krb5.conf and selects this key selection
197          * algorithm, then we get exactly what RFC4120 says.
198          */
199         for(i = 0; ret != 0 && i < len; i++) {
200
201             if (krb5_enctype_valid(context, etypes[i]) != 0 &&
202                 !_kdc_is_weak_exception(princ->entry.principal, etypes[i]))
203                 continue;
204
205             key = NULL;
206             while (ret != 0 &&
207                    hdb_next_enctype2key(context, &princ->entry, NULL,
208                                         etypes[i], &key) == 0) {
209                 if (key->key.keyvalue.length == 0) {
210                     ret = KRB5KDC_ERR_NULL_KEY;
211                     continue;
212                 }
213                 enctype = etypes[i];
214                 ret = 0;
215                 if (is_preauth && ret_key != NULL &&
216                     !is_default_salt_p(&def_salt, key))
217                     continue;
218             }
219         }
220     }
221
222     if (enctype == (krb5_enctype)ETYPE_NULL) {
223         /*
224          * if the service principal is one for which there is a known 1DES
225          * exception and no other enctype matches both the client request and
226          * the service key list, provide a DES-CBC-CRC key.
227          */
228         if (ret_key == NULL &&
229             _kdc_is_weak_exception(princ->entry.principal, ETYPE_DES_CBC_CRC)) {
230             ret = 0;
231             enctype = ETYPE_DES_CBC_CRC;
232         } else {
233             ret = KRB5KDC_ERR_ETYPE_NOSUPP;
234         }
235     }
236
237     if (ret == 0) {
238         if (ret_enctype != NULL)
239             *ret_enctype = enctype;
240         if (ret_key != NULL)
241             *ret_key = key;
242     }
243
244     krb5_free_salt (context, def_salt);
245     return ret;
246 }
247
248 krb5_error_code
249 _kdc_make_anonymous_principalname (PrincipalName *pn)
250 {
251     pn->name_type = KRB5_NT_PRINCIPAL;
252     pn->name_string.len = 1;
253     pn->name_string.val = malloc(sizeof(*pn->name_string.val));
254     if (pn->name_string.val == NULL)
255         return ENOMEM;
256     pn->name_string.val[0] = strdup("anonymous");
257     if (pn->name_string.val[0] == NULL) {
258         free(pn->name_string.val);
259         pn->name_string.val = NULL;
260         return ENOMEM;
261     }
262     return 0;
263 }
264
265 static void
266 _kdc_r_log(kdc_request_t r, int level, const char *fmt, ...)
267 {
268     va_list ap;
269     char *s;
270     va_start(ap, fmt);
271     s = kdc_log_msg_va(r->context, r->config, level, fmt, ap);
272     if(s) free(s);
273     va_end(ap);
274 }
275
276 static void
277 _kdc_set_e_text(kdc_request_t r, const char *e_text)
278 {
279     r->e_text = e_text;
280     kdc_log(r->context, r->config, 0, "%s", e_text);
281 }
282
283 void
284 _kdc_log_timestamp(krb5_context context,
285                    krb5_kdc_configuration *config,
286                    const char *type,
287                    KerberosTime authtime, KerberosTime *starttime,
288                    KerberosTime endtime, KerberosTime *renew_till)
289 {
290     char authtime_str[100], starttime_str[100],
291         endtime_str[100], renewtime_str[100];
292
293     krb5_format_time(context, authtime,
294                      authtime_str, sizeof(authtime_str), TRUE);
295     if (starttime)
296         krb5_format_time(context, *starttime,
297                          starttime_str, sizeof(starttime_str), TRUE);
298     else
299         strlcpy(starttime_str, "unset", sizeof(starttime_str));
300     krb5_format_time(context, endtime,
301                      endtime_str, sizeof(endtime_str), TRUE);
302     if (renew_till)
303         krb5_format_time(context, *renew_till,
304                          renewtime_str, sizeof(renewtime_str), TRUE);
305     else
306         strlcpy(renewtime_str, "unset", sizeof(renewtime_str));
307
308     kdc_log(context, config, 5,
309             "%s authtime: %s starttime: %s endtime: %s renew till: %s",
310             type, authtime_str, starttime_str, endtime_str, renewtime_str);
311 }
312
313 /*
314  *
315  */
316
317 #ifdef PKINIT
318
319 static krb5_error_code
320 pa_pkinit_validate(kdc_request_t r, const PA_DATA *pa)
321 {
322     pk_client_params *pkp = NULL;
323     char *client_cert = NULL;
324     krb5_error_code ret;
325
326     ret = _kdc_pk_rd_padata(r->context, r->config, &r->req, pa, r->client, &pkp);
327     if (ret || pkp == NULL) {
328         ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
329         _kdc_r_log(r, 5, "Failed to decode PKINIT PA-DATA -- %s",
330                    r->client_name);
331         goto out;
332     }
333     
334     ret = _kdc_pk_check_client(r->context,
335                                r->config,
336                                r->clientdb, 
337                                r->client,
338                                pkp,
339                                &client_cert);
340     if (ret) {
341         _kdc_set_e_text(r, "PKINIT certificate not allowed to "
342                         "impersonate principal");
343         goto out;
344     }
345
346     _kdc_r_log(r, 0, "PKINIT pre-authentication succeeded -- %s using %s",
347                r->client_name, client_cert);
348     free(client_cert);
349
350     ret = _kdc_pk_mk_pa_reply(r->context, r->config, pkp, r->client,
351                               r->sessionetype, &r->req, &r->request,
352                               &r->reply_key, &r->session_key, &r->outpadata);
353     if (ret) {
354         _kdc_set_e_text(r, "Failed to build PK-INIT reply");
355         goto out;
356     }
357 #if 0
358     ret = _kdc_add_inital_verified_cas(r->context, r->config,
359                                        pkp, &r->et);
360 #endif
361  out:
362     if (pkp)
363         _kdc_pk_free_client_param(r->context, pkp);
364
365     return ret;
366 }
367
368 #endif /* PKINIT */
369
370 /*
371  *
372  */
373
374 static krb5_error_code
375 make_pa_enc_challange(krb5_context context, METHOD_DATA *md,
376                       krb5_crypto crypto)
377 {
378     PA_ENC_TS_ENC p;
379     unsigned char *buf;
380     size_t buf_size;
381     size_t len;
382     EncryptedData encdata;
383     krb5_error_code ret;
384     int32_t usec;
385     int usec2;
386
387     krb5_us_timeofday (context, &p.patimestamp, &usec);
388     usec2         = usec;
389     p.pausec      = &usec2;
390
391     ASN1_MALLOC_ENCODE(PA_ENC_TS_ENC, buf, buf_size, &p, &len, ret);
392     if (ret)
393         return ret;
394     if(buf_size != len)
395         krb5_abortx(context, "internal error in ASN.1 encoder");
396
397     ret = krb5_encrypt_EncryptedData(context,
398                                      crypto,
399                                      KRB5_KU_ENC_CHALLENGE_KDC,
400                                      buf,
401                                      len,
402                                      0,
403                                      &encdata);
404     free(buf);
405     if (ret)
406         return ret;
407
408     ASN1_MALLOC_ENCODE(EncryptedData, buf, buf_size, &encdata, &len, ret);
409     free_EncryptedData(&encdata);
410     if (ret)
411         return ret;
412     if(buf_size != len)
413         krb5_abortx(context, "internal error in ASN.1 encoder");
414
415     ret = krb5_padata_add(context, md, KRB5_PADATA_ENCRYPTED_CHALLENGE, buf, len);
416     if (ret)
417         free(buf);
418     return ret;
419 }
420
421 static krb5_error_code
422 pa_enc_chal_validate(kdc_request_t r, const PA_DATA *pa)
423 {
424     krb5_data pepper1, pepper2, ts_data;
425     KDC_REQ_BODY *b = &r->req.req_body;
426     int invalidPassword = 0;
427     EncryptedData enc_data;
428     krb5_enctype aenctype;
429     krb5_error_code ret;
430     struct Key *k;
431     size_t size;
432     int i;
433
434     heim_assert(r->armor_crypto != NULL, "ENC-CHAL called for non FAST");
435     
436     if (_kdc_is_anon_request(b)) {
437         ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
438         kdc_log(r->context, r->config, 0, "ENC-CHALL doesn't support anon");
439         return ret;
440     }
441
442     ret = decode_EncryptedData(pa->padata_value.data,
443                                pa->padata_value.length,
444                                &enc_data,
445                                &size);
446     if (ret) {
447         ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
448         _kdc_r_log(r, 5, "Failed to decode PA-DATA -- %s",
449                    r->client_name);
450         return ret;
451     }
452
453     pepper1.data = "clientchallengearmor";
454     pepper1.length = strlen(pepper1.data);
455     pepper2.data = "challengelongterm";
456     pepper2.length = strlen(pepper2.data);
457
458     krb5_crypto_getenctype(r->context, r->armor_crypto, &aenctype);
459
460     for (i = 0; i < r->client->entry.keys.len; i++) {
461         krb5_crypto challangecrypto, longtermcrypto;
462         krb5_keyblock challangekey;
463         PA_ENC_TS_ENC p;
464
465         k = &r->client->entry.keys.val[i];
466         
467         ret = krb5_crypto_init(r->context, &k->key, 0, &longtermcrypto);
468         if (ret)
469             continue;                   
470         
471         ret = krb5_crypto_fx_cf2(r->context, r->armor_crypto, longtermcrypto,
472                                  &pepper1, &pepper2, aenctype,
473                                  &challangekey);
474         krb5_crypto_destroy(r->context, longtermcrypto);
475         if (ret)
476             continue;
477         
478         ret = krb5_crypto_init(r->context, &challangekey, 0,
479                                &challangecrypto);
480         if (ret)
481             continue;
482         
483         ret = krb5_decrypt_EncryptedData(r->context, challangecrypto,
484                                          KRB5_KU_ENC_CHALLENGE_CLIENT,
485                                          &enc_data,
486                                          &ts_data);
487         if (ret) {
488             const char *msg = krb5_get_error_message(r->context, ret);
489             krb5_error_code ret2;
490             char *str = NULL;
491
492             invalidPassword = 1;
493
494             ret2 = krb5_enctype_to_string(r->context, k->key.keytype, &str);
495             if (ret2)
496                 str = NULL;
497             _kdc_r_log(r, 5, "Failed to decrypt ENC-CHAL -- %s "
498                        "(enctype %s) error %s",
499                        r->client_name, str ? str : "unknown enctype", msg);
500             krb5_free_error_message(r->context, msg);
501             free(str);
502
503             continue;
504         }
505         
506         ret = decode_PA_ENC_TS_ENC(ts_data.data,
507                                    ts_data.length,
508                                    &p,
509                                    &size);
510         krb5_data_free(&ts_data);
511         if(ret){
512             krb5_crypto_destroy(r->context, challangecrypto);
513             ret = KRB5KDC_ERR_PREAUTH_FAILED;
514             _kdc_r_log(r, 5, "Failed to decode PA-ENC-TS_ENC -- %s",
515                        r->client_name);
516             continue;
517         }
518
519         if (labs(kdc_time - p.patimestamp) > r->context->max_skew) {
520             char client_time[100];
521
522             krb5_crypto_destroy(r->context, challangecrypto);
523
524             krb5_format_time(r->context, p.patimestamp,
525                              client_time, sizeof(client_time), TRUE);
526
527             ret = KRB5KRB_AP_ERR_SKEW;
528             _kdc_r_log(r, 0, "Too large time skew, "
529                        "client time %s is out by %u > %u seconds -- %s",
530                        client_time,
531                        (unsigned)labs(kdc_time - p.patimestamp),
532                        r->context->max_skew,
533                        r->client_name);
534
535             free_PA_ENC_TS_ENC(&p);
536             goto out;
537         }
538
539         free_PA_ENC_TS_ENC(&p);
540
541         ret = make_pa_enc_challange(r->context, &r->outpadata,
542                                     challangecrypto);
543         krb5_crypto_destroy(r->context, challangecrypto);
544         if (ret)
545             goto out;
546                                             
547         set_salt_padata(&r->outpadata, k->salt);
548         krb5_free_keyblock_contents(r->context,  &r->reply_key);
549         ret = krb5_copy_keyblock_contents(r->context, &k->key, &r->reply_key);
550         if (ret)
551             goto out;
552
553         /*
554          * Success
555          */
556         if (r->clientdb->hdb_auth_status)
557             r->clientdb->hdb_auth_status(r->context, r->clientdb, r->client,
558                                          HDB_AUTH_SUCCESS);
559         goto out;
560     }
561
562     if (invalidPassword && r->clientdb->hdb_auth_status) {
563         r->clientdb->hdb_auth_status(r->context, r->clientdb, r->client,
564                                      HDB_AUTH_WRONG_PASSWORD);
565         ret = KRB5KDC_ERR_PREAUTH_FAILED;
566     }
567  out:
568     free_EncryptedData(&enc_data);
569
570     return ret;
571 }
572
573 static krb5_error_code
574 pa_enc_ts_validate(kdc_request_t r, const PA_DATA *pa)
575 {
576     EncryptedData enc_data;
577     krb5_error_code ret;
578     krb5_crypto crypto;
579     krb5_data ts_data;
580     PA_ENC_TS_ENC p;
581     size_t len;
582     Key *pa_key;
583     char *str;
584         
585     if (_kdc_is_anon_request(&r->req.req_body)) {
586         ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
587         _kdc_set_e_text(r, "ENC-TS doesn't support anon");
588         goto out;
589     }
590
591     ret = decode_EncryptedData(pa->padata_value.data,
592                                pa->padata_value.length,
593                                &enc_data,
594                                &len);
595     if (ret) {
596         ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
597         _kdc_r_log(r, 5, "Failed to decode PA-DATA -- %s",
598                    r->client_name);
599         goto out;
600     }
601         
602     ret = hdb_enctype2key(r->context, &r->client->entry, NULL,
603                           enc_data.etype, &pa_key);
604     if(ret){
605         char *estr;
606         _kdc_set_e_text(r, "No key matching entype");
607         ret = KRB5KDC_ERR_ETYPE_NOSUPP;
608         if(krb5_enctype_to_string(r->context, enc_data.etype, &estr))
609             estr = NULL;
610         if(estr == NULL)
611             _kdc_r_log(r, 5,
612                        "No client key matching pa-data (%d) -- %s",
613                        enc_data.etype, r->client_name);
614         else
615             _kdc_r_log(r, 5,
616                        "No client key matching pa-data (%s) -- %s",
617                        estr, r->client_name);
618         free(estr);
619         free_EncryptedData(&enc_data);
620         goto out;
621     }
622
623  try_next_key:
624     ret = krb5_crypto_init(r->context, &pa_key->key, 0, &crypto);
625     if (ret) {
626         const char *msg = krb5_get_error_message(r->context, ret);
627         _kdc_r_log(r, 0, "krb5_crypto_init failed: %s", msg);
628         krb5_free_error_message(r->context, msg);
629         free_EncryptedData(&enc_data);
630         goto out;
631     }
632
633     ret = krb5_decrypt_EncryptedData (r->context,
634                                       crypto,
635                                       KRB5_KU_PA_ENC_TIMESTAMP,
636                                       &enc_data,
637                                       &ts_data);
638     krb5_crypto_destroy(r->context, crypto);
639     /*
640      * Since the user might have several keys with the same
641      * enctype but with diffrent salting, we need to try all
642      * the keys with the same enctype.
643      */
644     if(ret){
645         krb5_error_code ret2;
646         const char *msg = krb5_get_error_message(r->context, ret);
647
648         ret2 = krb5_enctype_to_string(r->context,
649                                       pa_key->key.keytype, &str);
650         if (ret2)
651             str = NULL;
652         _kdc_r_log(r, 5, "Failed to decrypt PA-DATA -- %s "
653                    "(enctype %s) error %s",
654                    r->client_name, str ? str : "unknown enctype", msg);
655         krb5_free_error_message(r->context, msg);
656         free(str);
657
658         if(hdb_next_enctype2key(r->context, &r->client->entry, NULL,
659                                 enc_data.etype, &pa_key) == 0)
660             goto try_next_key;
661
662         free_EncryptedData(&enc_data);
663
664         if (r->clientdb->hdb_auth_status)
665             r->clientdb->hdb_auth_status(r->context, r->clientdb, r->client,
666                                          HDB_AUTH_WRONG_PASSWORD);
667
668         ret = KRB5KDC_ERR_PREAUTH_FAILED;
669         goto out;
670     }
671     free_EncryptedData(&enc_data);
672     ret = decode_PA_ENC_TS_ENC(ts_data.data,
673                                ts_data.length,
674                                &p,
675                                &len);
676     krb5_data_free(&ts_data);
677     if(ret){
678         ret = KRB5KDC_ERR_PREAUTH_FAILED;
679         _kdc_r_log(r, 5, "Failed to decode PA-ENC-TS_ENC -- %s",
680                    r->client_name);
681         goto out;
682     }
683     if (labs(kdc_time - p.patimestamp) > r->context->max_skew) {
684         char client_time[100];
685                 
686         krb5_format_time(r->context, p.patimestamp,
687                          client_time, sizeof(client_time), TRUE);
688
689         ret = KRB5KRB_AP_ERR_SKEW;
690         _kdc_r_log(r, 0, "Too large time skew, "
691                    "client time %s is out by %u > %u seconds -- %s",
692                    client_time,
693                    (unsigned)labs(kdc_time - p.patimestamp),
694                    r->context->max_skew,
695                    r->client_name);
696
697         /*
698          * The following is needed to make windows clients to
699          * retry using the timestamp in the error message, if
700          * there is a e_text, they become unhappy.
701          */
702         r->e_text = NULL;
703         free_PA_ENC_TS_ENC(&p);
704         goto out;
705     }
706     free_PA_ENC_TS_ENC(&p);
707
708     set_salt_padata(&r->outpadata, pa_key->salt);
709
710     ret = krb5_copy_keyblock_contents(r->context, &pa_key->key, &r->reply_key);
711     if (ret)
712         return ret;
713
714     ret = krb5_enctype_to_string(r->context, pa_key->key.keytype, &str);
715     if (ret)
716         str = NULL;
717     _kdc_r_log(r, 2, "ENC-TS Pre-authentication succeeded -- %s using %s",
718                r->client_name, str ? str : "unknown enctype");
719     free(str);
720
721     ret = 0;
722
723  out:
724
725     return ret;
726 }
727
728 struct kdc_patypes {
729     int type;
730     char *name;
731     unsigned int flags;
732 #define PA_ANNOUNCE     1
733 #define PA_REQ_FAST     2 /* only use inside fast */
734     krb5_error_code (*validate)(kdc_request_t, const PA_DATA *pa);
735 };
736
737 static const struct kdc_patypes pat[] = {
738 #ifdef PKINIT
739     {
740         KRB5_PADATA_PK_AS_REQ, "PK-INIT(ietf)", PA_ANNOUNCE,
741         pa_pkinit_validate
742     },
743     {
744         KRB5_PADATA_PK_AS_REQ_WIN, "PK-INIT(win2k)", PA_ANNOUNCE,
745         pa_pkinit_validate
746     },
747     {
748         KRB5_PADATA_PKINIT_KX, "Anonymous PK-INIT", PA_ANNOUNCE,
749         NULL
750     },
751 #else
752     { KRB5_PADATA_PK_AS_REQ, "PK-INIT(ietf)", 0, NULL },
753     { KRB5_PADATA_PK_AS_REQ_WIN, "PK-INIT(win2k)", 0, NULL },
754     { KRB5_PADATA_PKINIT_KX, "Anonymous PK-INIT", 0, NULL },
755 #endif
756     { KRB5_PADATA_PA_PK_OCSP_RESPONSE , "OCSP", 0, NULL },
757     { 
758         KRB5_PADATA_ENC_TIMESTAMP , "ENC-TS",
759         PA_ANNOUNCE,
760         pa_enc_ts_validate
761     },
762     {
763         KRB5_PADATA_ENCRYPTED_CHALLENGE , "ENC-CHAL",
764         PA_ANNOUNCE | PA_REQ_FAST,
765         pa_enc_chal_validate
766     },
767     { KRB5_PADATA_REQ_ENC_PA_REP , "REQ-ENC-PA-REP", 0, NULL },
768     { KRB5_PADATA_FX_FAST, "FX-FAST", PA_ANNOUNCE, NULL },
769     { KRB5_PADATA_FX_ERROR, "FX-ERROR", 0, NULL },
770     { KRB5_PADATA_FX_COOKIE, "FX-COOKIE", 0, NULL }
771 };
772
773 static void
774 log_patypes(krb5_context context,
775             krb5_kdc_configuration *config,
776             METHOD_DATA *padata)
777 {
778     struct rk_strpool *p = NULL;
779     char *str;
780     size_t n, m;
781         
782     for (n = 0; n < padata->len; n++) {
783         for (m = 0; m < sizeof(pat) / sizeof(pat[0]); m++) {
784             if (padata->val[n].padata_type == pat[m].type) {
785                 p = rk_strpoolprintf(p, "%s", pat[m].name);
786                 break;
787             }
788         }
789         if (m == sizeof(pat) / sizeof(pat[0]))
790             p = rk_strpoolprintf(p, "%d", padata->val[n].padata_type);
791         if (p && n + 1 < padata->len)
792             p = rk_strpoolprintf(p, ", ");
793         if (p == NULL) {
794             kdc_log(context, config, 0, "out of memory");
795             return;
796         }
797     }
798     if (p == NULL)
799         p = rk_strpoolprintf(p, "none");
800
801     str = rk_strpoolcollect(p);
802     kdc_log(context, config, 0, "Client sent patypes: %s", str);
803     free(str);
804 }
805
806 /*
807  *
808  */
809
810 krb5_error_code
811 _kdc_encode_reply(krb5_context context,
812                   krb5_kdc_configuration *config,
813                   krb5_crypto armor_crypto, uint32_t nonce,
814                   KDC_REP *rep, EncTicketPart *et, EncKDCRepPart *ek,
815                   krb5_enctype etype,
816                   int skvno, const EncryptionKey *skey,
817                   int ckvno, const EncryptionKey *reply_key,
818                   int rk_is_subkey,
819                   const char **e_text,
820                   krb5_data *reply)
821 {
822     unsigned char *buf;
823     size_t buf_size;
824     size_t len = 0;
825     krb5_error_code ret;
826     krb5_crypto crypto;
827
828     ASN1_MALLOC_ENCODE(EncTicketPart, buf, buf_size, et, &len, ret);
829     if(ret) {
830         const char *msg = krb5_get_error_message(context, ret);
831         kdc_log(context, config, 0, "Failed to encode ticket: %s", msg);
832         krb5_free_error_message(context, msg);
833         return ret;
834     }
835     if(buf_size != len)
836         krb5_abortx(context, "Internal error in ASN.1 encoder");
837
838     ret = krb5_crypto_init(context, skey, etype, &crypto);
839     if (ret) {
840         const char *msg = krb5_get_error_message(context, ret);
841         kdc_log(context, config, 0, "krb5_crypto_init failed: %s", msg);
842         krb5_free_error_message(context, msg);
843         return ret;
844     }
845
846     ret = krb5_encrypt_EncryptedData(context,
847                                      crypto,
848                                      KRB5_KU_TICKET,
849                                      buf,
850                                      len,
851                                      skvno,
852                                      &rep->ticket.enc_part);
853     free(buf);
854     krb5_crypto_destroy(context, crypto);
855     if(ret) {
856         const char *msg = krb5_get_error_message(context, ret);
857         kdc_log(context, config, 0, "Failed to encrypt data: %s", msg);
858         krb5_free_error_message(context, msg);
859         return ret;
860     }
861
862     if (armor_crypto) {
863         krb5_data data;
864         krb5_keyblock *strengthen_key = NULL;
865         KrbFastFinished finished;
866
867         kdc_log(context, config, 0, "FAST armor protection");
868
869         memset(&finished, 0, sizeof(finished));
870         krb5_data_zero(&data);
871
872         finished.timestamp = kdc_time;
873         finished.usec = 0;
874         finished.crealm = et->crealm;
875         finished.cname = et->cname;
876
877         ASN1_MALLOC_ENCODE(Ticket, data.data, data.length,
878                            &rep->ticket, &len, ret);
879         if (ret)
880             return ret;
881         if (data.length != len)
882             krb5_abortx(context, "internal asn.1 error");
883
884         ret = krb5_create_checksum(context, armor_crypto,
885                                    KRB5_KU_FAST_FINISHED, 0,
886                                    data.data, data.length,
887                                    &finished.ticket_checksum);
888         krb5_data_free(&data);
889         if (ret)
890             return ret;
891
892         ret = _kdc_fast_mk_response(context, armor_crypto,
893                                     rep->padata, strengthen_key, &finished,
894                                     nonce, &data);
895         free_Checksum(&finished.ticket_checksum);
896         if (ret)
897             return ret;
898
899         if (rep->padata) {
900             free_METHOD_DATA(rep->padata);
901         } else {
902             rep->padata = calloc(1, sizeof(*(rep->padata)));
903             if (rep->padata == NULL) {
904                 krb5_data_free(&data);
905                 return ENOMEM;
906             }
907         }
908
909         ret = krb5_padata_add(context, rep->padata,
910                               KRB5_PADATA_FX_FAST,
911                               data.data, data.length);
912         if (ret)
913             return ret;
914
915         /*
916          * Hide client name of privacy reasons
917          */
918         if (1 /* r->fast_options.hide_client_names */) {
919             rep->crealm[0] = '\0';
920             free_PrincipalName(&rep->cname);
921             rep->cname.name_type = 0;
922         }
923     }
924
925     if(rep->msg_type == krb_as_rep && !config->encode_as_rep_as_tgs_rep)
926         ASN1_MALLOC_ENCODE(EncASRepPart, buf, buf_size, ek, &len, ret);
927     else
928         ASN1_MALLOC_ENCODE(EncTGSRepPart, buf, buf_size, ek, &len, ret);
929     if(ret) {
930         const char *msg = krb5_get_error_message(context, ret);
931         kdc_log(context, config, 0, "Failed to encode KDC-REP: %s", msg);
932         krb5_free_error_message(context, msg);
933         return ret;
934     }
935     if(buf_size != len) {
936         free(buf);
937         kdc_log(context, config, 0, "Internal error in ASN.1 encoder");
938         *e_text = "KDC internal error";
939         return KRB5KRB_ERR_GENERIC;
940     }
941     ret = krb5_crypto_init(context, reply_key, 0, &crypto);
942     if (ret) {
943         const char *msg = krb5_get_error_message(context, ret);
944         free(buf);
945         kdc_log(context, config, 0, "krb5_crypto_init failed: %s", msg);
946         krb5_free_error_message(context, msg);
947         return ret;
948     }
949     if(rep->msg_type == krb_as_rep) {
950         krb5_encrypt_EncryptedData(context,
951                                    crypto,
952                                    KRB5_KU_AS_REP_ENC_PART,
953                                    buf,
954                                    len,
955                                    ckvno,
956                                    &rep->enc_part);
957         free(buf);
958         ASN1_MALLOC_ENCODE(AS_REP, buf, buf_size, rep, &len, ret);
959     } else {
960         krb5_encrypt_EncryptedData(context,
961                                    crypto,
962                                    rk_is_subkey ? KRB5_KU_TGS_REP_ENC_PART_SUB_KEY : KRB5_KU_TGS_REP_ENC_PART_SESSION,
963                                    buf,
964                                    len,
965                                    ckvno,
966                                    &rep->enc_part);
967         free(buf);
968         ASN1_MALLOC_ENCODE(TGS_REP, buf, buf_size, rep, &len, ret);
969     }
970     krb5_crypto_destroy(context, crypto);
971     if(ret) {
972         const char *msg = krb5_get_error_message(context, ret);
973         kdc_log(context, config, 0, "Failed to encode KDC-REP: %s", msg);
974         krb5_free_error_message(context, msg);
975         return ret;
976     }
977     if(buf_size != len) {
978         free(buf);
979         kdc_log(context, config, 0, "Internal error in ASN.1 encoder");
980         *e_text = "KDC internal error";
981         return KRB5KRB_ERR_GENERIC;
982     }
983     reply->data = buf;
984     reply->length = buf_size;
985     return 0;
986 }
987
988 /*
989  * Return 1 if the client have only older enctypes, this is for
990  * determining if the server should send ETYPE_INFO2 or not.
991  */
992
993 static int
994 older_enctype(krb5_enctype enctype)
995 {
996     switch (enctype) {
997     case ETYPE_DES_CBC_CRC:
998     case ETYPE_DES_CBC_MD4:
999     case ETYPE_DES_CBC_MD5:
1000     case ETYPE_DES3_CBC_SHA1:
1001     case ETYPE_ARCFOUR_HMAC_MD5:
1002     case ETYPE_ARCFOUR_HMAC_MD5_56:
1003     /*
1004      * The following three is "old" windows enctypes and is needed for
1005      * windows 2000 hosts.
1006      */
1007     case ETYPE_ARCFOUR_MD4:
1008     case ETYPE_ARCFOUR_HMAC_OLD:
1009     case ETYPE_ARCFOUR_HMAC_OLD_EXP:
1010         return 1;
1011     default:
1012         return 0;
1013     }
1014 }
1015
1016 /*
1017  *
1018  */
1019
1020 static krb5_error_code
1021 make_etype_info_entry(krb5_context context, ETYPE_INFO_ENTRY *ent, Key *key)
1022 {
1023     ent->etype = key->key.keytype;
1024     if(key->salt){
1025 #if 0
1026         ALLOC(ent->salttype);
1027
1028         if(key->salt->type == hdb_pw_salt)
1029             *ent->salttype = 0; /* or 1? or NULL? */
1030         else if(key->salt->type == hdb_afs3_salt)
1031             *ent->salttype = 2;
1032         else {
1033             kdc_log(context, config, 0, "unknown salt-type: %d",
1034                     key->salt->type);
1035             return KRB5KRB_ERR_GENERIC;
1036         }
1037         /* according to `the specs', we can't send a salt if
1038            we have AFS3 salted key, but that requires that you
1039            *know* what cell you are using (e.g by assuming
1040            that the cell is the same as the realm in lower
1041            case) */
1042 #elif 0
1043         ALLOC(ent->salttype);
1044         *ent->salttype = key->salt->type;
1045 #else
1046         /*
1047          * We shouldn't sent salttype since it is incompatible with the
1048          * specification and it breaks windows clients.  The afs
1049          * salting problem is solved by using KRB5-PADATA-AFS3-SALT
1050          * implemented in Heimdal 0.7 and later.
1051          */
1052         ent->salttype = NULL;
1053 #endif
1054         krb5_copy_data(context, &key->salt->salt,
1055                        &ent->salt);
1056     } else {
1057         /* we return no salt type at all, as that should indicate
1058          * the default salt type and make everybody happy.  some
1059          * systems (like w2k) dislike being told the salt type
1060          * here. */
1061
1062         ent->salttype = NULL;
1063         ent->salt = NULL;
1064     }
1065     return 0;
1066 }
1067
1068 static krb5_error_code
1069 get_pa_etype_info(krb5_context context,
1070                   krb5_kdc_configuration *config,
1071                   METHOD_DATA *md, Key *ckey)
1072 {
1073     krb5_error_code ret = 0;
1074     ETYPE_INFO pa;
1075     unsigned char *buf;
1076     size_t len;
1077
1078
1079     pa.len = 1;
1080     pa.val = calloc(1, sizeof(pa.val[0]));
1081     if(pa.val == NULL)
1082         return ENOMEM;
1083
1084     ret = make_etype_info_entry(context, &pa.val[0], ckey);
1085     if (ret) {
1086         free_ETYPE_INFO(&pa);
1087         return ret;
1088     }
1089
1090     ASN1_MALLOC_ENCODE(ETYPE_INFO, buf, len, &pa, &len, ret);
1091     free_ETYPE_INFO(&pa);
1092     if(ret)
1093         return ret;
1094     ret = realloc_method_data(md);
1095     if(ret) {
1096         free(buf);
1097         return ret;
1098     }
1099     md->val[md->len - 1].padata_type = KRB5_PADATA_ETYPE_INFO;
1100     md->val[md->len - 1].padata_value.length = len;
1101     md->val[md->len - 1].padata_value.data = buf;
1102     return 0;
1103 }
1104
1105 /*
1106  *
1107  */
1108
1109 extern int _krb5_AES_SHA1_string_to_default_iterator;
1110 extern int _krb5_AES_SHA2_string_to_default_iterator;
1111
1112 static krb5_error_code
1113 make_s2kparams(int value, size_t len, krb5_data **ps2kparams)
1114 {
1115     krb5_data *s2kparams;
1116     krb5_error_code ret;
1117
1118     ALLOC(s2kparams);
1119     if (s2kparams == NULL)
1120         return ENOMEM;
1121     ret = krb5_data_alloc(s2kparams, len);
1122     if (ret) {
1123         free(s2kparams);
1124         return ret;
1125     }
1126     _krb5_put_int(s2kparams->data, value, len);
1127     *ps2kparams = s2kparams;
1128     return 0;
1129 }
1130
1131 static krb5_error_code
1132 make_etype_info2_entry(ETYPE_INFO2_ENTRY *ent, Key *key)
1133 {
1134     krb5_error_code ret;
1135
1136     ent->etype = key->key.keytype;
1137     if(key->salt) {
1138         ALLOC(ent->salt);
1139         if (ent->salt == NULL)
1140             return ENOMEM;
1141         *ent->salt = malloc(key->salt->salt.length + 1);
1142         if (*ent->salt == NULL) {
1143             free(ent->salt);
1144             ent->salt = NULL;
1145             return ENOMEM;
1146         }
1147         memcpy(*ent->salt, key->salt->salt.data, key->salt->salt.length);
1148         (*ent->salt)[key->salt->salt.length] = '\0';
1149     } else
1150         ent->salt = NULL;
1151
1152     ent->s2kparams = NULL;
1153
1154     switch (key->key.keytype) {
1155     case ETYPE_AES128_CTS_HMAC_SHA1_96:
1156     case ETYPE_AES256_CTS_HMAC_SHA1_96:
1157         ret = make_s2kparams(_krb5_AES_SHA1_string_to_default_iterator,
1158                              4, &ent->s2kparams);
1159         break;
1160     case KRB5_ENCTYPE_AES128_CTS_HMAC_SHA256_128:
1161     case KRB5_ENCTYPE_AES256_CTS_HMAC_SHA384_192:
1162         ret = make_s2kparams(_krb5_AES_SHA2_string_to_default_iterator,
1163                              4, &ent->s2kparams);
1164         break;
1165     case ETYPE_DES_CBC_CRC:
1166     case ETYPE_DES_CBC_MD4:
1167     case ETYPE_DES_CBC_MD5:
1168         /* Check if this was a AFS3 salted key */
1169         if(key->salt && key->salt->type == hdb_afs3_salt)
1170             ret = make_s2kparams(1, 1, &ent->s2kparams);
1171         else
1172             ret = 0;
1173         break;
1174     default:
1175         ret = 0;
1176         break;
1177     }
1178     return ret;
1179 }
1180
1181 /*
1182  * Return an ETYPE-INFO2. Enctypes are storted the same way as in the
1183  * database (client supported enctypes first, then the unsupported
1184  * enctypes).
1185  */
1186
1187 static krb5_error_code
1188 get_pa_etype_info2(krb5_context context,
1189                    krb5_kdc_configuration *config,
1190                    METHOD_DATA *md, Key *ckey)
1191 {
1192     krb5_error_code ret = 0;
1193     ETYPE_INFO2 pa;
1194     unsigned char *buf;
1195     size_t len;
1196
1197     pa.len = 1;
1198     pa.val = calloc(1, sizeof(pa.val[0]));
1199     if(pa.val == NULL)
1200         return ENOMEM;
1201
1202     ret = make_etype_info2_entry(&pa.val[0], ckey);
1203     if (ret) {
1204         free_ETYPE_INFO2(&pa);
1205         return ret;
1206     }
1207
1208     ASN1_MALLOC_ENCODE(ETYPE_INFO2, buf, len, &pa, &len, ret);
1209     free_ETYPE_INFO2(&pa);
1210     if(ret)
1211         return ret;
1212     ret = realloc_method_data(md);
1213     if(ret) {
1214         free(buf);
1215         return ret;
1216     }
1217     md->val[md->len - 1].padata_type = KRB5_PADATA_ETYPE_INFO2;
1218     md->val[md->len - 1].padata_value.length = len;
1219     md->val[md->len - 1].padata_value.data = buf;
1220     return 0;
1221 }
1222
1223 /*
1224  *
1225  */
1226
1227 static void
1228 log_as_req(krb5_context context,
1229            krb5_kdc_configuration *config,
1230            krb5_enctype cetype,
1231            krb5_enctype setype,
1232            const KDC_REQ_BODY *b)
1233 {
1234     krb5_error_code ret;
1235     struct rk_strpool *p;
1236     char *str;
1237     size_t i;
1238
1239     p = rk_strpoolprintf(NULL, "%s", "Client supported enctypes: ");
1240
1241     for (i = 0; i < b->etype.len; i++) {
1242         ret = krb5_enctype_to_string(context, b->etype.val[i], &str);
1243         if (ret == 0) {
1244             p = rk_strpoolprintf(p, "%s", str);
1245             free(str);
1246         } else
1247             p = rk_strpoolprintf(p, "%d", b->etype.val[i]);
1248         if (p && i + 1 < b->etype.len)
1249             p = rk_strpoolprintf(p, ", ");
1250         if (p == NULL) {
1251             kdc_log(context, config, 0, "out of memory");
1252             return;
1253         }
1254     }
1255     if (p == NULL)
1256         p = rk_strpoolprintf(p, "no encryption types");
1257
1258     {
1259         char *cet;
1260         char *set;
1261
1262         ret = krb5_enctype_to_string(context, cetype, &cet);
1263         if(ret == 0) {
1264             ret = krb5_enctype_to_string(context, setype, &set);
1265             if (ret == 0) {
1266                 p = rk_strpoolprintf(p, ", using %s/%s", cet, set);
1267                 free(set);
1268             }
1269             free(cet);
1270         }
1271         if (ret != 0)
1272             p = rk_strpoolprintf(p, ", using enctypes %d/%d",
1273                                  cetype, setype);
1274     }
1275
1276     str = rk_strpoolcollect(p);
1277     kdc_log(context, config, 0, "%s", str);
1278     free(str);
1279
1280     {
1281         char fixedstr[128];
1282         unparse_flags(KDCOptions2int(b->kdc_options), asn1_KDCOptions_units(),
1283                       fixedstr, sizeof(fixedstr));
1284         if(*fixedstr)
1285             kdc_log(context, config, 0, "Requested flags: %s", fixedstr);
1286     }
1287 }
1288
1289 /*
1290  * verify the flags on `client' and `server', returning 0
1291  * if they are OK and generating an error messages and returning
1292  * and error code otherwise.
1293  */
1294
1295 krb5_error_code
1296 kdc_check_flags(krb5_context context,
1297                 krb5_kdc_configuration *config,
1298                 hdb_entry_ex *client_ex, const char *client_name,
1299                 hdb_entry_ex *server_ex, const char *server_name,
1300                 krb5_boolean is_as_req)
1301 {
1302     if(client_ex != NULL) {
1303         hdb_entry *client = &client_ex->entry;
1304
1305         /* check client */
1306         if (client->flags.locked_out) {
1307             kdc_log(context, config, 0,
1308                     "Client (%s) is locked out", client_name);
1309             return KRB5KDC_ERR_POLICY;
1310         }
1311
1312         if (client->flags.invalid) {
1313             kdc_log(context, config, 0,
1314                     "Client (%s) has invalid bit set", client_name);
1315             return KRB5KDC_ERR_POLICY;
1316         }
1317
1318         if(!client->flags.client){
1319             kdc_log(context, config, 0,
1320                     "Principal may not act as client -- %s", client_name);
1321             return KRB5KDC_ERR_POLICY;
1322         }
1323
1324         if (client->valid_start && *client->valid_start > kdc_time) {
1325             char starttime_str[100];
1326             krb5_format_time(context, *client->valid_start,
1327                              starttime_str, sizeof(starttime_str), TRUE);
1328             kdc_log(context, config, 0,
1329                     "Client not yet valid until %s -- %s",
1330                     starttime_str, client_name);
1331             return KRB5KDC_ERR_CLIENT_NOTYET;
1332         }
1333
1334         if (client->valid_end && *client->valid_end < kdc_time) {
1335             char endtime_str[100];
1336             krb5_format_time(context, *client->valid_end,
1337                              endtime_str, sizeof(endtime_str), TRUE);
1338             kdc_log(context, config, 0,
1339                     "Client expired at %s -- %s",
1340                     endtime_str, client_name);
1341             return KRB5KDC_ERR_NAME_EXP;
1342         }
1343
1344         if (client->flags.require_pwchange &&
1345             (server_ex == NULL || !server_ex->entry.flags.change_pw)) {
1346             kdc_log(context, config, 0,
1347                     "Client's key must be changed -- %s", client_name);
1348             return KRB5KDC_ERR_KEY_EXPIRED;
1349         }
1350
1351         if (client->pw_end && *client->pw_end < kdc_time
1352             && (server_ex == NULL || !server_ex->entry.flags.change_pw)) {
1353             char pwend_str[100];
1354             krb5_format_time(context, *client->pw_end,
1355                              pwend_str, sizeof(pwend_str), TRUE);
1356             kdc_log(context, config, 0,
1357                     "Client's key has expired at %s -- %s",
1358                     pwend_str, client_name);
1359             return KRB5KDC_ERR_KEY_EXPIRED;
1360         }
1361     }
1362
1363     /* check server */
1364
1365     if (server_ex != NULL) {
1366         hdb_entry *server = &server_ex->entry;
1367
1368         if (server->flags.locked_out) {
1369             kdc_log(context, config, 0,
1370                     "Client server locked out -- %s", server_name);
1371             return KRB5KDC_ERR_POLICY;
1372         }
1373         if (server->flags.invalid) {
1374             kdc_log(context, config, 0,
1375                     "Server has invalid flag set -- %s", server_name);
1376             return KRB5KDC_ERR_POLICY;
1377         }
1378
1379         if(!server->flags.server){
1380             kdc_log(context, config, 0,
1381                     "Principal may not act as server -- %s", server_name);
1382             return KRB5KDC_ERR_POLICY;
1383         }
1384
1385         if(!is_as_req && server->flags.initial) {
1386             kdc_log(context, config, 0,
1387                     "AS-REQ is required for server -- %s", server_name);
1388             return KRB5KDC_ERR_POLICY;
1389         }
1390
1391         if (server->valid_start && *server->valid_start > kdc_time) {
1392             char starttime_str[100];
1393             krb5_format_time(context, *server->valid_start,
1394                              starttime_str, sizeof(starttime_str), TRUE);
1395             kdc_log(context, config, 0,
1396                     "Server not yet valid until %s -- %s",
1397                     starttime_str, server_name);
1398             return KRB5KDC_ERR_SERVICE_NOTYET;
1399         }
1400
1401         if (server->valid_end && *server->valid_end < kdc_time) {
1402             char endtime_str[100];
1403             krb5_format_time(context, *server->valid_end,
1404                              endtime_str, sizeof(endtime_str), TRUE);
1405             kdc_log(context, config, 0,
1406                     "Server expired at %s -- %s",
1407                     endtime_str, server_name);
1408             return KRB5KDC_ERR_SERVICE_EXP;
1409         }
1410
1411         if (server->pw_end && *server->pw_end < kdc_time) {
1412             char pwend_str[100];
1413             krb5_format_time(context, *server->pw_end,
1414                              pwend_str, sizeof(pwend_str), TRUE);
1415             kdc_log(context, config, 0,
1416                     "Server's key has expired at -- %s",
1417                     pwend_str, server_name);
1418             return KRB5KDC_ERR_KEY_EXPIRED;
1419         }
1420     }
1421     return 0;
1422 }
1423
1424 /*
1425  * Return TRUE if `from' is part of `addresses' taking into consideration
1426  * the configuration variables that tells us how strict we should be about
1427  * these checks
1428  */
1429
1430 krb5_boolean
1431 _kdc_check_addresses(krb5_context context,
1432                      krb5_kdc_configuration *config,
1433                      HostAddresses *addresses, const struct sockaddr *from)
1434 {
1435     krb5_error_code ret;
1436     krb5_address addr;
1437     krb5_boolean result;
1438     krb5_boolean only_netbios = TRUE;
1439     size_t i;
1440
1441     if(config->check_ticket_addresses == 0)
1442         return TRUE;
1443
1444     if(addresses == NULL)
1445         return config->allow_null_ticket_addresses;
1446
1447     for (i = 0; i < addresses->len; ++i) {
1448         if (addresses->val[i].addr_type != KRB5_ADDRESS_NETBIOS) {
1449             only_netbios = FALSE;
1450         }
1451     }
1452
1453     /* Windows sends it's netbios name, which I can only assume is
1454      * used for the 'allowed workstations' check.  This is painful,
1455      * but we still want to check IP addresses if they happen to be
1456      * present.
1457      */
1458
1459     if(only_netbios)
1460         return config->allow_null_ticket_addresses;
1461
1462     ret = krb5_sockaddr2address (context, from, &addr);
1463     if(ret)
1464         return FALSE;
1465
1466     result = krb5_address_search(context, &addr, addresses);
1467     krb5_free_address (context, &addr);
1468     return result;
1469 }
1470
1471 /*
1472  *
1473  */
1474
1475 static krb5_boolean
1476 send_pac_p(krb5_context context, KDC_REQ *req)
1477 {
1478     krb5_error_code ret;
1479     PA_PAC_REQUEST pacreq;
1480     const PA_DATA *pa;
1481     int i = 0;
1482
1483     pa = _kdc_find_padata(req, &i, KRB5_PADATA_PA_PAC_REQUEST);
1484     if (pa == NULL)
1485         return TRUE;
1486
1487     ret = decode_PA_PAC_REQUEST(pa->padata_value.data,
1488                                 pa->padata_value.length,
1489                                 &pacreq,
1490                                 NULL);
1491     if (ret)
1492         return TRUE;
1493     i = pacreq.include_pac;
1494     free_PA_PAC_REQUEST(&pacreq);
1495     if (i == 0)
1496         return FALSE;
1497     return TRUE;
1498 }
1499
1500 /*
1501  *
1502  */
1503
1504 static krb5_error_code
1505 generate_pac(kdc_request_t r, Key *skey)
1506 {
1507     krb5_error_code ret;
1508     krb5_pac p = NULL;
1509     krb5_data data;
1510
1511     ret = _kdc_pac_generate(r->context, r->client, &p);
1512     if (ret) {
1513         _kdc_r_log(r, 0, "PAC generation failed for -- %s",
1514                    r->client_name);
1515         return ret;
1516     }
1517     if (p == NULL)
1518         return 0;
1519
1520     ret = _krb5_pac_sign(r->context, p, r->et.authtime,
1521                          r->client->entry.principal,
1522                          &skey->key, /* Server key */
1523                          &skey->key, /* FIXME: should be krbtgt key */
1524                          &data);
1525     krb5_pac_free(r->context, p);
1526     if (ret) {
1527         _kdc_r_log(r, 0, "PAC signing failed for -- %s",
1528                    r->client_name);
1529         return ret;
1530     }
1531     
1532     ret = _kdc_tkt_add_if_relevant_ad(r->context, &r->et,
1533                                       KRB5_AUTHDATA_WIN2K_PAC,
1534                                       &data);
1535     krb5_data_free(&data);
1536
1537     return ret;
1538 }
1539
1540 /*
1541  *
1542  */
1543
1544 krb5_boolean
1545 _kdc_is_anonymous(krb5_context context, krb5_principal principal)
1546 {
1547     if ((principal->name.name_type != KRB5_NT_WELLKNOWN &&
1548          principal->name.name_type != KRB5_NT_UNKNOWN) ||
1549         principal->name.name_string.len != 2 ||
1550         strcmp(principal->name.name_string.val[0], KRB5_WELLKNOWN_NAME) != 0 ||
1551         strcmp(principal->name.name_string.val[1], KRB5_ANON_NAME) != 0)
1552         return 0;
1553     return 1;
1554 }
1555
1556 static int
1557 require_preauth_p(kdc_request_t r)
1558 {
1559     return r->config->require_preauth
1560         || r->client->entry.flags.require_preauth
1561         || r->server->entry.flags.require_preauth;
1562 }
1563
1564
1565 /*
1566  *
1567  */
1568
1569 static krb5_error_code
1570 add_enc_pa_rep(kdc_request_t r)
1571 {
1572     krb5_error_code ret;
1573     krb5_crypto crypto;
1574     Checksum checksum;
1575     krb5_data cdata;
1576     size_t len;
1577
1578     ret = krb5_crypto_init(r->context, &r->reply_key, 0, &crypto);
1579     if (ret)
1580         return ret;
1581
1582     ret = krb5_create_checksum(r->context, crypto,
1583                                KRB5_KU_AS_REQ, 0,
1584                                r->request.data, r->request.length,
1585                                &checksum);
1586     krb5_crypto_destroy(r->context, crypto);
1587     if (ret)
1588         return ret;
1589
1590     ASN1_MALLOC_ENCODE(Checksum, cdata.data, cdata.length,
1591                        &checksum, &len, ret);
1592     free_Checksum(&checksum);
1593     if (ret)
1594         return ret;
1595     heim_assert(cdata.length == len, "ASN.1 internal error");
1596
1597     if (r->ek.encrypted_pa_data == NULL) {
1598         ALLOC(r->ek.encrypted_pa_data);
1599         if (r->ek.encrypted_pa_data == NULL)
1600             return ENOMEM;
1601     }
1602     ret = krb5_padata_add(r->context, r->ek.encrypted_pa_data,
1603                           KRB5_PADATA_REQ_ENC_PA_REP, cdata.data, cdata.length);
1604     if (ret)
1605         return ret;
1606     
1607     return krb5_padata_add(r->context, r->ek.encrypted_pa_data,
1608                            KRB5_PADATA_FX_FAST, NULL, 0);
1609 }
1610
1611 /*
1612  *
1613  */
1614
1615 krb5_error_code
1616 _kdc_as_rep(kdc_request_t r,
1617             krb5_data *reply,
1618             const char *from,
1619             struct sockaddr *from_addr,
1620             int datagram_reply)
1621 {
1622     krb5_context context = r->context;
1623     krb5_kdc_configuration *config = r->config;
1624     KDC_REQ *req = &r->req;
1625     KDC_REQ_BODY *b = NULL;
1626     AS_REP rep;
1627     KDCOptions f;
1628     krb5_enctype setype;
1629     krb5_error_code ret = 0;
1630     Key *skey;
1631     int found_pa = 0;
1632     int i, flags = HDB_F_FOR_AS_REQ;
1633     METHOD_DATA error_method;
1634     const PA_DATA *pa;
1635
1636     memset(&rep, 0, sizeof(rep));
1637     error_method.len = 0;
1638     error_method.val = NULL;
1639
1640     /*
1641      * Look for FAST armor and unwrap
1642      */
1643     ret = _kdc_fast_unwrap_request(r);
1644     if (ret) {
1645         _kdc_r_log(r, 0, "FAST unwrap request from %s failed: %d", from, ret);
1646         goto out;
1647     }
1648
1649     b = &req->req_body;
1650     f = b->kdc_options;
1651
1652     if (f.canonicalize)
1653         flags |= HDB_F_CANON;
1654
1655     if(b->sname == NULL){
1656         ret = KRB5KRB_ERR_GENERIC;
1657         _kdc_set_e_text(r, "No server in request");
1658     } else{
1659         ret = _krb5_principalname2krb5_principal (context,
1660                                                   &r->server_princ,
1661                                                   *(b->sname),
1662                                                   b->realm);
1663         if (ret == 0)
1664             ret = krb5_unparse_name(context, r->server_princ, &r->server_name);
1665     }
1666     if (ret) {
1667         kdc_log(context, config, 0,
1668                 "AS-REQ malformed server name from %s", from);
1669         goto out;
1670     }
1671     if(b->cname == NULL){
1672         ret = KRB5KRB_ERR_GENERIC;
1673         _kdc_set_e_text(r, "No client in request");
1674     } else {
1675         ret = _krb5_principalname2krb5_principal (context,
1676                                                   &r->client_princ,
1677                                                   *(b->cname),
1678                                                   b->realm);
1679         if (ret)
1680             goto out;
1681
1682         ret = krb5_unparse_name(context, r->client_princ, &r->client_name);
1683     }
1684     if (ret) {
1685         kdc_log(context, config, 0,
1686                 "AS-REQ malformed client name from %s", from);
1687         goto out;
1688     }
1689
1690     kdc_log(context, config, 0, "AS-REQ %s from %s for %s",
1691             r->client_name, from, r->server_name);
1692
1693     /*
1694      *
1695      */
1696
1697     if (_kdc_is_anonymous(context, r->client_princ)) {
1698         if (!_kdc_is_anon_request(b)) {
1699             kdc_log(context, config, 0, "Anonymous ticket w/o anonymous flag");
1700             ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
1701             goto out;
1702         }
1703     } else if (_kdc_is_anon_request(b)) {
1704         kdc_log(context, config, 0,
1705                 "Request for a anonymous ticket with non "
1706                 "anonymous client name: %s", r->client_name);
1707         ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
1708         goto out;
1709     }
1710
1711     /*
1712      *
1713      */
1714
1715     ret = _kdc_db_fetch(context, config, r->client_princ,
1716                         HDB_F_GET_CLIENT | flags, NULL,
1717                         &r->clientdb, &r->client);
1718     if(ret == HDB_ERR_NOT_FOUND_HERE) {
1719         kdc_log(context, config, 5, "client %s does not have secrets at this KDC, need to proxy",
1720                 r->client_name);
1721         goto out;
1722     } else if (ret == HDB_ERR_WRONG_REALM) {
1723         char *fixed_client_name = NULL;
1724
1725         ret = krb5_unparse_name(context, r->client->entry.principal,
1726                                 &fixed_client_name);
1727         if (ret) {
1728             goto out;
1729         }
1730
1731         kdc_log(context, config, 0, "WRONG_REALM - %s -> %s",
1732                 r->client_name, fixed_client_name);
1733         free(fixed_client_name);
1734
1735         ret = _kdc_fast_mk_error(context, r,
1736                                  &error_method,
1737                                  r->armor_crypto,
1738                                  &req->req_body,
1739                                  KRB5_KDC_ERR_WRONG_REALM,
1740                                  NULL,
1741                                  r->server_princ,
1742                                  NULL,
1743                                  &r->client->entry.principal->realm,
1744                                  NULL, NULL,
1745                                  reply);
1746         goto out;
1747     } else if(ret){
1748         const char *msg = krb5_get_error_message(context, ret);
1749         kdc_log(context, config, 0, "UNKNOWN -- %s: %s", r->client_name, msg);
1750         krb5_free_error_message(context, msg);
1751         ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
1752         goto out;
1753     }
1754     ret = _kdc_db_fetch(context, config, r->server_princ,
1755                         HDB_F_GET_SERVER|HDB_F_GET_KRBTGT | flags,
1756                         NULL, NULL, &r->server);
1757     if(ret == HDB_ERR_NOT_FOUND_HERE) {
1758         kdc_log(context, config, 5, "target %s does not have secrets at this KDC, need to proxy",
1759                 r->server_name);
1760         goto out;
1761     } else if(ret){
1762         const char *msg = krb5_get_error_message(context, ret);
1763         kdc_log(context, config, 0, "UNKNOWN -- %s: %s", r->server_name, msg);
1764         krb5_free_error_message(context, msg);
1765         ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
1766         goto out;
1767     }
1768
1769     /*
1770      * Select a session enctype from the list of the crypto system
1771      * supported enctypes that is supported by the client and is one of
1772      * the enctype of the enctype of the service (likely krbtgt).
1773      *
1774      * The latter is used as a hint of what enctypes all KDC support,
1775      * to make sure a newer version of KDC won't generate a session
1776      * enctype that an older version of a KDC in the same realm can't
1777      * decrypt.
1778      */
1779
1780     ret = _kdc_find_etype(context,
1781                           krb5_principal_is_krbtgt(context, r->server_princ) ?
1782                           config->tgt_use_strongest_session_key :
1783                           config->svc_use_strongest_session_key, FALSE,
1784                           r->client, b->etype.val, b->etype.len, &r->sessionetype,
1785                           NULL);
1786     if (ret) {
1787         kdc_log(context, config, 0,
1788                 "Client (%s) from %s has no common enctypes with KDC "
1789                 "to use for the session key",
1790                 r->client_name, from);
1791         goto out;
1792     }
1793
1794     /*
1795      * Pre-auth processing
1796      */
1797
1798     if(req->padata){
1799         unsigned int n;
1800
1801         log_patypes(context, config, req->padata);
1802
1803         /* Check if preauth matching */
1804
1805         for (n = 0; !found_pa && n < sizeof(pat) / sizeof(pat[0]); n++) {
1806             if (pat[n].validate == NULL)
1807                 continue;
1808             if (r->armor_crypto == NULL && (pat[n].flags & PA_REQ_FAST))
1809                 continue;
1810
1811             kdc_log(context, config, 5,
1812                     "Looking for %s pa-data -- %s", pat[n].name, r->client_name);
1813             i = 0;
1814             pa = _kdc_find_padata(req, &i, pat[n].type);
1815             if (pa) {
1816                 ret = pat[n].validate(r, pa);
1817                 if (ret != 0) {
1818                     goto out;
1819                 }
1820                 kdc_log(context, config, 0,
1821                         "%s pre-authentication succeeded -- %s",
1822                         pat[n].name, r->client_name);
1823                 found_pa = 1;
1824                 r->et.flags.pre_authent = 1;
1825             }
1826         }
1827     }
1828
1829     if (found_pa == 0) {
1830         Key *ckey = NULL;
1831         size_t n;
1832
1833         for (n = 0; n < sizeof(pat) / sizeof(pat[0]); n++) {
1834             if ((pat[n].flags & PA_ANNOUNCE) == 0)
1835                 continue;
1836             ret = krb5_padata_add(context, &error_method,
1837                                   pat[n].type, NULL, 0);
1838             if (ret)
1839                 goto out;
1840         }
1841
1842         /*
1843          * If there is a client key, send ETYPE_INFO{,2}
1844          */
1845         ret = _kdc_find_etype(context,
1846                               config->preauth_use_strongest_session_key, TRUE,
1847                               r->client, b->etype.val, b->etype.len, NULL, &ckey);
1848         if (ret == 0) {
1849
1850             /*
1851              * RFC4120 requires:
1852              * - If the client only knows about old enctypes, then send
1853              *   both info replies (we send 'info' first in the list).
1854              * - If the client is 'modern', because it knows about 'new'
1855              *   enctype types, then only send the 'info2' reply.
1856              *
1857              * Before we send the full list of etype-info data, we pick
1858              * the client key we would have used anyway below, just pick
1859              * that instead.
1860              */
1861
1862             if (older_enctype(ckey->key.keytype)) {
1863                 ret = get_pa_etype_info(context, config,
1864                                         &error_method, ckey);
1865                 if (ret)
1866                     goto out;
1867             }
1868             ret = get_pa_etype_info2(context, config,
1869                                      &error_method, ckey);
1870             if (ret)
1871                 goto out;
1872         }
1873
1874         /* 
1875          * send requre preauth is its required or anon is requested,
1876          * anon is today only allowed via preauth mechanisms.
1877          */
1878         if (require_preauth_p(r) || _kdc_is_anon_request(b)) {
1879             ret = KRB5KDC_ERR_PREAUTH_REQUIRED;
1880             _kdc_set_e_text(r, "Need to use PA-ENC-TIMESTAMP/PA-PK-AS-REQ");
1881             goto out;
1882         }
1883
1884         if (ckey == NULL) {
1885             ret = KRB5KDC_ERR_CLIENT_NOTYET;
1886             _kdc_set_e_text(r, "Doesn't have a client key available");
1887             goto out;
1888         }
1889         krb5_free_keyblock_contents(r->context,  &r->reply_key);
1890         ret = krb5_copy_keyblock_contents(r->context, &ckey->key, &r->reply_key);
1891         if (ret)
1892             goto out;
1893     }
1894
1895     if (r->clientdb->hdb_auth_status) {
1896         r->clientdb->hdb_auth_status(context, r->clientdb, r->client, 
1897                                      HDB_AUTH_SUCCESS);
1898     }
1899
1900     /*
1901      * Verify flags after the user been required to prove its identity
1902      * with in a preauth mech.
1903      */
1904
1905     ret = _kdc_check_access(context, config, r->client, r->client_name,
1906                             r->server, r->server_name,
1907                             req, &error_method);
1908     if(ret)
1909         goto out;
1910
1911     /*
1912      * Select the best encryption type for the KDC with out regard to
1913      * the client since the client never needs to read that data.
1914      */
1915
1916     ret = _kdc_get_preferred_key(context, config,
1917                                  r->server, r->server_name,
1918                                  &setype, &skey);
1919     if(ret)
1920         goto out;
1921
1922     if(f.renew || f.validate || f.proxy || f.forwarded || f.enc_tkt_in_skey
1923        || (_kdc_is_anon_request(b) && !config->allow_anonymous)) {
1924         ret = KRB5KDC_ERR_BADOPTION;
1925         _kdc_set_e_text(r, "Bad KDC options");
1926         goto out;
1927     }
1928
1929     /*
1930      * Build reply
1931      */
1932
1933     rep.pvno = 5;
1934     rep.msg_type = krb_as_rep;
1935
1936     if (_kdc_is_anonymous(context, r->client_princ)) {
1937         Realm anon_realm=KRB5_ANON_REALM;
1938         ret = copy_Realm(&anon_realm, &rep.crealm);
1939     } else
1940         ret = copy_Realm(&r->client->entry.principal->realm, &rep.crealm);
1941     if (ret)
1942         goto out;
1943     ret = _krb5_principal2principalname(&rep.cname, r->client->entry.principal);
1944     if (ret)
1945         goto out;
1946
1947     rep.ticket.tkt_vno = 5;
1948     copy_Realm(&r->server->entry.principal->realm, &rep.ticket.realm);
1949     _krb5_principal2principalname(&rep.ticket.sname,
1950                                   r->server->entry.principal);
1951     /* java 1.6 expects the name to be the same type, lets allow that
1952      * uncomplicated name-types. */
1953 #define CNT(sp,t) (((sp)->sname->name_type) == KRB5_NT_##t)
1954     if (CNT(b, UNKNOWN) || CNT(b, PRINCIPAL) || CNT(b, SRV_INST) || CNT(b, SRV_HST) || CNT(b, SRV_XHST))
1955         rep.ticket.sname.name_type = b->sname->name_type;
1956 #undef CNT
1957
1958     r->et.flags.initial = 1;
1959     if(r->client->entry.flags.forwardable && r->server->entry.flags.forwardable)
1960         r->et.flags.forwardable = f.forwardable;
1961     else if (f.forwardable) {
1962         _kdc_set_e_text(r, "Ticket may not be forwardable");
1963         ret = KRB5KDC_ERR_POLICY;
1964         goto out;
1965     }
1966     if(r->client->entry.flags.proxiable && r->server->entry.flags.proxiable)
1967         r->et.flags.proxiable = f.proxiable;
1968     else if (f.proxiable) {
1969         _kdc_set_e_text(r, "Ticket may not be proxiable");
1970         ret = KRB5KDC_ERR_POLICY;
1971         goto out;
1972     }
1973     if(r->client->entry.flags.postdate && r->server->entry.flags.postdate)
1974         r->et.flags.may_postdate = f.allow_postdate;
1975     else if (f.allow_postdate){
1976         _kdc_set_e_text(r, "Ticket may not be postdate");
1977         ret = KRB5KDC_ERR_POLICY;
1978         goto out;
1979     }
1980
1981     /* check for valid set of addresses */
1982     if(!_kdc_check_addresses(context, config, b->addresses, from_addr)) {
1983         _kdc_set_e_text(r, "Bad address list in requested");
1984         ret = KRB5KRB_AP_ERR_BADADDR;
1985         goto out;
1986     }
1987
1988     ret = copy_PrincipalName(&rep.cname, &r->et.cname);
1989     if (ret)
1990         goto out;
1991     ret = copy_Realm(&rep.crealm, &r->et.crealm);
1992     if (ret)
1993         goto out;
1994
1995     {
1996         time_t start;
1997         time_t t;
1998         
1999         start = r->et.authtime = kdc_time;
2000
2001         if(f.postdated && req->req_body.from){
2002             ALLOC(r->et.starttime);
2003             start = *r->et.starttime = *req->req_body.from;
2004             r->et.flags.invalid = 1;
2005             r->et.flags.postdated = 1; /* XXX ??? */
2006         }
2007         _kdc_fix_time(&b->till);
2008         t = *b->till;
2009
2010         /* be careful not overflowing */
2011
2012         if(r->client->entry.max_life)
2013             t = start + min(t - start, *r->client->entry.max_life);
2014         if(r->server->entry.max_life)
2015             t = start + min(t - start, *r->server->entry.max_life);
2016 #if 0
2017         t = min(t, start + realm->max_life);
2018 #endif
2019         r->et.endtime = t;
2020         if(f.renewable_ok && r->et.endtime < *b->till){
2021             f.renewable = 1;
2022             if(b->rtime == NULL){
2023                 ALLOC(b->rtime);
2024                 *b->rtime = 0;
2025             }
2026             if(*b->rtime < *b->till)
2027                 *b->rtime = *b->till;
2028         }
2029         if(f.renewable && b->rtime){
2030             t = *b->rtime;
2031             if(t == 0)
2032                 t = MAX_TIME;
2033             if(r->client->entry.max_renew)
2034                 t = start + min(t - start, *r->client->entry.max_renew);
2035             if(r->server->entry.max_renew)
2036                 t = start + min(t - start, *r->server->entry.max_renew);
2037 #if 0
2038             t = min(t, start + realm->max_renew);
2039 #endif
2040             ALLOC(r->et.renew_till);
2041             *r->et.renew_till = t;
2042             r->et.flags.renewable = 1;
2043         }
2044     }
2045
2046     if (_kdc_is_anon_request(b))
2047         r->et.flags.anonymous = 1;
2048
2049     if(b->addresses){
2050         ALLOC(r->et.caddr);
2051         copy_HostAddresses(b->addresses, r->et.caddr);
2052     }
2053
2054     r->et.transited.tr_type = DOMAIN_X500_COMPRESS;
2055     krb5_data_zero(&r->et.transited.contents);
2056
2057     /* The MIT ASN.1 library (obviously) doesn't tell lengths encoded
2058      * as 0 and as 0x80 (meaning indefinite length) apart, and is thus
2059      * incapable of correctly decoding SEQUENCE OF's of zero length.
2060      *
2061      * To fix this, always send at least one no-op last_req
2062      *
2063      * If there's a pw_end or valid_end we will use that,
2064      * otherwise just a dummy lr.
2065      */
2066     r->ek.last_req.val = malloc(2 * sizeof(*r->ek.last_req.val));
2067     if (r->ek.last_req.val == NULL) {
2068         ret = ENOMEM;
2069         goto out;
2070     }
2071     r->ek.last_req.len = 0;
2072     if (r->client->entry.pw_end
2073         && (config->kdc_warn_pwexpire == 0
2074             || kdc_time + config->kdc_warn_pwexpire >= *r->client->entry.pw_end)) {
2075         r->ek.last_req.val[r->ek.last_req.len].lr_type  = LR_PW_EXPTIME;
2076         r->ek.last_req.val[r->ek.last_req.len].lr_value = *r->client->entry.pw_end;
2077         ++r->ek.last_req.len;
2078     }
2079     if (r->client->entry.valid_end) {
2080         r->ek.last_req.val[r->ek.last_req.len].lr_type  = LR_ACCT_EXPTIME;
2081         r->ek.last_req.val[r->ek.last_req.len].lr_value = *r->client->entry.valid_end;
2082         ++r->ek.last_req.len;
2083     }
2084     if (r->ek.last_req.len == 0) {
2085         r->ek.last_req.val[r->ek.last_req.len].lr_type  = LR_NONE;
2086         r->ek.last_req.val[r->ek.last_req.len].lr_value = 0;
2087         ++r->ek.last_req.len;
2088     }
2089     r->ek.nonce = b->nonce;
2090     if (r->client->entry.valid_end || r->client->entry.pw_end) {
2091         ALLOC(r->ek.key_expiration);
2092         if (r->client->entry.valid_end) {
2093             if (r->client->entry.pw_end)
2094                 *r->ek.key_expiration = min(*r->client->entry.valid_end,
2095                                          *r->client->entry.pw_end);
2096             else
2097                 *r->ek.key_expiration = *r->client->entry.valid_end;
2098         } else
2099             *r->ek.key_expiration = *r->client->entry.pw_end;
2100     } else
2101         r->ek.key_expiration = NULL;
2102     r->ek.flags = r->et.flags;
2103     r->ek.authtime = r->et.authtime;
2104     if (r->et.starttime) {
2105         ALLOC(r->ek.starttime);
2106         *r->ek.starttime = *r->et.starttime;
2107     }
2108     r->ek.endtime = r->et.endtime;
2109     if (r->et.renew_till) {
2110         ALLOC(r->ek.renew_till);
2111         *r->ek.renew_till = *r->et.renew_till;
2112     }
2113     copy_Realm(&rep.ticket.realm, &r->ek.srealm);
2114     copy_PrincipalName(&rep.ticket.sname, &r->ek.sname);
2115     if(r->et.caddr){
2116         ALLOC(r->ek.caddr);
2117         copy_HostAddresses(r->et.caddr, r->ek.caddr);
2118     }
2119
2120     /*
2121      * Check and session and reply keys
2122      */
2123
2124     if (r->session_key.keytype == ETYPE_NULL) {
2125         ret = krb5_generate_random_keyblock(context, r->sessionetype, &r->session_key);
2126         if (ret)
2127             goto out;
2128     }
2129
2130     if (r->reply_key.keytype == ETYPE_NULL) {
2131         _kdc_set_e_text(r, "Client have no reply key");
2132         ret = KRB5KDC_ERR_CLIENT_NOTYET;
2133         goto out;
2134     }
2135
2136     ret = copy_EncryptionKey(&r->session_key, &r->et.key);
2137     if (ret)
2138         goto out;
2139
2140     ret = copy_EncryptionKey(&r->session_key, &r->ek.key);
2141     if (ret)
2142         goto out;
2143
2144     if (r->outpadata.len) {
2145
2146         ALLOC(rep.padata);
2147         if (rep.padata == NULL) {
2148             ret = ENOMEM;
2149             goto out;
2150         }
2151         ret = copy_METHOD_DATA(&r->outpadata, rep.padata);
2152         if (ret)
2153             goto out;
2154     }
2155
2156     /* Add the PAC */
2157     if (send_pac_p(context, req)) {
2158         generate_pac(r, skey);
2159     }
2160
2161     _kdc_log_timestamp(context, config, "AS-REQ", r->et.authtime, r->et.starttime,
2162                        r->et.endtime, r->et.renew_till);
2163
2164     /* do this as the last thing since this signs the EncTicketPart */
2165     ret = _kdc_add_KRB5SignedPath(context,
2166                                   config,
2167                                   r->server,
2168                                   setype,
2169                                   r->client->entry.principal,
2170                                   NULL,
2171                                   NULL,
2172                                   &r->et);
2173     if (ret)
2174         goto out;
2175
2176     log_as_req(context, config, r->reply_key.keytype, setype, b);
2177
2178     /*
2179      * We always say we support FAST/enc-pa-rep
2180      */
2181
2182     r->et.flags.enc_pa_rep = r->ek.flags.enc_pa_rep = 1;
2183
2184     /*
2185      * Add REQ_ENC_PA_REP if client supports it
2186      */
2187
2188     i = 0;
2189     pa = _kdc_find_padata(req, &i, KRB5_PADATA_REQ_ENC_PA_REP);
2190     if (pa) {
2191
2192         ret = add_enc_pa_rep(r);
2193         if (ret) {
2194             const char *msg = krb5_get_error_message(r->context, ret);
2195             _kdc_r_log(r, 0, "add_enc_pa_rep failed: %s: %d", msg, ret);
2196             krb5_free_error_message(r->context, msg);
2197             goto out;
2198         }
2199     }
2200
2201     /*
2202      *
2203      */
2204
2205     ret = _kdc_encode_reply(context, config,
2206                             r->armor_crypto, req->req_body.nonce,
2207                             &rep, &r->et, &r->ek, setype, r->server->entry.kvno,
2208                             &skey->key, r->client->entry.kvno,
2209                             &r->reply_key, 0, &r->e_text, reply);
2210     if (ret)
2211         goto out;
2212
2213     /*
2214      * Check if message too large
2215      */
2216     if (datagram_reply && reply->length > config->max_datagram_reply_length) {
2217         krb5_data_free(reply);
2218         ret = KRB5KRB_ERR_RESPONSE_TOO_BIG;
2219         _kdc_set_e_text(r, "Reply packet too large");
2220     }
2221
2222 out:
2223     free_AS_REP(&rep);
2224
2225     /*
2226      * In case of a non proxy error, build an error message.
2227      */
2228     if(ret != 0 && ret != HDB_ERR_NOT_FOUND_HERE && reply->length == 0) {
2229         ret = _kdc_fast_mk_error(context, r,
2230                                  &error_method,
2231                                  r->armor_crypto,
2232                                  &req->req_body,
2233                                  ret, r->e_text,
2234                                  r->server_princ,
2235                                  &r->client_princ->name,
2236                                  &r->client_princ->realm,
2237                                  NULL, NULL,
2238                                  reply);
2239         if (ret)
2240             goto out2;
2241     }
2242 out2:
2243     free_EncTicketPart(&r->et);
2244     free_EncKDCRepPart(&r->ek);
2245     free_KDCFastState(&r->fast);
2246
2247     if (error_method.len)
2248         free_METHOD_DATA(&error_method);
2249     if (r->outpadata.len)
2250         free_METHOD_DATA(&r->outpadata);
2251     if (r->client_princ) {
2252         krb5_free_principal(context, r->client_princ);
2253         r->client_princ = NULL;
2254     }
2255     if (r->client_name) {
2256         free(r->client_name);
2257         r->client_name = NULL;
2258     }
2259     if (r->server_princ){
2260         krb5_free_principal(context, r->server_princ);
2261         r->server_princ = NULL;
2262     }
2263     if (r->server_name) {
2264         free(r->server_name);
2265         r->server_name = NULL;
2266     }
2267     if (r->client)
2268         _kdc_free_ent(context, r->client);
2269     if (r->server)
2270         _kdc_free_ent(context, r->server);
2271     if (r->armor_crypto) {
2272         krb5_crypto_destroy(r->context, r->armor_crypto);
2273         r->armor_crypto = NULL;
2274     }
2275     krb5_free_keyblock_contents(r->context, &r->reply_key);
2276     krb5_free_keyblock_contents(r->context, &r->session_key);
2277     return ret;
2278 }
2279
2280 /*
2281  * Add the AuthorizationData `data´ of `type´ to the last element in
2282  * the sequence of authorization_data in `tkt´ wrapped in an IF_RELEVANT
2283  */
2284
2285 krb5_error_code
2286 _kdc_tkt_add_if_relevant_ad(krb5_context context,
2287                             EncTicketPart *tkt,
2288                             int type,
2289                             const krb5_data *data)
2290 {
2291     krb5_error_code ret;
2292     size_t size = 0;
2293
2294     if (tkt->authorization_data == NULL) {
2295         tkt->authorization_data = calloc(1, sizeof(*tkt->authorization_data));
2296         if (tkt->authorization_data == NULL) {
2297             krb5_set_error_message(context, ENOMEM, "out of memory");
2298             return ENOMEM;
2299         }
2300     }
2301
2302     /* add the entry to the last element */
2303     {
2304         AuthorizationData ad = { 0, NULL };
2305         AuthorizationDataElement ade;
2306
2307         ade.ad_type = type;
2308         ade.ad_data = *data;
2309
2310         ret = add_AuthorizationData(&ad, &ade);
2311         if (ret) {
2312             krb5_set_error_message(context, ret, "add AuthorizationData failed");
2313             return ret;
2314         }
2315
2316         ade.ad_type = KRB5_AUTHDATA_IF_RELEVANT;
2317
2318         ASN1_MALLOC_ENCODE(AuthorizationData,
2319                            ade.ad_data.data, ade.ad_data.length,
2320                            &ad, &size, ret);
2321         free_AuthorizationData(&ad);
2322         if (ret) {
2323             krb5_set_error_message(context, ret, "ASN.1 encode of "
2324                                    "AuthorizationData failed");
2325             return ret;
2326         }
2327         if (ade.ad_data.length != size)
2328             krb5_abortx(context, "internal asn.1 encoder error");
2329
2330         ret = add_AuthorizationData(tkt->authorization_data, &ade);
2331         der_free_octet_string(&ade.ad_data);
2332         if (ret) {
2333             krb5_set_error_message(context, ret, "add AuthorizationData failed");
2334             return ret;
2335         }
2336     }
2337
2338     return 0;
2339 }
2340
2341 krb5_boolean
2342 _kdc_is_anon_request(const KDC_REQ_BODY *b)
2343 {
2344         /* some versions of heimdal use bit 14 instead of 16 for
2345            request_anonymous, as indicated in the anonymous draft prior to
2346            version 11. Bit 14 is assigned to S4U2Proxy, but all S4U2Proxy
2347            requests will have a second ticket; don't consider those anonymous */
2348         return (b->kdc_options.request_anonymous ||
2349                 (b->kdc_options.constrained_delegation && !b->additional_tickets));
2350 }