1/* $NetBSD: kerberos5.c,v 1.18 2011/04/24 19:00:31 elric 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 70extern int net; 71 72int forward_flags; /* Flags get set in telnet/main.c on -f and -F */ 73int got_forwarded_creds;/* Tell telnetd to pass -F or -f to login. */ 74 75int require_hwpreauth; 76 77const char *get_krb5_err_text(krb5_context, krb5_error_code); 78void kerberos5_forward(Authenticator *); 79 80static 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 92static krb5_data auth; 93static krb5_ticket *ticket; 94 95krb5_context telnet_context; 96static krb5_auth_context auth_context; 97 98static int 99Data(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 129const char * 130get_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 145int 146kerberos5_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 178int 179kerberos5_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, KEYTYPE_DES); 231 232 foo[0] = ap->type; 233 foo[1] = ap->way; 234 235 cksum_data.length = sizeof(foo); 236 cksum_data.data = foo; 237 ret = krb5_mk_req(telnet_context, &auth_context, ap_opts, "host", 238 RemoteHostName, &cksum_data, ccache, &auth); 239 if (ret) { 240 if (1 || auth_debug_mode) { 241 printf("Kerberos V5: mk_req failed (%s)\r\n", 242 get_krb5_err_text(telnet_context, ret)); 243 } 244 return (0); 245 } 246 247 if (!auth_sendname((unsigned char *) UserNameRequested, 248 strlen(UserNameRequested))) { 249 if (auth_debug_mode) 250 printf("Not enough room for user name\r\n"); 251 return (0); 252 } 253 if (!Data(ap, KRB_AUTH, auth.data, auth.length)) { 254 if (auth_debug_mode) 255 printf("Not enough room for authentication data\r\n"); 256 return (0); 257 } 258 if (auth_debug_mode) { 259 printf("Sent Kerberos V5 credentials to server\r\n"); 260 } 261 return (1); 262} 263 264void 265kerberos5_is(Authenticator * ap, unsigned char *data, int cnt) 266{ 267 krb5_error_code ret; 268 krb5_data outbuf; 269 krb5_keyblock *key_block; 270 char *name; 271 krb5_principal server; 272 int zero = 0; 273 274 if (cnt-- < 1) 275 return; 276 switch (*data++) { 277 case KRB_AUTH: 278 auth.data = (char *) data; 279 auth.length = cnt; 280 281 auth_context = NULL; 282 283 ret = krb5_auth_con_init(telnet_context, &auth_context); 284 if (ret) { 285 Data(ap, KRB_REJECT, "krb5_auth_con_init failed", -1); 286 auth_finished(ap, AUTH_REJECT); 287 if (auth_debug_mode) 288 printf("Kerberos V5: krb5_auth_con_init failed (%s)\r\n", 289 get_krb5_err_text(telnet_context, ret)); 290 return; 291 } 292 ret = krb5_auth_con_setaddrs_from_fd(telnet_context, 293 auth_context, &zero); 294 if (ret) { 295 Data(ap, KRB_REJECT, "krb5_auth_con_setaddrs_from_fd failed", -1); 296 auth_finished(ap, AUTH_REJECT); 297 if (auth_debug_mode) 298 printf("Kerberos V5: " 299 "krb5_auth_con_setaddrs_from_fd failed (%s)\r\n", 300 get_krb5_err_text(telnet_context, ret)); 301 return; 302 } 303 ret = krb5_sock_to_principal(telnet_context, 0, "host", 304 KRB5_NT_SRV_HST, &server); 305 if (ret) { 306 Data(ap, KRB_REJECT, "krb5_sock_to_principal failed", -1); 307 auth_finished(ap, AUTH_REJECT); 308 if (auth_debug_mode) 309 printf("Kerberos V5: " 310 "krb5_sock_to_principal failed (%s)\r\n", 311 get_krb5_err_text(telnet_context, ret)); 312 return; 313 } 314 ret = krb5_rd_req(telnet_context, &auth_context, &auth, 315 server, NULL, NULL, &ticket); 316 krb5_free_principal(telnet_context, server); 317 318 if (ret) { 319 char *errbuf; 320 321 asprintf(&errbuf, 322 "Read req failed: %s", 323 get_krb5_err_text(telnet_context, ret)); 324 Data(ap, KRB_REJECT, errbuf, -1); 325 if (auth_debug_mode) 326 printf("%s\r\n", errbuf); 327 free(errbuf); 328 return; 329 } { 330 char foo[2]; 331 332 foo[0] = ap->type; 333 foo[1] = ap->way; 334 335 ret = krb5_verify_authenticator_checksum(telnet_context, 336 auth_context, foo, sizeof(foo)); 337 338 if (ret) { 339 char *errbuf; 340 asprintf(&errbuf, "Bad checksum: %s", 341 get_krb5_err_text(telnet_context, ret)); 342 Data(ap, KRB_REJECT, errbuf, -1); 343 if (auth_debug_mode) 344 printf("%s\r\n", errbuf); 345 free(errbuf); 346 return; 347 } 348 } 349 ret = krb5_auth_con_getremotesubkey(telnet_context, 350 auth_context, &key_block); 351 352 if (ret) { 353 Data(ap, KRB_REJECT, "krb5_auth_con_getremotesubkey failed", -1); 354 auth_finished(ap, AUTH_REJECT); 355 if (auth_debug_mode) 356 printf("Kerberos V5: " 357 "krb5_auth_con_getremotesubkey failed (%s)\r\n", 358 get_krb5_err_text(telnet_context, ret)); 359 return; 360 } 361 if (key_block == NULL) { 362 ret = krb5_auth_con_getkey(telnet_context, 363 auth_context, 364 &key_block); 365 } 366 if (ret) { 367 Data(ap, KRB_REJECT, "krb5_auth_con_getkey failed", -1); 368 auth_finished(ap, AUTH_REJECT); 369 if (auth_debug_mode) 370 printf("Kerberos V5: " 371 "krb5_auth_con_getkey failed (%s)\r\n", 372 get_krb5_err_text(telnet_context, ret)); 373 return; 374 } 375 if (key_block == NULL) { 376 Data(ap, KRB_REJECT, "no subkey received", -1); 377 auth_finished(ap, AUTH_REJECT); 378 if (auth_debug_mode) 379 printf("Kerberos V5: " 380 "krb5_auth_con_getremotesubkey returned NULL key\r\n"); 381 return; 382 } 383 if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) { 384 ret = krb5_mk_rep(telnet_context, 385 auth_context, &outbuf); 386 if (ret) { 387 Data(ap, KRB_REJECT, 388 "krb5_mk_rep failed", -1); 389 auth_finished(ap, AUTH_REJECT); 390 if (auth_debug_mode) 391 printf("Kerberos V5: " 392 "krb5_mk_rep failed (%s)\r\n", 393 get_krb5_err_text(telnet_context, 394 ret)); 395 krb5_free_keyblock(telnet_context, key_block); 396 return; 397 } 398 Data(ap, KRB_RESPONSE, outbuf.data, outbuf.length); 399 } 400 if (krb5_unparse_name(telnet_context, ticket->client, &name)) 401 name = 0; 402 403 if (UserNameRequested && krb5_kuserok(telnet_context, 404 ticket->client, UserNameRequested)) { 405 Data(ap, KRB_ACCEPT, name ? name : "", name ? -1 : 0); 406 if (auth_debug_mode) { 407 printf("Kerberos5 identifies him as ``%s''\r\n", 408 name ? name : ""); 409 } 410 if (key_block->keytype == ETYPE_DES_CBC_MD5 || 411 key_block->keytype == ETYPE_DES_CBC_MD4 || 412 key_block->keytype == ETYPE_DES_CBC_CRC) { 413 Session_Key skey; 414 415 skey.type = SK_DES; 416 skey.length = 8; 417 skey.data = key_block->keyvalue.data; 418 encrypt_session_key(&skey, 0); 419 } 420 } else { 421 char *msg; 422 423 asprintf(&msg, "user `%s' is not authorized to " 424 "login as `%s'", 425 name ? name : "<unknown>", 426 UserNameRequested ? UserNameRequested : "<nobody>"); 427 if (msg == NULL) 428 Data(ap, KRB_REJECT, NULL, 0); 429 else { 430 Data(ap, KRB_REJECT, (void *) msg, -1); 431 free(msg); 432 } 433 auth_finished(ap, AUTH_REJECT); 434 krb5_free_keyblock(telnet_context, key_block); 435 break; 436 } 437 auth_finished(ap, AUTH_USER); 438 krb5_free_keyblock(telnet_context, key_block); 439 break; 440 case KRB_FORWARD:{ 441 struct passwd pws, *pwd; 442 char pwbuf[1024]; 443 char ccname[1024]; /* XXX */ 444 krb5_data inbuf; 445 krb5_ccache ccache; 446 inbuf.data = (char *) data; 447 inbuf.length = cnt; 448 449 if (getpwnam_r(UserNameRequested, &pws, pwbuf, 450 sizeof(pwbuf), &pwd) != 0 || pwd == NULL) 451 break; 452 453 snprintf(ccname, sizeof(ccname), 454 "FILE:/tmp/krb5cc_%u", pwd->pw_uid); 455 456 ret = krb5_cc_resolve(telnet_context, ccname, &ccache); 457 if (ret) { 458 if (auth_debug_mode) 459 printf("Kerberos V5: could not get ccache: %s\r\n", 460 get_krb5_err_text(telnet_context, 461 ret)); 462 break; 463 } 464 ret = krb5_cc_initialize(telnet_context, ccache, 465 ticket->client); 466 if (ret) { 467 if (auth_debug_mode) 468 printf("Kerberos V5: could not init ccache: %s\r\n", 469 get_krb5_err_text(telnet_context, 470 ret)); 471 break; 472 } 473 ret = krb5_rd_cred2(telnet_context, auth_context, 474 ccache, &inbuf); 475 if (ret) { 476 char *errbuf; 477 478 asprintf(&errbuf, 479 "Read forwarded creds failed: %s", 480 get_krb5_err_text(telnet_context, ret)); 481 if (errbuf == NULL) 482 Data(ap, KRB_FORWARD_REJECT, NULL, 0); 483 else 484 Data(ap, KRB_FORWARD_REJECT, errbuf, -1); 485 if (auth_debug_mode) 486 printf("Could not read forwarded credentials: %s\r\n", 487 errbuf); 488 free(errbuf); 489 } else 490 Data(ap, KRB_FORWARD_ACCEPT, 0, 0); 491 chown(ccname + 5, pwd->pw_uid, -1); 492 if (auth_debug_mode) 493 printf("Forwarded credentials obtained\r\n"); 494 break; 495 } 496 default: 497 if (auth_debug_mode) 498 printf("Unknown Kerberos option %d\r\n", data[-1]); 499 Data(ap, KRB_REJECT, 0, 0); 500 break; 501 } 502} 503 504void 505kerberos5_reply(Authenticator * ap, unsigned char *data, int cnt) 506{ 507 static int mutual_complete = 0; 508 509 if (cnt-- < 1) 510 return; 511 switch (*data++) { 512 case KRB_REJECT: 513 if (cnt > 0) { 514 printf("[ Kerberos V5 refuses authentication because %.*s ]\r\n", 515 cnt, data); 516 } else 517 printf("[ Kerberos V5 refuses authentication ]\r\n"); 518 auth_send_retry(); 519 return; 520 case KRB_ACCEPT:{ 521 krb5_error_code ret; 522 Session_Key skey; 523 krb5_keyblock *keyblock; 524 525 if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL && 526 !mutual_complete) { 527 printf("[ Kerberos V5 accepted you, but didn't provide mutual authentication! ]\r\n"); 528 auth_send_retry(); 529 return; 530 } 531 if (cnt) 532 printf("[ Kerberos V5 accepts you as ``%.*s'' ]\r\n", cnt, data); 533 else 534 printf("[ Kerberos V5 accepts you ]\r\n"); 535 536 ret = krb5_auth_con_getlocalsubkey(telnet_context, 537 auth_context, &keyblock); 538 if (ret) 539 ret = krb5_auth_con_getkey(telnet_context, 540 auth_context, &keyblock); 541 if (ret) { 542 printf("[ krb5_auth_con_getkey: %s ]\r\n", 543 get_krb5_err_text(telnet_context, ret)); 544 auth_send_retry(); 545 return; 546 } 547 skey.type = SK_DES; 548 skey.length = 8; 549 skey.data = keyblock->keyvalue.data; 550 encrypt_session_key(&skey, 0); 551 krb5_free_keyblock(telnet_context, keyblock); 552 auth_finished(ap, AUTH_USER); 553 if (forward_flags & OPTS_FORWARD_CREDS) 554 kerberos5_forward(ap); 555 break; 556 } 557 case KRB_RESPONSE: 558 if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) { 559 /* the rest of the reply should contain a krb_ap_rep */ 560 krb5_ap_rep_enc_part *reply; 561 krb5_data inbuf; 562 krb5_error_code ret; 563 564 inbuf.length = cnt; 565 inbuf.data = (char *) data; 566 567 ret = krb5_rd_rep(telnet_context, 568 auth_context, &inbuf, &reply); 569 if (ret) { 570 printf("[ Mutual authentication failed: %s ]\r\n", 571 get_krb5_err_text(telnet_context, ret)); 572 auth_send_retry(); 573 return; 574 } 575 krb5_free_ap_rep_enc_part(telnet_context, reply); 576 mutual_complete = 1; 577 } 578 return; 579 case KRB_FORWARD_ACCEPT: 580 printf("[ Kerberos V5 accepted forwarded credentials ]\r\n"); 581 return; 582 case KRB_FORWARD_REJECT: 583 printf("[ Kerberos V5 refuses forwarded credentials because %.*s ]\r\n", 584 cnt, data); 585 return; 586 default: 587 if (auth_debug_mode) 588 printf("Unknown Kerberos option %d\r\n", data[-1]); 589 return; 590 } 591} 592 593int 594kerberos5_status(Authenticator *ap, char *name, size_t l, int level) 595{ 596 if (level < AUTH_USER) 597 return (level); 598 599 if (UserNameRequested && 600 krb5_kuserok(telnet_context, ticket->client, UserNameRequested)) { 601 strlcpy(name, UserNameRequested, l); 602 return (AUTH_VALID); 603 } else 604 return (AUTH_USER); 605} 606#define BUMP(buf, len) while (*(buf)) {++(buf), --(len);} 607#define ADDC(buf, len, c) if ((len) > 0) {*(buf)++ = (c); --(len);} 608 609void 610kerberos5_printsub(unsigned char *data, int cnt, unsigned char *buf, int buflen) 611{ 612 int i; 613 614 buf[buflen - 1] = '\0'; /* make sure its NULL terminated */ 615 buflen -= 1; 616 617 switch (data[3]) { 618 case KRB_REJECT: /* Rejected (reason might follow) */ 619 strlcpy((char *) buf, " REJECT ", buflen); 620 goto common; 621 622 case KRB_ACCEPT: /* Accepted (name might follow) */ 623 strlcpy((char *) buf, " ACCEPT ", buflen); 624common: 625 BUMP(buf, buflen); 626 if (cnt <= 4) 627 break; 628 ADDC(buf, buflen, '"'); 629 for (i = 4; i < cnt; i++) 630 ADDC(buf, buflen, data[i]); 631 ADDC(buf, buflen, '"'); 632 ADDC(buf, buflen, '\0'); 633 break; 634 635 636 case KRB_AUTH: /* Authentication data follows */ 637 strlcpy((char *) buf, " AUTH", buflen); 638 goto common2; 639 640 case KRB_RESPONSE: 641 strlcpy((char *) buf, " RESPONSE", buflen); 642 goto common2; 643 644 case KRB_FORWARD: /* Forwarded credentials follow */ 645 strlcpy((char *) buf, " FORWARD", buflen); 646 goto common2; 647 648 case KRB_FORWARD_ACCEPT: /* Forwarded credentials accepted */ 649 strlcpy((char *) buf, " FORWARD_ACCEPT", buflen); 650 goto common2; 651 652 case KRB_FORWARD_REJECT: /* Forwarded credentials rejected */ 653 /* (reason might follow) */ 654 strlcpy((char *) buf, " FORWARD_REJECT", buflen); 655 goto common2; 656 657 default: 658 snprintf(buf, buflen, " %d (unknown)", data[3]); 659common2: 660 BUMP(buf, buflen); 661 for (i = 4; i < cnt; i++) { 662 snprintf(buf, buflen, " %d", data[i]); 663 BUMP(buf, buflen); 664 } 665 break; 666 } 667} 668 669void 670kerberos5_forward(Authenticator * ap) 671{ 672 krb5_error_code ret; 673 krb5_ccache ccache; 674 krb5_creds creds; 675 krb5_kdc_flags flags; 676 krb5_data out_data; 677 krb5_principal principal; 678 679 ret = krb5_cc_default(telnet_context, &ccache); 680 if (ret) { 681 if (auth_debug_mode) 682 printf("KerberosV5: could not get default ccache: %s\r\n", 683 get_krb5_err_text(telnet_context, ret)); 684 return; 685 } 686 ret = krb5_cc_get_principal(telnet_context, ccache, &principal); 687 if (ret) { 688 if (auth_debug_mode) 689 printf("KerberosV5: could not get principal: %s\r\n", 690 get_krb5_err_text(telnet_context, ret)); 691 return; 692 } 693 memset(&creds, 0, sizeof(creds)); 694 695 creds.client = principal; 696 697 ret = krb5_build_principal(telnet_context, &creds.server, 698 strlen(principal->realm), principal->realm, "krbtgt", 699 principal->realm, NULL); 700 701 if (ret) { 702 if (auth_debug_mode) 703 printf("KerberosV5: could not get principal: %s\r\n", 704 get_krb5_err_text(telnet_context, ret)); 705 return; 706 } 707 creds.times.endtime = 0; 708 709 flags.i = 0; 710 flags.b.forwarded = 1; 711 if (forward_flags & OPTS_FORWARDABLE_CREDS) 712 flags.b.forwardable = 1; 713 714 ret = krb5_get_forwarded_creds(telnet_context, auth_context, 715 ccache, flags.i, RemoteHostName, &creds, &out_data); 716 if (ret) { 717 if (auth_debug_mode) 718 printf("Kerberos V5: error getting forwarded creds: %s\r\n", 719 get_krb5_err_text(telnet_context, ret)); 720 return; 721 } 722 if (!Data(ap, KRB_FORWARD, out_data.data, out_data.length)) { 723 if (auth_debug_mode) 724 printf("Not enough room for authentication data\r\n"); 725 } else { 726 if (auth_debug_mode) 727 printf("Forwarded local Kerberos V5 credentials to server\r\n"); 728 } 729} 730#endif /* KRB5 */ 731