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