From fve@phgroup.com Wed Jul 31 00:52:06 1996 Received: from phgroup.com (root@phgroup.demon.co.uk [158.152.41.9]) by suburbia.net (8.7.4/Proff-950810) with SMTP id AAA07512 for ; Wed, 31 Jul 1996 00:50:52 +1000 Received: from bambi.phgroup.com (root@bambi.phgroup.com [192.168.1.100]) by phgroup.com (8.6.12/8.6.9) with ESMTP id PAA08680; Tue, 30 Jul 1996 15:48:05 +0100 Received: from godzilla (godzilla.phgroup.com [192.168.1.137]) by bambi.phgroup.com (8.6.12/8.6.9) with SMTP id PAA21884; Tue, 30 Jul 1996 15:47:49 +0100 Message-Id: <199607301447.PAA21884@bambi.phgroup.com> X-Sender: fve@mail X-Mailer: Windows Eudora Light Version 1.5.2 Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Date: Tue, 30 Jul 1996 15:47:46 +0100 To: fve From: Frederic Vander Elst Subject: NOTE: ppp/slip tunneling over ssh Cc: firewalls@greatcircle.com, best-of-security@suburbia.net, ylo@ssh.fi A patch of mine which enables ssh to tunnel ppp traffic and run client side "slaves" was recently sent to this list. DO NOT USE IT. I wrote that tunneling patch around 7 months ago, when I was staying in the country for a night and needed secure IP tunnel back home for the evening from a single user machine. It served that purpose amiably, but install it on a multi-user box and you are dead in the water; anyone who can run ssh -E can also run any command as root - which probably isn't what you were looking for. Included below is my current ssh tunneling/VPN patch. Use it instead. example: ssh -C -e none -t -E "pppd -asycmap 0" gatekeeper.dec.com pppd passive diff -u --recursive --exclude *.[oa] --minimal ssh-1.2.14.old/Makefile.in ssh-1.2.14/Makefile.in --- ssh-1.2.14.old/Makefile.in Thu Jun 6 23:47:08 1996 +++ ssh-1.2.14/Makefile.in Tue Jul 30 01:11:20 1996 @@ -163,7 +163,7 @@ log-server.o login.o hostfile.o canohost.o servconf.o tildexpand.o \ serverloop.o $(COMMON_OBJS) SSH_OBJS = ssh.o sshconnect.o log-client.o readconf.o hostfile.o readpass.o \ - tildexpand.o clientloop.o canohost.o $(COMMON_OBJS) + tildexpand.o clientloop.o canohost.o pty.o $(COMMON_OBJS) KEYGEN_OBJS = ssh-keygen.o log-client.o readpass.o rsa.o randoms.o md5.o \ buffer.o xmalloc.o authfile.o tss.o cipher.o des.o arcfour.o mpaux.o \ bufaux.o userfile.o signals.o $(LIBOBJS) $(CONFOBJS) diff -u --recursive --exclude *.[oa] --minimal ssh-1.2.14.old/clientloop.c ssh-1.2.14/clientloop.c --- ssh-1.2.14.old/clientloop.c Thu Jun 6 23:47:05 1996 +++ ssh-1.2.14/clientloop.c Tue Jul 30 05:57:59 1996 @@ -49,6 +49,11 @@ in a configuration file. */ extern char *host; +#ifndef NOPROFF +/* flag to quit client loop, and disconnect */ + int quit_pending; +#endif + #ifdef SIGWINCH /* Flag to indicate that we have received a window change signal which has not yet been processed. This will cause a message indicating the new @@ -85,7 +90,9 @@ static int connection_in; /* Connection to server (input). */ static int connection_out; /* Connection to server (output). */ static unsigned long stdin_bytes, stdout_bytes, stderr_bytes; +#ifdef NOPROFF static int quit_pending; /* Set to non-zero to quit the client loop. */ +#endif static int escape_char; /* Escape character. */ /* Returns the user\'s terminal to normal mode if it had been put in raw diff -u --recursive --exclude *.[oa] --minimal ssh-1.2.14.old/ssh.c ssh-1.2.14/ssh.c --- ssh-1.2.14.old/ssh.c Thu Jun 6 23:47:06 1996 +++ ssh-1.2.14/ssh.c Tue Jul 30 06:07:16 1996 @@ -94,6 +94,9 @@ #include "authfd.h" #include "readconf.h" #include "userfile.h" +#ifndef NOPROFF +# include "pty.h" +#endif /* Random number generator state. This is initialized in ssh_login, and left initialized. This is used both by the packet module and by various @@ -116,6 +119,13 @@ on the command line. */ int stdin_null_flag = 0; +#ifndef NOPROFF +/* Flag indicating that when the client is running a slave stderr should + be redirected to the remote host, rather than the users stderr. + This can be set on the command line. */ +int redirect_stderr_flag = 0; +#endif + /* Flag indicating that ssh should fork after authentication. This is useful so that the pasphrase can be entered manually, and then ssh goes to the background. */ @@ -147,7 +157,6 @@ /* Host private key. */ RSAPrivateKey host_private_key; - /* Prints a help message to the user. This function never returns. */ void usage() @@ -164,6 +173,10 @@ fprintf(stderr, " -q Quiet; don't display any warning messages.\n"); fprintf(stderr, " -f Fork into background after authentication.\n"); fprintf(stderr, " -e char Set escape character; ``none'' = disable (default: ~).\n"); +#ifndef NOPROFF + fprintf(stderr, " -E cmd Execute slave command under client, with stdin/out redirected.\n"); + fprintf(stderr, " -r When running a slave, redirect stderr too.\n"); +#endif fprintf(stderr, " -c cipher Select encryption algorithm: ``idea'' (default, secure),\n"); fprintf(stderr, " ``des'', ``3des'', ``tss'', ``arcfour'' (fast, suitable for bulk\n"); fprintf(stderr, " transfers), ``none'' (no encryption - for debugging only).\n"); @@ -246,16 +259,26 @@ #endif /* RSH_PATH */ } -/* Main program for the ssh client. */ +#ifndef NOPROFF +extern int quit_pending; +RETSIGTYPE sigchld_reaper(int sig) +{ + debug("Client received SIGCHILD from slave"); + quit_pending = 1; +} +#endif +/* Main program for the ssh client. */ int main(int ac, char **av) { int i, opt, optind, type, exit_status, ok, fwd_port, fwd_host_port, authfd; + char *optarg, *cp, buf[256]; Buffer command; struct stat st; struct passwd *pw, pwcopy; int interactive = 0, dummy; + char *execute=NULL; uid_t original_real_uid; uid_t original_effective_uid; #ifdef SIGWINCH @@ -330,7 +353,11 @@ opt = av[optind][1]; if (!opt) usage(); +#ifndef NOPROFF + if (strchr("EeilcpLRo", opt)) /* options with arguments */ +#else if (strchr("eilcpLRo", opt)) /* options with arguments */ +#endif { optarg = av[optind] + 2; if (strcmp(optarg, "") == 0) @@ -351,7 +378,14 @@ case 'n': stdin_null_flag = 1; break; - +#ifndef NOPROFF + case 'E': + execute = optarg; + break; + case 'r': + redirect_stderr_flag = 1; + break; +#endif case 'f': fork_after_authentication_flag = 1; stdin_null_flag = 1; @@ -498,7 +532,10 @@ if (optind == ac) { /* No command specified - execute shell on a tty. */ - tty_flag = 1; +#ifndef NOPROFF + if (!execute) +#endif + tty_flag = 1; } else { @@ -516,11 +553,19 @@ fatal("Cannot fork into background without a command to execute."); /* Allocate a tty by default if no command specified. */ +#ifndef NOPROFF + if (!execute && buffer_len(&command) == 0) +#else if (buffer_len(&command) == 0) +#endif tty_flag = 1; /* Do not allocate a tty if stdin is not a tty. */ +#ifndef NOPROFF + if (!execute && !isatty(fileno(stdin))) +#else if (!isatty(fileno(stdin))) +#endif { if (tty_flag) fprintf(stderr, "Pseudo-terminal will not be allocated because stdin is not a terminal.\n"); @@ -845,7 +890,134 @@ } /* Enter the interactive session. */ +#ifndef NOPROFF + if (execute) + { + /* name of slave pty */ + char ttydev[128] = ""; + + signal (SIGCHLD, sigchld_reaper); + if (tty_flag) + { + /* things like slip/ppp need a tty dicipline in the kernel to + attach themselves to, so, we create a tty for the slave + in order to allow such dependent protocols to tunnel over + ssh connections - Julian Assange (proff@suburbia.net) */ + + pid_t child; + int ptyfd, ttyfd; + if (!pty_allocate (&ptyfd, &ttyfd, ttydev)) + exit (1); + debug ("Client slave tty = %.127s", ttydev); + /* Change ownership of the tty. */ + debug ("Setting tty ownership to uid %d", original_real_uid); + chown (ttydev, original_real_uid, -1); /* gid not important with these perms */ + chmod (ttydev, 0600); + + if ((child = fork ()) == 0) + { +#ifdef USING_TERMIOS + struct termios tio; +#endif +#ifdef USING_SGTTY + struct sgttyb tio; +#endif + int init_tty; + signal (SIGCHLD, SIG_DFL); +#ifdef HAVE_SETSID + if (setsid () < 0) + error ("setsid: %.100s", strerror (errno)); +#endif /* HAVE_SETSID */ + close (ptyfd); + pty_make_controlling_tty (&ttyfd, ttydev); + /* if we were invoked from a tty, we steal our + initial settings from there */ + init_tty = isatty (fileno (stdin)) ? fileno (stdin) : ttyfd; +#ifdef USING_TERMIOS + tcgetattr (init_tty, &tio); +#endif +#ifdef USING_SGTTY + ioctl (init_tty, TIOCGETP, &tio); +#endif + /* bad things happen if we have echo + enabled at both ends of the tunnel ;) */ +#ifdef USING_TERMIOS + tio.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL); + tcsetattr (ttyfd, TCSANOW, &tio); +#endif +#ifdef USING_SGTTY + tio.sg_flags &= ~(ECHO); + ioctl (ttyfd, TIOCSETP, &tio); +#endif + debug ("(pid %d) running sh -c \"%.500s\"", getpid (), execute); + /* take over stdin/out */ + if (ttyfd != 0) + { + dup2 (ttyfd, 0); + close (ttyfd); + } + dup2 (0, 1); + if (redirect_stderr_flag) + dup2 (1, 2); + setuid (original_real_uid); + execl ("/bin/sh", "ssh-slave", "-c", execute); + perror ("sh"); + _exit (1); + } + if (child == -1) + { + perror ("fork"); + exit (1); + } + close (ttyfd); + if (ptyfd != 0) + { + dup2 (ptyfd, 0); + close (ptyfd); + } + dup2 (0, 1); + if (redirect_stderr_flag) + dup2 (1, 2); + } + else + { + /* simpler case, just use a pipe */ + + int p1[2], p2[2]; + pid_t child; + pipe (p1); + pipe (p2); + if ((child = fork ()) == 0) + { + signal (SIGCHLD, SIG_DFL); + close (p1[1]); + close (p2[0]); + dup2 (p1[0], 0); + dup2 (p2[1], 1); + if (redirect_stderr_flag) + dup2 (1, 2); + setuid (original_real_uid); + execl ("/bin/sh", "ssh-slave", "-c", execute); + perror ("sh"); + _exit (1); + } + if (child == -1) + { + perror ("fork"); + exit (1); + } + close (p1[0]); + close (p2[1]); + dup2 (p2[0], 0); + dup2 (p1[1], 1); + } + exit_status = client_loop (tty_flag, tty_flag ? options.escape_char : -1); + if (tty_flag) + pty_release (ttydev); +} +#else exit_status = client_loop(tty_flag, tty_flag ? options.escape_char : -1); +#endif /* Close the connection to the remote host. */ packet_close();