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