1 /* 2 * Copyright (c) 1997-2003 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,v 1.145.2.4 2004/08/13 19:28:26 lha Exp $"); 37 38 #define MAX_TIME ((time_t)((1U << 31) - 1)) 39 40 static void 41 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 void 51 set_salt_padata (METHOD_DATA **m, Salt *salt) 52 { 53 if (salt) { 54 ALLOC(*m); 55 (*m)->len = 1; 56 ALLOC((*m)->val); 57 (*m)->val->padata_type = salt->type; 58 copy_octet_string(&salt->salt, 59 &(*m)->val->padata_value); 60 } 61 } 62 63 static PA_DATA* 64 find_padata(KDC_REQ *req, int *start, int type) 65 { 66 while(*start < req->padata->len){ 67 (*start)++; 68 if(req->padata->val[*start - 1].padata_type == type) 69 return &req->padata->val[*start - 1]; 70 } 71 return NULL; 72 } 73 74 /* 75 * return the first appropriate key of `princ' in `ret_key'. Look for 76 * all the etypes in (`etypes', `len'), stopping as soon as we find 77 * one, but preferring one that has default salt 78 */ 79 80 static krb5_error_code 81 find_etype(hdb_entry *princ, krb5_enctype *etypes, unsigned len, 82 Key **ret_key, krb5_enctype *ret_etype) 83 { 84 int i; 85 krb5_error_code ret = KRB5KDC_ERR_ETYPE_NOSUPP; 86 87 for(i = 0; ret != 0 && i < len ; i++) { 88 Key *key = NULL; 89 90 while (hdb_next_enctype2key(context, princ, etypes[i], &key) == 0) { 91 if (key->key.keyvalue.length == 0) { 92 ret = KRB5KDC_ERR_NULL_KEY; 93 continue; 94 } 95 *ret_key = key; 96 *ret_etype = etypes[i]; 97 ret = 0; 98 if (key->salt == NULL) 99 return ret; 100 } 101 } 102 return ret; 103 } 104 105 static krb5_error_code 106 find_keys(hdb_entry *client, 107 hdb_entry *server, 108 Key **ckey, 109 krb5_enctype *cetype, 110 Key **skey, 111 krb5_enctype *setype, 112 krb5_enctype *etypes, 113 unsigned num_etypes) 114 { 115 krb5_error_code ret; 116 117 if(client){ 118 /* find client key */ 119 ret = find_etype(client, etypes, num_etypes, ckey, cetype); 120 if (ret) { 121 kdc_log(0, "Client has no support for etypes"); 122 return ret; 123 } 124 } 125 126 if(server){ 127 /* find server key */ 128 ret = find_etype(server, etypes, num_etypes, skey, setype); 129 if (ret) { 130 kdc_log(0, "Server has no support for etypes"); 131 return ret; 132 } 133 } 134 return 0; 135 } 136 137 static krb5_error_code 138 make_anonymous_principalname (PrincipalName *pn) 139 { 140 pn->name_type = KRB5_NT_PRINCIPAL; 141 pn->name_string.len = 1; 142 pn->name_string.val = malloc(sizeof(*pn->name_string.val)); 143 if (pn->name_string.val == NULL) 144 return ENOMEM; 145 pn->name_string.val[0] = strdup("anonymous"); 146 if (pn->name_string.val[0] == NULL) { 147 free(pn->name_string.val); 148 pn->name_string.val = NULL; 149 return ENOMEM; 150 } 151 return 0; 152 } 153 154 static krb5_error_code 155 encode_reply(KDC_REP *rep, EncTicketPart *et, EncKDCRepPart *ek, 156 krb5_enctype etype, 157 int skvno, EncryptionKey *skey, 158 int ckvno, EncryptionKey *ckey, 159 const char **e_text, 160 krb5_data *reply) 161 { 162 unsigned char *buf; 163 size_t buf_size; 164 size_t len; 165 krb5_error_code ret; 166 krb5_crypto crypto; 167 168 ASN1_MALLOC_ENCODE(EncTicketPart, buf, buf_size, et, &len, ret); 169 if(ret) { 170 kdc_log(0, "Failed to encode ticket: %s", 171 krb5_get_err_text(context, ret)); 172 return ret; 173 } 174 if(buf_size != len) { 175 free(buf); 176 kdc_log(0, "Internal error in ASN.1 encoder"); 177 *e_text = "KDC internal error"; 178 return KRB5KRB_ERR_GENERIC; 179 } 180 181 ret = krb5_crypto_init(context, skey, etype, &crypto); 182 if (ret) { 183 free(buf); 184 kdc_log(0, "krb5_crypto_init failed: %s", 185 krb5_get_err_text(context, ret)); 186 return ret; 187 } 188 189 ret = krb5_encrypt_EncryptedData(context, 190 crypto, 191 KRB5_KU_TICKET, 192 buf, 193 len, 194 skvno, 195 &rep->ticket.enc_part); 196 free(buf); 197 krb5_crypto_destroy(context, crypto); 198 if(ret) { 199 kdc_log(0, "Failed to encrypt data: %s", 200 krb5_get_err_text(context, ret)); 201 return ret; 202 } 203 204 if(rep->msg_type == krb_as_rep && !encode_as_rep_as_tgs_rep) 205 ASN1_MALLOC_ENCODE(EncASRepPart, buf, buf_size, ek, &len, ret); 206 else 207 ASN1_MALLOC_ENCODE(EncTGSRepPart, buf, buf_size, ek, &len, ret); 208 if(ret) { 209 kdc_log(0, "Failed to encode KDC-REP: %s", 210 krb5_get_err_text(context, ret)); 211 return ret; 212 } 213 if(buf_size != len) { 214 free(buf); 215 kdc_log(0, "Internal error in ASN.1 encoder"); 216 *e_text = "KDC internal error"; 217 return KRB5KRB_ERR_GENERIC; 218 } 219 ret = krb5_crypto_init(context, ckey, 0, &crypto); 220 if (ret) { 221 free(buf); 222 kdc_log(0, "krb5_crypto_init failed: %s", 223 krb5_get_err_text(context, ret)); 224 return ret; 225 } 226 if(rep->msg_type == krb_as_rep) { 227 krb5_encrypt_EncryptedData(context, 228 crypto, 229 KRB5_KU_AS_REP_ENC_PART, 230 buf, 231 len, 232 ckvno, 233 &rep->enc_part); 234 free(buf); 235 ASN1_MALLOC_ENCODE(AS_REP, buf, buf_size, rep, &len, ret); 236 } else { 237 krb5_encrypt_EncryptedData(context, 238 crypto, 239 KRB5_KU_TGS_REP_ENC_PART_SESSION, 240 buf, 241 len, 242 ckvno, 243 &rep->enc_part); 244 free(buf); 245 ASN1_MALLOC_ENCODE(TGS_REP, buf, buf_size, rep, &len, ret); 246 } 247 krb5_crypto_destroy(context, crypto); 248 if(ret) { 249 kdc_log(0, "Failed to encode KDC-REP: %s", 250 krb5_get_err_text(context, ret)); 251 return ret; 252 } 253 if(buf_size != len) { 254 free(buf); 255 kdc_log(0, "Internal error in ASN.1 encoder"); 256 *e_text = "KDC internal error"; 257 return KRB5KRB_ERR_GENERIC; 258 } 259 reply->data = buf; 260 reply->length = buf_size; 261 return 0; 262 } 263 264 static int 265 realloc_method_data(METHOD_DATA *md) 266 { 267 PA_DATA *pa; 268 pa = realloc(md->val, (md->len + 1) * sizeof(*md->val)); 269 if(pa == NULL) 270 return ENOMEM; 271 md->val = pa; 272 md->len++; 273 return 0; 274 } 275 276 static krb5_error_code 277 make_etype_info_entry(ETYPE_INFO_ENTRY *ent, Key *key) 278 { 279 ent->etype = key->key.keytype; 280 if(key->salt){ 281 ALLOC(ent->salttype); 282 #if 0 283 if(key->salt->type == hdb_pw_salt) 284 *ent->salttype = 0; /* or 1? or NULL? */ 285 else if(key->salt->type == hdb_afs3_salt) 286 *ent->salttype = 2; 287 else { 288 kdc_log(0, "unknown salt-type: %d", 289 key->salt->type); 290 return KRB5KRB_ERR_GENERIC; 291 } 292 /* according to `the specs', we can't send a salt if 293 we have AFS3 salted key, but that requires that you 294 *know* what cell you are using (e.g by assuming 295 that the cell is the same as the realm in lower 296 case) */ 297 #else 298 *ent->salttype = key->salt->type; 299 #endif 300 krb5_copy_data(context, &key->salt->salt, 301 &ent->salt); 302 } else { 303 /* we return no salt type at all, as that should indicate 304 * the default salt type and make everybody happy. some 305 * systems (like w2k) dislike being told the salt type 306 * here. */ 307 308 ent->salttype = NULL; 309 ent->salt = NULL; 310 } 311 return 0; 312 } 313 314 static krb5_error_code 315 get_pa_etype_info(METHOD_DATA *md, hdb_entry *client, 316 ENCTYPE *etypes, unsigned int etypes_len) 317 { 318 krb5_error_code ret = 0; 319 int i, j; 320 unsigned int n = 0; 321 ETYPE_INFO pa; 322 unsigned char *buf; 323 size_t len; 324 325 326 pa.len = client->keys.len; 327 if(pa.len > UINT_MAX/sizeof(*pa.val)) 328 return ERANGE; 329 pa.val = malloc(pa.len * sizeof(*pa.val)); 330 if(pa.val == NULL) 331 return ENOMEM; 332 333 for(j = 0; j < etypes_len; j++) { 334 for (i = 0; i < n; i++) 335 if (pa.val[i].etype == etypes[j]) 336 goto skip1; 337 for(i = 0; i < client->keys.len; i++) { 338 if(client->keys.val[i].key.keytype == etypes[j]) 339 if((ret = make_etype_info_entry(&pa.val[n++], 340 &client->keys.val[i])) != 0) { 341 free_ETYPE_INFO(&pa); 342 return ret; 343 } 344 } 345 skip1:; 346 } 347 for(i = 0; i < client->keys.len; i++) { 348 for(j = 0; j < etypes_len; j++) { 349 if(client->keys.val[i].key.keytype == etypes[j]) 350 goto skip2; 351 } 352 if((ret = make_etype_info_entry(&pa.val[n++], 353 &client->keys.val[i])) != 0) { 354 free_ETYPE_INFO(&pa); 355 return ret; 356 } 357 skip2:; 358 } 359 360 if(n != pa.len) { 361 char *name; 362 krb5_unparse_name(context, client->principal, &name); 363 kdc_log(0, "internal error in get_pa_etype_info(%s): %d != %d", 364 name, n, pa.len); 365 free(name); 366 pa.len = n; 367 } 368 369 ASN1_MALLOC_ENCODE(ETYPE_INFO, buf, len, &pa, &len, ret); 370 free_ETYPE_INFO(&pa); 371 if(ret) 372 return ret; 373 ret = realloc_method_data(md); 374 if(ret) { 375 free(buf); 376 return ret; 377 } 378 md->val[md->len - 1].padata_type = KRB5_PADATA_ETYPE_INFO; 379 md->val[md->len - 1].padata_value.length = len; 380 md->val[md->len - 1].padata_value.data = buf; 381 return 0; 382 } 383 384 /* 385 * verify the flags on `client' and `server', returning 0 386 * if they are OK and generating an error messages and returning 387 * and error code otherwise. 388 */ 389 390 krb5_error_code 391 check_flags(hdb_entry *client, const char *client_name, 392 hdb_entry *server, const char *server_name, 393 krb5_boolean is_as_req) 394 { 395 if(client != NULL) { 396 /* check client */ 397 if (client->flags.invalid) { 398 kdc_log(0, "Client (%s) has invalid bit set", client_name); 399 return KRB5KDC_ERR_POLICY; 400 } 401 402 if(!client->flags.client){ 403 kdc_log(0, "Principal may not act as client -- %s", 404 client_name); 405 return KRB5KDC_ERR_POLICY; 406 } 407 408 if (client->valid_start && *client->valid_start > kdc_time) { 409 kdc_log(0, "Client not yet valid -- %s", client_name); 410 return KRB5KDC_ERR_CLIENT_NOTYET; 411 } 412 413 if (client->valid_end && *client->valid_end < kdc_time) { 414 kdc_log(0, "Client expired -- %s", client_name); 415 return KRB5KDC_ERR_NAME_EXP; 416 } 417 418 if (client->pw_end && *client->pw_end < kdc_time 419 && !server->flags.change_pw) { 420 kdc_log(0, "Client's key has expired -- %s", client_name); 421 return KRB5KDC_ERR_KEY_EXPIRED; 422 } 423 } 424 425 /* check server */ 426 427 if (server != NULL) { 428 if (server->flags.invalid) { 429 kdc_log(0, "Server has invalid flag set -- %s", server_name); 430 return KRB5KDC_ERR_POLICY; 431 } 432 433 if(!server->flags.server){ 434 kdc_log(0, "Principal may not act as server -- %s", 435 server_name); 436 return KRB5KDC_ERR_POLICY; 437 } 438 439 if(!is_as_req && server->flags.initial) { 440 kdc_log(0, "AS-REQ is required for server -- %s", server_name); 441 return KRB5KDC_ERR_POLICY; 442 } 443 444 if (server->valid_start && *server->valid_start > kdc_time) { 445 kdc_log(0, "Server not yet valid -- %s", server_name); 446 return KRB5KDC_ERR_SERVICE_NOTYET; 447 } 448 449 if (server->valid_end && *server->valid_end < kdc_time) { 450 kdc_log(0, "Server expired -- %s", server_name); 451 return KRB5KDC_ERR_SERVICE_EXP; 452 } 453 454 if (server->pw_end && *server->pw_end < kdc_time) { 455 kdc_log(0, "Server's key has expired -- %s", server_name); 456 return KRB5KDC_ERR_KEY_EXPIRED; 457 } 458 } 459 return 0; 460 } 461 462 /* 463 * Return TRUE if `from' is part of `addresses' taking into consideration 464 * the configuration variables that tells us how strict we should be about 465 * these checks 466 */ 467 468 static krb5_boolean 469 check_addresses(HostAddresses *addresses, const struct sockaddr *from) 470 { 471 krb5_error_code ret; 472 krb5_address addr; 473 krb5_boolean result; 474 475 if(check_ticket_addresses == 0) 476 return TRUE; 477 478 if(addresses == NULL) 479 return allow_null_ticket_addresses; 480 481 ret = krb5_sockaddr2address (context, from, &addr); 482 if(ret) 483 return FALSE; 484 485 result = krb5_address_search(context, &addr, addresses); 486 krb5_free_address (context, &addr); 487 return result; 488 } 489 490 krb5_error_code 491 as_rep(KDC_REQ *req, 492 krb5_data *reply, 493 const char *from, 494 struct sockaddr *from_addr) 495 { 496 KDC_REQ_BODY *b = &req->req_body; 497 AS_REP rep; 498 KDCOptions f = b->kdc_options; 499 hdb_entry *client = NULL, *server = NULL; 500 krb5_enctype cetype, setype; 501 EncTicketPart et; 502 EncKDCRepPart ek; 503 krb5_principal client_princ = NULL, server_princ = NULL; 504 char *client_name = NULL, *server_name = NULL; 505 krb5_error_code ret = 0; 506 const char *e_text = NULL; 507 krb5_crypto crypto; 508 Key *ckey, *skey; 509 510 memset(&rep, 0, sizeof(rep)); 511 512 if(b->sname == NULL){ 513 ret = KRB5KRB_ERR_GENERIC; 514 e_text = "No server in request"; 515 } else{ 516 principalname2krb5_principal (&server_princ, *(b->sname), b->realm); 517 krb5_unparse_name(context, server_princ, &server_name); 518 } 519 if (ret) { 520 kdc_log(0, "AS-REQ malformed server name from %s", from); 521 goto out; 522 } 523 524 if(b->cname == NULL){ 525 ret = KRB5KRB_ERR_GENERIC; 526 e_text = "No client in request"; 527 } else { 528 principalname2krb5_principal (&client_princ, *(b->cname), b->realm); 529 krb5_unparse_name(context, client_princ, &client_name); 530 } 531 if (ret) { 532 kdc_log(0, "AS-REQ malformed client name from %s", from); 533 goto out; 534 } 535 536 kdc_log(0, "AS-REQ %s from %s for %s", client_name, from, server_name); 537 538 ret = db_fetch(client_princ, &client); 539 if(ret){ 540 kdc_log(0, "UNKNOWN -- %s: %s", client_name, 541 krb5_get_err_text(context, ret)); 542 ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN; 543 goto out; 544 } 545 546 ret = db_fetch(server_princ, &server); 547 if(ret){ 548 kdc_log(0, "UNKNOWN -- %s: %s", server_name, 549 krb5_get_err_text(context, ret)); 550 ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN; 551 goto out; 552 } 553 554 ret = check_flags(client, client_name, server, server_name, TRUE); 555 if(ret) 556 goto out; 557 558 memset(&et, 0, sizeof(et)); 559 memset(&ek, 0, sizeof(ek)); 560 561 if(req->padata){ 562 int i = 0; 563 PA_DATA *pa; 564 int found_pa = 0; 565 kdc_log(5, "Looking for pa-data -- %s", client_name); 566 while((pa = find_padata(req, &i, KRB5_PADATA_ENC_TIMESTAMP))){ 567 krb5_data ts_data; 568 PA_ENC_TS_ENC p; 569 time_t patime; 570 size_t len; 571 EncryptedData enc_data; 572 Key *pa_key; 573 574 found_pa = 1; 575 576 ret = decode_EncryptedData(pa->padata_value.data, 577 pa->padata_value.length, 578 &enc_data, 579 &len); 580 if (ret) { 581 ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; 582 kdc_log(5, "Failed to decode PA-DATA -- %s", 583 client_name); 584 goto out; 585 } 586 587 ret = hdb_enctype2key(context, client, enc_data.etype, &pa_key); 588 if(ret){ 589 char *estr; 590 e_text = "No key matches pa-data"; 591 ret = KRB5KDC_ERR_PREAUTH_FAILED; 592 if(krb5_enctype_to_string(context, enc_data.etype, &estr)) 593 estr = NULL; 594 if(estr == NULL) 595 kdc_log(5, "No client key matching pa-data (%d) -- %s", 596 enc_data.etype, client_name); 597 else 598 kdc_log(5, "No client key matching pa-data (%s) -- %s", 599 estr, client_name); 600 free(estr); 601 602 free_EncryptedData(&enc_data); 603 continue; 604 } 605 606 try_next_key: 607 ret = krb5_crypto_init(context, &pa_key->key, 0, &crypto); 608 if (ret) { 609 kdc_log(0, "krb5_crypto_init failed: %s", 610 krb5_get_err_text(context, ret)); 611 free_EncryptedData(&enc_data); 612 continue; 613 } 614 615 ret = krb5_decrypt_EncryptedData (context, 616 crypto, 617 KRB5_KU_PA_ENC_TIMESTAMP, 618 &enc_data, 619 &ts_data); 620 krb5_crypto_destroy(context, crypto); 621 if(ret){ 622 if(hdb_next_enctype2key(context, client, 623 enc_data.etype, &pa_key) == 0) 624 goto try_next_key; 625 free_EncryptedData(&enc_data); 626 e_text = "Failed to decrypt PA-DATA"; 627 kdc_log (5, "Failed to decrypt PA-DATA -- %s", 628 client_name); 629 ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; 630 continue; 631 } 632 free_EncryptedData(&enc_data); 633 ret = decode_PA_ENC_TS_ENC(ts_data.data, 634 ts_data.length, 635 &p, 636 &len); 637 krb5_data_free(&ts_data); 638 if(ret){ 639 e_text = "Failed to decode PA-ENC-TS-ENC"; 640 ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; 641 kdc_log (5, "Failed to decode PA-ENC-TS_ENC -- %s", 642 client_name); 643 continue; 644 } 645 patime = p.patimestamp; 646 free_PA_ENC_TS_ENC(&p); 647 if (abs(kdc_time - p.patimestamp) > context->max_skew) { 648 ret = KRB5KDC_ERR_PREAUTH_FAILED; 649 e_text = "Too large time skew"; 650 kdc_log(0, "Too large time skew -- %s", client_name); 651 goto out; 652 } 653 et.flags.pre_authent = 1; 654 kdc_log(2, "Pre-authentication succeded -- %s", client_name); 655 break; 656 } 657 if(found_pa == 0 && require_preauth) 658 goto use_pa; 659 /* We come here if we found a pa-enc-timestamp, but if there 660 was some problem with it, other than too large skew */ 661 if(found_pa && et.flags.pre_authent == 0){ 662 kdc_log(0, "%s -- %s", e_text, client_name); 663 e_text = NULL; 664 goto out; 665 } 666 }else if (require_preauth 667 || client->flags.require_preauth 668 || server->flags.require_preauth) { 669 METHOD_DATA method_data; 670 PA_DATA *pa; 671 unsigned char *buf; 672 size_t len; 673 krb5_data foo_data; 674 675 use_pa: 676 method_data.len = 0; 677 method_data.val = NULL; 678 679 ret = realloc_method_data(&method_data); 680 pa = &method_data.val[method_data.len-1]; 681 pa->padata_type = KRB5_PADATA_ENC_TIMESTAMP; 682 pa->padata_value.length = 0; 683 pa->padata_value.data = NULL; 684 685 ret = get_pa_etype_info(&method_data, client, 686 b->etype.val, b->etype.len); /* XXX check ret */ 687 688 ASN1_MALLOC_ENCODE(METHOD_DATA, buf, len, &method_data, &len, ret); 689 free_METHOD_DATA(&method_data); 690 foo_data.data = buf; 691 foo_data.length = len; 692 693 ret = KRB5KDC_ERR_PREAUTH_REQUIRED; 694 krb5_mk_error(context, 695 ret, 696 "Need to use PA-ENC-TIMESTAMP", 697 &foo_data, 698 client_princ, 699 server_princ, 700 NULL, 701 NULL, 702 reply); 703 free(buf); 704 kdc_log(0, "No PA-ENC-TIMESTAMP -- %s", client_name); 705 ret = 0; 706 goto out2; 707 } 708 709 ret = find_keys(client, server, &ckey, &cetype, &skey, &setype, 710 b->etype.val, b->etype.len); 711 if(ret) { 712 kdc_log(0, "Server/client has no support for etypes"); 713 goto out; 714 } 715 716 { 717 char *cet; 718 char *set; 719 720 ret = krb5_enctype_to_string(context, cetype, &cet); 721 if(ret == 0) { 722 ret = krb5_enctype_to_string(context, setype, &set); 723 if (ret == 0) { 724 kdc_log(5, "Using %s/%s", cet, set); 725 free(set); 726 } 727 free(cet); 728 } 729 if (ret != 0) 730 kdc_log(5, "Using e-types %d/%d", cetype, setype); 731 } 732 733 { 734 char str[128]; 735 unparse_flags(KDCOptions2int(f), KDCOptions_units, str, sizeof(str)); 736 if(*str) 737 kdc_log(2, "Requested flags: %s", str); 738 } 739 740 741 if(f.renew || f.validate || f.proxy || f.forwarded || f.enc_tkt_in_skey 742 || (f.request_anonymous && !allow_anonymous)) { 743 ret = KRB5KDC_ERR_BADOPTION; 744 kdc_log(0, "Bad KDC options -- %s", client_name); 745 goto out; 746 } 747 748 rep.pvno = 5; 749 rep.msg_type = krb_as_rep; 750 copy_Realm(&b->realm, &rep.crealm); 751 if (f.request_anonymous) 752 make_anonymous_principalname (&rep.cname); 753 else 754 copy_PrincipalName(b->cname, &rep.cname); 755 rep.ticket.tkt_vno = 5; 756 copy_Realm(&b->realm, &rep.ticket.realm); 757 copy_PrincipalName(b->sname, &rep.ticket.sname); 758 759 et.flags.initial = 1; 760 if(client->flags.forwardable && server->flags.forwardable) 761 et.flags.forwardable = f.forwardable; 762 else if (f.forwardable) { 763 ret = KRB5KDC_ERR_POLICY; 764 kdc_log(0, "Ticket may not be forwardable -- %s", client_name); 765 goto out; 766 } 767 if(client->flags.proxiable && server->flags.proxiable) 768 et.flags.proxiable = f.proxiable; 769 else if (f.proxiable) { 770 ret = KRB5KDC_ERR_POLICY; 771 kdc_log(0, "Ticket may not be proxiable -- %s", client_name); 772 goto out; 773 } 774 if(client->flags.postdate && server->flags.postdate) 775 et.flags.may_postdate = f.allow_postdate; 776 else if (f.allow_postdate){ 777 ret = KRB5KDC_ERR_POLICY; 778 kdc_log(0, "Ticket may not be postdatable -- %s", client_name); 779 goto out; 780 } 781 782 /* check for valid set of addresses */ 783 if(!check_addresses(b->addresses, from_addr)) { 784 ret = KRB5KRB_AP_ERR_BADADDR; 785 kdc_log(0, "Bad address list requested -- %s", client_name); 786 goto out; 787 } 788 789 krb5_generate_random_keyblock(context, setype, &et.key); 790 copy_PrincipalName(&rep.cname, &et.cname); 791 copy_Realm(&b->realm, &et.crealm); 792 793 { 794 time_t start; 795 time_t t; 796 797 start = et.authtime = kdc_time; 798 799 if(f.postdated && req->req_body.from){ 800 ALLOC(et.starttime); 801 start = *et.starttime = *req->req_body.from; 802 et.flags.invalid = 1; 803 et.flags.postdated = 1; /* XXX ??? */ 804 } 805 fix_time(&b->till); 806 t = *b->till; 807 808 /* be careful not overflowing */ 809 810 if(client->max_life) 811 t = start + min(t - start, *client->max_life); 812 if(server->max_life) 813 t = start + min(t - start, *server->max_life); 814 #if 0 815 t = min(t, start + realm->max_life); 816 #endif 817 et.endtime = t; 818 if(f.renewable_ok && et.endtime < *b->till){ 819 f.renewable = 1; 820 if(b->rtime == NULL){ 821 ALLOC(b->rtime); 822 *b->rtime = 0; 823 } 824 if(*b->rtime < *b->till) 825 *b->rtime = *b->till; 826 } 827 if(f.renewable && b->rtime){ 828 t = *b->rtime; 829 if(t == 0) 830 t = MAX_TIME; 831 if(client->max_renew) 832 t = start + min(t - start, *client->max_renew); 833 if(server->max_renew) 834 t = start + min(t - start, *server->max_renew); 835 #if 0 836 t = min(t, start + realm->max_renew); 837 #endif 838 ALLOC(et.renew_till); 839 *et.renew_till = t; 840 et.flags.renewable = 1; 841 } 842 } 843 844 if (f.request_anonymous) 845 et.flags.anonymous = 1; 846 847 if(b->addresses){ 848 ALLOC(et.caddr); 849 copy_HostAddresses(b->addresses, et.caddr); 850 } 851 852 et.transited.tr_type = DOMAIN_X500_COMPRESS; 853 krb5_data_zero(&et.transited.contents); 854 855 copy_EncryptionKey(&et.key, &ek.key); 856 857 /* The MIT ASN.1 library (obviously) doesn't tell lengths encoded 858 * as 0 and as 0x80 (meaning indefinite length) apart, and is thus 859 * incapable of correctly decoding SEQUENCE OF's of zero length. 860 * 861 * To fix this, always send at least one no-op last_req 862 * 863 * If there's a pw_end or valid_end we will use that, 864 * otherwise just a dummy lr. 865 */ 866 ek.last_req.val = malloc(2 * sizeof(*ek.last_req.val)); 867 ek.last_req.len = 0; 868 if (client->pw_end 869 && (kdc_warn_pwexpire == 0 870 || kdc_time + kdc_warn_pwexpire <= *client->pw_end)) { 871 ek.last_req.val[ek.last_req.len].lr_type = LR_PW_EXPTIME; 872 ek.last_req.val[ek.last_req.len].lr_value = *client->pw_end; 873 ++ek.last_req.len; 874 } 875 if (client->valid_end) { 876 ek.last_req.val[ek.last_req.len].lr_type = LR_ACCT_EXPTIME; 877 ek.last_req.val[ek.last_req.len].lr_value = *client->valid_end; 878 ++ek.last_req.len; 879 } 880 if (ek.last_req.len == 0) { 881 ek.last_req.val[ek.last_req.len].lr_type = LR_NONE; 882 ek.last_req.val[ek.last_req.len].lr_value = 0; 883 ++ek.last_req.len; 884 } 885 ek.nonce = b->nonce; 886 if (client->valid_end || client->pw_end) { 887 ALLOC(ek.key_expiration); 888 if (client->valid_end) { 889 if (client->pw_end) 890 *ek.key_expiration = min(*client->valid_end, *client->pw_end); 891 else 892 *ek.key_expiration = *client->valid_end; 893 } else 894 *ek.key_expiration = *client->pw_end; 895 } else 896 ek.key_expiration = NULL; 897 ek.flags = et.flags; 898 ek.authtime = et.authtime; 899 if (et.starttime) { 900 ALLOC(ek.starttime); 901 *ek.starttime = *et.starttime; 902 } 903 ek.endtime = et.endtime; 904 if (et.renew_till) { 905 ALLOC(ek.renew_till); 906 *ek.renew_till = *et.renew_till; 907 } 908 copy_Realm(&rep.ticket.realm, &ek.srealm); 909 copy_PrincipalName(&rep.ticket.sname, &ek.sname); 910 if(et.caddr){ 911 ALLOC(ek.caddr); 912 copy_HostAddresses(et.caddr, ek.caddr); 913 } 914 915 set_salt_padata (&rep.padata, ckey->salt); 916 ret = encode_reply(&rep, &et, &ek, setype, server->kvno, &skey->key, 917 client->kvno, &ckey->key, &e_text, reply); 918 free_EncTicketPart(&et); 919 free_EncKDCRepPart(&ek); 920 out: 921 free_AS_REP(&rep); 922 if(ret){ 923 krb5_mk_error(context, 924 ret, 925 e_text, 926 NULL, 927 client_princ, 928 server_princ, 929 NULL, 930 NULL, 931 reply); 932 ret = 0; 933 } 934 out2: 935 if (client_princ) 936 krb5_free_principal(context, client_princ); 937 free(client_name); 938 if (server_princ) 939 krb5_free_principal(context, server_princ); 940 free(server_name); 941 if(client) 942 free_ent(client); 943 if(server) 944 free_ent(server); 945 return ret; 946 } 947 948 949 static krb5_error_code 950 check_tgs_flags(KDC_REQ_BODY *b, EncTicketPart *tgt, EncTicketPart *et) 951 { 952 KDCOptions f = b->kdc_options; 953 954 if(f.validate){ 955 if(!tgt->flags.invalid || tgt->starttime == NULL){ 956 kdc_log(0, "Bad request to validate ticket"); 957 return KRB5KDC_ERR_BADOPTION; 958 } 959 if(*tgt->starttime > kdc_time){ 960 kdc_log(0, "Early request to validate ticket"); 961 return KRB5KRB_AP_ERR_TKT_NYV; 962 } 963 /* XXX tkt = tgt */ 964 et->flags.invalid = 0; 965 }else if(tgt->flags.invalid){ 966 kdc_log(0, "Ticket-granting ticket has INVALID flag set"); 967 return KRB5KRB_AP_ERR_TKT_INVALID; 968 } 969 970 if(f.forwardable){ 971 if(!tgt->flags.forwardable){ 972 kdc_log(0, "Bad request for forwardable ticket"); 973 return KRB5KDC_ERR_BADOPTION; 974 } 975 et->flags.forwardable = 1; 976 } 977 if(f.forwarded){ 978 if(!tgt->flags.forwardable){ 979 kdc_log(0, "Request to forward non-forwardable ticket"); 980 return KRB5KDC_ERR_BADOPTION; 981 } 982 et->flags.forwarded = 1; 983 et->caddr = b->addresses; 984 } 985 if(tgt->flags.forwarded) 986 et->flags.forwarded = 1; 987 988 if(f.proxiable){ 989 if(!tgt->flags.proxiable){ 990 kdc_log(0, "Bad request for proxiable ticket"); 991 return KRB5KDC_ERR_BADOPTION; 992 } 993 et->flags.proxiable = 1; 994 } 995 if(f.proxy){ 996 if(!tgt->flags.proxiable){ 997 kdc_log(0, "Request to proxy non-proxiable ticket"); 998 return KRB5KDC_ERR_BADOPTION; 999 } 1000 et->flags.proxy = 1; 1001 et->caddr = b->addresses; 1002 } 1003 if(tgt->flags.proxy) 1004 et->flags.proxy = 1; 1005 1006 if(f.allow_postdate){ 1007 if(!tgt->flags.may_postdate){ 1008 kdc_log(0, "Bad request for post-datable ticket"); 1009 return KRB5KDC_ERR_BADOPTION; 1010 } 1011 et->flags.may_postdate = 1; 1012 } 1013 if(f.postdated){ 1014 if(!tgt->flags.may_postdate){ 1015 kdc_log(0, "Bad request for postdated ticket"); 1016 return KRB5KDC_ERR_BADOPTION; 1017 } 1018 if(b->from) 1019 *et->starttime = *b->from; 1020 et->flags.postdated = 1; 1021 et->flags.invalid = 1; 1022 }else if(b->from && *b->from > kdc_time + context->max_skew){ 1023 kdc_log(0, "Ticket cannot be postdated"); 1024 return KRB5KDC_ERR_CANNOT_POSTDATE; 1025 } 1026 1027 if(f.renewable){ 1028 if(!tgt->flags.renewable){ 1029 kdc_log(0, "Bad request for renewable ticket"); 1030 return KRB5KDC_ERR_BADOPTION; 1031 } 1032 et->flags.renewable = 1; 1033 ALLOC(et->renew_till); 1034 fix_time(&b->rtime); 1035 *et->renew_till = *b->rtime; 1036 } 1037 if(f.renew){ 1038 time_t old_life; 1039 if(!tgt->flags.renewable || tgt->renew_till == NULL){ 1040 kdc_log(0, "Request to renew non-renewable ticket"); 1041 return KRB5KDC_ERR_BADOPTION; 1042 } 1043 old_life = tgt->endtime; 1044 if(tgt->starttime) 1045 old_life -= *tgt->starttime; 1046 else 1047 old_life -= tgt->authtime; 1048 et->endtime = *et->starttime + old_life; 1049 if (et->renew_till != NULL) 1050 et->endtime = min(*et->renew_till, et->endtime); 1051 } 1052 1053 /* checks for excess flags */ 1054 if(f.request_anonymous && !allow_anonymous){ 1055 kdc_log(0, "Request for anonymous ticket"); 1056 return KRB5KDC_ERR_BADOPTION; 1057 } 1058 return 0; 1059 } 1060 1061 static krb5_error_code 1062 fix_transited_encoding(krb5_boolean check_policy, 1063 TransitedEncoding *tr, 1064 EncTicketPart *et, 1065 const char *client_realm, 1066 const char *server_realm, 1067 const char *tgt_realm) 1068 { 1069 krb5_error_code ret = 0; 1070 char **realms, **tmp; 1071 int num_realms; 1072 int i; 1073 1074 if(tr->tr_type != DOMAIN_X500_COMPRESS) { 1075 kdc_log(0, "Unknown transited type: %u", tr->tr_type); 1076 return KRB5KDC_ERR_TRTYPE_NOSUPP; 1077 } 1078 1079 ret = krb5_domain_x500_decode(context, 1080 tr->contents, 1081 &realms, 1082 &num_realms, 1083 client_realm, 1084 server_realm); 1085 if(ret){ 1086 krb5_warn(context, ret, "Decoding transited encoding"); 1087 return ret; 1088 } 1089 if(strcmp(client_realm, tgt_realm) && strcmp(server_realm, tgt_realm)) { 1090 /* not us, so add the previous realm to transited set */ 1091 if (num_realms < 0 || num_realms + 1 > UINT_MAX/sizeof(*realms)) { 1092 ret = ERANGE; 1093 goto free_realms; 1094 } 1095 tmp = realloc(realms, (num_realms + 1) * sizeof(*realms)); 1096 if(tmp == NULL){ 1097 ret = ENOMEM; 1098 goto free_realms; 1099 } 1100 realms = tmp; 1101 realms[num_realms] = strdup(tgt_realm); 1102 if(realms[num_realms] == NULL){ 1103 ret = ENOMEM; 1104 goto free_realms; 1105 } 1106 num_realms++; 1107 } 1108 if(num_realms == 0) { 1109 if(strcmp(client_realm, server_realm)) 1110 kdc_log(0, "cross-realm %s -> %s", client_realm, server_realm); 1111 } else { 1112 size_t l = 0; 1113 char *rs; 1114 for(i = 0; i < num_realms; i++) 1115 l += strlen(realms[i]) + 2; 1116 rs = malloc(l); 1117 if(rs != NULL) { 1118 *rs = '\0'; 1119 for(i = 0; i < num_realms; i++) { 1120 if(i > 0) 1121 strlcat(rs, ", ", l); 1122 strlcat(rs, realms[i], l); 1123 } 1124 kdc_log(0, "cross-realm %s -> %s via [%s]", client_realm, server_realm, rs); 1125 free(rs); 1126 } 1127 } 1128 if(check_policy) { 1129 ret = krb5_check_transited(context, client_realm, 1130 server_realm, 1131 realms, num_realms, NULL); 1132 if(ret) { 1133 krb5_warn(context, ret, "cross-realm %s -> %s", 1134 client_realm, server_realm); 1135 goto free_realms; 1136 } 1137 et->flags.transited_policy_checked = 1; 1138 } 1139 et->transited.tr_type = DOMAIN_X500_COMPRESS; 1140 ret = krb5_domain_x500_encode(realms, num_realms, &et->transited.contents); 1141 if(ret) 1142 krb5_warn(context, ret, "Encoding transited encoding"); 1143 free_realms: 1144 for(i = 0; i < num_realms; i++) 1145 free(realms[i]); 1146 free(realms); 1147 return ret; 1148 } 1149 1150 1151 static krb5_error_code 1152 tgs_make_reply(KDC_REQ_BODY *b, 1153 EncTicketPart *tgt, 1154 EncTicketPart *adtkt, 1155 AuthorizationData *auth_data, 1156 hdb_entry *server, 1157 hdb_entry *client, 1158 krb5_principal client_principal, 1159 hdb_entry *krbtgt, 1160 krb5_enctype cetype, 1161 const char **e_text, 1162 krb5_data *reply) 1163 { 1164 KDC_REP rep; 1165 EncKDCRepPart ek; 1166 EncTicketPart et; 1167 KDCOptions f = b->kdc_options; 1168 krb5_error_code ret; 1169 krb5_enctype etype; 1170 Key *skey; 1171 EncryptionKey *ekey; 1172 1173 if(adtkt) { 1174 int i; 1175 krb5_keytype kt; 1176 ekey = &adtkt->key; 1177 for(i = 0; i < b->etype.len; i++){ 1178 ret = krb5_enctype_to_keytype(context, b->etype.val[i], &kt); 1179 if(ret) 1180 continue; 1181 if(adtkt->key.keytype == kt) 1182 break; 1183 } 1184 if(i == b->etype.len) 1185 return KRB5KDC_ERR_ETYPE_NOSUPP; 1186 etype = b->etype.val[i]; 1187 }else{ 1188 ret = find_keys(NULL, server, NULL, NULL, &skey, &etype, 1189 b->etype.val, b->etype.len); 1190 if(ret) { 1191 kdc_log(0, "Server has no support for etypes"); 1192 return ret; 1193 } 1194 ekey = &skey->key; 1195 } 1196 1197 memset(&rep, 0, sizeof(rep)); 1198 memset(&et, 0, sizeof(et)); 1199 memset(&ek, 0, sizeof(ek)); 1200 1201 rep.pvno = 5; 1202 rep.msg_type = krb_tgs_rep; 1203 1204 et.authtime = tgt->authtime; 1205 fix_time(&b->till); 1206 et.endtime = min(tgt->endtime, *b->till); 1207 ALLOC(et.starttime); 1208 *et.starttime = kdc_time; 1209 1210 ret = check_tgs_flags(b, tgt, &et); 1211 if(ret) 1212 goto out; 1213 1214 /* We should check the transited encoding if: 1215 1) the request doesn't ask not to be checked 1216 2) globally enforcing a check 1217 3) principal requires checking 1218 4) we allow non-check per-principal, but principal isn't marked as allowing this 1219 5) we don't globally allow this 1220 */ 1221 1222 #define GLOBAL_FORCE_TRANSITED_CHECK (trpolicy == TRPOLICY_ALWAYS_CHECK) 1223 #define GLOBAL_ALLOW_PER_PRINCIPAL (trpolicy == TRPOLICY_ALLOW_PER_PRINCIPAL) 1224 #define GLOBAL_ALLOW_DISABLE_TRANSITED_CHECK (trpolicy == TRPOLICY_ALWAYS_HONOUR_REQUEST) 1225 /* these will consult the database in future release */ 1226 #define PRINCIPAL_FORCE_TRANSITED_CHECK(P) 0 1227 #define PRINCIPAL_ALLOW_DISABLE_TRANSITED_CHECK(P) 0 1228 1229 ret = fix_transited_encoding(!f.disable_transited_check || 1230 GLOBAL_FORCE_TRANSITED_CHECK || 1231 PRINCIPAL_FORCE_TRANSITED_CHECK(server) || 1232 !((GLOBAL_ALLOW_PER_PRINCIPAL && 1233 PRINCIPAL_ALLOW_DISABLE_TRANSITED_CHECK(server)) || 1234 GLOBAL_ALLOW_DISABLE_TRANSITED_CHECK), 1235 &tgt->transited, &et, 1236 *krb5_princ_realm(context, client_principal), 1237 *krb5_princ_realm(context, server->principal), 1238 *krb5_princ_realm(context, krbtgt->principal)); 1239 if(ret) 1240 goto out; 1241 1242 copy_Realm(krb5_princ_realm(context, server->principal), 1243 &rep.ticket.realm); 1244 krb5_principal2principalname(&rep.ticket.sname, server->principal); 1245 copy_Realm(&tgt->crealm, &rep.crealm); 1246 if (f.request_anonymous) 1247 make_anonymous_principalname (&tgt->cname); 1248 else 1249 copy_PrincipalName(&tgt->cname, &rep.cname); 1250 rep.ticket.tkt_vno = 5; 1251 1252 ek.caddr = et.caddr; 1253 if(et.caddr == NULL) 1254 et.caddr = tgt->caddr; 1255 1256 { 1257 time_t life; 1258 life = et.endtime - *et.starttime; 1259 if(client && client->max_life) 1260 life = min(life, *client->max_life); 1261 if(server->max_life) 1262 life = min(life, *server->max_life); 1263 et.endtime = *et.starttime + life; 1264 } 1265 if(f.renewable_ok && tgt->flags.renewable && 1266 et.renew_till == NULL && et.endtime < *b->till){ 1267 et.flags.renewable = 1; 1268 ALLOC(et.renew_till); 1269 *et.renew_till = *b->till; 1270 } 1271 if(et.renew_till){ 1272 time_t renew; 1273 renew = *et.renew_till - et.authtime; 1274 if(client && client->max_renew) 1275 renew = min(renew, *client->max_renew); 1276 if(server->max_renew) 1277 renew = min(renew, *server->max_renew); 1278 *et.renew_till = et.authtime + renew; 1279 } 1280 1281 if(et.renew_till){ 1282 *et.renew_till = min(*et.renew_till, *tgt->renew_till); 1283 *et.starttime = min(*et.starttime, *et.renew_till); 1284 et.endtime = min(et.endtime, *et.renew_till); 1285 } 1286 1287 *et.starttime = min(*et.starttime, et.endtime); 1288 1289 if(*et.starttime == et.endtime){ 1290 ret = KRB5KDC_ERR_NEVER_VALID; 1291 goto out; 1292 } 1293 if(et.renew_till && et.endtime == *et.renew_till){ 1294 free(et.renew_till); 1295 et.renew_till = NULL; 1296 et.flags.renewable = 0; 1297 } 1298 1299 et.flags.pre_authent = tgt->flags.pre_authent; 1300 et.flags.hw_authent = tgt->flags.hw_authent; 1301 et.flags.anonymous = tgt->flags.anonymous; 1302 1303 /* XXX Check enc-authorization-data */ 1304 et.authorization_data = auth_data; 1305 1306 krb5_generate_random_keyblock(context, etype, &et.key); 1307 et.crealm = tgt->crealm; 1308 et.cname = tgt->cname; 1309 1310 ek.key = et.key; 1311 /* MIT must have at least one last_req */ 1312 ek.last_req.len = 1; 1313 ek.last_req.val = calloc(1, sizeof(*ek.last_req.val)); 1314 ek.nonce = b->nonce; 1315 ek.flags = et.flags; 1316 ek.authtime = et.authtime; 1317 ek.starttime = et.starttime; 1318 ek.endtime = et.endtime; 1319 ek.renew_till = et.renew_till; 1320 ek.srealm = rep.ticket.realm; 1321 ek.sname = rep.ticket.sname; 1322 1323 /* It is somewhat unclear where the etype in the following 1324 encryption should come from. What we have is a session 1325 key in the passed tgt, and a list of preferred etypes 1326 *for the new ticket*. Should we pick the best possible 1327 etype, given the keytype in the tgt, or should we look 1328 at the etype list here as well? What if the tgt 1329 session key is DES3 and we want a ticket with a (say) 1330 CAST session key. Should the DES3 etype be added to the 1331 etype list, even if we don't want a session key with 1332 DES3? */ 1333 ret = encode_reply(&rep, &et, &ek, etype, adtkt ? 0 : server->kvno, ekey, 1334 0, &tgt->key, e_text, reply); 1335 out: 1336 free_TGS_REP(&rep); 1337 free_TransitedEncoding(&et.transited); 1338 if(et.starttime) 1339 free(et.starttime); 1340 if(et.renew_till) 1341 free(et.renew_till); 1342 free_LastReq(&ek.last_req); 1343 memset(et.key.keyvalue.data, 0, et.key.keyvalue.length); 1344 free_EncryptionKey(&et.key); 1345 return ret; 1346 } 1347 1348 static krb5_error_code 1349 tgs_check_authenticator(krb5_auth_context ac, 1350 KDC_REQ_BODY *b, 1351 const char **e_text, 1352 krb5_keyblock *key) 1353 { 1354 krb5_authenticator auth; 1355 size_t len; 1356 unsigned char *buf; 1357 size_t buf_size; 1358 krb5_error_code ret; 1359 krb5_crypto crypto; 1360 1361 krb5_auth_con_getauthenticator(context, ac, &auth); 1362 if(auth->cksum == NULL){ 1363 kdc_log(0, "No authenticator in request"); 1364 ret = KRB5KRB_AP_ERR_INAPP_CKSUM; 1365 goto out; 1366 } 1367 /* 1368 * according to RFC1510 it doesn't need to be keyed, 1369 * but according to the latest draft it needs to. 1370 */ 1371 if ( 1372 #if 0 1373 !krb5_checksum_is_keyed(context, auth->cksum->cksumtype) 1374 || 1375 #endif 1376 !krb5_checksum_is_collision_proof(context, auth->cksum->cksumtype)) { 1377 kdc_log(0, "Bad checksum type in authenticator: %d", 1378 auth->cksum->cksumtype); 1379 ret = KRB5KRB_AP_ERR_INAPP_CKSUM; 1380 goto out; 1381 } 1382 1383 /* XXX should not re-encode this */ 1384 ASN1_MALLOC_ENCODE(KDC_REQ_BODY, buf, buf_size, b, &len, ret); 1385 if(ret){ 1386 kdc_log(0, "Failed to encode KDC-REQ-BODY: %s", 1387 krb5_get_err_text(context, ret)); 1388 goto out; 1389 } 1390 if(buf_size != len) { 1391 free(buf); 1392 kdc_log(0, "Internal error in ASN.1 encoder"); 1393 *e_text = "KDC internal error"; 1394 ret = KRB5KRB_ERR_GENERIC; 1395 goto out; 1396 } 1397 ret = krb5_crypto_init(context, key, 0, &crypto); 1398 if (ret) { 1399 free(buf); 1400 kdc_log(0, "krb5_crypto_init failed: %s", 1401 krb5_get_err_text(context, ret)); 1402 goto out; 1403 } 1404 ret = krb5_verify_checksum(context, 1405 crypto, 1406 KRB5_KU_TGS_REQ_AUTH_CKSUM, 1407 buf, 1408 len, 1409 auth->cksum); 1410 free(buf); 1411 krb5_crypto_destroy(context, crypto); 1412 if(ret){ 1413 kdc_log(0, "Failed to verify checksum: %s", 1414 krb5_get_err_text(context, ret)); 1415 } 1416 out: 1417 free_Authenticator(auth); 1418 free(auth); 1419 return ret; 1420 } 1421 1422 /* 1423 * return the realm of a krbtgt-ticket or NULL 1424 */ 1425 1426 static Realm 1427 get_krbtgt_realm(const PrincipalName *p) 1428 { 1429 if(p->name_string.len == 2 1430 && strcmp(p->name_string.val[0], KRB5_TGS_NAME) == 0) 1431 return p->name_string.val[1]; 1432 else 1433 return NULL; 1434 } 1435 1436 static Realm 1437 find_rpath(Realm crealm, Realm srealm) 1438 { 1439 const char *new_realm = krb5_config_get_string(context, 1440 NULL, 1441 "capaths", 1442 crealm, 1443 srealm, 1444 NULL); 1445 return (Realm)new_realm; 1446 } 1447 1448 1449 static krb5_boolean 1450 need_referral(krb5_principal server, krb5_realm **realms) 1451 { 1452 if(server->name.name_type != KRB5_NT_SRV_INST || 1453 server->name.name_string.len != 2) 1454 return FALSE; 1455 1456 return krb5_get_host_realm_int(context, server->name.name_string.val[1], 1457 FALSE, realms) == 0; 1458 } 1459 1460 static krb5_error_code 1461 tgs_rep2(KDC_REQ_BODY *b, 1462 PA_DATA *tgs_req, 1463 krb5_data *reply, 1464 const char *from, 1465 const struct sockaddr *from_addr, 1466 time_t **csec, 1467 int **cusec) 1468 { 1469 krb5_ap_req ap_req; 1470 krb5_error_code ret; 1471 krb5_principal princ; 1472 krb5_auth_context ac = NULL; 1473 krb5_ticket *ticket = NULL; 1474 krb5_flags ap_req_options; 1475 krb5_flags verify_ap_req_flags; 1476 const char *e_text = NULL; 1477 krb5_crypto crypto; 1478 1479 hdb_entry *krbtgt = NULL; 1480 EncTicketPart *tgt; 1481 Key *tkey; 1482 krb5_enctype cetype; 1483 krb5_principal cp = NULL; 1484 krb5_principal sp = NULL; 1485 AuthorizationData *auth_data = NULL; 1486 1487 *csec = NULL; 1488 *cusec = NULL; 1489 1490 memset(&ap_req, 0, sizeof(ap_req)); 1491 ret = krb5_decode_ap_req(context, &tgs_req->padata_value, &ap_req); 1492 if(ret){ 1493 kdc_log(0, "Failed to decode AP-REQ: %s", 1494 krb5_get_err_text(context, ret)); 1495 goto out2; 1496 } 1497 1498 if(!get_krbtgt_realm(&ap_req.ticket.sname)){ 1499 /* XXX check for ticket.sname == req.sname */ 1500 kdc_log(0, "PA-DATA is not a ticket-granting ticket"); 1501 ret = KRB5KDC_ERR_POLICY; /* ? */ 1502 goto out2; 1503 } 1504 1505 principalname2krb5_principal(&princ, 1506 ap_req.ticket.sname, 1507 ap_req.ticket.realm); 1508 1509 ret = db_fetch(princ, &krbtgt); 1510 1511 if(ret) { 1512 char *p; 1513 krb5_unparse_name(context, princ, &p); 1514 krb5_free_principal(context, princ); 1515 kdc_log(0, "Ticket-granting ticket not found in database: %s: %s", 1516 p, krb5_get_err_text(context, ret)); 1517 free(p); 1518 ret = KRB5KRB_AP_ERR_NOT_US; 1519 goto out2; 1520 } 1521 1522 if(ap_req.ticket.enc_part.kvno && 1523 *ap_req.ticket.enc_part.kvno != krbtgt->kvno){ 1524 char *p; 1525 1526 krb5_unparse_name (context, princ, &p); 1527 krb5_free_principal(context, princ); 1528 kdc_log(0, "Ticket kvno = %d, DB kvno = %d (%s)", 1529 *ap_req.ticket.enc_part.kvno, 1530 krbtgt->kvno, 1531 p); 1532 free (p); 1533 ret = KRB5KRB_AP_ERR_BADKEYVER; 1534 goto out2; 1535 } 1536 1537 ret = hdb_enctype2key(context, krbtgt, ap_req.ticket.enc_part.etype, &tkey); 1538 if(ret){ 1539 char *str; 1540 krb5_enctype_to_string(context, ap_req.ticket.enc_part.etype, &str); 1541 kdc_log(0, "No server key found for %s", str); 1542 free(str); 1543 ret = KRB5KRB_AP_ERR_BADKEYVER; 1544 goto out2; 1545 } 1546 1547 if (b->kdc_options.validate) 1548 verify_ap_req_flags = KRB5_VERIFY_AP_REQ_IGNORE_INVALID; 1549 else 1550 verify_ap_req_flags = 0; 1551 1552 ret = krb5_verify_ap_req2(context, 1553 &ac, 1554 &ap_req, 1555 princ, 1556 &tkey->key, 1557 verify_ap_req_flags, 1558 &ap_req_options, 1559 &ticket, 1560 KRB5_KU_TGS_REQ_AUTH); 1561 1562 krb5_free_principal(context, princ); 1563 if(ret) { 1564 kdc_log(0, "Failed to verify AP-REQ: %s", 1565 krb5_get_err_text(context, ret)); 1566 goto out2; 1567 } 1568 1569 { 1570 krb5_authenticator auth; 1571 1572 ret = krb5_auth_con_getauthenticator(context, ac, &auth); 1573 if (ret == 0) { 1574 *csec = malloc(sizeof(**csec)); 1575 if (*csec == NULL) { 1576 krb5_free_authenticator(context, &auth); 1577 kdc_log(0, "malloc failed"); 1578 goto out2; 1579 } 1580 **csec = auth->ctime; 1581 *cusec = malloc(sizeof(**cusec)); 1582 if (*cusec == NULL) { 1583 krb5_free_authenticator(context, &auth); 1584 kdc_log(0, "malloc failed"); 1585 goto out2; 1586 } 1587 **csec = auth->cusec; 1588 krb5_free_authenticator(context, &auth); 1589 } 1590 } 1591 1592 cetype = ap_req.authenticator.etype; 1593 1594 tgt = &ticket->ticket; 1595 1596 ret = tgs_check_authenticator(ac, b, &e_text, &tgt->key); 1597 1598 if (b->enc_authorization_data) { 1599 krb5_keyblock *subkey; 1600 krb5_data ad; 1601 ret = krb5_auth_con_getremotesubkey(context, 1602 ac, 1603 &subkey); 1604 if(ret){ 1605 krb5_auth_con_free(context, ac); 1606 kdc_log(0, "Failed to get remote subkey: %s", 1607 krb5_get_err_text(context, ret)); 1608 goto out2; 1609 } 1610 if(subkey == NULL){ 1611 ret = krb5_auth_con_getkey(context, ac, &subkey); 1612 if(ret) { 1613 krb5_auth_con_free(context, ac); 1614 kdc_log(0, "Failed to get session key: %s", 1615 krb5_get_err_text(context, ret)); 1616 goto out2; 1617 } 1618 } 1619 if(subkey == NULL){ 1620 krb5_auth_con_free(context, ac); 1621 kdc_log(0, "Failed to get key for enc-authorization-data"); 1622 ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */ 1623 goto out2; 1624 } 1625 ret = krb5_crypto_init(context, subkey, 0, &crypto); 1626 if (ret) { 1627 krb5_auth_con_free(context, ac); 1628 kdc_log(0, "krb5_crypto_init failed: %s", 1629 krb5_get_err_text(context, ret)); 1630 goto out2; 1631 } 1632 ret = krb5_decrypt_EncryptedData (context, 1633 crypto, 1634 KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY, 1635 b->enc_authorization_data, 1636 &ad); 1637 krb5_crypto_destroy(context, crypto); 1638 if(ret){ 1639 krb5_auth_con_free(context, ac); 1640 kdc_log(0, "Failed to decrypt enc-authorization-data"); 1641 ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */ 1642 goto out2; 1643 } 1644 krb5_free_keyblock(context, subkey); 1645 ALLOC(auth_data); 1646 ret = decode_AuthorizationData(ad.data, ad.length, auth_data, NULL); 1647 if(ret){ 1648 krb5_auth_con_free(context, ac); 1649 free(auth_data); 1650 auth_data = NULL; 1651 kdc_log(0, "Failed to decode authorization data"); 1652 ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */ 1653 goto out2; 1654 } 1655 } 1656 1657 krb5_auth_con_free(context, ac); 1658 1659 if(ret){ 1660 kdc_log(0, "Failed to verify authenticator: %s", 1661 krb5_get_err_text(context, ret)); 1662 goto out2; 1663 } 1664 1665 { 1666 PrincipalName *s; 1667 Realm r; 1668 char *spn = NULL, *cpn = NULL; 1669 hdb_entry *server = NULL, *client = NULL; 1670 int loop = 0; 1671 EncTicketPart adtkt; 1672 char opt_str[128]; 1673 1674 s = b->sname; 1675 r = b->realm; 1676 if(b->kdc_options.enc_tkt_in_skey){ 1677 Ticket *t; 1678 hdb_entry *uu; 1679 krb5_principal p; 1680 Key *tkey; 1681 1682 if(b->additional_tickets == NULL || 1683 b->additional_tickets->len == 0){ 1684 ret = KRB5KDC_ERR_BADOPTION; /* ? */ 1685 kdc_log(0, "No second ticket present in request"); 1686 goto out; 1687 } 1688 t = &b->additional_tickets->val[0]; 1689 if(!get_krbtgt_realm(&t->sname)){ 1690 kdc_log(0, "Additional ticket is not a ticket-granting ticket"); 1691 ret = KRB5KDC_ERR_POLICY; 1692 goto out2; 1693 } 1694 principalname2krb5_principal(&p, t->sname, t->realm); 1695 ret = db_fetch(p, &uu); 1696 krb5_free_principal(context, p); 1697 if(ret){ 1698 if (ret == HDB_ERR_NOENTRY) 1699 ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN; 1700 goto out; 1701 } 1702 ret = hdb_enctype2key(context, uu, t->enc_part.etype, &tkey); 1703 if(ret){ 1704 ret = KRB5KDC_ERR_ETYPE_NOSUPP; /* XXX */ 1705 goto out; 1706 } 1707 ret = krb5_decrypt_ticket(context, t, &tkey->key, &adtkt, 0); 1708 1709 if(ret) 1710 goto out; 1711 s = &adtkt.cname; 1712 r = adtkt.crealm; 1713 } 1714 1715 principalname2krb5_principal(&sp, *s, r); 1716 krb5_unparse_name(context, sp, &spn); 1717 principalname2krb5_principal(&cp, tgt->cname, tgt->crealm); 1718 krb5_unparse_name(context, cp, &cpn); 1719 unparse_flags (KDCOptions2int(b->kdc_options), KDCOptions_units, 1720 opt_str, sizeof(opt_str)); 1721 if(*opt_str) 1722 kdc_log(0, "TGS-REQ %s from %s for %s [%s]", 1723 cpn, from, spn, opt_str); 1724 else 1725 kdc_log(0, "TGS-REQ %s from %s for %s", cpn, from, spn); 1726 server_lookup: 1727 ret = db_fetch(sp, &server); 1728 1729 if(ret){ 1730 Realm req_rlm, new_rlm; 1731 krb5_realm *realms; 1732 1733 if ((req_rlm = get_krbtgt_realm(&sp->name)) != NULL) { 1734 if(loop++ < 2) { 1735 new_rlm = find_rpath(tgt->crealm, req_rlm); 1736 if(new_rlm) { 1737 kdc_log(5, "krbtgt for realm %s not found, trying %s", 1738 req_rlm, new_rlm); 1739 krb5_free_principal(context, sp); 1740 free(spn); 1741 krb5_make_principal(context, &sp, r, 1742 KRB5_TGS_NAME, new_rlm, NULL); 1743 krb5_unparse_name(context, sp, &spn); 1744 goto server_lookup; 1745 } 1746 } 1747 } else if(need_referral(sp, &realms)) { 1748 if (strcmp(realms[0], sp->realm) != 0) { 1749 kdc_log(5, "returning a referral to realm %s for " 1750 "server %s that was not found", 1751 realms[0], spn); 1752 krb5_free_principal(context, sp); 1753 free(spn); 1754 krb5_make_principal(context, &sp, r, KRB5_TGS_NAME, 1755 realms[0], NULL); 1756 krb5_unparse_name(context, sp, &spn); 1757 krb5_free_host_realm(context, realms); 1758 goto server_lookup; 1759 } 1760 krb5_free_host_realm(context, realms); 1761 } 1762 kdc_log(0, "Server not found in database: %s: %s", spn, 1763 krb5_get_err_text(context, ret)); 1764 if (ret == HDB_ERR_NOENTRY) 1765 ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN; 1766 goto out; 1767 } 1768 1769 ret = db_fetch(cp, &client); 1770 if(ret) 1771 kdc_log(1, "Client not found in database: %s: %s", 1772 cpn, krb5_get_err_text(context, ret)); 1773 #if 0 1774 /* XXX check client only if same realm as krbtgt-instance */ 1775 if(ret){ 1776 kdc_log(0, "Client not found in database: %s: %s", 1777 cpn, krb5_get_err_text(context, ret)); 1778 if (ret == HDB_ERR_NOENTRY) 1779 ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN; 1780 goto out; 1781 } 1782 #endif 1783 1784 if(strcmp(krb5_principal_get_realm(context, sp), 1785 krb5_principal_get_comp_string(context, krbtgt->principal, 1)) != 0) { 1786 char *tpn; 1787 ret = krb5_unparse_name(context, krbtgt->principal, &tpn); 1788 kdc_log(0, "Request with wrong krbtgt: %s", (ret == 0) ? tpn : "<unknown>"); 1789 if(ret == 0) 1790 free(tpn); 1791 ret = KRB5KRB_AP_ERR_NOT_US; 1792 goto out; 1793 1794 } 1795 1796 ret = check_flags(client, cpn, server, spn, FALSE); 1797 if(ret) 1798 goto out; 1799 1800 if((b->kdc_options.validate || b->kdc_options.renew) && 1801 !krb5_principal_compare(context, 1802 krbtgt->principal, 1803 server->principal)){ 1804 kdc_log(0, "Inconsistent request."); 1805 ret = KRB5KDC_ERR_SERVER_NOMATCH; 1806 goto out; 1807 } 1808 1809 /* check for valid set of addresses */ 1810 if(!check_addresses(tgt->caddr, from_addr)) { 1811 ret = KRB5KRB_AP_ERR_BADADDR; 1812 kdc_log(0, "Request from wrong address"); 1813 goto out; 1814 } 1815 1816 ret = tgs_make_reply(b, 1817 tgt, 1818 b->kdc_options.enc_tkt_in_skey ? &adtkt : NULL, 1819 auth_data, 1820 server, 1821 client, 1822 cp, 1823 krbtgt, 1824 cetype, 1825 &e_text, 1826 reply); 1827 1828 out: 1829 free(spn); 1830 free(cpn); 1831 1832 if(server) 1833 free_ent(server); 1834 if(client) 1835 free_ent(client); 1836 } 1837 out2: 1838 if(ret) { 1839 krb5_mk_error(context, 1840 ret, 1841 e_text, 1842 NULL, 1843 cp, 1844 sp, 1845 NULL, 1846 NULL, 1847 reply); 1848 free(*csec); 1849 free(*cusec); 1850 *csec = NULL; 1851 *cusec = NULL; 1852 } 1853 krb5_free_principal(context, cp); 1854 krb5_free_principal(context, sp); 1855 if (ticket) { 1856 krb5_free_ticket(context, ticket); 1857 free(ticket); 1858 } 1859 free_AP_REQ(&ap_req); 1860 if(auth_data){ 1861 free_AuthorizationData(auth_data); 1862 free(auth_data); 1863 } 1864 1865 if(krbtgt) 1866 free_ent(krbtgt); 1867 1868 return ret; 1869 } 1870 1871 1872 krb5_error_code 1873 tgs_rep(KDC_REQ *req, 1874 krb5_data *data, 1875 const char *from, 1876 struct sockaddr *from_addr) 1877 { 1878 krb5_error_code ret; 1879 int i = 0; 1880 PA_DATA *tgs_req = NULL; 1881 time_t *csec = NULL; 1882 int *cusec = NULL; 1883 1884 if(req->padata == NULL){ 1885 ret = KRB5KDC_ERR_PREAUTH_REQUIRED; /* XXX ??? */ 1886 kdc_log(0, "TGS-REQ from %s without PA-DATA", from); 1887 goto out; 1888 } 1889 1890 tgs_req = find_padata(req, &i, KRB5_PADATA_TGS_REQ); 1891 1892 if(tgs_req == NULL){ 1893 ret = KRB5KDC_ERR_PADATA_TYPE_NOSUPP; 1894 1895 kdc_log(0, "TGS-REQ from %s without PA-TGS-REQ", from); 1896 goto out; 1897 } 1898 ret = tgs_rep2(&req->req_body, tgs_req, data, from, from_addr, 1899 &csec, &cusec); 1900 out: 1901 if(ret && data->data == NULL){ 1902 krb5_mk_error(context, 1903 ret, 1904 NULL, 1905 NULL, 1906 NULL, 1907 NULL, 1908 csec, 1909 cusec, 1910 data); 1911 } 1912 free(csec); 1913 free(cusec); 1914 return 0; 1915 } 1916