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