1 /* $NetBSD: kerberos5.c,v 1.12 2003/08/07 16:44:55 agc 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 return; 379 } 380 Data(ap, KRB_RESPONSE, outbuf.data, outbuf.length); 381 } 382 if (krb5_unparse_name(telnet_context, ticket->client, &name)) 383 name = 0; 384 385 if (UserNameRequested && krb5_kuserok(telnet_context, 386 ticket->client, UserNameRequested)) { 387 Data(ap, KRB_ACCEPT, name, name ? -1 : 0); 388 if (auth_debug_mode) { 389 printf("Kerberos5 identifies him as ``%s''\r\n", 390 name ? name : ""); 391 } 392 if (key_block->keytype == ETYPE_DES_CBC_MD5 || 393 key_block->keytype == ETYPE_DES_CBC_MD4 || 394 key_block->keytype == ETYPE_DES_CBC_CRC) { 395 Session_Key skey; 396 397 skey.type = SK_DES; 398 skey.length = 8; 399 skey.data = key_block->keyvalue.data; 400 encrypt_session_key(&skey, 0); 401 } 402 } else { 403 char *msg; 404 405 asprintf(&msg, "user `%s' is not authorized to " 406 "login as `%s'", 407 name ? name : "<unknown>", 408 UserNameRequested ? UserNameRequested : "<nobody>"); 409 if (msg == NULL) 410 Data(ap, KRB_REJECT, NULL, 0); 411 else { 412 Data(ap, KRB_REJECT, (void *) msg, -1); 413 free(msg); 414 } 415 auth_finished(ap, AUTH_REJECT); 416 krb5_free_keyblock_contents(telnet_context, key_block); 417 break; 418 } 419 auth_finished(ap, AUTH_USER); 420 krb5_free_keyblock_contents(telnet_context, key_block); 421 422 break; 423 case KRB_FORWARD:{ 424 struct passwd *pwd; 425 char ccname[1024]; /* XXX */ 426 krb5_data inbuf; 427 krb5_ccache ccache; 428 inbuf.data = (char *) data; 429 inbuf.length = cnt; 430 431 pwd = getpwnam(UserNameRequested); 432 if (pwd == NULL) 433 break; 434 435 snprintf(ccname, sizeof(ccname), 436 "FILE:/tmp/krb5cc_%u", pwd->pw_uid); 437 438 ret = krb5_cc_resolve(telnet_context, ccname, &ccache); 439 if (ret) { 440 if (auth_debug_mode) 441 printf("Kerberos V5: could not get ccache: %s\r\n", 442 krb5_get_err_text(telnet_context, 443 ret)); 444 break; 445 } 446 ret = krb5_cc_initialize(telnet_context, ccache, 447 ticket->client); 448 if (ret) { 449 if (auth_debug_mode) 450 printf("Kerberos V5: could not init ccache: %s\r\n", 451 krb5_get_err_text(telnet_context, 452 ret)); 453 break; 454 } 455 ret = krb5_rd_cred2(telnet_context, auth_context, 456 ccache, &inbuf); 457 if (ret) { 458 char *errbuf; 459 460 asprintf(&errbuf, 461 "Read forwarded creds failed: %s", 462 krb5_get_err_text(telnet_context, ret)); 463 if (errbuf == NULL) 464 Data(ap, KRB_FORWARD_REJECT, NULL, 0); 465 else 466 Data(ap, KRB_FORWARD_REJECT, errbuf, -1); 467 if (auth_debug_mode) 468 printf("Could not read forwarded credentials: %s\r\n", 469 errbuf); 470 free(errbuf); 471 } else 472 Data(ap, KRB_FORWARD_ACCEPT, 0, 0); 473 chown(ccname + 5, pwd->pw_uid, -1); 474 if (auth_debug_mode) 475 printf("Forwarded credentials obtained\r\n"); 476 break; 477 } 478 default: 479 if (auth_debug_mode) 480 printf("Unknown Kerberos option %d\r\n", data[-1]); 481 Data(ap, KRB_REJECT, 0, 0); 482 break; 483 } 484 } 485 486 void 487 kerberos5_reply(Authenticator * ap, unsigned char *data, int cnt) 488 { 489 static int mutual_complete = 0; 490 491 if (cnt-- < 1) 492 return; 493 switch (*data++) { 494 case KRB_REJECT: 495 if (cnt > 0) { 496 printf("[ Kerberos V5 refuses authentication because %.*s ]\r\n", 497 cnt, data); 498 } else 499 printf("[ Kerberos V5 refuses authentication ]\r\n"); 500 auth_send_retry(); 501 return; 502 case KRB_ACCEPT:{ 503 krb5_error_code ret; 504 Session_Key skey; 505 krb5_keyblock *keyblock; 506 507 if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL && 508 !mutual_complete) { 509 printf("[ Kerberos V5 accepted you, but didn't provide mutual authentication! ]\r\n"); 510 auth_send_retry(); 511 return; 512 } 513 if (cnt) 514 printf("[ Kerberos V5 accepts you as ``%.*s'' ]\r\n", cnt, data); 515 else 516 printf("[ Kerberos V5 accepts you ]\r\n"); 517 518 ret = krb5_auth_con_getlocalsubkey(telnet_context, 519 auth_context, &keyblock); 520 if (ret) 521 ret = krb5_auth_con_getkey(telnet_context, 522 auth_context, &keyblock); 523 if (ret) { 524 printf("[ krb5_auth_con_getkey: %s ]\r\n", 525 krb5_get_err_text(telnet_context, ret)); 526 auth_send_retry(); 527 return; 528 } 529 skey.type = SK_DES; 530 skey.length = 8; 531 skey.data = keyblock->keyvalue.data; 532 encrypt_session_key(&skey, 0); 533 krb5_free_keyblock_contents(telnet_context, keyblock); 534 auth_finished(ap, AUTH_USER); 535 if (forward_flags & OPTS_FORWARD_CREDS) 536 kerberos5_forward(ap); 537 break; 538 } 539 case KRB_RESPONSE: 540 if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) { 541 /* the rest of the reply should contain a krb_ap_rep */ 542 krb5_ap_rep_enc_part *reply; 543 krb5_data inbuf; 544 krb5_error_code ret; 545 546 inbuf.length = cnt; 547 inbuf.data = (char *) data; 548 549 ret = krb5_rd_rep(telnet_context, 550 auth_context, &inbuf, &reply); 551 if (ret) { 552 printf("[ Mutual authentication failed: %s ]\r\n", 553 krb5_get_err_text(telnet_context, ret)); 554 auth_send_retry(); 555 return; 556 } 557 krb5_free_ap_rep_enc_part(telnet_context, reply); 558 mutual_complete = 1; 559 } 560 return; 561 case KRB_FORWARD_ACCEPT: 562 printf("[ Kerberos V5 accepted forwarded credentials ]\r\n"); 563 return; 564 case KRB_FORWARD_REJECT: 565 printf("[ Kerberos V5 refuses forwarded credentials because %.*s ]\r\n", 566 cnt, data); 567 return; 568 default: 569 if (auth_debug_mode) 570 printf("Unknown Kerberos option %d\r\n", data[-1]); 571 return; 572 } 573 } 574 575 int 576 kerberos5_status(Authenticator *ap, char *name, size_t l, int level) 577 { 578 if (level < AUTH_USER) 579 return (level); 580 581 if (UserNameRequested && 582 krb5_kuserok(telnet_context, ticket->client, UserNameRequested)) { 583 strlcpy(name, UserNameRequested, l); 584 return (AUTH_VALID); 585 } else 586 return (AUTH_USER); 587 } 588 #define BUMP(buf, len) while (*(buf)) {++(buf), --(len);} 589 #define ADDC(buf, len, c) if ((len) > 0) {*(buf)++ = (c); --(len);} 590 591 void 592 kerberos5_printsub(unsigned char *data, int cnt, unsigned char *buf, int buflen) 593 { 594 int i; 595 596 buf[buflen - 1] = '\0'; /* make sure its NULL terminated */ 597 buflen -= 1; 598 599 switch (data[3]) { 600 case KRB_REJECT: /* Rejected (reason might follow) */ 601 strlcpy((char *) buf, " REJECT ", buflen); 602 goto common; 603 604 case KRB_ACCEPT: /* Accepted (name might follow) */ 605 strlcpy((char *) buf, " ACCEPT ", buflen); 606 common: 607 BUMP(buf, buflen); 608 if (cnt <= 4) 609 break; 610 ADDC(buf, buflen, '"'); 611 for (i = 4; i < cnt; i++) 612 ADDC(buf, buflen, data[i]); 613 ADDC(buf, buflen, '"'); 614 ADDC(buf, buflen, '\0'); 615 break; 616 617 618 case KRB_AUTH: /* Authentication data follows */ 619 strlcpy((char *) buf, " AUTH", buflen); 620 goto common2; 621 622 case KRB_RESPONSE: 623 strlcpy((char *) buf, " RESPONSE", buflen); 624 goto common2; 625 626 case KRB_FORWARD: /* Forwarded credentials follow */ 627 strlcpy((char *) buf, " FORWARD", buflen); 628 goto common2; 629 630 case KRB_FORWARD_ACCEPT: /* Forwarded credentials accepted */ 631 strlcpy((char *) buf, " FORWARD_ACCEPT", buflen); 632 goto common2; 633 634 case KRB_FORWARD_REJECT: /* Forwarded credentials rejected */ 635 /* (reason might follow) */ 636 strlcpy((char *) buf, " FORWARD_REJECT", buflen); 637 goto common2; 638 639 default: 640 snprintf(buf, buflen, " %d (unknown)", data[3]); 641 common2: 642 BUMP(buf, buflen); 643 for (i = 4; i < cnt; i++) { 644 snprintf(buf, buflen, " %d", data[i]); 645 BUMP(buf, buflen); 646 } 647 break; 648 } 649 } 650 651 void 652 kerberos5_forward(Authenticator * ap) 653 { 654 krb5_error_code ret; 655 krb5_ccache ccache; 656 krb5_creds creds; 657 krb5_kdc_flags flags; 658 krb5_data out_data; 659 krb5_principal principal; 660 661 ret = krb5_cc_default(telnet_context, &ccache); 662 if (ret) { 663 if (auth_debug_mode) 664 printf("KerberosV5: could not get default ccache: %s\r\n", 665 krb5_get_err_text(telnet_context, ret)); 666 return; 667 } 668 ret = krb5_cc_get_principal(telnet_context, ccache, &principal); 669 if (ret) { 670 if (auth_debug_mode) 671 printf("KerberosV5: could not get principal: %s\r\n", 672 krb5_get_err_text(telnet_context, ret)); 673 return; 674 } 675 memset(&creds, 0, sizeof(creds)); 676 677 creds.client = principal; 678 679 ret = krb5_build_principal(telnet_context, &creds.server, 680 strlen(principal->realm), principal->realm, "krbtgt", 681 principal->realm, NULL); 682 683 if (ret) { 684 if (auth_debug_mode) 685 printf("KerberosV5: could not get principal: %s\r\n", 686 krb5_get_err_text(telnet_context, ret)); 687 return; 688 } 689 creds.times.endtime = 0; 690 691 flags.i = 0; 692 flags.b.forwarded = 1; 693 if (forward_flags & OPTS_FORWARDABLE_CREDS) 694 flags.b.forwardable = 1; 695 696 ret = krb5_get_forwarded_creds(telnet_context, auth_context, 697 ccache, flags.i, RemoteHostName, &creds, &out_data); 698 if (ret) { 699 if (auth_debug_mode) 700 printf("Kerberos V5: error getting forwarded creds: %s\r\n", 701 krb5_get_err_text(telnet_context, ret)); 702 return; 703 } 704 if (!Data(ap, KRB_FORWARD, out_data.data, out_data.length)) { 705 if (auth_debug_mode) 706 printf("Not enough room for authentication data\r\n"); 707 } else { 708 if (auth_debug_mode) 709 printf("Forwarded local Kerberos V5 credentials to server\r\n"); 710 } 711 } 712 #endif /* KRB5 */ 713