(Note: the size given by unshar may be wrong due to tab mangling.) Subject: Script for running ppp over ssh From: Olaf Titz Date: 12 Oct 1996 Message-Id: Organization: private Linux site, southern Germany Newsgroups: alt.sources,comp.security.unix This program is a bit trivial IMHO, but there seems to be popular demand for it. :-) Note that on my system (Linux 2.0.12, ssh 1.2.13) the original version of this program fails in a subtle way. After requesting a pty, the local ssh process hangs in some blocking read operation. It can however be revived by sending the process SIGSTOP and then SIGCONT. Looks like a problem with nonblocking I/O (or failure to activate it). I don't know if the error exists in other versions of ssh or on other platforms. I have included a kluge around that: -b will send it the mentioned signals after seconds. olaf #!/bin/sh # This is a shell archive (produced by GNU sharutils 4.1). # To extract the files from this archive, save it to some FILE, remove # everything before the `!/bin/sh' line above, then type `sh FILE'. # # Made on 1996-10-12 22:32 MET DST by . # Source directory was `/var/home/olaf/security'. # # Existing files will *not* be overwritten unless `-c' is specified. # # This shar contains: # length mode name # ------ ---------- ------------------------------------------ # 1787 -rwxrwxr-x ssh-ppp # touch -am 1231235999 $$.touch >/dev/null 2>&1 if test ! -f 1231235999 && test -f $$.touch; then shar_touch=touch else shar_touch=: echo echo 'WARNING: not restoring timestamps. Consider getting and' echo "installing GNU \`touch', distributed in GNU File Utilities..." echo fi rm -f 1231235999 $$.touch # # ============= ssh-ppp ============== if test -f 'ssh-ppp' && test X"$1" != X"-c"; then echo 'x - skipping ssh-ppp (file already exists)' else echo 'x - extracting ssh-ppp (text)' sed 's/^X//' << 'SHAR_EOF' > 'ssh-ppp' && #!/usr/bin/perl X # Start an ssh connection and a pppd running on top of it. # Usage: ssh-ppp [-l user] [-c command] [-b seconds] host # Connect to "host" using the user name "user" and run "command" on the # remote end. (Default is "root" and "/usr/sbin/pppd") # by Olaf Titz, July 1996 X require "getopts.pl"; require "sys/syscall.ph"; X # Customize if necessary $ssh="/usr/local/bin/ssh"; $pppd="/usr/sbin/pppd"; X # defaults $opt_l="root"; $opt_c="/usr/sbin/pppd"; &Getopts("l:c:b:"); ($host=shift) || die "usage: $0 [-l user] [-c command] host"; X foreach $maj ("p".."s") { # adjust this to the ptys you have X foreach $min ("0".."9", "a".."f") { X &tryopen("$maj$min"); X } } die "Couldn't alloc master pty\n"; X sub tryopen { X local($d)=@_; X $master=sprintf("/dev/pty%s", $d); X $slave=sprintf("/dev/tty%s", $d); X if (open(PTY, "+>$master")) { X $pid=fork; X defined($pid) || die "can't fork"; X if (!$pid) { X close PTY; X (syscall(&SYS_setsid)>0) || die "setsid: $!"; X open(STDIN, "+>$slave") || X die "open slave: $!"; X open(STDOUT, ">&STDIN"); X open(STDERR, ">&STDIN"); X print STDOUT "\n"; X exec $pppd; X die "exec $pppd: $!"; X } X open(STDIN, "<&PTY") || die "reopen stdin"; X open(STDOUT, ">&PTY") || die "reopen stout"; X close PTY; X $opt_l="-l$opt_l"; X &bugdaemon($opt_b) if ($opt_b); X print STDERR "running on $master; ssh=$$, pppd=$pid\n"; X exec $ssh, "-t", $opt_l, $host, $opt_c; X die "exec $ssh: $!"; X } } X sub bugdaemon # This cures a "hang" of the local ssh process { X local($secs)=@_; X local($p)=fork; X if (!defined($p)) { X warn "can't fork, no bug daemon"; X return; X } X return if (!$p); X # returning the child avoids a zombie X sleep $secs; X kill "STOP", $p; X sleep 1; X kill "CONT", $p; X exit 0; } SHAR_EOF $shar_touch -am 1012222596 'ssh-ppp' && chmod 0775 'ssh-ppp' || echo 'restore of ssh-ppp failed' shar_count="`wc -c < 'ssh-ppp'`" test 1787 -eq "$shar_count" || echo "ssh-ppp: original size 1787, current size $shar_count" fi exit 0 -- ___ Olaf.Titz@inka.de or @{stud,informatik}.uni-karlsruhe.de ____ __ o __/<_ >> Just as long as the wheels keep on turning round _)>(_)______________ I will live for the groove 'til the sun goes down << ____