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