1/*- 2 * Copyright (c) 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34/* 35 * Copyright (C) 1990 by the Massachusetts Institute of Technology 36 * 37 * Export of this software from the United States of America is assumed 38 * to require a specific license from the United States Government. 39 * It is the responsibility of any person or organization contemplating 40 * export to obtain such a license before exporting. 41 * 42 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 43 * distribute this software and its documentation for any purpose and 44 * without fee is hereby granted, provided that the above copyright 45 * notice appear in all copies and that both that copyright notice and 46 * this permission notice appear in supporting documentation, and that 47 * the name of M.I.T. not be used in advertising or publicity pertaining 48 * to distribution of the software without specific, written prior 49 * permission. M.I.T. makes no representations about the suitability of 50 * this software for any purpose. It is provided "as is" without express 51 * or implied warranty. 52 */ 53 54#ifdef HAVE_CONFIG_H 55#include <config.h> 56#endif 57 58RCSID("$Id: kerberos.c 22071 2007-11-14 20:04:50Z lha $"); 59 60#ifdef KRB4 61#ifdef HAVE_SYS_TYPES_H 62#include <sys/types.h> 63#endif 64#ifdef HAVE_ARPA_TELNET_H 65#include <arpa/telnet.h> 66#endif 67#include <stdio.h> 68#include <krb.h> 69#include <pwd.h> 70#include <stdlib.h> 71#include <string.h> 72#include <roken.h> 73#ifdef SOCKS 74#include <socks.h> 75#endif 76 77 78#include "encrypt.h" 79#include "auth.h" 80#include "misc.h" 81 82int kerberos4_cksum (unsigned char *, int); 83extern int auth_debug_mode; 84 85static unsigned char str_data[2048] = { IAC, SB, TELOPT_AUTHENTICATION, 0, 86 AUTHTYPE_KERBEROS_V4, }; 87 88#define KRB_AUTH 0 /* Authentication data follows */ 89#define KRB_REJECT 1 /* Rejected (reason might follow) */ 90#define KRB_ACCEPT 2 /* Accepted */ 91#define KRB_CHALLENGE 3 /* Challenge for mutual auth. */ 92#define KRB_RESPONSE 4 /* Response for mutual auth. */ 93 94#define KRB_FORWARD 5 /* */ 95#define KRB_FORWARD_ACCEPT 6 /* */ 96#define KRB_FORWARD_REJECT 7 /* */ 97 98#define KRB_SERVICE_NAME "rcmd" 99 100static KTEXT_ST auth; 101static char name[ANAME_SZ]; 102static AUTH_DAT adat; 103static des_cblock session_key; 104static des_cblock cred_session; 105static des_key_schedule sched; 106static des_cblock challenge; 107static int auth_done; /* XXX */ 108 109static int pack_cred(CREDENTIALS *cred, unsigned char *buf); 110static int unpack_cred(unsigned char *buf, int len, CREDENTIALS *cred); 111 112 113static int 114Data(Authenticator *ap, int type, const void *d, int c) 115{ 116 unsigned char *p = str_data + 4; 117 const unsigned char *cd = (const unsigned char *)d; 118 119 if (c == -1) 120 c = strlen((const char *)cd); 121 122 if (auth_debug_mode) { 123 printf("%s:%d: [%d] (%d)", 124 str_data[3] == TELQUAL_IS ? ">>>IS" : ">>>REPLY", 125 str_data[3], 126 type, c); 127 printd(d, c); 128 printf("\r\n"); 129 } 130 *p++ = ap->type; 131 *p++ = ap->way; 132 *p++ = type; 133 while (c-- > 0) { 134 if ((*p++ = *cd++) == IAC) 135 *p++ = IAC; 136 } 137 *p++ = IAC; 138 *p++ = SE; 139 if (str_data[3] == TELQUAL_IS) 140 printsub('>', &str_data[2], p - (&str_data[2])); 141 return(telnet_net_write(str_data, p - str_data)); 142} 143 144int 145kerberos4_init(Authenticator *ap, int server) 146{ 147 FILE *fp; 148 149 if (server) { 150 str_data[3] = TELQUAL_REPLY; 151 if ((fp = fopen(KEYFILE, "r")) == NULL) 152 return(0); 153 fclose(fp); 154 } else { 155 str_data[3] = TELQUAL_IS; 156 } 157 return(1); 158} 159 160char dst_realm_buf[REALM_SZ], *dest_realm = NULL; 161int dst_realm_sz = REALM_SZ; 162 163static int 164kerberos4_send(char *name, Authenticator *ap) 165{ 166 KTEXT_ST auth; 167 char instance[INST_SZ]; 168 char *realm; 169 CREDENTIALS cred; 170 int r; 171 172 if (!UserNameRequested) { 173 if (auth_debug_mode) { 174 printf("Kerberos V4: no user name supplied\r\n"); 175 } 176 return(0); 177 } 178 179 memset(instance, 0, sizeof(instance)); 180 181 strlcpy (instance, 182 krb_get_phost(RemoteHostName), 183 INST_SZ); 184 185 realm = dest_realm ? dest_realm : krb_realmofhost(RemoteHostName); 186 187 if (!realm) { 188 printf("Kerberos V4: no realm for %s\r\n", RemoteHostName); 189 return(0); 190 } 191 printf("[ Trying %s (%s.%s@%s) ... ]\r\n", name, 192 KRB_SERVICE_NAME, instance, realm); 193 r = krb_mk_req(&auth, KRB_SERVICE_NAME, instance, realm, 0L); 194 if (r) { 195 printf("mk_req failed: %s\r\n", krb_get_err_text(r)); 196 return(0); 197 } 198 r = krb_get_cred(KRB_SERVICE_NAME, instance, realm, &cred); 199 if (r) { 200 printf("get_cred failed: %s\r\n", krb_get_err_text(r)); 201 return(0); 202 } 203 if (!auth_sendname((unsigned char*)UserNameRequested, 204 strlen(UserNameRequested))) { 205 if (auth_debug_mode) 206 printf("Not enough room for user name\r\n"); 207 return(0); 208 } 209 if (auth_debug_mode) 210 printf("Sent %d bytes of authentication data\r\n", auth.length); 211 if (!Data(ap, KRB_AUTH, (void *)auth.dat, auth.length)) { 212 if (auth_debug_mode) 213 printf("Not enough room for authentication data\r\n"); 214 return(0); 215 } 216#ifdef ENCRYPTION 217 /* create challenge */ 218 if ((ap->way & AUTH_HOW_MASK)==AUTH_HOW_MUTUAL) { 219 int i; 220 221 des_key_sched(&cred.session, sched); 222 memcpy (&cred_session, &cred.session, sizeof(cred_session)); 223#ifndef HAVE_OPENSSL 224 des_init_random_number_generator(&cred.session); 225#endif 226 des_new_random_key(&session_key); 227 des_ecb_encrypt(&session_key, &session_key, sched, 0); 228 des_ecb_encrypt(&session_key, &challenge, sched, 0); 229 230 /* 231 old code 232 Some CERT Advisory thinks this is a bad thing... 233 234 des_init_random_number_generator(&cred.session); 235 des_new_random_key(&challenge); 236 des_ecb_encrypt(&challenge, &session_key, sched, 1); 237 */ 238 239 /* 240 * Increment the challenge by 1, and encrypt it for 241 * later comparison. 242 */ 243 for (i = 7; i >= 0; --i) 244 if(++challenge[i] != 0) /* No carry! */ 245 break; 246 des_ecb_encrypt(&challenge, &challenge, sched, 1); 247 } 248 249#endif 250 251 if (auth_debug_mode) { 252 printf("CK: %d:", kerberos4_cksum(auth.dat, auth.length)); 253 printd(auth.dat, auth.length); 254 printf("\r\n"); 255 printf("Sent Kerberos V4 credentials to server\r\n"); 256 } 257 return(1); 258} 259int 260kerberos4_send_mutual(Authenticator *ap) 261{ 262 return kerberos4_send("mutual KERBEROS4", ap); 263} 264 265int 266kerberos4_send_oneway(Authenticator *ap) 267{ 268 return kerberos4_send("KERBEROS4", ap); 269} 270 271void 272kerberos4_is(Authenticator *ap, unsigned char *data, int cnt) 273{ 274 struct sockaddr_in addr; 275 char realm[REALM_SZ]; 276 char instance[INST_SZ]; 277 int r; 278 socklen_t addr_len; 279 280 if (cnt-- < 1) 281 return; 282 switch (*data++) { 283 case KRB_AUTH: 284 if (krb_get_lrealm(realm, 1) != KSUCCESS) { 285 Data(ap, KRB_REJECT, (void *)"No local V4 Realm.", -1); 286 auth_finished(ap, AUTH_REJECT); 287 if (auth_debug_mode) 288 printf("No local realm\r\n"); 289 return; 290 } 291 memmove(auth.dat, data, auth.length = cnt); 292 if (auth_debug_mode) { 293 printf("Got %d bytes of authentication data\r\n", cnt); 294 printf("CK: %d:", kerberos4_cksum(auth.dat, auth.length)); 295 printd(auth.dat, auth.length); 296 printf("\r\n"); 297 } 298 k_getsockinst(0, instance, sizeof(instance)); 299 addr_len = sizeof(addr); 300 if(getpeername(0, (struct sockaddr *)&addr, &addr_len) < 0) { 301 if(auth_debug_mode) 302 printf("getpeername failed\r\n"); 303 Data(ap, KRB_REJECT, "getpeername failed", -1); 304 auth_finished(ap, AUTH_REJECT); 305 return; 306 } 307 if (addr.sin_family != AF_INET) { 308 if (auth_debug_mode) 309 printf("unknown address family: %d\r\n", addr.sin_family); 310 Data(ap, KRB_REJECT, "bad address family", -1); 311 auth_finished(ap, AUTH_REJECT); 312 return; 313 } 314 315 r = krb_rd_req(&auth, KRB_SERVICE_NAME, 316 instance, addr.sin_addr.s_addr, &adat, ""); 317 if (r) { 318 if (auth_debug_mode) 319 printf("Kerberos failed him as %s\r\n", name); 320 Data(ap, KRB_REJECT, (void *)krb_get_err_text(r), -1); 321 auth_finished(ap, AUTH_REJECT); 322 return; 323 } 324 /* save the session key */ 325 memmove(session_key, adat.session, sizeof(adat.session)); 326 krb_kntoln(&adat, name); 327 328 if (UserNameRequested && !kuserok(&adat, UserNameRequested)){ 329 char ts[MaxPathLen]; 330 struct passwd *pw = getpwnam(UserNameRequested); 331 332 if(pw){ 333 snprintf(ts, sizeof(ts), 334 "%s%u", 335 TKT_ROOT, 336 (unsigned)pw->pw_uid); 337 esetenv("KRBTKFILE", ts, 1); 338 339 if (pw->pw_uid == 0) 340 syslog(LOG_INFO|LOG_AUTH, 341 "ROOT Kerberos login from %s on %s\n", 342 krb_unparse_name_long(adat.pname, 343 adat.pinst, 344 adat.prealm), 345 RemoteHostName); 346 } 347 Data(ap, KRB_ACCEPT, NULL, 0); 348 } else { 349 char *msg; 350 int ret; 351 352 ret = asprintf (&msg, "user `%s' is not authorized to " 353 "login as `%s'", 354 krb_unparse_name_long(adat.pname, 355 adat.pinst, 356 adat.prealm), 357 UserNameRequested ? UserNameRequested : "<nobody>"); 358 if (ret == -1) 359 Data(ap, KRB_REJECT, NULL, 0); 360 else { 361 Data(ap, KRB_REJECT, (void *)msg, -1); 362 free(msg); 363 } 364 auth_finished(ap, AUTH_REJECT); 365 break; 366 } 367 auth_finished(ap, AUTH_USER); 368 break; 369 370 case KRB_CHALLENGE: 371#ifndef ENCRYPTION 372 Data(ap, KRB_RESPONSE, NULL, 0); 373#else 374 if(!VALIDKEY(session_key)){ 375 Data(ap, KRB_RESPONSE, NULL, 0); 376 break; 377 } 378 des_key_sched(&session_key, sched); 379 { 380 des_cblock d_block; 381 int i; 382 Session_Key skey; 383 384 memmove(d_block, data, sizeof(d_block)); 385 386 /* make a session key for encryption */ 387 des_ecb_encrypt(&d_block, &session_key, sched, 1); 388 skey.type=SK_DES; 389 skey.length=8; 390 skey.data=session_key; 391 encrypt_session_key(&skey, 1); 392 393 /* decrypt challenge, add one and encrypt it */ 394 des_ecb_encrypt(&d_block, &challenge, sched, 0); 395 for (i = 7; i >= 0; i--) 396 if(++challenge[i] != 0) 397 break; 398 des_ecb_encrypt(&challenge, &challenge, sched, 1); 399 Data(ap, KRB_RESPONSE, (void *)challenge, sizeof(challenge)); 400 } 401#endif 402 break; 403 404 case KRB_FORWARD: 405 { 406 des_key_schedule ks; 407 unsigned char netcred[sizeof(CREDENTIALS)]; 408 CREDENTIALS cred; 409 int ret; 410 if(cnt > sizeof(cred)) 411 abort(); 412 413 memcpy (session_key, adat.session, sizeof(session_key)); 414 des_set_key(&session_key, ks); 415 des_pcbc_encrypt((void*)data, (void*)netcred, cnt, 416 ks, &session_key, DES_DECRYPT); 417 unpack_cred(netcred, cnt, &cred); 418 { 419 if(strcmp(cred.service, KRB_TICKET_GRANTING_TICKET) || 420 strncmp(cred.instance, cred.realm, sizeof(cred.instance)) || 421 cred.lifetime < 0 || cred.lifetime > 255 || 422 cred.kvno < 0 || cred.kvno > 255 || 423 cred.issue_date < 0 || 424 cred.issue_date > time(0) + CLOCK_SKEW || 425 strncmp(cred.pname, adat.pname, sizeof(cred.pname)) || 426 strncmp(cred.pinst, adat.pinst, sizeof(cred.pinst))){ 427 Data(ap, KRB_FORWARD_REJECT, "Bad credentials", -1); 428 }else{ 429 if((ret = tf_setup(&cred, 430 cred.pname, 431 cred.pinst)) == KSUCCESS){ 432 struct passwd *pw = getpwnam(UserNameRequested); 433 434 if (pw) 435 chown(tkt_string(), pw->pw_uid, pw->pw_gid); 436 Data(ap, KRB_FORWARD_ACCEPT, 0, 0); 437 } else{ 438 Data(ap, KRB_FORWARD_REJECT, 439 krb_get_err_text(ret), -1); 440 } 441 } 442 } 443 memset(data, 0, cnt); 444 memset(&ks, 0, sizeof(ks)); 445 memset(&cred, 0, sizeof(cred)); 446 } 447 448 break; 449 450 default: 451 if (auth_debug_mode) 452 printf("Unknown Kerberos option %d\r\n", data[-1]); 453 Data(ap, KRB_REJECT, 0, 0); 454 break; 455 } 456} 457 458void 459kerberos4_reply(Authenticator *ap, unsigned char *data, int cnt) 460{ 461 Session_Key skey; 462 463 if (cnt-- < 1) 464 return; 465 switch (*data++) { 466 case KRB_REJECT: 467 if(auth_done){ /* XXX Ick! */ 468 printf("[ Kerberos V4 received unknown opcode ]\r\n"); 469 }else{ 470 printf("[ Kerberos V4 refuses authentication "); 471 if (cnt > 0) 472 printf("because %.*s ", cnt, data); 473 printf("]\r\n"); 474 auth_send_retry(); 475 } 476 return; 477 case KRB_ACCEPT: 478 printf("[ Kerberos V4 accepts you ]\r\n"); 479 auth_done = 1; 480 if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) { 481 /* 482 * Send over the encrypted challenge. 483 */ 484 Data(ap, KRB_CHALLENGE, session_key, 485 sizeof(session_key)); 486 des_ecb_encrypt(&session_key, &session_key, sched, 1); 487 skey.type = SK_DES; 488 skey.length = 8; 489 skey.data = session_key; 490 encrypt_session_key(&skey, 0); 491#if 0 492 kerberos4_forward(ap, &cred_session); 493#endif 494 return; 495 } 496 auth_finished(ap, AUTH_USER); 497 return; 498 case KRB_RESPONSE: 499 /* make sure the response is correct */ 500 if ((cnt != sizeof(des_cblock)) || 501 (memcmp(data, challenge, sizeof(challenge)))){ 502 printf("[ Kerberos V4 challenge failed!!! ]\r\n"); 503 auth_send_retry(); 504 return; 505 } 506 printf("[ Kerberos V4 challenge successful ]\r\n"); 507 auth_finished(ap, AUTH_USER); 508 break; 509 case KRB_FORWARD_ACCEPT: 510 printf("[ Kerberos V4 accepted forwarded credentials ]\r\n"); 511 break; 512 case KRB_FORWARD_REJECT: 513 printf("[ Kerberos V4 rejected forwarded credentials: `%.*s']\r\n", 514 cnt, data); 515 break; 516 default: 517 if (auth_debug_mode) 518 printf("Unknown Kerberos option %d\r\n", data[-1]); 519 return; 520 } 521} 522 523int 524kerberos4_status(Authenticator *ap, char *name, size_t name_sz, int level) 525{ 526 if (level < AUTH_USER) 527 return(level); 528 529 if (UserNameRequested && !kuserok(&adat, UserNameRequested)) { 530 strlcpy(name, UserNameRequested, name_sz); 531 return(AUTH_VALID); 532 } else 533 return(AUTH_USER); 534} 535 536#define BUMP(buf, len) while (*(buf)) {++(buf), --(len);} 537#define ADDC(buf, len, c) if ((len) > 0) {*(buf)++ = (c); --(len);} 538 539void 540kerberos4_printsub(unsigned char *data, int cnt, unsigned char *buf, int buflen) 541{ 542 int i; 543 544 buf[buflen-1] = '\0'; /* make sure it's NULL terminated */ 545 buflen -= 1; 546 547 switch(data[3]) { 548 case KRB_REJECT: /* Rejected (reason might follow) */ 549 strlcpy((char *)buf, " REJECT ", buflen); 550 goto common; 551 552 case KRB_ACCEPT: /* Accepted (name might follow) */ 553 strlcpy((char *)buf, " ACCEPT ", buflen); 554 common: 555 BUMP(buf, buflen); 556 if (cnt <= 4) 557 break; 558 ADDC(buf, buflen, '"'); 559 for (i = 4; i < cnt; i++) 560 ADDC(buf, buflen, data[i]); 561 ADDC(buf, buflen, '"'); 562 ADDC(buf, buflen, '\0'); 563 break; 564 565 case KRB_AUTH: /* Authentication data follows */ 566 strlcpy((char *)buf, " AUTH", buflen); 567 goto common2; 568 569 case KRB_CHALLENGE: 570 strlcpy((char *)buf, " CHALLENGE", buflen); 571 goto common2; 572 573 case KRB_RESPONSE: 574 strlcpy((char *)buf, " RESPONSE", buflen); 575 goto common2; 576 577 default: 578 snprintf((char*)buf, buflen, " %d (unknown)", data[3]); 579 common2: 580 BUMP(buf, buflen); 581 for (i = 4; i < cnt; i++) { 582 snprintf((char*)buf, buflen, " %d", data[i]); 583 BUMP(buf, buflen); 584 } 585 break; 586 } 587} 588 589int 590kerberos4_cksum(unsigned char *d, int n) 591{ 592 int ck = 0; 593 594 /* 595 * A comment is probably needed here for those not 596 * well versed in the "C" language. Yes, this is 597 * supposed to be a "switch" with the body of the 598 * "switch" being a "while" statement. The whole 599 * purpose of the switch is to allow us to jump into 600 * the middle of the while() loop, and then not have 601 * to do any more switch()s. 602 * 603 * Some compilers will spit out a warning message 604 * about the loop not being entered at the top. 605 */ 606 switch (n&03) 607 while (n > 0) { 608 case 0: 609 ck ^= (int)*d++ << 24; 610 --n; 611 case 3: 612 ck ^= (int)*d++ << 16; 613 --n; 614 case 2: 615 ck ^= (int)*d++ << 8; 616 --n; 617 case 1: 618 ck ^= (int)*d++; 619 --n; 620 } 621 return(ck); 622} 623 624static int 625pack_cred(CREDENTIALS *cred, unsigned char *buf) 626{ 627 unsigned char *p = buf; 628 629 memcpy (p, cred->service, ANAME_SZ); 630 p += ANAME_SZ; 631 memcpy (p, cred->instance, INST_SZ); 632 p += INST_SZ; 633 memcpy (p, cred->realm, REALM_SZ); 634 p += REALM_SZ; 635 memcpy(p, cred->session, 8); 636 p += 8; 637 p += KRB_PUT_INT(cred->lifetime, p, 4, 4); 638 p += KRB_PUT_INT(cred->kvno, p, 4, 4); 639 p += KRB_PUT_INT(cred->ticket_st.length, p, 4, 4); 640 memcpy(p, cred->ticket_st.dat, cred->ticket_st.length); 641 p += cred->ticket_st.length; 642 p += KRB_PUT_INT(0, p, 4, 4); 643 p += KRB_PUT_INT(cred->issue_date, p, 4, 4); 644 memcpy (p, cred->pname, ANAME_SZ); 645 p += ANAME_SZ; 646 memcpy (p, cred->pinst, INST_SZ); 647 p += INST_SZ; 648 return p - buf; 649} 650 651static int 652unpack_cred(unsigned char *buf, int len, CREDENTIALS *cred) 653{ 654 char *p = (char*)buf; 655 uint32_t tmp; 656 657 strncpy (cred->service, p, ANAME_SZ); 658 cred->service[ANAME_SZ - 1] = '\0'; 659 p += ANAME_SZ; 660 strncpy (cred->instance, p, INST_SZ); 661 cred->instance[INST_SZ - 1] = '\0'; 662 p += INST_SZ; 663 strncpy (cred->realm, p, REALM_SZ); 664 cred->realm[REALM_SZ - 1] = '\0'; 665 p += REALM_SZ; 666 667 memcpy(cred->session, p, 8); 668 p += 8; 669 p += krb_get_int(p, &tmp, 4, 0); 670 cred->lifetime = tmp; 671 p += krb_get_int(p, &tmp, 4, 0); 672 cred->kvno = tmp; 673 674 p += krb_get_int(p, &cred->ticket_st.length, 4, 0); 675 memcpy(cred->ticket_st.dat, p, cred->ticket_st.length); 676 p += cred->ticket_st.length; 677 p += krb_get_int(p, &tmp, 4, 0); 678 cred->ticket_st.mbz = 0; 679 p += krb_get_int(p, (uint32_t *)&cred->issue_date, 4, 0); 680 681 strncpy (cred->pname, p, ANAME_SZ); 682 cred->pname[ANAME_SZ - 1] = '\0'; 683 p += ANAME_SZ; 684 strncpy (cred->pinst, p, INST_SZ); 685 cred->pinst[INST_SZ - 1] = '\0'; 686 p += INST_SZ; 687 return 0; 688} 689 690 691int 692kerberos4_forward(Authenticator *ap, void *v) 693{ 694 des_cblock *key = (des_cblock *)v; 695 CREDENTIALS cred; 696 char *realm; 697 des_key_schedule ks; 698 int len; 699 unsigned char netcred[sizeof(CREDENTIALS)]; 700 int ret; 701 702 realm = krb_realmofhost(RemoteHostName); 703 if(realm == NULL) 704 return -1; 705 memset(&cred, 0, sizeof(cred)); 706 ret = krb_get_cred(KRB_TICKET_GRANTING_TICKET, 707 realm, 708 realm, 709 &cred); 710 if(ret) 711 return ret; 712 des_set_key(key, ks); 713 len = pack_cred(&cred, netcred); 714 des_pcbc_encrypt((void*)netcred, (void*)netcred, len, 715 ks, key, DES_ENCRYPT); 716 memset(&ks, 0, sizeof(ks)); 717 Data(ap, KRB_FORWARD, netcred, len); 718 memset(netcred, 0, sizeof(netcred)); 719 return 0; 720} 721 722#endif /* KRB4 */ 723 724