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