1 /* $NetBSD: kerberos5.c,v 1.20 2014/04/26 22:10:40 joerg Exp $ */ 2 3 /*- 4 * Copyright (c) 1991, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the University nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 /* 33 * Copyright (C) 1990 by the Massachusetts Institute of Technology 34 * 35 * Export of this software from the United States of America may 36 * require a specific license from the United States Government. 37 * It is the responsibility of any person or organization contemplating 38 * export to obtain such a license before exporting. 39 * 40 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 41 * distribute this software and its documentation for any purpose and 42 * without fee is hereby granted, provided that the above copyright 43 * notice appear in all copies and that both that copyright notice and 44 * this permission notice appear in supporting documentation, and that 45 * the name of M.I.T. not be used in advertising or publicity pertaining 46 * to distribution of the software without specific, written prior 47 * permission. M.I.T. makes no representations about the suitability of 48 * this software for any purpose. It is provided "as is" without express 49 * or implied warranty. 50 */ 51 52 #ifdef KRB5 53 #include <arpa/telnet.h> 54 #include <stdio.h> 55 #include <stdlib.h> 56 #include <string.h> 57 #include <unistd.h> 58 #include <netdb.h> 59 #include <ctype.h> 60 #include <pwd.h> 61 #define Authenticator k5_Authenticator 62 #include <krb5.h> 63 #undef Authenticator 64 /* #include <roken.h> */ 65 66 #include "encrypt.h" 67 #include "auth.h" 68 #include "misc.h" 69 70 extern int net; 71 72 int forward_flags; /* Flags get set in telnet/main.c on -f and -F */ 73 int got_forwarded_creds;/* Tell telnetd to pass -F or -f to login. */ 74 75 int require_hwpreauth; 76 77 const char *get_krb5_err_text(krb5_context, krb5_error_code); 78 void kerberos5_forward(Authenticator *); 79 80 static unsigned char str_data[1024] = {IAC, SB, TELOPT_AUTHENTICATION, 0, 81 AUTHTYPE_KERBEROS_V5,}; 82 83 #define KRB_AUTH 0 /* Authentication data follows */ 84 #define KRB_REJECT 1 /* Rejected (reason might follow) */ 85 #define KRB_ACCEPT 2 /* Accepted */ 86 #define KRB_RESPONSE 3 /* Response for mutual auth. */ 87 88 #define KRB_FORWARD 4 /* Forwarded credentials follow */ 89 #define KRB_FORWARD_ACCEPT 5 /* Forwarded credentials accepted */ 90 #define KRB_FORWARD_REJECT 6 /* Forwarded credentials rejected */ 91 92 static krb5_data auth; 93 static krb5_ticket *ticket; 94 95 krb5_context telnet_context; 96 static krb5_auth_context auth_context; 97 98 static int 99 Data(Authenticator *ap, int type, const void *d, int c) 100 { 101 unsigned char *p = str_data + 4; 102 const unsigned char *cd = (const unsigned char *) d; 103 104 if (c == -1) 105 c = strlen(cd); 106 107 if (auth_debug_mode) { 108 printf("%s:%d: [%d] (%d)", 109 str_data[3] == TELQUAL_IS ? ">>>IS" : ">>>REPLY", 110 str_data[3], 111 type, c); 112 printd(d, c); 113 printf("\r\n"); 114 } 115 *p++ = ap->type; 116 *p++ = ap->way; 117 *p++ = type; 118 while (c-- > 0) { 119 if ((*p++ = *cd++) == IAC) 120 *p++ = IAC; 121 } 122 *p++ = IAC; 123 *p++ = SE; 124 if (str_data[3] == TELQUAL_IS) 125 printsub('>', &str_data[2], p - &str_data[2]); 126 return (telnet_net_write(str_data, p - str_data)); 127 } 128 129 const char * 130 get_krb5_err_text(krb5_context ctx, krb5_error_code ret) 131 { 132 static const char *str = NULL; 133 134 if (str) 135 krb5_free_error_message(ctx, str); 136 137 str = krb5_get_error_message(ctx, ret); 138 139 if (str != NULL) 140 return str; 141 142 return "unknown"; 143 } 144 145 int 146 kerberos5_init(Authenticator *ap, int server) 147 { 148 krb5_error_code ret; 149 150 if (telnet_context == 0) { 151 ret = krb5_init_context(&telnet_context); 152 if (ret) 153 return 0; 154 } 155 156 if (server) { 157 krb5_keytab kt; 158 krb5_kt_cursor cursor; 159 160 ret = krb5_kt_default(telnet_context, &kt); 161 if (ret) 162 return 0; 163 164 ret = krb5_kt_start_seq_get(telnet_context, kt, &cursor); 165 if (ret) { 166 krb5_kt_close(telnet_context, kt); 167 return 0; 168 } 169 krb5_kt_end_seq_get(telnet_context, kt, &cursor); 170 krb5_kt_close(telnet_context, kt); 171 172 str_data[3] = TELQUAL_REPLY; 173 } else 174 str_data[3] = TELQUAL_IS; 175 return (1); 176 } 177 178 int 179 kerberos5_send(Authenticator *ap) 180 { 181 krb5_error_code ret; 182 krb5_ccache ccache; 183 int ap_opts; 184 krb5_data cksum_data; 185 char foo[2]; 186 187 printf("[ Trying KERBEROS5 ... ]\r\n"); 188 189 if (!UserNameRequested) { 190 if (auth_debug_mode) { 191 printf("Kerberos V5: no user name supplied\r\n"); 192 } 193 return (0); 194 } 195 ret = krb5_cc_default(telnet_context, &ccache); 196 if (ret) { 197 if (auth_debug_mode) { 198 printf( 199 "Kerberos V5: could not get default ccache: %s\r\n", 200 get_krb5_err_text(telnet_context, ret)); 201 } 202 return (0); 203 } 204 if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) 205 ap_opts = AP_OPTS_MUTUAL_REQUIRED; 206 else 207 ap_opts = 0; 208 209 ap_opts |= AP_OPTS_USE_SUBKEY; 210 211 ret = krb5_auth_con_init(telnet_context, &auth_context); 212 if (ret) { 213 if (auth_debug_mode) { 214 printf( 215 "Kerberos V5: krb5_auth_con_init failed: %s\r\n", 216 get_krb5_err_text(telnet_context, ret)); 217 } 218 return (0); 219 } 220 ret = krb5_auth_con_setaddrs_from_fd(telnet_context, 221 auth_context, &net); 222 if (ret) { 223 if (auth_debug_mode) { 224 printf("Kerberos V5: " 225 "krb5_auth_con_setaddrs_from_fd failed: %s\r\n", 226 get_krb5_err_text(telnet_context, ret)); 227 } 228 return (0); 229 } 230 krb5_auth_con_setkeytype(telnet_context, auth_context, 231 ETYPE_DES_CBC_CRC); 232 233 foo[0] = ap->type; 234 foo[1] = ap->way; 235 236 cksum_data.length = sizeof(foo); 237 cksum_data.data = foo; 238 ret = krb5_mk_req(telnet_context, &auth_context, ap_opts, "host", 239 RemoteHostName, &cksum_data, ccache, &auth); 240 if (ret) { 241 if (1 || auth_debug_mode) { 242 printf("Kerberos V5: mk_req failed (%s)\r\n", 243 get_krb5_err_text(telnet_context, ret)); 244 } 245 return (0); 246 } 247 248 if (!auth_sendname((unsigned char *) UserNameRequested, 249 strlen(UserNameRequested))) { 250 if (auth_debug_mode) 251 printf("Not enough room for user name\r\n"); 252 return (0); 253 } 254 if (!Data(ap, KRB_AUTH, auth.data, auth.length)) { 255 if (auth_debug_mode) 256 printf("Not enough room for authentication data\r\n"); 257 return (0); 258 } 259 if (auth_debug_mode) { 260 printf("Sent Kerberos V5 credentials to server\r\n"); 261 } 262 return (1); 263 } 264 265 void 266 kerberos5_is(Authenticator * ap, unsigned char *data, int cnt) 267 { 268 krb5_error_code ret; 269 krb5_data outbuf; 270 krb5_keyblock *key_block; 271 char *name; 272 krb5_principal server; 273 int zero = 0; 274 275 if (cnt-- < 1) 276 return; 277 switch (*data++) { 278 case KRB_AUTH: 279 auth.data = (char *) data; 280 auth.length = cnt; 281 282 auth_context = NULL; 283 284 ret = krb5_auth_con_init(telnet_context, &auth_context); 285 if (ret) { 286 Data(ap, KRB_REJECT, "krb5_auth_con_init failed", -1); 287 auth_finished(ap, AUTH_REJECT); 288 if (auth_debug_mode) 289 printf("Kerberos V5: krb5_auth_con_init failed (%s)\r\n", 290 get_krb5_err_text(telnet_context, ret)); 291 return; 292 } 293 ret = krb5_auth_con_setaddrs_from_fd(telnet_context, 294 auth_context, &zero); 295 if (ret) { 296 Data(ap, KRB_REJECT, "krb5_auth_con_setaddrs_from_fd failed", -1); 297 auth_finished(ap, AUTH_REJECT); 298 if (auth_debug_mode) 299 printf("Kerberos V5: " 300 "krb5_auth_con_setaddrs_from_fd failed (%s)\r\n", 301 get_krb5_err_text(telnet_context, ret)); 302 return; 303 } 304 ret = krb5_sock_to_principal(telnet_context, 0, "host", 305 KRB5_NT_SRV_HST, &server); 306 if (ret) { 307 Data(ap, KRB_REJECT, "krb5_sock_to_principal failed", -1); 308 auth_finished(ap, AUTH_REJECT); 309 if (auth_debug_mode) 310 printf("Kerberos V5: " 311 "krb5_sock_to_principal failed (%s)\r\n", 312 get_krb5_err_text(telnet_context, ret)); 313 return; 314 } 315 ret = krb5_rd_req(telnet_context, &auth_context, &auth, 316 server, NULL, NULL, &ticket); 317 krb5_free_principal(telnet_context, server); 318 319 if (ret) { 320 char *errbuf; 321 322 asprintf(&errbuf, 323 "Read req failed: %s", 324 get_krb5_err_text(telnet_context, ret)); 325 Data(ap, KRB_REJECT, errbuf, -1); 326 if (auth_debug_mode) 327 printf("%s\r\n", errbuf); 328 free(errbuf); 329 return; 330 } { 331 char foo[2]; 332 333 foo[0] = ap->type; 334 foo[1] = ap->way; 335 336 ret = krb5_verify_authenticator_checksum(telnet_context, 337 auth_context, foo, sizeof(foo)); 338 339 if (ret) { 340 char *errbuf; 341 asprintf(&errbuf, "Bad checksum: %s", 342 get_krb5_err_text(telnet_context, ret)); 343 Data(ap, KRB_REJECT, errbuf, -1); 344 if (auth_debug_mode) 345 printf("%s\r\n", errbuf); 346 free(errbuf); 347 return; 348 } 349 } 350 ret = krb5_auth_con_getremotesubkey(telnet_context, 351 auth_context, &key_block); 352 353 if (ret) { 354 Data(ap, KRB_REJECT, "krb5_auth_con_getremotesubkey failed", -1); 355 auth_finished(ap, AUTH_REJECT); 356 if (auth_debug_mode) 357 printf("Kerberos V5: " 358 "krb5_auth_con_getremotesubkey failed (%s)\r\n", 359 get_krb5_err_text(telnet_context, ret)); 360 return; 361 } 362 if (key_block == NULL) { 363 ret = krb5_auth_con_getkey(telnet_context, 364 auth_context, 365 &key_block); 366 } 367 if (ret) { 368 Data(ap, KRB_REJECT, "krb5_auth_con_getkey failed", -1); 369 auth_finished(ap, AUTH_REJECT); 370 if (auth_debug_mode) 371 printf("Kerberos V5: " 372 "krb5_auth_con_getkey failed (%s)\r\n", 373 get_krb5_err_text(telnet_context, ret)); 374 return; 375 } 376 if (key_block == NULL) { 377 Data(ap, KRB_REJECT, "no subkey received", -1); 378 auth_finished(ap, AUTH_REJECT); 379 if (auth_debug_mode) 380 printf("Kerberos V5: " 381 "krb5_auth_con_getremotesubkey returned NULL key\r\n"); 382 return; 383 } 384 if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) { 385 ret = krb5_mk_rep(telnet_context, 386 auth_context, &outbuf); 387 if (ret) { 388 Data(ap, KRB_REJECT, 389 "krb5_mk_rep failed", -1); 390 auth_finished(ap, AUTH_REJECT); 391 if (auth_debug_mode) 392 printf("Kerberos V5: " 393 "krb5_mk_rep failed (%s)\r\n", 394 get_krb5_err_text(telnet_context, 395 ret)); 396 krb5_free_keyblock(telnet_context, key_block); 397 return; 398 } 399 Data(ap, KRB_RESPONSE, outbuf.data, outbuf.length); 400 } 401 if (krb5_unparse_name(telnet_context, ticket->client, &name)) 402 name = 0; 403 404 if (UserNameRequested && krb5_kuserok(telnet_context, 405 ticket->client, UserNameRequested)) { 406 Data(ap, KRB_ACCEPT, name ? name : "", name ? -1 : 0); 407 if (auth_debug_mode) { 408 printf("Kerberos5 identifies him as ``%s''\r\n", 409 name ? name : ""); 410 } 411 if (key_block->keytype == ETYPE_DES_CBC_MD5 || 412 key_block->keytype == ETYPE_DES_CBC_MD4 || 413 key_block->keytype == ETYPE_DES_CBC_CRC) { 414 Session_Key skey; 415 416 skey.type = SK_DES; 417 skey.length = 8; 418 skey.data = key_block->keyvalue.data; 419 encrypt_session_key(&skey, 0); 420 } 421 } else { 422 char *msg; 423 424 asprintf(&msg, "user `%s' is not authorized to " 425 "login as `%s'", 426 name ? name : "<unknown>", 427 UserNameRequested ? UserNameRequested : "<nobody>"); 428 if (msg == NULL) 429 Data(ap, KRB_REJECT, NULL, 0); 430 else { 431 Data(ap, KRB_REJECT, (void *) msg, -1); 432 free(msg); 433 } 434 auth_finished(ap, AUTH_REJECT); 435 krb5_free_keyblock(telnet_context, key_block); 436 break; 437 } 438 auth_finished(ap, AUTH_USER); 439 krb5_free_keyblock(telnet_context, key_block); 440 break; 441 case KRB_FORWARD:{ 442 struct passwd pws, *pwd; 443 char pwbuf[1024]; 444 char ccname[1024]; /* XXX */ 445 krb5_data inbuf; 446 krb5_ccache ccache; 447 inbuf.data = (char *) data; 448 inbuf.length = cnt; 449 450 if (getpwnam_r(UserNameRequested, &pws, pwbuf, 451 sizeof(pwbuf), &pwd) != 0 || pwd == NULL) 452 break; 453 454 snprintf(ccname, sizeof(ccname), 455 "FILE:/tmp/krb5cc_%u", pwd->pw_uid); 456 457 ret = krb5_cc_resolve(telnet_context, ccname, &ccache); 458 if (ret) { 459 if (auth_debug_mode) 460 printf("Kerberos V5: could not get ccache: %s\r\n", 461 get_krb5_err_text(telnet_context, 462 ret)); 463 break; 464 } 465 ret = krb5_cc_initialize(telnet_context, ccache, 466 ticket->client); 467 if (ret) { 468 if (auth_debug_mode) 469 printf("Kerberos V5: could not init ccache: %s\r\n", 470 get_krb5_err_text(telnet_context, 471 ret)); 472 break; 473 } 474 ret = krb5_rd_cred2(telnet_context, auth_context, 475 ccache, &inbuf); 476 if (ret) { 477 char *errbuf; 478 479 asprintf(&errbuf, 480 "Read forwarded creds failed: %s", 481 get_krb5_err_text(telnet_context, ret)); 482 if (errbuf == NULL) 483 Data(ap, KRB_FORWARD_REJECT, NULL, 0); 484 else 485 Data(ap, KRB_FORWARD_REJECT, errbuf, -1); 486 if (auth_debug_mode) 487 printf("Could not read forwarded credentials: %s\r\n", 488 errbuf); 489 free(errbuf); 490 } else 491 Data(ap, KRB_FORWARD_ACCEPT, 0, 0); 492 chown(ccname + 5, pwd->pw_uid, -1); 493 if (auth_debug_mode) 494 printf("Forwarded credentials obtained\r\n"); 495 break; 496 } 497 default: 498 if (auth_debug_mode) 499 printf("Unknown Kerberos option %d\r\n", data[-1]); 500 Data(ap, KRB_REJECT, 0, 0); 501 break; 502 } 503 } 504 505 void 506 kerberos5_reply(Authenticator * ap, unsigned char *data, int cnt) 507 { 508 static int mutual_complete = 0; 509 510 if (cnt-- < 1) 511 return; 512 switch (*data++) { 513 case KRB_REJECT: 514 if (cnt > 0) { 515 printf("[ Kerberos V5 refuses authentication because %.*s ]\r\n", 516 cnt, data); 517 } else 518 printf("[ Kerberos V5 refuses authentication ]\r\n"); 519 auth_send_retry(); 520 return; 521 case KRB_ACCEPT:{ 522 krb5_error_code ret; 523 Session_Key skey; 524 krb5_keyblock *keyblock; 525 526 if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL && 527 !mutual_complete) { 528 printf("[ Kerberos V5 accepted you, but didn't provide mutual authentication! ]\r\n"); 529 auth_send_retry(); 530 return; 531 } 532 if (cnt) 533 printf("[ Kerberos V5 accepts you as ``%.*s'' ]\r\n", cnt, data); 534 else 535 printf("[ Kerberos V5 accepts you ]\r\n"); 536 537 ret = krb5_auth_con_getlocalsubkey(telnet_context, 538 auth_context, &keyblock); 539 if (ret) 540 ret = krb5_auth_con_getkey(telnet_context, 541 auth_context, &keyblock); 542 if (ret) { 543 printf("[ krb5_auth_con_getkey: %s ]\r\n", 544 get_krb5_err_text(telnet_context, ret)); 545 auth_send_retry(); 546 return; 547 } 548 skey.type = SK_DES; 549 skey.length = 8; 550 skey.data = keyblock->keyvalue.data; 551 encrypt_session_key(&skey, 0); 552 krb5_free_keyblock(telnet_context, keyblock); 553 auth_finished(ap, AUTH_USER); 554 if (forward_flags & OPTS_FORWARD_CREDS) 555 kerberos5_forward(ap); 556 break; 557 } 558 case KRB_RESPONSE: 559 if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) { 560 /* the rest of the reply should contain a krb_ap_rep */ 561 krb5_ap_rep_enc_part *reply; 562 krb5_data inbuf; 563 krb5_error_code ret; 564 565 inbuf.length = cnt; 566 inbuf.data = (char *) data; 567 568 ret = krb5_rd_rep(telnet_context, 569 auth_context, &inbuf, &reply); 570 if (ret) { 571 printf("[ Mutual authentication failed: %s ]\r\n", 572 get_krb5_err_text(telnet_context, ret)); 573 auth_send_retry(); 574 return; 575 } 576 krb5_free_ap_rep_enc_part(telnet_context, reply); 577 mutual_complete = 1; 578 } 579 return; 580 case KRB_FORWARD_ACCEPT: 581 printf("[ Kerberos V5 accepted forwarded credentials ]\r\n"); 582 return; 583 case KRB_FORWARD_REJECT: 584 printf("[ Kerberos V5 refuses forwarded credentials because %.*s ]\r\n", 585 cnt, data); 586 return; 587 default: 588 if (auth_debug_mode) 589 printf("Unknown Kerberos option %d\r\n", data[-1]); 590 return; 591 } 592 } 593 594 int 595 kerberos5_status(Authenticator *ap, char *name, size_t l, int level) 596 { 597 if (level < AUTH_USER) 598 return (level); 599 600 if (UserNameRequested && 601 krb5_kuserok(telnet_context, ticket->client, UserNameRequested)) { 602 strlcpy(name, UserNameRequested, l); 603 return (AUTH_VALID); 604 } else 605 return (AUTH_USER); 606 } 607 #define BUMP(buf, len) while (*(buf)) {++(buf), --(len);} 608 #define ADDC(buf, len, c) if ((len) > 0) {*(buf)++ = (c); --(len);} 609 610 void 611 kerberos5_printsub(unsigned char *data, int cnt, unsigned char *buf, int buflen) 612 { 613 int i; 614 615 buf[buflen - 1] = '\0'; /* make sure its NULL terminated */ 616 buflen -= 1; 617 618 switch (data[3]) { 619 case KRB_REJECT: /* Rejected (reason might follow) */ 620 strlcpy((char *) buf, " REJECT ", buflen); 621 goto common; 622 623 case KRB_ACCEPT: /* Accepted (name might follow) */ 624 strlcpy((char *) buf, " ACCEPT ", buflen); 625 common: 626 BUMP(buf, buflen); 627 if (cnt <= 4) 628 break; 629 ADDC(buf, buflen, '"'); 630 for (i = 4; i < cnt; i++) 631 ADDC(buf, buflen, data[i]); 632 ADDC(buf, buflen, '"'); 633 ADDC(buf, buflen, '\0'); 634 break; 635 636 637 case KRB_AUTH: /* Authentication data follows */ 638 strlcpy((char *) buf, " AUTH", buflen); 639 goto common2; 640 641 case KRB_RESPONSE: 642 strlcpy((char *) buf, " RESPONSE", buflen); 643 goto common2; 644 645 case KRB_FORWARD: /* Forwarded credentials follow */ 646 strlcpy((char *) buf, " FORWARD", buflen); 647 goto common2; 648 649 case KRB_FORWARD_ACCEPT: /* Forwarded credentials accepted */ 650 strlcpy((char *) buf, " FORWARD_ACCEPT", buflen); 651 goto common2; 652 653 case KRB_FORWARD_REJECT: /* Forwarded credentials rejected */ 654 /* (reason might follow) */ 655 strlcpy((char *) buf, " FORWARD_REJECT", buflen); 656 goto common2; 657 658 default: 659 snprintf(buf, buflen, " %d (unknown)", data[3]); 660 common2: 661 BUMP(buf, buflen); 662 for (i = 4; i < cnt; i++) { 663 snprintf(buf, buflen, " %d", data[i]); 664 BUMP(buf, buflen); 665 } 666 break; 667 } 668 } 669 670 void 671 kerberos5_forward(Authenticator * ap) 672 { 673 krb5_error_code ret; 674 krb5_ccache ccache; 675 krb5_creds creds; 676 krb5_kdc_flags flags; 677 krb5_data out_data; 678 krb5_principal principal; 679 680 ret = krb5_cc_default(telnet_context, &ccache); 681 if (ret) { 682 if (auth_debug_mode) 683 printf("KerberosV5: could not get default ccache: %s\r\n", 684 get_krb5_err_text(telnet_context, ret)); 685 return; 686 } 687 ret = krb5_cc_get_principal(telnet_context, ccache, &principal); 688 if (ret) { 689 if (auth_debug_mode) 690 printf("KerberosV5: could not get principal: %s\r\n", 691 get_krb5_err_text(telnet_context, ret)); 692 return; 693 } 694 memset(&creds, 0, sizeof(creds)); 695 696 creds.client = principal; 697 698 ret = krb5_build_principal(telnet_context, &creds.server, 699 strlen(principal->realm), principal->realm, "krbtgt", 700 principal->realm, NULL); 701 702 if (ret) { 703 if (auth_debug_mode) 704 printf("KerberosV5: could not get principal: %s\r\n", 705 get_krb5_err_text(telnet_context, ret)); 706 return; 707 } 708 creds.times.endtime = 0; 709 710 flags.i = 0; 711 flags.b.forwarded = 1; 712 if (forward_flags & OPTS_FORWARDABLE_CREDS) 713 flags.b.forwardable = 1; 714 715 ret = krb5_get_forwarded_creds(telnet_context, auth_context, 716 ccache, flags.i, RemoteHostName, &creds, &out_data); 717 if (ret) { 718 if (auth_debug_mode) 719 printf("Kerberos V5: error getting forwarded creds: %s\r\n", 720 get_krb5_err_text(telnet_context, ret)); 721 return; 722 } 723 if (!Data(ap, KRB_FORWARD, out_data.data, out_data.length)) { 724 if (auth_debug_mode) 725 printf("Not enough room for authentication data\r\n"); 726 } else { 727 if (auth_debug_mode) 728 printf("Forwarded local Kerberos V5 credentials to server\r\n"); 729 } 730 } 731 #endif /* KRB5 */ 732