diff -r a5a1e5f284d2 -r 5f08067bc677 vpn --- a/vpn Thu Oct 16 18:11:38 2008 +0000 +++ b/vpn Thu Nov 13 10:16:29 2008 +0000 @@ -1,4 +1,4 @@ -#! /usr/bin/perl +#! /usr/bin/perl -T # $Id$ # $URL$ # based on a version Uwe Werler downloaded from f5networks developer @@ -10,9 +10,16 @@ use Getopt::Long qw(:config no_ignore_case bundling); use Pod::Usage; use File::Basename; +use English qw(-no_match_vars); + +($EUID, $UID) = ($UID, $EUID); # release ROOT +($0) = ($0 =~ /(\w+)/); # untaint $0 use constant ME => basename $0; +delete @ENV{ grep /PATH/, keys %ENV }; +$ENV{PATH} = "/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/sbin:/bin"; + ### ### STEP 0 :: Verify that we have the necessary requirements. ### @@ -32,8 +39,8 @@ # name of our Network Access favorite, and our username/pasword. All of these # can be passed as arguments, if desired. -my $user; -my $passcode; +my $opt_user; +my $opt_passcode; my $opt_host = 'connectwdf.sap.com'; my $opt_name = 'SAP Network Access'; my $opt_help = 0; @@ -45,8 +52,8 @@ MAIN: { GetOptions( - "u|user=s" => \$user, - "p|passcode=s" => \$passcode, + "u|user=s" => \$opt_user, + "p|passcode=s" => \$opt_passcode, "H|host=s" => \$opt_host, "n|favorite=s" => \$opt_name, "d|debug" => \$opt_debug, @@ -56,23 +63,32 @@ "s|script" => \$opt_script, ) or pod2usage(); - die ME . ": need to run with root permissions!\n" if $> != 0; - pod2usage(-verbose => 1, -exitval => 0) if $opt_help; pod2usage(-verbose => 2, -exitval => 0) if $opt_man; - pod2usage(-verbose => 0, -exitval => 0) if not defined $user; + pod2usage(-verbose => 0, -exitval => 0) if not defined $opt_user; - if (not defined $passcode) { + (my $user) = ($opt_user =~ /([a-z]\d+)/i); + die ME . ": username \"$opt_user\" didn't pass verification\n" + if $user ne $opt_user; + + die ME . ": need to run with root permissions!\n" + if not $EUID == 0 || $UID == 0; + + if (not defined $opt_passcode) { chomp(my $settings = qx{stty "-g"}); open(IN, "/dev/tty") or die ME . ": Can't open /dev/tty: $!\n"; - print "Passcode: "; + print "Passcode for $opt_user: "; system stty => "-echo"; - chomp($passcode = ); + chomp($opt_passcode = ); system stty => $settings; print "\n"; } - pod2usage(-verbose => 0, -exitval => 0) if not defined $passcode; + pod2usage(-verbose => 0, -exitval => 0) if not defined $opt_passcode; + (my $passcode) = ($opt_passcode =~ /(\d+)/i); + die ME . ": passcode didn't pass verification\n" + if $passcode ne $opt_passcode; + -x $opt_script or die ME . ": Script $opt_script is not executable: $!\n" if defined $opt_script; @@ -164,14 +180,19 @@ $request = "GET /myvpn?sess=${sessionid} HTTP/1.0\r\n" . "Cookie: MRHSession=${sessionid}\r\n" . "\r\n"; $request = "chat -v '' '${request}'"; - system( - pppd => @ppp_opts, - pty => ${openssl}, - connect => ${request}, - linkname => "sap-vpn", - qw(noauth crtscts passive noproxyarp - local), - ); + + { + local $EUID = $UID; # get ROOT, the pppd want's to see + # the UID and the EUID to be ROOT + system( + pppd => @ppp_opts, + pty => ${openssl}, + connect => ${request}, + linkname => "sap-vpn", + qw(noauth crtscts passive noproxyarp + local), + ); + } # Voila! We should now have a PPP connection running over SSL. We can exit # from this script cleanly, and move on to setting up routes to the remote @@ -195,8 +216,10 @@ =head1 DESCRIPTION Ths script establishes a VPN connecttion to a FirePass server. -B This script requires root privileges and should be run via sudo -or some other approbiate mechanism. +B This script requires B privileges and should be run via sudo +or some other approbiate mechanism. (You may install it SUID root. This +is the safest way, since the script rises its privileges only when +necessary, instead of operating all the time as root.) =head1 OPTIONS