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