kerberos5.c revision 84305
1/* 2 * $Source: /mit/krb5/.cvsroot/src/appl/telnet/libtelnet/kerberos5.c,v $ 3 * $Author: tytso $ 4 * $Id: kerberos5.c,v 1.1 1997/09/04 06:11:15 markm Exp $ 5 */ 6 7#include <sys/cdefs.h> 8__FBSDID("$FreeBSD: head/contrib/telnet/libtelnet/kerberos5.c 84305 2001-10-01 16:04:55Z markm $"); 9 10/*- 11 * Copyright (c) 1991, 1993 12 * The Regents of the University of California. All rights reserved. 13 * 14 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions 16 * are met: 17 * 1. Redistributions of source code must retain the above copyright 18 * notice, this list of conditions and the following disclaimer. 19 * 2. Redistributions in binary form must reproduce the above copyright 20 * notice, this list of conditions and the following disclaimer in the 21 * documentation and/or other materials provided with the distribution. 22 * 3. All advertising materials mentioning features or use of this software 23 * must display the following acknowledgement: 24 * This product includes software developed by the University of 25 * California, Berkeley and its contributors. 26 * 4. Neither the name of the University nor the names of its contributors 27 * may be used to endorse or promote products derived from this software 28 * without specific prior written permission. 29 * 30 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 31 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 32 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 33 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 34 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 35 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 36 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 37 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 38 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 39 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 40 * SUCH DAMAGE. 41 */ 42 43#ifndef lint 44static const char sccsid[] = "@(#)kerberos5.c 8.3 (Berkeley) 5/30/95"; 45#endif /* not lint */ 46 47/* 48 * Copyright (C) 1990 by the Massachusetts Institute of Technology 49 * 50 * Export of this software from the United States of America may 51 * require a specific license from the United States Government. 52 * It is the responsibility of any person or organization contemplating 53 * export to obtain such a license before exporting. 54 * 55 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 56 * distribute this software and its documentation for any purpose and 57 * without fee is hereby granted, provided that the above copyright 58 * notice appear in all copies and that both that copyright notice and 59 * this permission notice appear in supporting documentation, and that 60 * the name of M.I.T. not be used in advertising or publicity pertaining 61 * to distribution of the software without specific, written prior 62 * permission. M.I.T. makes no representations about the suitability of 63 * this software for any purpose. It is provided "as is" without express 64 * or implied warranty. 65 */ 66 67 68#ifdef KRB5 69#include <arpa/telnet.h> 70#include <com_err.h> 71#include <ctype.h> 72#include <krb5.h> 73#include <krb5_asn1.h> 74#include <netdb.h> 75#include <stdio.h> 76#include <stdlib.h> 77#include <string.h> 78 79/* kerberos 5 include files (ext-proto.h) will get an appropriate stdlib.h 80 and string.h/strings.h */ 81 82#include "encrypt.h" 83#include "auth.h" 84#include "misc.h" 85 86extern int auth_debug_mode; 87 88#ifdef FORWARD 89int forward_flags = 0; /* Flags get set in telnet/main.c on -f and -F */ 90 91/* These values need to be the same as those defined in telnet/main.c. */ 92/* Either define them in both places, or put in some common header file. */ 93#define OPTS_FORWARD_CREDS 0x00000002 94#define OPTS_FORWARDABLE_CREDS 0x00000001 95 96void kerberos5_forward(); 97 98#endif /* FORWARD */ 99 100static unsigned char str_data[1024] = { IAC, SB, TELOPT_AUTHENTICATION, 0, 101 AUTHTYPE_KERBEROS_V5, }; 102/*static unsigned char str_name[1024] = { IAC, SB, TELOPT_AUTHENTICATION, 103 TELQUAL_NAME, };*/ 104 105#define KRB_AUTH 0 /* Authentication data follows */ 106#define KRB_REJECT 1 /* Rejected (reason might follow) */ 107#define KRB_ACCEPT 2 /* Accepted */ 108#define KRB_RESPONSE 3 /* Response for mutual auth. */ 109 110#ifdef FORWARD 111#define KRB_FORWARD 4 /* Forwarded credentials follow */ 112#define KRB_FORWARD_ACCEPT 5 /* Forwarded credentials accepted */ 113#define KRB_FORWARD_REJECT 6 /* Forwarded credentials rejected */ 114#endif /* FORWARD */ 115 116static krb5_data auth; 117 /* telnetd gets session key from here */ 118static krb5_tkt_authent *authdat = NULL; 119/* telnet matches the AP_REQ and AP_REP with this */ 120static krb5_authenticator authenticator; 121 122/* some compilers can't hack void *, so we use the Kerberos krb5_pointer, 123 which is either void * or char *, depending on the compiler. */ 124 125#define Voidptr krb5_pointer 126 127Block session_key; 128 129 static int 130Data(ap, type, d, c) 131 Authenticator *ap; 132 int type; 133 Voidptr d; 134 int c; 135{ 136 unsigned char *p = str_data + 4; 137 unsigned char *cd = (unsigned char *)d; 138 139 if (c == -1) 140 c = strlen((char *)cd); 141 142 if (auth_debug_mode) { 143 printf("%s:%d: [%d] (%d)", 144 str_data[3] == TELQUAL_IS ? ">>>IS" : ">>>REPLY", 145 str_data[3], 146 type, c); 147 printd(d, c); 148 printf("\r\n"); 149 } 150 *p++ = ap->type; 151 *p++ = ap->way; 152 *p++ = type; 153 while (c-- > 0) { 154 if ((*p++ = *cd++) == IAC) 155 *p++ = IAC; 156 } 157 *p++ = IAC; 158 *p++ = SE; 159 if (str_data[3] == TELQUAL_IS) 160 printsub('>', &str_data[2], p - &str_data[2]); 161 return(net_write(str_data, p - str_data)); 162} 163 164 int 165kerberos5_init(ap, server) 166 Authenticator *ap; 167 int server; 168{ 169 if (server) 170 str_data[3] = TELQUAL_REPLY; 171 else 172 str_data[3] = TELQUAL_IS; 173 krb5_init_ets(); 174 return(1); 175} 176 177 int 178kerberos5_send(ap) 179 Authenticator *ap; 180{ 181 char **realms; 182 char *name; 183 char *p1, *p2; 184 krb5_checksum ksum; 185 krb5_octet sum[CRC32_CKSUM_LENGTH]; 186 krb5_principal server; 187 krb5_error_code r; 188 krb5_ccache ccache; 189 krb5_creds creds; /* telnet gets session key from here */ 190 extern krb5_flags krb5_kdc_default_options; 191 int ap_opts; 192 193#ifdef ENCRYPTION 194 krb5_keyblock *newkey = 0; 195#endif /* ENCRYPTION */ 196 197 ksum.checksum_type = CKSUMTYPE_CRC32; 198 ksum.contents = sum; 199 ksum.length = sizeof(sum); 200 memset((Voidptr )sum, 0, sizeof(sum)); 201 202 if (!UserNameRequested) { 203 if (auth_debug_mode) { 204 printf("Kerberos V5: no user name supplied\r\n"); 205 } 206 return(0); 207 } 208 209 if (r = krb5_cc_default(&ccache)) { 210 if (auth_debug_mode) { 211 printf("Kerberos V5: could not get default ccache\r\n"); 212 } 213 return(0); 214 } 215 216 if ((name = malloc(strlen(RemoteHostName)+1)) == NULL) { 217 if (auth_debug_mode) 218 printf("Out of memory for hostname in Kerberos V5\r\n"); 219 return(0); 220 } 221 222 if (r = krb5_get_host_realm(RemoteHostName, &realms)) { 223 if (auth_debug_mode) 224 printf("Kerberos V5: no realm for %s\r\n", RemoteHostName); 225 free(name); 226 return(0); 227 } 228 229 p1 = RemoteHostName; 230 p2 = name; 231 232 while (*p2 = *p1++) { 233 if (isupper(*p2)) 234 *p2 |= 040; 235 ++p2; 236 } 237 238 if (r = krb5_build_principal_ext(&server, 239 strlen(realms[0]), realms[0], 240 4, "host", 241 p2 - name, name, 242 0)) { 243 if (auth_debug_mode) { 244 printf("Kerberos V5: failure setting up principal (%s)\r\n", 245 error_message(r)); 246 } 247 free(name); 248 krb5_free_host_realm(realms); 249 return(0); 250 } 251 252 253 memset((char *)&creds, 0, sizeof(creds)); 254 creds.server = server; 255 256 if (r = krb5_cc_get_principal(ccache, &creds.client)) { 257 if (auth_debug_mode) { 258 printf("Kerberos V5: failure on principal (%s)\r\n", 259 error_message(r)); 260 } 261 free(name); 262 krb5_free_principal(server); 263 krb5_free_host_realm(realms); 264 return(0); 265 } 266 267 if (r = krb5_get_credentials(krb5_kdc_default_options, ccache, &creds)) { 268 if (auth_debug_mode) { 269 printf("Kerberos V5: failure on credentials(%d)\r\n",r); 270 } 271 free(name); 272 krb5_free_host_realm(realms); 273 krb5_free_principal(server); 274 return(0); 275 } 276 277 if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) 278 ap_opts = AP_OPTS_MUTUAL_REQUIRED; 279 else 280 ap_opts = 0; 281 282 r = krb5_mk_req_extended(ap_opts, &ksum, krb5_kdc_default_options, 0, 283#ifdef ENCRYPTION 284 &newkey, 285#else /* ENCRYPTION */ 286 0, 287#endif /* ENCRYPTION */ 288 ccache, &creds, &authenticator, &auth); 289 /* don't let the key get freed if we clean up the authenticator */ 290 authenticator.subkey = 0; 291 292 free(name); 293 krb5_free_host_realm(realms); 294 krb5_free_principal(server); 295#ifdef ENCRYPTION 296 if (newkey) { 297 /* keep the key in our private storage, but don't use it 298 yet---see kerberos5_reply() below */ 299 if (newkey->keytype != KEYTYPE_DES) { 300 if (creds.keyblock.keytype == KEYTYPE_DES) 301 /* use the session key in credentials instead */ 302 memmove((char *)session_key, 303 (char *)creds.keyblock.contents, sizeof(Block)); 304 else 305 /* XXX ? */; 306 } else { 307 memmove((char *)session_key, (char *)newkey->contents, 308 sizeof(Block)); 309 } 310 krb5_free_keyblock(newkey); 311 } 312#endif /* ENCRYPTION */ 313 if (r) { 314 if (auth_debug_mode) { 315 printf("Kerberos V5: mk_req failed (%s)\r\n", 316 error_message(r)); 317 } 318 return(0); 319 } 320 321 if (!auth_sendname(UserNameRequested, strlen(UserNameRequested))) { 322 if (auth_debug_mode) 323 printf("Not enough room for user name\r\n"); 324 return(0); 325 } 326 if (!Data(ap, KRB_AUTH, auth.data, auth.length)) { 327 if (auth_debug_mode) 328 printf("Not enough room for authentication data\r\n"); 329 return(0); 330 } 331 if (auth_debug_mode) { 332 printf("Sent Kerberos V5 credentials to server\r\n"); 333 } 334 return(1); 335} 336 337 void 338kerberos5_is(ap, data, cnt) 339 Authenticator *ap; 340 unsigned char *data; 341 int cnt; 342{ 343 int r; 344 struct hostent *hp; 345 char *p1, *p2; 346 static char *realm = NULL; 347 krb5_principal server; 348 krb5_ap_rep_enc_part reply; 349 krb5_data outbuf; 350#ifdef ENCRYPTION 351 Session_Key skey; 352#endif /* ENCRYPTION */ 353 char *name; 354 char *getenv(); 355 krb5_data inbuf; 356 357 if (cnt-- < 1) 358 return; 359 switch (*data++) { 360 case KRB_AUTH: 361 auth.data = (char *)data; 362 auth.length = cnt; 363 364 if (!(hp = gethostbyname(LocalHostName))) { 365 if (auth_debug_mode) 366 printf("Cannot resolve local host name\r\n"); 367 Data(ap, KRB_REJECT, "Unknown local hostname.", -1); 368 auth_finished(ap, AUTH_REJECT); 369 return; 370 } 371 372 if (!realm && (krb5_get_default_realm(&realm))) { 373 if (auth_debug_mode) 374 printf("Could not get default realm\r\n"); 375 Data(ap, KRB_REJECT, "Could not get default realm.", -1); 376 auth_finished(ap, AUTH_REJECT); 377 return; 378 } 379 380 if ((name = malloc(strlen(hp->h_name)+1)) == NULL) { 381 if (auth_debug_mode) 382 printf("Out of memory for hostname in Kerberos V5\r\n"); 383 Data(ap, KRB_REJECT, "Out of memory.", -1); 384 auth_finished(ap, AUTH_REJECT); 385 return; 386 } 387 388 p1 = hp->h_name; 389 p2 = name; 390 391 while (*p2 = *p1++) { 392 if (isupper(*p2)) 393 *p2 |= 040; 394 ++p2; 395 } 396 397 if (authdat) 398 krb5_free_tkt_authent(authdat); 399 400 r = krb5_build_principal_ext(&server, 401 strlen(realm), realm, 402 4, "host", 403 p2 - name, name, 404 0); 405 if (!r) { 406 r = krb5_rd_req_simple(&auth, server, 0, &authdat); 407 krb5_free_principal(server); 408 } 409 if (r) { 410 char errbuf[128]; 411 412 errout: 413 authdat = 0; 414 (void) strcpy(errbuf, "Read req failed: "); 415 (void) strcat(errbuf, error_message(r)); 416 Data(ap, KRB_REJECT, errbuf, -1); 417 if (auth_debug_mode) 418 printf("%s\r\n", errbuf); 419 return; 420 } 421 free(name); 422 if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) { 423 /* do ap_rep stuff here */ 424 reply.ctime = authdat->authenticator->ctime; 425 reply.cusec = authdat->authenticator->cusec; 426 reply.subkey = 0; /* use the one he gave us, so don't 427 need to return one here */ 428 reply.seq_number = 0; /* we don't do seq #'s. */ 429 430 if (r = krb5_mk_rep(&reply, 431 authdat->authenticator->subkey ? 432 authdat->authenticator->subkey : 433 authdat->ticket->enc_part2->session, 434 &outbuf)) { 435 goto errout; 436 } 437 Data(ap, KRB_RESPONSE, outbuf.data, outbuf.length); 438 } 439 if (krb5_unparse_name(authdat->ticket->enc_part2 ->client, 440 &name)) 441 name = 0; 442 Data(ap, KRB_ACCEPT, name, name ? -1 : 0); 443 if (auth_debug_mode) { 444 printf("Kerberos5 identifies him as ``%s''\r\n", 445 name ? name : ""); 446 } 447 auth_finished(ap, AUTH_USER); 448 449 free(name); 450 if (authdat->authenticator->subkey && 451 authdat->authenticator->subkey->keytype == KEYTYPE_DES) { 452 memmove((Voidptr )session_key, 453 (Voidptr )authdat->authenticator->subkey->contents, 454 sizeof(Block)); 455 } else if (authdat->ticket->enc_part2->session->keytype == 456 KEYTYPE_DES) { 457 memmove((Voidptr )session_key, 458 (Voidptr )authdat->ticket->enc_part2->session->contents, 459 sizeof(Block)); 460 } else 461 break; 462 463#ifdef ENCRYPTION 464 skey.type = SK_DES; 465 skey.length = 8; 466 skey.data = session_key; 467 encrypt_session_key(&skey, 1); 468#endif /* ENCRYPTION */ 469 break; 470#ifdef FORWARD 471 case KRB_FORWARD: 472 inbuf.data = (char *)data; 473 inbuf.length = cnt; 474 if (r = rd_and_store_for_creds(&inbuf, authdat->ticket, 475 UserNameRequested)) { 476 char errbuf[128]; 477 478 (void) strcpy(errbuf, "Read forwarded creds failed: "); 479 (void) strcat(errbuf, error_message(r)); 480 Data(ap, KRB_FORWARD_REJECT, errbuf, -1); 481 if (auth_debug_mode) 482 printf("Could not read forwarded credentials\r\n"); 483 } 484 else 485 Data(ap, KRB_FORWARD_ACCEPT, 0, 0); 486 if (auth_debug_mode) 487 printf("Forwarded credentials obtained\r\n"); 488 break; 489#endif /* FORWARD */ 490 default: 491 if (auth_debug_mode) 492 printf("Unknown Kerberos option %d\r\n", data[-1]); 493 Data(ap, KRB_REJECT, 0, 0); 494 break; 495 } 496} 497 498 void 499kerberos5_reply(ap, data, cnt) 500 Authenticator *ap; 501 unsigned char *data; 502 int cnt; 503{ 504 Session_Key skey; 505 static int mutual_complete = 0; 506 507 if (cnt-- < 1) 508 return; 509 switch (*data++) { 510 case KRB_REJECT: 511 if (cnt > 0) { 512 printf("[ Kerberos V5 refuses authentication because %.*s ]\r\n", 513 cnt, data); 514 } else 515 printf("[ Kerberos V5 refuses authentication ]\r\n"); 516 auth_send_retry(); 517 return; 518 case KRB_ACCEPT: 519 if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL && 520 !mutual_complete) { 521 printf("[ Kerberos V5 accepted you, but didn't provide mutual authentication! ]\n"); 522 auth_send_retry(); 523 return; 524 } 525 if (cnt) 526 printf("[ Kerberos V5 accepts you as ``%.*s'' ]\n", cnt, data); 527 else 528 printf("[ Kerberos V5 accepts you ]\n"); 529 auth_finished(ap, AUTH_USER); 530#ifdef FORWARD 531 if (forward_flags & OPTS_FORWARD_CREDS) 532 kerberos5_forward(ap); 533#endif /* FORWARD */ 534 break; 535 case KRB_RESPONSE: 536 if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) { 537 /* the rest of the reply should contain a krb_ap_rep */ 538 krb5_ap_rep_enc_part *reply; 539 krb5_data inbuf; 540 krb5_error_code r; 541 krb5_keyblock tmpkey; 542 543 inbuf.length = cnt; 544 inbuf.data = (char *)data; 545 546 tmpkey.keytype = KEYTYPE_DES; 547 tmpkey.contents = session_key; 548 tmpkey.length = sizeof(Block); 549 550 if (r = krb5_rd_rep(&inbuf, &tmpkey, &reply)) { 551 printf("[ Mutual authentication failed: %s ]\n", 552 error_message(r)); 553 auth_send_retry(); 554 return; 555 } 556 if (reply->ctime != authenticator.ctime || 557 reply->cusec != authenticator.cusec) { 558 printf("[ Mutual authentication failed (mismatched KRB_AP_REP) ]\n"); 559 auth_send_retry(); 560 return; 561 } 562 krb5_free_ap_rep_enc_part(reply); 563#ifdef ENCRYPTION 564 skey.type = SK_DES; 565 skey.length = 8; 566 skey.data = session_key; 567 encrypt_session_key(&skey, 0); 568#endif /* ENCRYPTION */ 569 mutual_complete = 1; 570 } 571 return; 572#ifdef FORWARD 573 case KRB_FORWARD_ACCEPT: 574 printf("[ Kerberos V5 accepted forwarded credentials ]\n"); 575 return; 576 case KRB_FORWARD_REJECT: 577 printf("[ Kerberos V5 refuses forwarded credentials because %.*s ]\r\n", 578 cnt, data); 579 return; 580#endif /* FORWARD */ 581 default: 582 if (auth_debug_mode) 583 printf("Unknown Kerberos option %d\r\n", data[-1]); 584 return; 585 } 586} 587 588 int 589kerberos5_status(ap, name, level) 590 Authenticator *ap; 591 char *name; 592 int level; 593{ 594 if (level < AUTH_USER) 595 return(level); 596 597 if (UserNameRequested && 598 krb5_kuserok(authdat->ticket->enc_part2->client, UserNameRequested)) 599 { 600 strcpy(name, UserNameRequested); 601 return(AUTH_VALID); 602 } else 603 return(AUTH_USER); 604} 605 606#define BUMP(buf, len) while (*(buf)) {++(buf), --(len);} 607#define ADDC(buf, len, c) if ((len) > 0) {*(buf)++ = (c); --(len);} 608 609 void 610kerberos5_printsub(data, cnt, buf, buflen) 611 unsigned char *data, *buf; 612 int cnt, buflen; 613{ 614 char lbuf[32]; 615 register int i; 616 617 buf[buflen-1] = '\0'; /* make sure its NULL terminated */ 618 buflen -= 1; 619 620 switch(data[3]) { 621 case KRB_REJECT: /* Rejected (reason might follow) */ 622 strncpy((char *)buf, " REJECT ", buflen); 623 goto common; 624 625 case KRB_ACCEPT: /* Accepted (name might follow) */ 626 strncpy((char *)buf, " ACCEPT ", buflen); 627 common: 628 BUMP(buf, buflen); 629 if (cnt <= 4) 630 break; 631 ADDC(buf, buflen, '"'); 632 for (i = 4; i < cnt; i++) 633 ADDC(buf, buflen, data[i]); 634 ADDC(buf, buflen, '"'); 635 ADDC(buf, buflen, '\0'); 636 break; 637 638 639 case KRB_AUTH: /* Authentication data follows */ 640 strncpy((char *)buf, " AUTH", buflen); 641 goto common2; 642 643 case KRB_RESPONSE: 644 strncpy((char *)buf, " RESPONSE", buflen); 645 goto common2; 646 647#ifdef FORWARD 648 case KRB_FORWARD: /* Forwarded credentials follow */ 649 strncpy((char *)buf, " FORWARD", buflen); 650 goto common2; 651 652 case KRB_FORWARD_ACCEPT: /* Forwarded credentials accepted */ 653 strncpy((char *)buf, " FORWARD_ACCEPT", buflen); 654 goto common2; 655 656 case KRB_FORWARD_REJECT: /* Forwarded credentials rejected */ 657 /* (reason might follow) */ 658 strncpy((char *)buf, " FORWARD_REJECT", buflen); 659 goto common2; 660#endif /* FORWARD */ 661 662 default: 663 sprintf(lbuf, " %d (unknown)", data[3]); 664 strncpy((char *)buf, lbuf, buflen); 665 common2: 666 BUMP(buf, buflen); 667 for (i = 4; i < cnt; i++) { 668 sprintf(lbuf, " %d", data[i]); 669 strncpy((char *)buf, lbuf, buflen); 670 BUMP(buf, buflen); 671 } 672 break; 673 } 674} 675 676#ifdef FORWARD 677 void 678kerberos5_forward(ap) 679 Authenticator *ap; 680{ 681 struct hostent *hp; 682 krb5_creds *local_creds; 683 krb5_error_code r; 684 krb5_data forw_creds; 685 extern krb5_cksumtype krb5_kdc_req_sumtype; 686 krb5_ccache ccache; 687 int i; 688 689 if (!(local_creds = (krb5_creds *) 690 calloc(1, sizeof(*local_creds)))) { 691 if (auth_debug_mode) 692 printf("Kerberos V5: could not allocate memory for credentials\r\n"); 693 return; 694 } 695 696 if (r = krb5_sname_to_principal(RemoteHostName, "host", 1, 697 &local_creds->server)) { 698 if (auth_debug_mode) 699 printf("Kerberos V5: could not build server name - %s\r\n", 700 error_message(r)); 701 krb5_free_creds(local_creds); 702 return; 703 } 704 705 if (r = krb5_cc_default(&ccache)) { 706 if (auth_debug_mode) 707 printf("Kerberos V5: could not get default ccache - %s\r\n", 708 error_message(r)); 709 krb5_free_creds(local_creds); 710 return; 711 } 712 713 if (r = krb5_cc_get_principal(ccache, &local_creds->client)) { 714 if (auth_debug_mode) 715 printf("Kerberos V5: could not get default principal - %s\r\n", 716 error_message(r)); 717 krb5_free_creds(local_creds); 718 return; 719 } 720 721 /* Get ticket from credentials cache */ 722 if (r = krb5_get_credentials(KRB5_GC_CACHED, ccache, local_creds)) { 723 if (auth_debug_mode) 724 printf("Kerberos V5: could not obtain credentials - %s\r\n", 725 error_message(r)); 726 krb5_free_creds(local_creds); 727 return; 728 } 729 730 if (r = get_for_creds(ETYPE_DES_CBC_CRC, 731 krb5_kdc_req_sumtype, 732 RemoteHostName, 733 local_creds->client, 734 &local_creds->keyblock, 735 forward_flags & OPTS_FORWARDABLE_CREDS, 736 &forw_creds)) { 737 if (auth_debug_mode) 738 printf("Kerberos V5: error getting forwarded creds - %s\r\n", 739 error_message(r)); 740 krb5_free_creds(local_creds); 741 return; 742 } 743 744 /* Send forwarded credentials */ 745 if (!Data(ap, KRB_FORWARD, forw_creds.data, forw_creds.length)) { 746 if (auth_debug_mode) 747 printf("Not enough room for authentication data\r\n"); 748 } 749 else { 750 if (auth_debug_mode) 751 printf("Forwarded local Kerberos V5 credentials to server\r\n"); 752 } 753 754 krb5_free_creds(local_creds); 755} 756#endif /* FORWARD */ 757 758#endif /* KRB5 */ 759