1 /* $NetBSD: kerberos5.c,v 1.17 2006/03/22 16:32:39 christos 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 void kerberos5_forward(Authenticator *); 78 79 static unsigned char str_data[1024] = {IAC, SB, TELOPT_AUTHENTICATION, 0, 80 AUTHTYPE_KERBEROS_V5,}; 81 82 #define KRB_AUTH 0 /* Authentication data follows */ 83 #define KRB_REJECT 1 /* Rejected (reason might follow) */ 84 #define KRB_ACCEPT 2 /* Accepted */ 85 #define KRB_RESPONSE 3 /* Response for mutual auth. */ 86 87 #define KRB_FORWARD 4 /* Forwarded credentials follow */ 88 #define KRB_FORWARD_ACCEPT 5 /* Forwarded credentials accepted */ 89 #define KRB_FORWARD_REJECT 6 /* Forwarded credentials rejected */ 90 91 static krb5_data auth; 92 static krb5_ticket *ticket; 93 94 krb5_context telnet_context; 95 static krb5_auth_context auth_context; 96 97 static int 98 Data(Authenticator *ap, int type, void *d, int c) 99 { 100 unsigned char *p = str_data + 4; 101 unsigned char *cd = (unsigned char *) d; 102 103 if (c == -1) 104 c = strlen(cd); 105 106 if (auth_debug_mode) { 107 printf("%s:%d: [%d] (%d)", 108 str_data[3] == TELQUAL_IS ? ">>>IS" : ">>>REPLY", 109 str_data[3], 110 type, c); 111 printd(d, c); 112 printf("\r\n"); 113 } 114 *p++ = ap->type; 115 *p++ = ap->way; 116 *p++ = type; 117 while (c-- > 0) { 118 if ((*p++ = *cd++) == IAC) 119 *p++ = IAC; 120 } 121 *p++ = IAC; 122 *p++ = SE; 123 if (str_data[3] == TELQUAL_IS) 124 printsub('>', &str_data[2], p - &str_data[2]); 125 return (telnet_net_write(str_data, p - str_data)); 126 } 127 128 int 129 kerberos5_init(Authenticator *ap, int server) 130 { 131 krb5_error_code ret; 132 133 if (telnet_context == 0) { 134 ret = krb5_init_context(&telnet_context); 135 if (ret) 136 return 0; 137 } 138 139 if (server) { 140 krb5_keytab kt; 141 krb5_kt_cursor cursor; 142 143 ret = krb5_kt_default(telnet_context, &kt); 144 if (ret) 145 return 0; 146 147 ret = krb5_kt_start_seq_get(telnet_context, kt, &cursor); 148 if (ret) { 149 krb5_kt_close(telnet_context, kt); 150 return 0; 151 } 152 krb5_kt_end_seq_get(telnet_context, kt, &cursor); 153 krb5_kt_close(telnet_context, kt); 154 155 str_data[3] = TELQUAL_REPLY; 156 } else 157 str_data[3] = TELQUAL_IS; 158 return (1); 159 } 160 161 int 162 kerberos5_send(Authenticator *ap) 163 { 164 krb5_error_code ret; 165 krb5_ccache ccache; 166 int ap_opts; 167 krb5_data cksum_data; 168 char foo[2]; 169 170 printf("[ Trying KERBEROS5 ... ]\r\n"); 171 172 if (!UserNameRequested) { 173 if (auth_debug_mode) { 174 printf("Kerberos V5: no user name supplied\r\n"); 175 } 176 return (0); 177 } 178 ret = krb5_cc_default(telnet_context, &ccache); 179 if (ret) { 180 if (auth_debug_mode) { 181 printf( 182 "Kerberos V5: could not get default ccache: %s\r\n", 183 krb5_get_err_text(telnet_context, ret)); 184 } 185 return (0); 186 } 187 if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) 188 ap_opts = AP_OPTS_MUTUAL_REQUIRED; 189 else 190 ap_opts = 0; 191 192 ap_opts |= AP_OPTS_USE_SUBKEY; 193 194 ret = krb5_auth_con_init(telnet_context, &auth_context); 195 if (ret) { 196 if (auth_debug_mode) { 197 printf( 198 "Kerberos V5: krb5_auth_con_init failed: %s\r\n", 199 krb5_get_err_text(telnet_context, ret)); 200 } 201 return (0); 202 } 203 ret = krb5_auth_con_setaddrs_from_fd(telnet_context, 204 auth_context, &net); 205 if (ret) { 206 if (auth_debug_mode) { 207 printf("Kerberos V5: " 208 "krb5_auth_con_setaddrs_from_fd failed: %s\r\n", 209 krb5_get_err_text(telnet_context, ret)); 210 } 211 return (0); 212 } 213 krb5_auth_con_setkeytype(telnet_context, auth_context, KEYTYPE_DES); 214 215 foo[0] = ap->type; 216 foo[1] = ap->way; 217 218 cksum_data.length = sizeof(foo); 219 cksum_data.data = foo; 220 ret = krb5_mk_req(telnet_context, &auth_context, ap_opts, "host", 221 RemoteHostName, &cksum_data, ccache, &auth); 222 if (ret) { 223 if (1 || auth_debug_mode) { 224 printf("Kerberos V5: mk_req failed (%s)\r\n", 225 krb5_get_err_text(telnet_context, ret)); 226 } 227 return (0); 228 } 229 230 if (!auth_sendname((unsigned char *) UserNameRequested, 231 strlen(UserNameRequested))) { 232 if (auth_debug_mode) 233 printf("Not enough room for user name\r\n"); 234 return (0); 235 } 236 if (!Data(ap, KRB_AUTH, auth.data, auth.length)) { 237 if (auth_debug_mode) 238 printf("Not enough room for authentication data\r\n"); 239 return (0); 240 } 241 if (auth_debug_mode) { 242 printf("Sent Kerberos V5 credentials to server\r\n"); 243 } 244 return (1); 245 } 246 247 void 248 kerberos5_is(Authenticator * ap, unsigned char *data, int cnt) 249 { 250 krb5_error_code ret; 251 krb5_data outbuf; 252 krb5_keyblock *key_block; 253 char *name; 254 krb5_principal server; 255 int zero = 0; 256 257 if (cnt-- < 1) 258 return; 259 switch (*data++) { 260 case KRB_AUTH: 261 auth.data = (char *) data; 262 auth.length = cnt; 263 264 auth_context = NULL; 265 266 ret = krb5_auth_con_init(telnet_context, &auth_context); 267 if (ret) { 268 Data(ap, KRB_REJECT, "krb5_auth_con_init failed", -1); 269 auth_finished(ap, AUTH_REJECT); 270 if (auth_debug_mode) 271 printf("Kerberos V5: krb5_auth_con_init failed (%s)\r\n", 272 krb5_get_err_text(telnet_context, ret)); 273 return; 274 } 275 ret = krb5_auth_con_setaddrs_from_fd(telnet_context, 276 auth_context, &zero); 277 if (ret) { 278 Data(ap, KRB_REJECT, "krb5_auth_con_setaddrs_from_fd failed", -1); 279 auth_finished(ap, AUTH_REJECT); 280 if (auth_debug_mode) 281 printf("Kerberos V5: " 282 "krb5_auth_con_setaddrs_from_fd failed (%s)\r\n", 283 krb5_get_err_text(telnet_context, ret)); 284 return; 285 } 286 ret = krb5_sock_to_principal(telnet_context, 0, "host", 287 KRB5_NT_SRV_HST, &server); 288 if (ret) { 289 Data(ap, KRB_REJECT, "krb5_sock_to_principal failed", -1); 290 auth_finished(ap, AUTH_REJECT); 291 if (auth_debug_mode) 292 printf("Kerberos V5: " 293 "krb5_sock_to_principal failed (%s)\r\n", 294 krb5_get_err_text(telnet_context, ret)); 295 return; 296 } 297 ret = krb5_rd_req(telnet_context, &auth_context, &auth, 298 server, NULL, NULL, &ticket); 299 krb5_free_principal(telnet_context, server); 300 301 if (ret) { 302 char *errbuf; 303 304 asprintf(&errbuf, 305 "Read req failed: %s", 306 krb5_get_err_text(telnet_context, ret)); 307 Data(ap, KRB_REJECT, errbuf, -1); 308 if (auth_debug_mode) 309 printf("%s\r\n", errbuf); 310 free(errbuf); 311 return; 312 } { 313 char foo[2]; 314 315 foo[0] = ap->type; 316 foo[1] = ap->way; 317 318 ret = krb5_verify_authenticator_checksum(telnet_context, 319 auth_context, foo, sizeof(foo)); 320 321 if (ret) { 322 char *errbuf; 323 asprintf(&errbuf, "Bad checksum: %s", 324 krb5_get_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 } 332 ret = krb5_auth_con_getremotesubkey(telnet_context, 333 auth_context, &key_block); 334 335 if (ret) { 336 Data(ap, KRB_REJECT, "krb5_auth_con_getremotesubkey failed", -1); 337 auth_finished(ap, AUTH_REJECT); 338 if (auth_debug_mode) 339 printf("Kerberos V5: " 340 "krb5_auth_con_getremotesubkey failed (%s)\r\n", 341 krb5_get_err_text(telnet_context, ret)); 342 return; 343 } 344 if (key_block == NULL) { 345 ret = krb5_auth_con_getkey(telnet_context, 346 auth_context, 347 &key_block); 348 } 349 if (ret) { 350 Data(ap, KRB_REJECT, "krb5_auth_con_getkey failed", -1); 351 auth_finished(ap, AUTH_REJECT); 352 if (auth_debug_mode) 353 printf("Kerberos V5: " 354 "krb5_auth_con_getkey failed (%s)\r\n", 355 krb5_get_err_text(telnet_context, ret)); 356 return; 357 } 358 if (key_block == NULL) { 359 Data(ap, KRB_REJECT, "no subkey received", -1); 360 auth_finished(ap, AUTH_REJECT); 361 if (auth_debug_mode) 362 printf("Kerberos V5: " 363 "krb5_auth_con_getremotesubkey returned NULL key\r\n"); 364 return; 365 } 366 if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) { 367 ret = krb5_mk_rep(telnet_context, 368 auth_context, &outbuf); 369 if (ret) { 370 Data(ap, KRB_REJECT, 371 "krb5_mk_rep failed", -1); 372 auth_finished(ap, AUTH_REJECT); 373 if (auth_debug_mode) 374 printf("Kerberos V5: " 375 "krb5_mk_rep failed (%s)\r\n", 376 krb5_get_err_text(telnet_context, 377 ret)); 378 krb5_free_keyblock(telnet_context, key_block); 379 return; 380 } 381 Data(ap, KRB_RESPONSE, outbuf.data, outbuf.length); 382 } 383 if (krb5_unparse_name(telnet_context, ticket->client, &name)) 384 name = 0; 385 386 if (UserNameRequested && krb5_kuserok(telnet_context, 387 ticket->client, UserNameRequested)) { 388 Data(ap, KRB_ACCEPT, name ? name : "", name ? -1 : 0); 389 if (auth_debug_mode) { 390 printf("Kerberos5 identifies him as ``%s''\r\n", 391 name ? name : ""); 392 } 393 if (key_block->keytype == ETYPE_DES_CBC_MD5 || 394 key_block->keytype == ETYPE_DES_CBC_MD4 || 395 key_block->keytype == ETYPE_DES_CBC_CRC) { 396 Session_Key skey; 397 398 skey.type = SK_DES; 399 skey.length = 8; 400 skey.data = key_block->keyvalue.data; 401 encrypt_session_key(&skey, 0); 402 } 403 } else { 404 char *msg; 405 406 asprintf(&msg, "user `%s' is not authorized to " 407 "login as `%s'", 408 name ? name : "<unknown>", 409 UserNameRequested ? UserNameRequested : "<nobody>"); 410 if (msg == NULL) 411 Data(ap, KRB_REJECT, NULL, 0); 412 else { 413 Data(ap, KRB_REJECT, (void *) msg, -1); 414 free(msg); 415 } 416 auth_finished(ap, AUTH_REJECT); 417 krb5_free_keyblock(telnet_context, key_block); 418 break; 419 } 420 auth_finished(ap, AUTH_USER); 421 krb5_free_keyblock(telnet_context, key_block); 422 break; 423 case KRB_FORWARD:{ 424 struct passwd pws, *pwd; 425 char pwbuf[1024]; 426 char ccname[1024]; /* XXX */ 427 krb5_data inbuf; 428 krb5_ccache ccache; 429 inbuf.data = (char *) data; 430 inbuf.length = cnt; 431 432 if (getpwnam_r(UserNameRequested, &pws, pwbuf, 433 sizeof(pwbuf), &pwd) != 0 || pwd == NULL) 434 break; 435 436 snprintf(ccname, sizeof(ccname), 437 "FILE:/tmp/krb5cc_%u", pwd->pw_uid); 438 439 ret = krb5_cc_resolve(telnet_context, ccname, &ccache); 440 if (ret) { 441 if (auth_debug_mode) 442 printf("Kerberos V5: could not get ccache: %s\r\n", 443 krb5_get_err_text(telnet_context, 444 ret)); 445 break; 446 } 447 ret = krb5_cc_initialize(telnet_context, ccache, 448 ticket->client); 449 if (ret) { 450 if (auth_debug_mode) 451 printf("Kerberos V5: could not init ccache: %s\r\n", 452 krb5_get_err_text(telnet_context, 453 ret)); 454 break; 455 } 456 ret = krb5_rd_cred2(telnet_context, auth_context, 457 ccache, &inbuf); 458 if (ret) { 459 char *errbuf; 460 461 asprintf(&errbuf, 462 "Read forwarded creds failed: %s", 463 krb5_get_err_text(telnet_context, ret)); 464 if (errbuf == NULL) 465 Data(ap, KRB_FORWARD_REJECT, NULL, 0); 466 else 467 Data(ap, KRB_FORWARD_REJECT, errbuf, -1); 468 if (auth_debug_mode) 469 printf("Could not read forwarded credentials: %s\r\n", 470 errbuf); 471 free(errbuf); 472 } else 473 Data(ap, KRB_FORWARD_ACCEPT, 0, 0); 474 chown(ccname + 5, pwd->pw_uid, -1); 475 if (auth_debug_mode) 476 printf("Forwarded credentials obtained\r\n"); 477 break; 478 } 479 default: 480 if (auth_debug_mode) 481 printf("Unknown Kerberos option %d\r\n", data[-1]); 482 Data(ap, KRB_REJECT, 0, 0); 483 break; 484 } 485 } 486 487 void 488 kerberos5_reply(Authenticator * ap, unsigned char *data, int cnt) 489 { 490 static int mutual_complete = 0; 491 492 if (cnt-- < 1) 493 return; 494 switch (*data++) { 495 case KRB_REJECT: 496 if (cnt > 0) { 497 printf("[ Kerberos V5 refuses authentication because %.*s ]\r\n", 498 cnt, data); 499 } else 500 printf("[ Kerberos V5 refuses authentication ]\r\n"); 501 auth_send_retry(); 502 return; 503 case KRB_ACCEPT:{ 504 krb5_error_code ret; 505 Session_Key skey; 506 krb5_keyblock *keyblock; 507 508 if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL && 509 !mutual_complete) { 510 printf("[ Kerberos V5 accepted you, but didn't provide mutual authentication! ]\r\n"); 511 auth_send_retry(); 512 return; 513 } 514 if (cnt) 515 printf("[ Kerberos V5 accepts you as ``%.*s'' ]\r\n", cnt, data); 516 else 517 printf("[ Kerberos V5 accepts you ]\r\n"); 518 519 ret = krb5_auth_con_getlocalsubkey(telnet_context, 520 auth_context, &keyblock); 521 if (ret) 522 ret = krb5_auth_con_getkey(telnet_context, 523 auth_context, &keyblock); 524 if (ret) { 525 printf("[ krb5_auth_con_getkey: %s ]\r\n", 526 krb5_get_err_text(telnet_context, ret)); 527 auth_send_retry(); 528 return; 529 } 530 skey.type = SK_DES; 531 skey.length = 8; 532 skey.data = keyblock->keyvalue.data; 533 encrypt_session_key(&skey, 0); 534 krb5_free_keyblock(telnet_context, keyblock); 535 auth_finished(ap, AUTH_USER); 536 if (forward_flags & OPTS_FORWARD_CREDS) 537 kerberos5_forward(ap); 538 break; 539 } 540 case KRB_RESPONSE: 541 if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) { 542 /* the rest of the reply should contain a krb_ap_rep */ 543 krb5_ap_rep_enc_part *reply; 544 krb5_data inbuf; 545 krb5_error_code ret; 546 547 inbuf.length = cnt; 548 inbuf.data = (char *) data; 549 550 ret = krb5_rd_rep(telnet_context, 551 auth_context, &inbuf, &reply); 552 if (ret) { 553 printf("[ Mutual authentication failed: %s ]\r\n", 554 krb5_get_err_text(telnet_context, ret)); 555 auth_send_retry(); 556 return; 557 } 558 krb5_free_ap_rep_enc_part(telnet_context, reply); 559 mutual_complete = 1; 560 } 561 return; 562 case KRB_FORWARD_ACCEPT: 563 printf("[ Kerberos V5 accepted forwarded credentials ]\r\n"); 564 return; 565 case KRB_FORWARD_REJECT: 566 printf("[ Kerberos V5 refuses forwarded credentials because %.*s ]\r\n", 567 cnt, data); 568 return; 569 default: 570 if (auth_debug_mode) 571 printf("Unknown Kerberos option %d\r\n", data[-1]); 572 return; 573 } 574 } 575 576 int 577 kerberos5_status(Authenticator *ap, char *name, size_t l, int level) 578 { 579 if (level < AUTH_USER) 580 return (level); 581 582 if (UserNameRequested && 583 krb5_kuserok(telnet_context, ticket->client, UserNameRequested)) { 584 strlcpy(name, UserNameRequested, l); 585 return (AUTH_VALID); 586 } else 587 return (AUTH_USER); 588 } 589 #define BUMP(buf, len) while (*(buf)) {++(buf), --(len);} 590 #define ADDC(buf, len, c) if ((len) > 0) {*(buf)++ = (c); --(len);} 591 592 void 593 kerberos5_printsub(unsigned char *data, int cnt, unsigned char *buf, int buflen) 594 { 595 int i; 596 597 buf[buflen - 1] = '\0'; /* make sure its NULL terminated */ 598 buflen -= 1; 599 600 switch (data[3]) { 601 case KRB_REJECT: /* Rejected (reason might follow) */ 602 strlcpy((char *) buf, " REJECT ", buflen); 603 goto common; 604 605 case KRB_ACCEPT: /* Accepted (name might follow) */ 606 strlcpy((char *) buf, " ACCEPT ", buflen); 607 common: 608 BUMP(buf, buflen); 609 if (cnt <= 4) 610 break; 611 ADDC(buf, buflen, '"'); 612 for (i = 4; i < cnt; i++) 613 ADDC(buf, buflen, data[i]); 614 ADDC(buf, buflen, '"'); 615 ADDC(buf, buflen, '\0'); 616 break; 617 618 619 case KRB_AUTH: /* Authentication data follows */ 620 strlcpy((char *) buf, " AUTH", buflen); 621 goto common2; 622 623 case KRB_RESPONSE: 624 strlcpy((char *) buf, " RESPONSE", buflen); 625 goto common2; 626 627 case KRB_FORWARD: /* Forwarded credentials follow */ 628 strlcpy((char *) buf, " FORWARD", buflen); 629 goto common2; 630 631 case KRB_FORWARD_ACCEPT: /* Forwarded credentials accepted */ 632 strlcpy((char *) buf, " FORWARD_ACCEPT", buflen); 633 goto common2; 634 635 case KRB_FORWARD_REJECT: /* Forwarded credentials rejected */ 636 /* (reason might follow) */ 637 strlcpy((char *) buf, " FORWARD_REJECT", buflen); 638 goto common2; 639 640 default: 641 snprintf(buf, buflen, " %d (unknown)", data[3]); 642 common2: 643 BUMP(buf, buflen); 644 for (i = 4; i < cnt; i++) { 645 snprintf(buf, buflen, " %d", data[i]); 646 BUMP(buf, buflen); 647 } 648 break; 649 } 650 } 651 652 void 653 kerberos5_forward(Authenticator * ap) 654 { 655 krb5_error_code ret; 656 krb5_ccache ccache; 657 krb5_creds creds; 658 krb5_kdc_flags flags; 659 krb5_data out_data; 660 krb5_principal principal; 661 662 ret = krb5_cc_default(telnet_context, &ccache); 663 if (ret) { 664 if (auth_debug_mode) 665 printf("KerberosV5: could not get default ccache: %s\r\n", 666 krb5_get_err_text(telnet_context, ret)); 667 return; 668 } 669 ret = krb5_cc_get_principal(telnet_context, ccache, &principal); 670 if (ret) { 671 if (auth_debug_mode) 672 printf("KerberosV5: could not get principal: %s\r\n", 673 krb5_get_err_text(telnet_context, ret)); 674 return; 675 } 676 memset(&creds, 0, sizeof(creds)); 677 678 creds.client = principal; 679 680 ret = krb5_build_principal(telnet_context, &creds.server, 681 strlen(principal->realm), principal->realm, "krbtgt", 682 principal->realm, NULL); 683 684 if (ret) { 685 if (auth_debug_mode) 686 printf("KerberosV5: could not get principal: %s\r\n", 687 krb5_get_err_text(telnet_context, ret)); 688 return; 689 } 690 creds.times.endtime = 0; 691 692 flags.i = 0; 693 flags.b.forwarded = 1; 694 if (forward_flags & OPTS_FORWARDABLE_CREDS) 695 flags.b.forwardable = 1; 696 697 ret = krb5_get_forwarded_creds(telnet_context, auth_context, 698 ccache, flags.i, RemoteHostName, &creds, &out_data); 699 if (ret) { 700 if (auth_debug_mode) 701 printf("Kerberos V5: error getting forwarded creds: %s\r\n", 702 krb5_get_err_text(telnet_context, ret)); 703 return; 704 } 705 if (!Data(ap, KRB_FORWARD, out_data.data, out_data.length)) { 706 if (auth_debug_mode) 707 printf("Not enough room for authentication data\r\n"); 708 } else { 709 if (auth_debug_mode) 710 printf("Forwarded local Kerberos V5 credentials to server\r\n"); 711 } 712 } 713 #endif /* KRB5 */ 714