vpn
changeset 3 01314d620fe0
parent 2 5f08067bc677
child 4 74ef29e9ab00
--- a/vpn	Thu Nov 13 10:16:29 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,282 +0,0 @@
-#! /usr/bin/perl -T
-# $Id$
-# $URL$
-# based on a version Uwe Werler downloaded from f5networks developer
-# area http://devcentral.f5.com/SDK/sslvpn.public.pl.txt
-
-use 5.8.8;
-use strict;
-use warnings;
-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.
-###
-### This script requires recent versions of Perl, OpenSSL and PPPD (including
-### the 'chat' program), and that they all be in our PATH.  This script was
-### written and tested with the following versions:
-###	FirePass:	5.5 and 6.0
-###	Perl:		5.8.8
-###	OpenSSL:	0.9.8b
-###	PPPD:		2.4.4
-
-###
-### STEP 1 :: Set up variables with the proper information to log in.
-###
-
-# Default values for the FQDN or IP of the FirePass we wish to connect to, the
-# name of our Network Access favorite, and our username/pasword.  All of these
-# can be passed as arguments, if desired.
-
-my $opt_user;
-my $opt_passcode;
-my $opt_host = 'connectwdf.sap.com';
-my $opt_name = 'SAP Network Access';
-my $opt_help = 0;
-my $opt_man  = 0;
-my @ppp_opts = ();
-my $opt_debug;
-my $opt_script;
-
-MAIN: {
-
-    GetOptions(
-        "u|user=s"     => \$opt_user,
-        "p|passcode=s" => \$opt_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();
-
-    pod2usage(-verbose => 1, -exitval => 0) if $opt_help;
-    pod2usage(-verbose => 2, -exitval => 0) if $opt_man;
-    pod2usage(-verbose => 0, -exitval => 0) if not defined $opt_user;
-
-    (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 for $opt_user: ";
-        system stty => "-echo";
-        chomp($opt_passcode = <IN>);
-        system stty => $settings;
-        print "\n";
-    }
-
-    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;
-
-    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);
-
-    # Store the OpenSSL command in a variable for convienence.
-    my $openssl =
-        "openssl s_client"
-      . (-d "/etc/ssl/certs" ? " -CApath /etc/ssl/certs" : "")
-      . " -ign_eof -quiet -connect ${opt_host}:443";
-
-    # Make initial request to get client_data
-    $request =
-        "GET /my.logon.php3?check=1 HTTP/1.0\r\n"
-      . "Content-Type: application/x-www-form-urlencoded\r\n"
-      . "Connection: close\r\n" . "\r\n";
-
-    $response = qx(echo "${request}" | ${openssl} 2>/dev/null)
-      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;
-
-###
-### STEP 2 :: Log in to FirePass.
-###
-
-  # This is the bare minimum required in order to successfully log in.  A normal
-  # browser will make many more requests than this to complete the log in
-  # sequence, but all that is required is this POST with our credentails.  This
-  # 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: ${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
-  # SessionID.  In this example, we print out the SessionID in order to verify
-  # that our log in attempt worked.
-    $response =~ /MRHSession=(\w+);/;
-    $sessionid = $1;
-    print "SessionID: ${sessionid}\n" if $opt_debug;
-
-###
-### STEP 3 :: Create the SSL VPN tunnel.
-###
-
-   # Now that we are authenticated and have a valid SessionID, we must request
-   # 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";
-    $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 =~ /${opt_name}[^\n]+\n[^Z]+Z=\d+,(\d+)/;
-    $favorite = $1;
-    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.
-    foreach my $uri ("/vdesk/", "/vdesk/vpn/connect.php3?Z=0,${favorite}",) {
-        $request = "GET ${uri} HTTP/1.0\r\n"
-          . "Cookie: MRHSession=${sessionid}\r\n" . "\r\n";
-        system("echo \"${request}\" | ${openssl} >/dev/null 2>&1");
-    }
-
-# We are now authenticated, and have requested the necessary pre-tunnel
-# pages/objects.  It's time to start our SSL VPN connection.  To do this, we are
-# simply calling PPPD, and having it use OpenSSL as a psuedo terminal device.
-    $request = "GET /myvpn?sess=${sessionid} HTTP/1.0\r\n"
-      . "Cookie: MRHSession=${sessionid}\r\n" . "\r\n";
-    $request = "chat -v '' '${request}'";
-
-    {
-        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
-    # network using our favorite networking tools.  Happy hacking!
-
-    exit(0);
-
-}
-
-__END__
-
-=head1 SYNOPSIS
-
- vpn [-d|--debug] [-H|--host <host>] [-o|--opt <ppp option>]...
-     [-s|--script <script>]
-     [-u|--user <user>] [-p|--passcode <passcode>]
-
- vpn [-h|--help]
- vpn [-m|--man]
-
-=head1 DESCRIPTION
-
-Ths script establishes a VPN connecttion to a FirePass server.
-B<Note:> This script requires B<root> 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
-
-=over
-
-=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>)
-
-=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<-s>|B<--script> I<script>
-
-Script to execute after establishing the IP link. (See the B<-d> option
-above!). (no default)
-
-B<Note:> You should consider using the F</etc/ppp/ip-up.d/> scripts.
-(see below)
-
-B<Note2:> NOT IMPLEMENTED YET!
-
-
-=item B<-u>|B<--user> I<user>
-
-Your D|C|I user, not really optional. (no default)
-
-=back
-
-=cut
-
-###
-### End of file.
-###