vpn
changeset 1 a5a1e5f284d2
parent 0 6f74002230f0
child 2 5f08067bc677
--- a/vpn	Thu Oct 16 16:50:38 2008 +0000
+++ b/vpn	Thu Oct 16 18:11:38 2008 +0000
@@ -1,7 +1,8 @@
 #! /usr/bin/perl
-
+# $Id$
+# $URL$
 # based on a version Uwe Werler downloaded from f5networks developer
-# area
+# area http://devcentral.f5.com/SDK/sslvpn.public.pl.txt
 
 use 5.8.8;
 use strict;
@@ -33,26 +34,26 @@
 
 my $user;
 my $passcode;
-my $host     = 'connectwdf.sap.com';
-my $name     = 'SAP Network Access';
+my $opt_host = 'connectwdf.sap.com';
+my $opt_name = 'SAP Network Access';
 my $opt_help = 0;
 my $opt_man  = 0;
-my $debug;
-my $ppp_opts = [];
+my @ppp_opts = ();
+my $opt_debug;
 my $opt_script;
 
 MAIN: {
 
     GetOptions(
-        "u|user=s"      => \$user,
-        "p|passcode=s"  => \$passcode,
-        "H|host=s"      => \$host,
-        "n|favorite=s" => \$name,
-        "d|debug"       => \$debug,
-        "o|opts=s"      => $ppp_opts,
-        "h|help"        => \$opt_help,
-        "m|man"         => \$opt_man,
-	"s|script"	=> \$opt_script,
+        "u|user=s"     => \$user,
+        "p|passcode=s" => \$passcode,
+        "H|host=s"     => \$opt_host,
+        "n|favorite=s" => \$opt_name,
+        "d|debug"      => \$opt_debug,
+        "o|opts=s"     => \@ppp_opts,
+        "h|help"       => \$opt_help,
+        "m|man"        => \$opt_man,
+        "s|script"     => \$opt_script,
     ) or pod2usage();
 
     die ME . ": need to run with root permissions!\n" if $> != 0;
@@ -62,22 +63,24 @@
     pod2usage(-verbose => 0, -exitval => 0) if not defined $user;
 
     if (not defined $passcode) {
-	chomp(my $settings = qx{stty "-g"});
-	open(IN, "/dev/tty") or die "Can't open /dev/tty: $!\n";
-	print "Passcode: ";
-	system stty => "-echo";
-	chomp($passcode = <IN>);
-	system stty => $settings;
-	print "\n";
+        chomp(my $settings = qx{stty "-g"});
+        open(IN, "/dev/tty") or die ME . ": Can't open /dev/tty: $!\n";
+        print "Passcode: ";
+        system stty => "-echo";
+        chomp($passcode = <IN>);
+        system stty => $settings;
+        print "\n";
     }
 
     pod2usage(-verbose => 0, -exitval => 0) if not defined $passcode;
+    -x $opt_script
+      or die ME . ": Script $opt_script is not executable: $!\n"
+      if defined $opt_script;
 
-    push @$ppp_opts, "nodetach" if !@$ppp_opts;
-    push @$ppp_opts, $debug ? "debug" : "nolog";
-    push @$ppp_opts, "nodefaultroute" if not grep /^defaultroute$/, @$ppp_opts;
-    $ppp_opts = join(" ", @$ppp_opts);
-    print "\nPPP-Options: $ppp_opts\n" if $debug;
+    push @ppp_opts, "nodetach" if $opt_debug;
+    push @ppp_opts, $opt_debug ? "debug" : "nolog";
+    push @ppp_opts, "nodefaultroute" if not grep /^defaultroute$/, @ppp_opts;
+    print "\nPPP-Options: @ppp_opts\n" if $opt_debug;
 
     # Declare variables used throughout the rest of the script.
     my ($request, $response, $sessionid, $favorite);
@@ -86,7 +89,7 @@
     my $openssl =
         "openssl s_client"
       . (-d "/etc/ssl/certs" ? " -CApath /etc/ssl/certs" : "")
-      . " -ign_eof -quiet -connect ${host}:443";
+      . " -ign_eof -quiet -connect ${opt_host}:443";
 
     # Make initial request to get client_data
     $request =
@@ -95,7 +98,7 @@
       . "Connection: close\r\n" . "\r\n";
 
     $response = qx(echo "${request}" | ${openssl} 2>/dev/null)
-      or die "Invalid Host spezified or not reachable: $host\n";
+      or die ME . ": Invalid Host specified or not reachable: $opt_host\n";
 
     $response =~ s/<INPUT type="hidden" name="client_data" value="(.*)">/$1/;
     my $client_data = $1;
@@ -110,14 +113,16 @@
   # may fail if the FirePass has End-Point Security Policies configured.
     $request =
 "check=1&username=${user}&password=${passcode}&mrhlogonform=1&client_data=${client_data}";
+
     $request =
         "POST /my.activation.php3 HTTP/1.0\r\n"
-      . "Host: ${host}\r\n"
+      . "Host: ${opt_host}\r\n"
       . "Content-Type: application/x-www-form-urlencoded\r\n"
       . "Content-Length: "
       . length($request) . "\r\n"
       . "Connection: close\r\n" . "\r\n"
       . "${request}\r\n";
+
     $response = qx(echo "${request}" | ${openssl} 2>/dev/null);
 
   # We can then parse the response for the MRHSession Cookie, which contains our
@@ -125,7 +130,7 @@
   # that our log in attempt worked.
     $response =~ /MRHSession=(\w+);/;
     $sessionid = $1;
-    print "SessionID: ${sessionid}\n" if $debug;
+    print "SessionID: ${sessionid}\n" if $opt_debug;
 
 ###
 ### STEP 3 :: Create the SSL VPN tunnel.
@@ -135,15 +140,15 @@
    # specific pages/objects in order to initiate a SSL VPN tunnel.  Before we do
    # this, let's determine the resource locator for our Network Access favorite.
     $request = "GET /vdesk/vpn/index.php3?outform=xml HTTP/1.0\r\n"
-      . "Cookie: MRHSession=${sessionid}\r\n\r\n";
+      . "Cookie: MRHSession=${sessionid}\r\n" . "\r\n";
     $response = qx(echo "${request}" | ${openssl} 2>/dev/null);
 
  # The response is XML, so we can safely grab what we are looking for using some
  # regular expression magic.  Same with the SessionID, we're printing out the
  # final value to make sure we're on the right track.
-    $response =~ /${name}[^\n]+\n[^Z]+Z=\d+,(\d+)/;
+    $response =~ /${opt_name}[^\n]+\n[^Z]+Z=\d+,(\d+)/;
     $favorite = $1;
-    print "Favorite: ${favorite}\n" if $debug;
+    print "Favorite: ${favorite}\n" if $opt_debug;
 
     # We're all set!  Let's visit the necessary pages/objects to notify FirePass
     # that we wish to open a SSL VPN tunnel.
@@ -160,7 +165,12 @@
       . "Cookie: MRHSession=${sessionid}\r\n" . "\r\n";
     $request = "chat -v '' '${request}'";
     system(
-"pppd ${ppp_opts} noauth crtscts passive noproxyarp local pty \"${openssl}\" connect \"${request}\""
+        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
@@ -185,39 +195,60 @@
 =head1 DESCRIPTION
 
 Ths script establishes a VPN connecttion to a FirePass server.
-B<Note:> This script requires root privileges and should be run via sudo.
+B<Note:> This script requires root privileges and should be run via sudo
+or some other approbiate mechanism.
 
 =head1 OPTIONS
 
-
 =over
 
-=item B<-u>|B<--user> I<user>
+=item B<-d>
+
+Print debug output from pppd. In this mode the script (and the pppd)
+will not detach from your terminal and the script code will not be
+executed.  (default: 0)
+
+=item B<-h>|B<--help>
+
+A short help. (defualt: off)
+
+=item B<-H>|B<--host> I<host>
+
+Host to connect to. (defaults to C<connectwdf.sap.corp>)
 
-Your D|C|I user, not really optional. (no default)
+=item B<-m>|B<--man>
+
+This man page. (default: off)
+
+=item B<-n>|B<--name> I<name>
+
+Name of the service(?). (default: to 'SAP Network Access')
+
+=item B<-o>|B<--opts> I<ppp options>
+
+Additional options for ppp. Can be specified multiple times. (default: nodetach)
+Good choices are C<detach>, or C<updetach>.
+B<Note:> The C<nodefaultroute> is set automatically.
 
 =item B<-p>|B<--passcode> I<passcode>
 
 Your passcode, if not supplied, F</dev/tty> is opened for reading
 the passcode. (no default)
 
-=item B<-H>|B<--host> I<host>
-
-Host to connect to. (defaults to C<connectwdf.sap.corp>)
+=item B<-s>|B<--script> I<script>
 
-=item B<-n>|B<--name> I<name>
-
-Name of the service(?). (default: to 'SAP Network Access')
+Script to execute after establishing the IP link. (See the B<-d> option
+above!). (no default)
 
-=item B<-d>
+B<Note:> You should consider using the F</etc/ppp/ip-up.d/> scripts.
+(see below)
 
-Print debug output from pppd. (default: 0)
+B<Note2:> NOT IMPLEMENTED YET!
 
-=item B<-o>|B<--opts> I<ppp options>
 
-Additional options for ppp. Can be specified multiple times. (default: nodetach)
-Good choices are C<detach>, or C<updetach>.
-B<Note:> The C<nodefaultroute> is set automatically.
+=item B<-u>|B<--user> I<user>
+
+Your D|C|I user, not really optional. (no default)
 
 =back