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"; |
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 |