[990] in Kerberos-V5-bugs
Encrypted rsh
daemon@ATHENA.MIT.EDU (Andrew Gross)
Sat Dec 17 04:02:56 1994
Date: Sat, 17 Dec 94 01:02:25 -0800
From: Andrew Gross <drew@drew.sdsc.edu>
To: krb5-bugs@MIT.EDU
Hello,
Attached are patches that I made to appl/bsd/krsh.c and
appl/bsd/krshd.c to add encrypted rshs. I just grabbed port
2106 for ekshell in /etc/services.
Andrew Gross
=========================================================================
*** xrsh.c Fri Nov 11 02:49:43 1994
--- krsh.c Thu Aug 18 14:05:09 1994
***************
*** 74,96 ****
char *krb_realm = (char *)0;
void try_normal();
#define UCB_RSH "/usr/ucb/rsh"
-
- #ifdef BUFSIZ
- #undef BUFSIZ
#endif
- #define BUFSIZ 4096
- char des_inbuf[2*BUFSIZ]; /* needs to be > largest read size */
- char des_outbuf[2*BUFSIZ]; /* needs to be > largest write size */
- krb5_data desinbuf,desoutbuf;
- krb5_encrypt_block eblock; /* eblock for encrypt/decrypt */
- krb5_creds *cred;
- int encrypt_flag=0;
- #else
- #define des_read read
- #define des_write write
- #endif
-
#ifndef RLOGIN_PROGRAM
#ifdef KERBEROS
#define RLOGIN_PROGRAM KRB5_PATH_RLOGIN
--- 74,81 ----
***************
*** 123,128 ****
--- 108,114 ----
krb5_flags authopts;
krb5_error_code status;
int fflag = 0, Fflag = 0;
+ int xflag = 0;
int debug_port = 0;
#endif /* KERBEROS */
***************
*** 183,189 ****
*/
if (argc > 0 && !strncmp(*argv, "-x", 2)) {
argv++, argc--;
! encrypt_flag++;
goto another;
}
if (argc > 0 && !strncmp(*argv, "-f", 2)) {
--- 169,175 ----
*/
if (argc > 0 && !strncmp(*argv, "-x", 2)) {
argv++, argc--;
! xflag++;
goto another;
}
if (argc > 0 && !strncmp(*argv, "-f", 2)) {
***************
*** 269,282 ****
given and rlogin is not run, because the user could be
dangerously confused otherwise. He might think he's got a
secure rsh channel, and there's no such thing yet. */
! /*
! if (encrypt_flag)
{
fprintf (stderr, "%s: Encrypted rsh is not yet available.\n",
argv0[0]);
return 1;
}
- */
pwd = getpwuid(getuid());
if (pwd == 0) {
--- 255,266 ----
given and rlogin is not run, because the user could be
dangerously confused otherwise. He might think he's got a
secure rsh channel, and there's no such thing yet. */
! if (xflag)
{
fprintf (stderr, "%s: Encrypted rsh is not yet available.\n",
argv0[0]);
return 1;
}
pwd = getpwuid(getuid());
if (pwd == 0) {
***************
*** 295,303 ****
*cp++ = ' ';
}
#ifdef KERBEROS
- if (encrypt_flag)
- sp = getservbyname("ekshell","tcp");
- else
sp = getservbyname("kshell", "tcp");
#else
sp = getservbyname("shell", "tcp");
--- 279,284 ----
***************
*** 304,311 ****
#endif /* KERBEROS */
if (sp == 0) {
#ifdef KERBEROS
! fprintf(stderr, "rsh: %s/tcp: unknown service\n",
! encrypt_flag ? "ekshell" : "kshell");
try_normal(argv0);
#else
fprintf(stderr, "rsh: shell/tcp: unknown service\n");
--- 285,291 ----
#endif /* KERBEROS */
if (sp == 0) {
#ifdef KERBEROS
! fprintf(stderr, "rsh: kshell/tcp: unknown service\n");
try_normal(argv0);
#else
fprintf(stderr, "rsh: shell/tcp: unknown service\n");
***************
*** 318,325 ****
#ifdef KERBEROS
krb5_init_ets();
- desinbuf.data = des_inbuf;
- desoutbuf.data = des_outbuf; /* Set up des buffers */
authopts = AP_OPTS_MUTUAL_REQUIRED;
/* Piggy-back forwarding flags on top of authopts; */
--- 298,303 ----
***************
*** 333,339 ****
pwd->pw_name,
user ? user : pwd->pw_name,
args, &rfd2, "host", krb_realm,
! &cred,
0, /* No need for sequence number */
0, /* No need for server seq # */
(struct sockaddr_in *) 0,
--- 311,317 ----
pwd->pw_name,
user ? user : pwd->pw_name,
args, &rfd2, "host", krb_realm,
! 0, /* No need for returned credentials */
0, /* No need for sequence number */
0, /* No need for server seq # */
(struct sockaddr_in *) 0,
***************
*** 346,359 ****
error_message(status));
try_normal(argv0);
}
- /* setup eblock for des_read and write */
- krb5_use_keytype(&eblock,cred->keyblock.keytype);
- if ( status = krb5_process_key(&eblock,&cred->keyblock)) {
- fprintf(stderr,
- "%s: Cannot process session key : %s.\n",
- argv0, error_message(status));
- exit(1);
- }
#else /* !KERBEROS */
rem = rcmd(&host, sp->s_port, pwd->pw_name,
user ? user : pwd->pw_name, args, &rfd2);
--- 324,329 ----
***************
*** 397,407 ****
exit(1);
}
}
- /* as per rlogind, crypto will fail on NB sockets... */
- if (!encrypt_flag) {
ioctl(rfd2, FIONBIO, &one);
ioctl(rem, FIONBIO, &one);
- }
if (nflag == 0 && pid == 0) {
char *bp; int rembits, wc;
(void) close(rfd2);
--- 367,374 ----
***************
*** 422,428 ****
}
if ((rembits & (1<<rem)) == 0)
goto rewrite;
! wc = des_write(rem, bp, cc);
if (wc < 0) {
if (errno == EWOULDBLOCK)
goto rewrite;
--- 389,395 ----
}
if ((rembits & (1<<rem)) == 0)
goto rewrite;
! wc = write(rem, bp, cc);
if (wc < 0) {
if (errno == EWOULDBLOCK)
goto rewrite;
***************
*** 455,461 ****
}
if (ready & (1<<rfd2)) {
errno = 0;
! cc = des_read(rfd2, buf, sizeof buf);
if (cc <= 0) {
if (errno != EWOULDBLOCK)
readfrom &= ~(1<<rfd2);
--- 422,428 ----
}
if (ready & (1<<rfd2)) {
errno = 0;
! cc = read(rfd2, buf, sizeof buf);
if (cc <= 0) {
if (errno != EWOULDBLOCK)
readfrom &= ~(1<<rfd2);
***************
*** 464,470 ****
}
if (ready & (1<<rem)) {
errno = 0;
! cc = des_read(rem, buf, sizeof buf);
if (cc <= 0) {
if (errno != EWOULDBLOCK)
readfrom &= ~(1<<rem);
--- 431,437 ----
}
if (ready & (1<<rem)) {
errno = 0;
! cc = read(rem, buf, sizeof buf);
if (cc <= 0) {
if (errno != EWOULDBLOCK)
readfrom &= ~(1<<rem);
***************
*** 477,485 ****
exit(0);
usage:
fprintf(stderr,
! "usage: \trsh host [ -l login ] [ -x ] [ -n ] [ -f / -F] command\n");
fprintf(stderr,
! "OR \trsh [ -l login ] [-n ] [ -x ] [ -f / -F ] host command\n");
exit(1);
}
--- 444,452 ----
exit(0);
usage:
fprintf(stderr,
! "usage: \trsh host [ -l login ] [ -n ] [ -f / -F] command\n");
fprintf(stderr,
! "OR \trsh [ -l login ] [-n ] [ -f / -F ] host command\n");
exit(1);
}
***************
*** 489,495 ****
char signo;
{
! (void) des_write(rfd2, &signo, 1);
}
--- 456,462 ----
char signo;
{
! (void) write(rfd2, &signo, 1);
}
***************
*** 507,515 ****
* We always want to call the Berkeley rsh as 'host mumble'
*/
- if (encrypt_flag)
- exit(1);
-
host = strrchr(argv[0], '/');
if (host)
host++;
--- 474,479 ----
***************
*** 525,651 ****
execv(UCB_RSH, argv);
perror("exec");
exit(1);
- }
-
- char storage[2*BUFSIZ]; /* storage for the decryption */
- int nstored = 0;
- char *store_ptr = storage;
-
- int des_read(fd, buf, len)
- int fd;
- register char *buf;
- int len;
- {
- int nreturned = 0;
- long net_len,rd_len;
- int cc;
-
- if (!encrypt_flag)
- return(read(fd, buf, len));
-
- if (nstored >= len) {
- memcpy(buf, store_ptr, len);
- store_ptr += len;
- nstored -= len;
- return(len);
- } else if (nstored) {
- memcpy(buf, store_ptr, nstored);
- nreturned += nstored;
- buf += nstored;
- len -= nstored;
- nstored = 0;
- }
-
- #ifdef BITS64
- /*
- * XXX Ick. This assumes big endian byte order.
- */
- rd_len = 0;
- if ((cc = krb5_net_read(fd, (char *)&rd_len + 4, 4)) != 4) {
- #else
- if ((cc = krb5_net_read(fd, (char *)&rd_len, sizeof(rd_len))) !=
- sizeof(rd_len)) {
- #endif
- /* XXX can't read enough, pipe
- must have closed */
- return(0);
- }
- rd_len = ntohl(rd_len);
- net_len = krb5_encrypt_size(rd_len,eblock.crypto_entry);
- if (net_len <= 0 || net_len > sizeof(des_inbuf)) {
- /* preposterous length; assume out-of-sync; only
- recourse is to close connection, so return 0 */
- fprintf(stderr,"Read size problem.\n");
- return(0);
- }
- if ((cc = krb5_net_read(fd, desinbuf.data, net_len)) != net_len) {
- /* pipe must have closed, return 0 */
- fprintf(stderr,
- "Read error: length received %d != expected %d.\n",
- cc,net_len);
- return(0);
- }
- /* decrypt info */
- if ((krb5_decrypt(desinbuf.data,
- (krb5_pointer) storage,
- net_len,
- &eblock, 0))) {
- fprintf(stderr,"Cannot decrypt data from network.\n");
- return(0);
- }
- store_ptr = storage;
- nstored = rd_len;
- if (nstored > len) {
- memcpy(buf, store_ptr, len);
- nreturned += len;
- store_ptr += len;
- nstored -= len;
- } else {
- memcpy(buf, store_ptr, nstored);
- nreturned += nstored;
- nstored = 0;
- }
-
- return(nreturned);
- }
-
-
-
- int des_write(fd, buf, len)
- int fd;
- char *buf;
- int len;
- {
- long net_len;
-
- if (!encrypt_flag)
- return(write(fd, buf, len));
-
- desoutbuf.length = krb5_encrypt_size(len,eblock.crypto_entry);
- if (desoutbuf.length > sizeof(des_outbuf)){
- fprintf(stderr,"Write size problem.\n");
- return(-1);
- }
- if (( krb5_encrypt((krb5_pointer)buf,
- desoutbuf.data,
- len,
- &eblock,
- 0))){
- fprintf(stderr,"Write encrypt problem.\n");
- return(-1);
- }
-
-
- net_len = htonl(len);
- #ifdef BITS64
- (void) write(fd,(char *)&net_len + 4, 4);
- #else
- (void) write(fd, &net_len, sizeof(net_len));
- #endif
- if (write(fd, desoutbuf.data,desoutbuf.length) != desoutbuf.length){
- fprintf(stderr,"Could not write out all data.\n");
- return(-1);
- }
- else return(len);
}
#endif /* KERBEROS */
--- 489,493 ----
========================================================================
*** xrshd.c Fri Nov 11 02:51:02 1994
--- krshd.c Tue Nov 8 23:24:57 1994
***************
*** 64,71 ****
/* DEFINES:
* KERBEROS - Define this if application is to be kerberised.
! * KRB5_KRB4_COMPAT - Define this if v4 rlogin clients are also to be served.
! * CRYPT - Define this if encryption is to be an option.
* ALWAYS_V5_KUSEROK - Define this if you want .k5login to be
* checked even for v4 clients (instead of .klogin).
* LOG_ALL_LOGINS - Define this if you want to log all logins.
--- 64,70 ----
/* DEFINES:
* KERBEROS - Define this if application is to be kerberised.
! * SERVE_V4 - Define this if v4 rlogin clients are also to be served.
* ALWAYS_V5_KUSEROK - Define this if you want .k5login to be
* checked even for v4 clients (instead of .klogin).
* LOG_ALL_LOGINS - Define this if you want to log all logins.
***************
*** 80,87 ****
* Note: Root account access is always logged.
*/
! #define CRYPT
! /*#define SERVE_NON_KRB */
#define LOG_REMOTE_REALM
#define LOG_ALL_LOGINS
#define LOG_CMD
--- 79,86 ----
* Note: Root account access is always logged.
*/
! #define SERVE_V4
! #define SERVE_NON_KRB
#define LOG_REMOTE_REALM
#define LOG_ALL_LOGINS
#define LOG_CMD
***************
*** 170,209 ****
#include <krb5/crc-32.h>
#include <krb5/mit-des.h>
#include <krb5/ext-proto.h>
- #include <kerberosIV/krb.h>
#include <com_err.h>
#include "loginpaths.h"
- #ifdef BUFSIZ
- #undef BUFSIZ
- #endif
-
- int auth_sys = 0; /* Which version of Kerberos used to
- authenticate */
-
- #define KRB5_RECVAUTH_V4 4
- #define KRB5_RECVAUTH_V5 5
-
- AUTH_DAT *v4_kdata;
- Key_schedule v4_schedule;
- int v4_des_read(), v4_des_write();
-
- #define BUFSIZ 5120
-
- int v5_des_read(), v5_des_write();
-
- #define SECURE_MESSAGE "This rsh session is using DES encryption for all data transmissions.\r\n"
-
- int (*des_read)(), (*des_write)();
- char des_inbuf[2*BUFSIZ]; /* needs to be > largest read size */
- krb5_encrypt_block eblock; /* eblock for encrypt/decrypt */
- char des_outbuf[2*BUFSIZ]; /* needs to be > largest write size */
- krb5_data desinbuf,desoutbuf;
- #define MAXRETRIES 4
-
-
#ifndef SETPGRP_TWOARG
#define setpgrp(a,b) setpgrp()
#endif
--- 169,179 ----
***************
*** 225,241 ****
#endif
/** XXX **/
! void fatal();
! #define ARGSTR "rRxXeEkKD:?"
#else /* !KERBEROS */
#define ARGSTR "rRD:?"
- #define (*des_read) read
- #define (*des_write) write
#endif /* KERBEROS */
int must_pass_rhosts = 0, must_pass_k5 = 0, must_pass_one = 0;
! int failed_k5 = 0, do_encrypt = 0, netf = -1;
char *progname;
#define MAX_PROG_NAME 10
--- 195,208 ----
#endif
/** XXX **/
! #define ARGSTR "rRkKD:?"
#else /* !KERBEROS */
#define ARGSTR "rRD:?"
#endif /* KERBEROS */
int must_pass_rhosts = 0, must_pass_k5 = 0, must_pass_one = 0;
! int failed_k5 = 0;
char *progname;
#define MAX_PROG_NAME 10
***************
*** 279,286 ****
#ifndef LOG_DAEMON
#define LOG_DAEMON 0
#endif
! /* openlog(progname, LOG_PID | LOG_ODELAY, LOG_DAEMON); */
! openlog(progname, LOG_PID | LOG_ODELAY, LOG_LOCAL6);
#endif /* 4.2 syslog */
if (argc == 1) { /* Get parameters from program name. */
--- 246,252 ----
#ifndef LOG_DAEMON
#define LOG_DAEMON 0
#endif
! openlog(progname, LOG_PID | LOG_ODELAY, LOG_DAEMON);
#endif /* 4.2 syslog */
if (argc == 1) { /* Get parameters from program name. */
***************
*** 326,340 ****
if (must_pass_one)
must_pass_one = 0;
break;
- #ifdef CRYPT
- case 'x': /* Use encryption. */
- case 'X':
- case 'e':
- case 'E':
- do_encrypt = 1;
- break;
#endif
- #endif
case 'D':
debug_port = atoi(optarg);
break;
--- 292,298 ----
***************
*** 466,477 ****
krb5_principal client;
krb5_authenticator *kdata;
! #ifdef KRB5_KRB4_COMPAT
#include <kerberosIV/krb.h>
AUTH_DAT *v4_kdata;
KTEXT v4_ticket;
#endif
#define KRB5_RECVAUTH_V4 4
#define KRB5_RECVAUTH_V5 5
--- 424,436 ----
krb5_principal client;
krb5_authenticator *kdata;
! #ifdef SERVE_V4
#include <kerberosIV/krb.h>
AUTH_DAT *v4_kdata;
KTEXT v4_ticket;
#endif
+ int auth_sys = 0; /* Which version of Kerberos used to authenticate */
#define KRB5_RECVAUTH_V4 4
#define KRB5_RECVAUTH_V5 5
***************
*** 485,491 ****
#ifdef KERBEROS
krb5_address peeraddr;
krb5_error_code status;
- char buferror[255];
#endif
int tmpint;
--- 444,449 ----
***************
*** 521,527 ****
struct hostent *hp;
char *hostname;
short port;
! int pv[2], pw[2], cc;
long ready, readfrom;
char buf[BUFSIZ], sig;
int one = 1;
--- 479,485 ----
struct hostent *hp;
char *hostname;
short port;
! int pv[2], cc;
long ready, readfrom;
char buf[BUFSIZ], sig;
int one = 1;
***************
*** 564,573 ****
exit(1);
}
#ifdef KERBEROS
- netf = f;
krb5_init_ets();
- desinbuf.data = des_inbuf;
- desoutbuf.data = des_outbuf; /* Set up des buffers */
if ((must_pass_rhosts || must_pass_one)
&& (fromp->sin_port >= IPPORT_RESERVED ||
fromp->sin_port < IPPORT_RESERVED/2))
--- 522,528 ----
***************
*** 677,687 ****
error("Authentication failed: %s\n", error_message(status));
exit(1);
}
- #ifndef KRB5_KRB4_COMPAT
- if (auth_sys == KRB5_RECVAUTH_V4) {
- fatal(f, "This server does not support Kerberos V4");
- }
- #endif
#else
getstr(f, remuser, sizeof(remuser), "remuser");
getstr(f, locuser, sizeof(locuser), "locuser");
--- 632,637 ----
***************
*** 704,710 ****
}
#endif /* CRAY */
! pwd = (struct passwd *)getpwnam(locuser);
if (pwd == (struct passwd *) 0 ) {
syslog(LOG_ERR ,
"Principal %s (%s@%s) for local user %s has no account.\n",
--- 654,660 ----
}
#endif /* CRAY */
! pwd = getpwnam(locuser);
if (pwd == (struct passwd *) 0 ) {
syslog(LOG_ERR ,
"Principal %s (%s@%s) for local user %s has no account.\n",
***************
*** 1071,1077 ****
}
#endif
! (void) write(2, "", 1);
if (port) {
if (pipe(pv) < 0) {
--- 1021,1027 ----
}
#endif
! (void) write(2, "\0", 1);
if (port) {
if (pipe(pv) < 0) {
***************
*** 1078,1087 ****
error("Can't make pipe.\n");
goto signout_please;
}
- if (pipe(pw) < 0) {
- error("Can't make pipe 2.\n");
- goto signout_please;
- }
pid = fork();
if (pid == -1) {
error("Fork failed.\n");
--- 1028,1033 ----
***************
*** 1096,1113 ****
signal(SIGCHLD,SIG_IGN);
(void) close(0); (void) close(1); (void) close(2);
! /*(void) close(f);*/ (void) close(pv[1]); (void) close(pw[1]);
! readfrom = (1L<<s) | (1L<<pv[0]) | (1L<<pw[0]);
! #ifdef KERBEROS
! if (do_encrypt) {
! if (((*des_write)(s, SECURE_MESSAGE, sizeof(SECURE_MESSAGE))) < 0){
! sprintf(buferror, "Cannot encrypt-write network.");
! fatal(pw[0],buferror);
! }
! }
! #endif
ioctl(pv[0], FIONBIO, (char *)&one);
- ioctl(pw[0], FIONBIO, (char *)&one);
/* should set s nbio! */
do {
ready = readfrom;
--- 1042,1050 ----
signal(SIGCHLD,SIG_IGN);
(void) close(0); (void) close(1); (void) close(2);
! (void) close(f); (void) close(pv[1]);
! readfrom = (1L<<s) | (1L<<pv[0]);
ioctl(pv[0], FIONBIO, (char *)&one);
/* should set s nbio! */
do {
ready = readfrom;
***************
*** 1115,1121 ****
(fd_set *)0, (struct timeval *)0) < 0)
break;
if (ready & (1L<<s)) {
! if ((*des_read)(s, &sig, 1) <= 0)
readfrom &= ~(1L<<s);
else {
signal(sig, cleanup);
--- 1052,1058 ----
(fd_set *)0, (struct timeval *)0) < 0)
break;
if (ready & (1L<<s)) {
! if (read(s, &sig, 1) <= 0)
readfrom &= ~(1L<<s);
else {
signal(sig, cleanup);
***************
*** 1129,1145 ****
shutdown(s, 1+1);
readfrom &= ~(1L<<pv[0]);
} else
! (void) (*des_write)(s, buf, cc);
}
- if (ready & (1L<<pw[0])) {
- errno = 0;
- cc = read(pw[0], buf, sizeof (buf));
- if (cc <= 0) {
- shutdown(f, 1+1);
- readfrom &= ~(1L<<pw[0]);
- } else
- (void) (*des_write)(f, buf, cc);
- }
} while (readfrom);
#ifdef KERBEROS
syslog(LOG_INFO ,
--- 1066,1073 ----
shutdown(s, 1+1);
readfrom &= ~(1L<<pv[0]);
} else
! (void) write(s, buf, cc);
}
} while (readfrom);
#ifdef KERBEROS
syslog(LOG_INFO ,
***************
*** 1154,1162 ****
exit(0);
}
setpgrp(0, getpid());
! (void) close(s); (void) close(pv[0]); (void) close(pw[0]);
! dup2(pw[1], 1); dup2(pv[1], 2);
! (void) close(pv[1]); (void) close(pw[1]);
}
/* We are simply execing a program over rshd : log entry into wtmp,
--- 1082,1090 ----
exit(0);
}
setpgrp(0, getpid());
! (void) close(s); (void) close(pv[0]);
! dup2(pv[1], 2);
! (void) close(pv[1]);
}
/* We are simply execing a program over rshd : log entry into wtmp,
***************
*** 1480,1513 ****
#ifdef KERBEROS
- void fatal(f, msg)
- int f;
- char *msg;
- {
- char buf[512];
- int out = 1 ; /* Output queue of f */
-
- buf[0] = '\01'; /* error indicator */
- (void) sprintf(buf + 1, "%s: %s.\r\n",progname, msg);
- if ((f == netf) && (pid > 0))
- (void) (*des_write)(f, buf, strlen(buf));
- else
- (void) write(f, buf, strlen(buf));
- syslog(LOG_ERR,"%s\n",msg);
- if (pid > 0) {
- signal(SIGCHLD,SIG_IGN);
- kill(pid,SIGKILL);
- #ifdef TIOCFLUSH
- (void) ioctl(f, TIOCFLUSH, (char *)&out);
- #else
- (void) ioctl(f, TCFLSH, out);
- #endif
- cleanup();
- }
- exit(1);
- }
-
-
#ifndef KRB_SENDAUTH_VLEN
#define KRB_SENDAUTH_VLEN 8 /* length for version strings */
#endif
--- 1408,1413 ----
***************
*** 1586,1592 ****
0, /* default rc_type */
0, /* no flags */
! do_encrypt ? KOPT_DO_MUTUAL : 0, /*v4_opts*/
"rcmd", /* v4_service */
v4_instance, /* v4_instance */
&peersin, /* foriegn address */
--- 1486,1492 ----
0, /* default rc_type */
0, /* no flags */
! 0, /*v4_opts*/
"rcmd", /* v4_service */
v4_instance, /* v4_instance */
&peersin, /* foriegn address */
***************
*** 1599,1605 ****
&ticket, /* return ticket */
&kdata, /* return authenticator */
! &v4_kdata, v4_schedule, v4_version);
if (status) {
if (auth_sys == KRB5_RECVAUTH_V5) {
--- 1499,1505 ----
&ticket, /* return ticket */
&kdata, /* return authenticator */
! &v4_kdata, 0, v4_version);
if (status) {
if (auth_sys == KRB5_RECVAUTH_V5) {
***************
*** 1616,1627 ****
getstr(netf, locuser, sizeof(locuser), "locuser");
getstr(netf, cmdbuf, sizeof(cmdbuf), "command");
- #ifdef KRB5_KRB4_COMPAT
if (auth_sys == KRB5_RECVAUTH_V4) {
-
- des_read = v4_des_read;
- des_write = v4_des_write;
-
/* We do not really know the remote user's login name.
* Assume it to be the same as the first component of the
* principal's name.
--- 1516,1522 ----
***************
*** 1637,1666 ****
return(status);
return 0;
}
- #endif
/* Must be V5 */
- des_read = v5_des_read;
- des_write = v5_des_write;
-
getstr(netf, remuser, sizeof(locuser), "remuser");
if (status = krb5_unparse_name(client, &kremuser))
return status;
- /* Setup up eblock if encrypted login session */
- /* otherwise zero out session key */
- if (do_encrypt) {
- krb5_use_keytype(&eblock,
- ticket->enc_part2->session->keytype);
- if (status = krb5_process_key(&eblock,
- ticket->enc_part2->session))
- fatal(netf, "Permission denied");
- ticket->enc_part2->session=0;
- }
-
-
if (status = krb5_read_message((krb5_pointer)&netf, &inbuf)) {
error("Error reading message: %s\n",
error_message(status));
--- 1532,1545 ----
***************
*** 1678,1951 ****
return 0;
}
-
- char storage[2*BUFSIZ]; /* storage for the decryption */
- int nstored = 0;
- char *store_ptr = storage;
-
- int
- v5_des_read(fd, buf, len)
- int fd;
- register char *buf;
- int len;
- {
- int nreturned = 0;
- long net_len,rd_len;
- int cc,retry;
-
- if (!do_encrypt)
- return(read(fd, buf, len));
-
- if (nstored >= len) {
- memcpy(buf, store_ptr, len);
- store_ptr += len;
- nstored -= len;
- return(len);
- } else if (nstored) {
- memcpy(buf, store_ptr, nstored);
- nreturned += nstored;
- buf += nstored;
- len -= nstored;
- nstored = 0;
- }
-
- #ifdef BITS64
- rd_len = 0;
- if ((cc = krb5_net_read(fd, (char *)&rd_len + 4, 4)) != 4) {
- #else
- if ((cc = krb5_net_read(fd, (char *)&rd_len, sizeof(rd_len))) !=
- sizeof(rd_len)) {
- #endif
- if ((cc < 0) && (errno == EWOULDBLOCK)) return(cc);
- /* XXX can't read enough, pipe
- must have closed */
- return(0);
- }
- rd_len = ntohl(rd_len);
- net_len = krb5_encrypt_size(rd_len,eblock.crypto_entry);
- if (net_len < 0 || net_len > sizeof(des_inbuf)) {
- /* XXX preposterous length, probably out of sync.
- act as if pipe closed */
- syslog(LOG_ERR,"Read size problem.");
- return(0);
- }
- retry = 0;
- datard:
- if ((cc = krb5_net_read(fd, desinbuf.data, net_len)) != net_len) {
- /* XXX can't read enough, pipe
- must have closed */
- if ((cc < 0) && (errno == EWOULDBLOCK)) {
- retry++;
- sleep(1);
- if (retry > MAXRETRIES){
- syslog(LOG_ERR,
- "des_read retry count exceeded %d\n",
- retry);
- return(0);
- }
- goto datard;
- }
- syslog(LOG_ERR,
- "Read data received %d != expected %d.",
- cc, net_len);
- return(0);
- }
- /* decrypt info */
- if ((krb5_decrypt(desinbuf.data,
- (krb5_pointer) storage,
- net_len,
- &eblock, 0))) {
- syslog(LOG_ERR,"Read decrypt problem.");
- return(0);
- }
- store_ptr = storage;
- nstored = rd_len;
- if (nstored > len) {
- memcpy(buf, store_ptr, len);
- nreturned += len;
- store_ptr += len;
- nstored -= len;
- } else {
- memcpy(buf, store_ptr, nstored);
- nreturned += nstored;
- nstored = 0;
- }
- return(nreturned);
- }
-
-
- int
- v5_des_write(fd, buf, len)
- int fd;
- char *buf;
- int len;
- {
- long net_len;
-
- if (!do_encrypt)
- return(write(fd, buf, len));
-
-
- desoutbuf.length = krb5_encrypt_size(len,eblock.crypto_entry);
- if (desoutbuf.length > sizeof(des_outbuf)){
- syslog(LOG_ERR,"Write size problem.");
- return(-1);
- }
- if ((krb5_encrypt((krb5_pointer)buf,
- desoutbuf.data,
- len,
- &eblock,
- 0))){
- syslog(LOG_ERR,"Write encrypt problem.");
- return(-1);
- }
-
- net_len = htonl(len);
- #ifdef BITS64
- (void) write(fd,(char *)&net_len + 4, 4);
- #else
- (void) write(fd, &net_len, sizeof(net_len));
- #endif
- if (write(fd, desoutbuf.data,desoutbuf.length) != desoutbuf.length){
- syslog(LOG_ERR,"Could not write out all data.");
- return(-1);
- }
- else return(len);
- }
-
- #ifdef KRB5_KRB4_COMPAT
-
- int
- v4_des_read(fd, buf, len)
- int fd;
- register char *buf;
- int len;
- {
- int nreturned = 0;
- long net_len, rd_len;
- int cc;
-
- if (!do_encrypt)
- return(read(fd, buf, len));
-
- if (nstored >= len) {
- memcpy(buf, store_ptr, len);
- store_ptr += len;
- nstored -= len;
- return(len);
- } else if (nstored) {
- memcpy(buf, store_ptr, nstored);
- nreturned += nstored;
- buf += nstored;
- len -= nstored;
- nstored = 0;
- }
-
- if ((cc = krb_net_read(fd, &net_len, sizeof(net_len))) != sizeof(net_len)) {
- /* XXX can't read enough, pipe
- must have closed */
- return(0);
- }
- net_len = ntohl(net_len);
- if (net_len < 0 || net_len > sizeof(des_inbuf)) {
- /* XXX preposterous length, probably out of sync.
- act as if pipe closed */
- return(0);
- }
- /* the writer tells us how much real data we are getting, but
- we need to read the pad bytes (8-byte boundary) */
- rd_len = roundup(net_len, 8);
- if ((cc = krb_net_read(fd, des_inbuf, rd_len)) != rd_len) {
- /* XXX can't read enough, pipe
- must have closed */
- return(0);
- }
- (void) pcbc_encrypt(des_inbuf,
- storage,
- (net_len < 8) ? 8 : net_len,
- v4_schedule,
- v4_kdata->session,
- DECRYPT);
- /*
- * when the cleartext block is < 8 bytes, it is "right-justified"
- * in the block, so we need to adjust the pointer to the data
- */
- if (net_len < 8)
- store_ptr = storage + 8 - net_len;
- else
- store_ptr = storage;
- nstored = net_len;
- if (nstored > len) {
- memcpy(buf, store_ptr, len);
- nreturned += len;
- store_ptr += len;
- nstored -= len;
- } else {
- memcpy(buf, store_ptr, nstored);
- nreturned += nstored;
- nstored = 0;
- }
-
- return(nreturned);
- }
-
- int
- v4_des_write(fd, buf, len)
- int fd;
- char *buf;
- int len;
- {
- long net_len;
- static int seeded = 0;
- static char garbage_buf[8];
- long garbage;
-
- if (!do_encrypt)
- return(write(fd, buf, len));
-
- /*
- * pcbc_encrypt outputs in 8-byte (64 bit) increments
- *
- * it zero-fills the cleartext to 8-byte padding,
- * so if we have cleartext of < 8 bytes, we want
- * to insert random garbage before it so that the ciphertext
- * differs for each transmission of the same cleartext.
- * if len < 8 - sizeof(long), sizeof(long) bytes of random
- * garbage should be sufficient; leave the rest as-is in the buffer.
- * if len > 8 - sizeof(long), just garbage fill the rest.
- */
-
- #ifdef min
- #undef min
- #endif
- #define min(a,b) ((a < b) ? a : b)
-
- if (len < 8) {
- if (!seeded) {
- seeded = 1;
- srandom((int) time((long *)0));
- }
- garbage = random();
- /* insert random garbage */
- (void) memcpy(garbage_buf, &garbage, min(sizeof(long),8));
-
- /* this "right-justifies" the data in the buffer */
- (void) memcpy(garbage_buf + 8 - len, buf, len);
- }
- (void) pcbc_encrypt((len < 8) ? garbage_buf : buf,
- des_outbuf,
- (len < 8) ? 8 : len,
- v4_schedule,
- v4_kdata->session,
- ENCRYPT);
-
- /* tell the other end the real amount, but send an 8-byte padded
- packet */
- net_len = htonl(len);
- (void) write(fd, &net_len, sizeof(net_len));
- (void) write(fd, des_outbuf, roundup(len,8));
- return(len);
- }
-
- #endif /* KRB5_KRB4_COMPAT */
#endif /* KERBEROS */
--- 1557,1560 ----