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