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