sap-vpn.pl
changeset 7 f9fbeced9093
parent 6 9ff263c701ef
child 8 9f1f562a69a1
equal deleted inserted replaced
6:9ff263c701ef 7:f9fbeced9093
    11 use Pod::Usage;
    11 use Pod::Usage;
    12 use File::Basename;
    12 use File::Basename;
    13 use English qw(-no_match_vars);
    13 use English qw(-no_match_vars);
    14 
    14 
    15 ($EUID, $UID) = ($UID, $EUID);    # release ROOT, doesn't harm, if not suid
    15 ($EUID, $UID) = ($UID, $EUID);    # release ROOT, doesn't harm, if not suid
    16 ($0) = ($0 =~ /([\/\w-]+)/);      # untaint $0
    16 ($0) = ($0 =~ /([.\/\w-]+)/);     # untaint $0
    17 
    17 
    18 use constant ME => basename $0;
    18 use constant ME => basename $0;
    19 
    19 
    20 delete @ENV{ grep /PATH/, keys %ENV };
    20 delete @ENV{ grep /PATH/, keys %ENV };
    21 $ENV{PATH} = "/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/sbin:/bin";
    21 $ENV{PATH} = "/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/sbin:/bin";
    48 my $opt_man      = 0;
    48 my $opt_man      = 0;
    49 my @ppp_opts     = ();
    49 my @ppp_opts     = ();
    50 my $opt_debug    = 0;
    50 my $opt_debug    = 0;
    51 my $opt_verbose  = 0;
    51 my $opt_verbose  = 0;
    52 my $opt_script;
    52 my $opt_script;
    53 my $opt_ppp = 1;
    53 my $opt_ppp  = 1;
    54 
    54 my $opt_kill = 0;
    55 sub untaint($) {
    55 
    56     my ($x) = ($_[0] =~ /([\/\w.-]+)/i);
    56 sub untaint(;$) {
    57     return $_[0] = $_[0] eq $x ? $x : undef;
    57     my $ref = @_ ? \$_[0] : \$_;
       
    58     my ($x) = ($$ref =~ /([\/\w.-]+)/i);
       
    59     return $$ref = $$ref eq $x ? $x : undef;
    58 }
    60 }
    59 
    61 
    60 sub verbose(@) { print STDERR @_ if $opt_verbose }
    62 sub verbose(@) { print STDERR @_ if $opt_verbose }
    61 sub debug(@)   { warn @_         if $opt_debug }
    63 sub debug(@)   { warn @_         if $opt_debug }
       
    64 sub do_kill($);
    62 
    65 
    63 MAIN: {
    66 MAIN: {
    64 
    67 
    65     GetOptions(
    68     GetOptions(
    66         "u|user=s"     => \$opt_user,
    69         "u|user=s"     => \$opt_user,
    73         "m|man"        => \$opt_man,
    76         "m|man"        => \$opt_man,
    74         "s|script=s"   => \$opt_script,
    77         "s|script=s"   => \$opt_script,
    75         "l|linkname"   => \$opt_linkname,
    78         "l|linkname"   => \$opt_linkname,
    76         "ppp!"         => \$opt_ppp,
    79         "ppp!"         => \$opt_ppp,
    77         "v|verbose"    => \$opt_verbose,
    80         "v|verbose"    => \$opt_verbose,
       
    81         "k|kill"       => \$opt_kill,
    78     ) or pod2usage();
    82     ) or pod2usage();
    79 
    83 
    80     pod2usage(-verbose => 1, -exitval => 0) if $opt_help;
    84     pod2usage(-verbose => 1, -exitval => 0) if $opt_help;
    81     pod2usage(-verbose => 2, -exitval => 0) if $opt_man;
    85     pod2usage(-verbose => 2, -exitval => 0) if $opt_man;
    82     pod2usage(-verbose => 0, -exitval => 0) if not defined $opt_user;
    86     pod2usage(-verbose => 0, -exitval => 0)
       
    87       if not defined $opt_user
       
    88           and not defined $opt_kill;
    83 
    89 
    84     $opt_verbose += $opt_debug;
    90     $opt_verbose += $opt_debug;
       
    91 
       
    92     untaint($opt_linkname) or die ME . ": linkname didn't pass verification\n";
       
    93     untaint($opt_script)
       
    94       or die ME . ": script name didn't pass verification\n"
       
    95       if $opt_script;
       
    96     map { untaint } @ppp_opts;
       
    97 
       
    98     die ME . ": need to run with root permissions!\n"
       
    99       if not $EUID == 0 || $UID == 0;
       
   100 
       
   101     exit do_kill($opt_linkname) if $opt_kill;
    85 
   102 
    86     untaint($opt_user)
   103     untaint($opt_user)
    87       or die ME . ": username \"$opt_user\" didn't pass verification\n";
   104       or die ME . ": username \"$opt_user\" didn't pass verification\n";
    88 
       
    89     die ME . ": need to run with root permissions!\n"
       
    90       if not $EUID == 0 || $UID == 0;
       
    91 
   105 
    92     if (not defined $opt_passcode) {
   106     if (not defined $opt_passcode) {
    93         chomp(my $settings = qx{stty "-g"});
   107         chomp(my $settings = qx{stty "-g"});
    94         open(IN, "/dev/tty") or die ME . ": Can't open /dev/tty: $!\n";
   108         open(IN, "/dev/tty") or die ME . ": Can't open /dev/tty: $!\n";
    95         print "Passcode for $opt_user: ";
   109         print "Passcode for $opt_user: ";
    96         system stty => "-echo";
   110         system stty => "-echo";
    97         chomp($opt_passcode = <IN>);
   111         chomp($opt_passcode = <IN>);
    98         system stty => $settings;
   112         system stty => $settings;
    99         print "\n";
   113         print "\n";
   100     }
   114     }
   101 
   115     untaint($opt_passcode) or die ME . ": passcode didn't pass verification\n";
   102     pod2usage(-verbose => 0, -exitval => 0) if not defined $opt_passcode;
   116     pod2usage(-verbose => 0, -exitval => 0) if not defined $opt_passcode;
   103 
       
   104     untaint($opt_passcode) or die ME . ": passcode didn't pass verification\n";
       
   105     untaint($opt_linkname) or die ME . ": linkname didn't pass verification\n";
       
   106     untaint($opt_script) or die ME . ": script name didn't pass verification\n";
       
   107 
   117 
   108     -x $opt_script
   118     -x $opt_script
   109       or die ME . ": Script $opt_script is not executable: $!\n"
   119       or die ME . ": Script $opt_script is not executable: $!\n"
   110       if defined $opt_script;
   120       if defined $opt_script;
   111 
   121 
   258 
   268 
   259     exit(0);
   269     exit(0);
   260 
   270 
   261 }
   271 }
   262 
   272 
       
   273 sub do_kill($) {
       
   274     my $linkname = shift;
       
   275     open((my $fh), $_ = "/var/run/ppp-$linkname.pid")
       
   276 	or die ME . ": Can't open the link file \"$_\": $!\n";
       
   277 
       
   278     my $pid   = <$fh>;
       
   279     my $iface = <$fh>;
       
   280 
       
   281     map { chomp; untaint } $pid, $iface;
       
   282 
       
   283     # become root doesn't seem to be necessary, as long as our
       
   284     # real uid is 0
       
   285     kill 15, $pid or die ME . ": Can't kill pid $pid: $!\n";
       
   286 
       
   287     waitpid $pid, 0 != -1 
       
   288 	or die ME . ": was not able to wait for the ppp process: $!\n";
       
   289 
       
   290     verbose "% process killed, rc: @{[$? >> 8]}, sig: @{[$? & 0xff]}\n";
       
   291 }
       
   292 
   263 __END__
   293 __END__
   264 
   294 
   265 =head1 SYNOPSIS
   295 =head1 SYNOPSIS
   266 
   296 
   267  sap-vpn [-d|--debug] [-v|--verbose] [--[no]ppp] 
   297  sap-vpn [-d|--debug] [-v|--verbose] [--[no]ppp] 
   268      [-o|--opt <ppp option>]
   298      [-o|--opt <ppp option>]
       
   299      [-l|--linkname <link name>]
   269      [-u|--user <user>] [-p|--passcode <passcode>]
   300      [-u|--user <user>] [-p|--passcode <passcode>]
   270      [-H|--host <host>]
   301      [-H|--host <host>]
   271      [-s|--script <script>]
   302      [-s|--script <script>]
       
   303 
       
   304  sap-vpn [-l|--linkname <link name>] -k|--kill
   272 
   305 
   273  sap-vpn [-h|--help]
   306  sap-vpn [-h|--help]
   274  sap-vpn [-m|--man]
   307  sap-vpn [-m|--man]
   275 
   308 
   276 =head1 DESCRIPTION
   309 =head1 DESCRIPTION
   297 
   330 
   298 =item B<-H>|B<--host> I<host>
   331 =item B<-H>|B<--host> I<host>
   299 
   332 
   300 Host to connect to. (defaults to C<connectwdf.sap.corp>)
   333 Host to connect to. (defaults to C<connectwdf.sap.corp>)
   301 
   334 
       
   335 =item B<-k>|B<--kill>
       
   336 
       
   337 This is not really an option. It kills the link. This functionality
       
   338 relies on finding the PID file of the PPPD in
       
   339 F</var/run/ppp->I<linkname>F<.pid>.
       
   340 
   302 =item B<-l>|B<--linkname> I<linkname>
   341 =item B<-l>|B<--linkname> I<linkname>
   303 
   342 
   304 The name for the PPP link. Only word characters and "-" (minus sign) are
   343 The name for the PPP link. Only word characters and "-" (minus sign) are
   305 allowed. (default: base name of this script)
   344 allowed. (default: base name of this script)
   306 
   345