diff options
Diffstat (limited to 'src/appl/bsd/krsh.c')
-rw-r--r-- | src/appl/bsd/krsh.c | 595 |
1 files changed, 0 insertions, 595 deletions
diff --git a/src/appl/bsd/krsh.c b/src/appl/bsd/krsh.c deleted file mode 100644 index 028d3dd62b..0000000000 --- a/src/appl/bsd/krsh.c +++ /dev/null @@ -1,595 +0,0 @@ -/* - * appl/bsd/krsh.c - */ - -/* - * Copyright (c) 1983 The Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by the University of California, Berkeley. The name of the - * University may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#ifndef lint -char copyright[] = - "@(#) Copyright (c) 1983 The Regents of the University of California.\n\ - All rights reserved.\n"; -#endif /* not lint */ - -/* based on @(#)rsh.c 5.7 (Berkeley) 9/20/88 */ - -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/ioctl.h> -#include <sys/file.h> -#include <sys/time.h> - -#include <netinet/in.h> - -#ifdef HAVE_STDLIB_H -#include <stdlib.h> -#endif -#ifdef HAVE_STRING_H -#include <string.h> -#else -#include <strings.h> -#endif -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif -#include <stdio.h> -#include <errno.h> -#include <signal.h> -#include <pwd.h> -#include <netdb.h> - -#ifdef HAVE_SYS_SELECT_H -#include <sys/select.h> -#endif - -#ifdef HAVE_SYS_FILIO_H -/* get FIONBIO from sys/filio.h, so what if it is a compatibility feature */ -#include <sys/filio.h> -#endif - -#ifdef KERBEROS -#include <krb5.h> -#include <com_err.h> -#include "defines.h" -#endif /* KERBEROS */ - -/* - * rsh - remote shell - */ -#define SECURE_MESSAGE "This rsh session is encrypting input/output data transmissions.\r\n" - -int error(); - -int options; -int rfd2; -int nflag; -krb5_sigtype sendsig(int); - -#ifdef KERBEROS - -#ifndef UCB_RSH -#define UCB_RSH "/usr/ucb/rsh" -#endif - -krb5_context bsd_context; -krb5_creds *cred; - -int encrypt_flag = 0; -char *krb_realm = (char *)0; -void try_normal(char **); - -#endif /* KERBEROS */ - -#ifndef RLOGIN_PROGRAM -#ifdef KERBEROS -#define RLOGIN_PROGRAM KRB5_PATH_RLOGIN -#else /* KERBEROS */ -#ifndef UCB_RLOGIN -#define UCB_RLOGIN "/usr/ucb/rlogin" -#endif -#define RLOGIN_PROGRAM UCB_RLOGIN -#endif /* KERBEROS */ -#endif /* !RLOGIN_PROGRAM */ - -#ifndef POSIX_SIGNALS -#define mask(s) (1 << ((s) - 1)) -#endif /* POSIX_SIGNALS */ - -int -main(argc, argv0) - int argc; - char **argv0; -{ - int rem, pid = 0; - char *host=0, **ap, buf[RCMD_BUFSIZ], *args, **argv = argv0, *user = 0; - register int cc; - struct passwd *pwd; - fd_set readfrom, ready; - int one = 1; - struct servent *sp; - struct servent defaultservent; - struct sockaddr_in local, foreign; - int suppress = 0; - -#ifdef POSIX_SIGNALS - sigset_t omask, igmask; - struct sigaction sa, osa; -#else - int omask; -#endif -#ifdef KERBEROS - krb5_flags authopts; - krb5_error_code status; - krb5_auth_context auth_context; - int fflag = 0, Fflag = 0; -#endif /* KERBEROS */ - int debug_port = 0; - enum kcmd_proto kcmd_proto = KCMD_PROTOCOL_COMPAT_HACK; - - memset(&defaultservent, 0, sizeof(struct servent)); - if (strrchr(argv[0], '/')) - argv[0] = strrchr(argv[0], '/')+1; - - if ( argc < 2 ) goto usage; - argc--; - argv++; - - another: - if (argc > 0 && host == 0 && strncmp(*argv, "-", 1)) { - host = *argv; - argv++, argc--; - goto another; - } - - if (argc > 0 && !strcmp(*argv, "-D")) { - argv++; argc--; - debug_port = htons(atoi(*argv)); - argv++; argc--; - goto another; - } - - if (argc > 0 && !strcmp(*argv, "-l")) { - argv++, argc--; - if (argc > 0) - user = *argv++, argc--; - goto another; - } - if (argc > 0 && !strcmp(*argv, "-n")) { - argv++, argc--; - nflag++; - goto another; - } - if (argc > 0 && !strcmp(*argv, "-d")) { - argv++, argc--; - options |= SO_DEBUG; - goto another; - } -#ifdef KERBEROS - if (argc > 0 && !strcmp(*argv, "-k")) { - argv++, argc--; - if (argc == 0) { - fprintf(stderr, "rsh(kerberos): -k flag must have a realm after it.\n"); - exit (1); - } - if(!(krb_realm = strdup(*argv))){ - fprintf(stderr, "rsh(kerberos): Cannot malloc.\n"); - exit(1); - } - argv++, argc--; - goto another; - } - /* - * Ignore -x from kerberos rlogin - */ - if (argc > 0 && !strncmp(*argv, "-x", 2)) { - argv++, argc--; - encrypt_flag++; - goto another; - } - if (argc > 0 && !strncmp(*argv, "-f", 2)) { - if (Fflag) { - fprintf(stderr, "rsh: Only one of -f and -F allowed\n"); - goto usage; - } - fflag++; - argv++, argc--; - goto another; - } - if (argc > 0 && !strncmp(*argv, "-F", 2)) { - if (fflag) { - fprintf(stderr, "rsh: Only one of -f and -F allowed\n"); - goto usage; - } - Fflag++; - argv++, argc--; - goto another; - } - if (argc > 0 && !strncmp(*argv, "-A", 2)) { - argv++, argc--; - goto another; - } - if (argc > 0 && !strcmp(*argv, "-PO")) { - argv++, argc--; - kcmd_proto = KCMD_OLD_PROTOCOL; - goto another; - } - if (argc > 0 && !strcmp(*argv, "-PN")) { - argv++, argc--; - kcmd_proto = KCMD_NEW_PROTOCOL; - goto another; - } -#endif /* KERBEROS */ - /* - * Ignore the -L, -w, -e and -8 flags to allow aliases with rlogin - * to work - * - * There must be a better way to do this! -jmb - */ - if (argc > 0 && !strncmp(*argv, "-L", 2)) { - argv++, argc--; - goto another; - } - if (argc > 0 && !strncmp(*argv, "-w", 2)) { - argv++, argc--; - goto another; - } - if (argc > 0 && !strncmp(*argv, "-e", 2)) { - argv++, argc--; - goto another; - } - if (argc > 0 && !strncmp(*argv, "-8", 2)) { - argv++, argc--; - goto another; - } -#ifdef ATHENA - /* additional Athena flags to be ignored */ - if (argc > 0 && !strcmp(*argv, "-noflow")) { /* No local flow control option for rlogin */ - argv++, argc--; - goto another; - } - if (argc > 0 && !strcmp(*argv, "-7")) { - argv++, argc--; - goto another; - } - if (argc > 0 && !strcmp(*argv, "-c")) { - argv++, argc--; - goto another; - } - if (argc > 0 && !strcmp(*argv, "-a")) { - argv++, argc--; - goto another; - } - if (argc > 0 && !strcmp(*argv, "-n")) { - argv++, argc--; - goto another; - } - /* - ** Also ignore -t ttytype - */ - if (argc > 0 && !strcmp(*argv, "-t")) { - argv++; argv++; argc--; argc--; - goto another; - } -#endif /* ATHENA */ - if (host == 0) - goto usage; - if (argv[0] == 0) { - execv(RLOGIN_PROGRAM, argv0); - perror(RLOGIN_PROGRAM); - exit(1); - } - - pwd = getpwuid(getuid()); - if (pwd == 0) { - fprintf(stderr, "who are you?\n"); - exit(1); - } - cc = 0; - for (ap = argv; *ap; ap++) - cc += strlen(*ap) + 1; - if (encrypt_flag) - cc += 3; - args = (char *) malloc((unsigned) cc); - *args = '\0'; - if (encrypt_flag) - strlcpy(args, "-x ", cc); - for (ap = argv; *ap; ap++) { - (void) strlcat(args, *ap, cc); - if (ap[1]) - strlcat(args, " ", cc); - } - - if(debug_port == 0) { -#ifdef KERBEROS - sp = getservbyname("kshell", "tcp"); -#else - sp = getservbyname("shell", "tcp"); -#endif /* KERBEROS */ - if (sp == 0) { -#ifdef KERBEROS - sp = &defaultservent; - sp->s_port = htons(544); -#else - fprintf(stderr, "rsh: shell/tcp: unknown service\n"); - exit(1); -#endif /* KERBEROS */ - } - - debug_port = sp->s_port; - } - -#ifdef KERBEROS - status = krb5_init_context(&bsd_context); - if (status) { - com_err(argv[0], status, "while initializing krb5"); - exit(1); - } - authopts = AP_OPTS_MUTUAL_REQUIRED; - - /* Piggy-back forwarding flags on top of authopts; */ - /* they will be reset in kcmd */ - if (fflag || Fflag) - authopts |= OPTS_FORWARD_CREDS; - if (Fflag) - authopts |= OPTS_FORWARDABLE_CREDS; -#ifdef HAVE_ISATTY - suppress = !isatty(fileno(stderr)); -#endif - status = kcmd(&rem, &host, debug_port, - 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 # */ - &local, &foreign, - &auth_context, authopts, - 1, /* Always set anyport, there is no need not to. --proven */ - suppress, - &kcmd_proto); - if (status) { - /* If new protocol requested, don't fall back to less secure - ones. */ - if (kcmd_proto == KCMD_NEW_PROTOCOL) - exit (1); - try_normal(argv0); - } else { - krb5_keyblock *key = &cred->keyblock; - - if (kcmd_proto == KCMD_NEW_PROTOCOL) { - status = krb5_auth_con_getsendsubkey (bsd_context, auth_context, - &key); - if (status) { - com_err (argv[0], status, "determining subkey for session"); - exit (1); - } - if (!key) { - com_err (argv[0], 0, "no subkey negotiated for connection"); - exit (1); - } - } - - rcmd_stream_init_krb5(key, encrypt_flag, 0, 1, kcmd_proto); - } - -#ifdef HAVE_ISATTY - if(encrypt_flag&&isatty(2)) { - write(2,SECURE_MESSAGE, strlen(SECURE_MESSAGE)); - } -#endif - -#else /* !KERBEROS */ - rem = rcmd(&host, debug_port, pwd->pw_name, - user ? user : pwd->pw_name, args, &rfd2); - if (rem < 0) - exit(1); -#endif /* KERBEROS */ - if (rfd2 < 0) { - fprintf(stderr, "rsh: can't establish stderr\n"); - exit(2); - } - if (options & SO_DEBUG) { - if (setsockopt(rem, SOL_SOCKET, SO_DEBUG, - (const char *) &one, sizeof (one)) < 0) - perror("setsockopt (stdin)"); - if (setsockopt(rfd2, SOL_SOCKET, SO_DEBUG, - (const char *) &one, sizeof (one)) < 0) - perror("setsockopt (stderr)"); - } - (void) setuid(getuid()); -#ifdef POSIX_SIGNALS - sigemptyset(&igmask); - sigaddset(&igmask, SIGINT); - sigaddset(&igmask, SIGQUIT); - sigaddset(&igmask, SIGTERM); - sigprocmask(SIG_BLOCK, &igmask, &omask); - - (void)sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; - sa.sa_handler = sendsig; - - (void)sigaction(SIGINT, (struct sigaction *)0, &osa); - if (osa.sa_handler != SIG_IGN) - (void)sigaction(SIGINT, &sa, (struct sigaction *)0); - - (void)sigaction(SIGQUIT, (struct sigaction *)0, &osa); - if (osa.sa_handler != SIG_IGN) - (void)sigaction(SIGQUIT, &sa, (struct sigaction *)0); - - (void)sigaction(SIGTERM, (struct sigaction *)0, &osa); - if (osa.sa_handler != SIG_IGN) - (void)sigaction(SIGTERM, &sa, (struct sigaction *)0); -#else -#ifdef sgi - omask = sigignore(mask(SIGINT)|mask(SIGQUIT)|mask(SIGTERM)); -#else - omask = sigblock(mask(SIGINT)|mask(SIGQUIT)|mask(SIGTERM)); -#endif - if (signal(SIGINT, SIG_IGN) != SIG_IGN) - signal(SIGINT, sendsig); - if (signal(SIGQUIT, SIG_IGN) != SIG_IGN) - signal(SIGQUIT, sendsig); - if (signal(SIGTERM, SIG_IGN) != SIG_IGN) - signal(SIGTERM, sendsig); -#endif /* POSIX_SIGNALS */ - if (nflag == 0) { - pid = fork(); - if (pid < 0) { - perror("fork"); - exit(1); - } - } - if (!encrypt_flag) { - ioctl(rfd2, FIONBIO, &one); - ioctl(rem, FIONBIO, &one); - } - if (nflag == 0 && pid == 0) { - char *bp; - int wc; - fd_set rembits; - - (void) close(rfd2); - reread: - errno = 0; - cc = read(0, buf, sizeof buf); - if (cc <= 0) - goto done; - bp = buf; - rewrite: - FD_ZERO(&rembits); - FD_SET(rem, &rembits); - if (select(rem + 1, 0, &rembits, 0, 0) < 0) { - if (errno != EINTR) { - perror("select"); - exit(1); - } - goto rewrite; - } - if (FD_ISSET(rem, &rembits) == 0) - goto rewrite; - wc = rcmd_stream_write(rem, bp, cc, 0); - if (wc < 0) { - if ((errno == EWOULDBLOCK) || (errno == EAGAIN)) - goto rewrite; - goto done; - } - cc -= wc; bp += wc; - if (cc == 0) - goto reread; - goto rewrite; - done: - (void) shutdown(rem, 1); -#ifdef KERBEROS - krb5_free_context(bsd_context); -#endif - exit(0); - } -#ifdef POSIX_SIGNALS - sigprocmask(SIG_SETMASK, &omask, (sigset_t*)0); -#else -#ifndef sgi - sigsetmask(omask); -#endif -#endif /* POSIX_SIGNALS */ - FD_ZERO(&readfrom); - FD_SET(rfd2, &readfrom); - FD_SET(rem, &readfrom); - do { - ready = readfrom; - if (select(((rfd2 > rem) ? rfd2 : rem) + 1, &ready, 0, 0, 0) < 0) { - if (errno != EINTR) { - perror("select"); - exit(1); - } - continue; - } - if (FD_ISSET(rfd2, &ready)) { - errno = 0; - cc = rcmd_stream_read(rfd2, buf, sizeof buf, 1); - if (cc <= 0) { - if ((errno != EWOULDBLOCK) && (errno != EAGAIN)) - FD_CLR(rfd2, &readfrom); - } else - (void) write(2, buf, (unsigned) cc); - } - if (FD_ISSET(rem, &ready)) { - errno = 0; - cc = rcmd_stream_read(rem, buf, sizeof buf, 0); - if (cc <= 0) { - if ((errno != EWOULDBLOCK) && (errno != EAGAIN)) - FD_CLR(rem, &readfrom); - } else - (void) write(1, buf, (unsigned) cc); - } - } while (FD_ISSET(rem, &readfrom) || FD_ISSET(rfd2, &readfrom)); - if (nflag == 0) - (void) kill(pid, SIGKILL); -#ifdef KERBEROS - krb5_free_context(bsd_context); -#endif - exit(0); - usage: - fprintf(stderr, - "usage: \trsh host [ -PN / -PO ] [ -l login ] [ -n ] [ -x ] [ -f / -F] command\n"); - fprintf(stderr, - "OR \trsh [ -PN / -PO ] [ -l login ] [-n ] [ -x ] [ -f / -F ] host command\n"); - exit(1); -} - - - -krb5_sigtype sendsig(signo) - char signo; -{ - (void) rcmd_stream_write(rfd2, &signo, 1, 1); -} - - - -#ifdef KERBEROS -void try_normal(argv) - char **argv; -{ - char *host; - -#ifndef KRB5_ATHENA_COMPAT - if (encrypt_flag) - exit(1); -#endif - /* - * if we were invoked as 'rsh host mumble', strip off the rsh - * from arglist. - * - * We always want to call the Berkeley rsh as 'host mumble' - */ - host = strrchr(argv[0], '/'); - if (host) - host++; - else - host = argv[0]; - - if (!strcmp(host, "rsh")) - argv++; - - fprintf(stderr,"trying normal rsh (%s)\n", - UCB_RSH); - fflush(stderr); - execv(UCB_RSH, argv); - perror("exec"); - exit(1); -} -#endif /* KERBEROS */ |