mirror of
https://github.com/webmin/webmin.git
synced 2025-07-21 23:40:34 +00:00
202 lines
5.7 KiB
Perl
Executable File
202 lines
5.7 KiB
Perl
Executable File
#!/usr/local/bin/perl
|
|
# save.cgi
|
|
# Create, update or delete a PPTP tunnel
|
|
|
|
require './pptp-client-lib.pl';
|
|
&ReadParse();
|
|
@tunnels = &list_tunnels();
|
|
@secs = &list_secrets();
|
|
if (!$in{'new'}) {
|
|
($tunnel) = grep { $_->{'name'} eq $in{'old'} } @tunnels;
|
|
&parse_comments($tunnel);
|
|
$name = &find("name", $tunnel->{'opts'});
|
|
$remote = &find("remotename", $tunnel->{'opts'});
|
|
$sec = &find_secret($name ? $name->{'value'} : &get_system_hostname(1),
|
|
$remote ? $remote->{'value'} : undef);
|
|
&lock_file($tunnel->{'file'});
|
|
}
|
|
else {
|
|
$tunnel = { 'opts' => [ ] };
|
|
}
|
|
&error_setup($text{'save_err'});
|
|
&lock_file($config{'pap_file'});
|
|
|
|
if ($in{'delete'}) {
|
|
# Just delete this tunnel and it's secret (if not used by any other)
|
|
unlink($tunnel->{'file'});
|
|
}
|
|
else {
|
|
# Validate inputs
|
|
$in{'tunnel'} =~ /\S/ || &error($text{'save_ename'});
|
|
&to_ipaddress($in{'server'}) || &error($text{'save_eserver'});
|
|
$in{'login_def'} || $in{'login'} =~ /^\S+$/ ||
|
|
&error($text{'save_elogin'});
|
|
$in{'remote_def'} || $in{'remote'} =~ /^\S+$/ ||
|
|
&error($text{'save_eremote'});
|
|
$in{'file_def'} < 2 || -r $in{'file'} ||
|
|
&error($text{'save_efile'});
|
|
|
|
# Add default route changes
|
|
if ($in{'deldef'}) {
|
|
push(@routes, "delete default");
|
|
}
|
|
if ($in{'adddef'} == 1) {
|
|
push(@routes, "add default dev TUNNEL_DEV");
|
|
}
|
|
elsif ($in{'adddef'} == 2) {
|
|
&to_ipaddress($in{'def'}) || &error($text{'save_edef'});
|
|
push(@routes, "add default gw ".$in{'def'});
|
|
}
|
|
|
|
# Parse and add extra route commands
|
|
$in{'unknown'} =~ s/\r//g;
|
|
push(@routes, grep { /\S/ } split(/\n/, $in{'unknown'}));
|
|
|
|
# Parse and add static routes
|
|
for($i=0; defined($t = $in{"type_$i"}); $i++) {
|
|
next if (!$t);
|
|
if ($t == 1) {
|
|
&check_ipaddress($in{"net_$i"}) ||
|
|
&error(&text('save_enet', $i+1));
|
|
&check_ipaddress($in{"mask_$i"}) ||
|
|
&error(&text('save_emask', $i+1));
|
|
$in{"gw_def_$i"} || &check_ipaddress($in{"gw_$i"}) ||
|
|
&error(&text('save_egw', $i+1));
|
|
if ($in{"gw_def_$i"}) {
|
|
push(@routes,
|
|
sprintf("add -net %s dev %s netmask %s",
|
|
$in{"net_$i"}, 'TUNNEL_DEV',
|
|
$in{"mask_$i"}));
|
|
}
|
|
else {
|
|
push(@routes,
|
|
sprintf("add -net %s gw %s netmask %s",
|
|
$in{"net_$i"}, $in{"gw_$i"},
|
|
$in{"mask_$i"}));
|
|
}
|
|
}
|
|
else {
|
|
&check_ipaddress($in{"net_$i"}) ||
|
|
&error(&text('save_ehost', $i+1));
|
|
$in{"mask_$i"} && &error(&text('save_emask2', $i+1));
|
|
$in{"gw_def_$i"} || &check_ipaddress($in{"gw_$i"}) ||
|
|
&error(&text('save_egw2', $i+1));
|
|
if ($in{"gw_def_$i"}) {
|
|
push(@routes,
|
|
sprintf("add -host %s dev %s",
|
|
$in{"net_$i"}, 'TUNNEL_DEV'));
|
|
}
|
|
else {
|
|
push(@routes,
|
|
sprintf("add -host %s gw %s",
|
|
$in{"net_$i"}, $in{"gw_$i"}));
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
mkdir($config{'peers_dir'}, 0755);
|
|
if ($in{'new'}) {
|
|
&check_clash();
|
|
|
|
# Create file and set default options
|
|
$tunnel->{'name'} = $in{'tunnel'};
|
|
$tunnel->{'file'} = "$config{'peers_dir'}/$in{'tunnel'}";
|
|
&lock_file($tunnel->{'file'});
|
|
&save_ppp_option($tunnel->{'opts'}, $tunnel->{'file'}, undef,
|
|
{ 'comment' => "PPTP Tunnel configuration for tunnel $in{'tunnel'}" });
|
|
}
|
|
else {
|
|
# Check for a re-name
|
|
if ($in{'tunnel'} ne $tunnel->{'name'}) {
|
|
&check_clash();
|
|
$tunnel->{'name'} = $in{'tunnel'};
|
|
$nf = "$config{'peers_dir'}/$in{'tunnel'}";
|
|
rename($tunnel->{'file'}, $nf) ||
|
|
&error($text{'save_erename'});
|
|
$tunnel->{'file'} = $nf;
|
|
}
|
|
}
|
|
|
|
# Save server IP
|
|
&save_ppp_option($tunnel->{'opts'}, $tunnel->{'file'},
|
|
$tunnel->{'server_c'},
|
|
{ 'comment' => "Server IP: $in{'server'}" } );
|
|
|
|
# Save all routes
|
|
@or = @{$tunnel->{'routes_c'}};
|
|
for($i=0; $i<@routes || $i<@or; $i++) {
|
|
&save_ppp_option($tunnel->{'opts'}, $tunnel->{'file'},
|
|
$or[$i], $routes[$i] ?
|
|
{ 'comment' => "Route: $routes[$i]" } : undef);
|
|
}
|
|
|
|
# Save PPP options
|
|
&save_ppp_option($tunnel->{'opts'}, $tunnel->{'file'}, "name",
|
|
$in{'login_def'} ? undef :
|
|
{ 'name' => 'name', 'value' => $in{'login'} } );
|
|
&save_ppp_option($tunnel->{'opts'}, $tunnel->{'file'}, "remotename",
|
|
$in{'remote_def'} ? undef :
|
|
{ 'name' => 'remotename','value' => $in{'remote'} } );
|
|
&save_ppp_option($tunnel->{'opts'}, $tunnel->{'file'}, "file",
|
|
$in{'file_def'} == 0 ? undef :
|
|
$in{'file_def'} == 1 ?
|
|
{ 'name' => 'file',
|
|
'value' => $config{'pptp_options'} } :
|
|
{ 'name' => 'file',
|
|
'value' => $in{'file'} });
|
|
&parse_mppe_options($tunnel->{'opts'}, $tunnel->{'file'});
|
|
|
|
# Update or add to the secrets file
|
|
$newname = $in{'login_def'} ? &get_system_hostname(1) : $in{'login'};
|
|
$newremote = $in{'remote_def'} ? "*" : $in{'remote'};
|
|
if (!$sec) {
|
|
# No old secret was found, so look for one matching the new
|
|
# details
|
|
$sec = &find_secret($newname, $newremote);
|
|
}
|
|
if ($sec) {
|
|
# Just update the secret for our login name with the new login
|
|
# and password. This can happen when re-naming, or if a secret
|
|
# for the name already exists
|
|
$sec->{'client'} = $newname;
|
|
if ($sec->{'server'} ne '*' && $newremote ne '*') {
|
|
$sec->{'server'} = $newremote;
|
|
}
|
|
$sec->{'secret'} = $in{'spass'};
|
|
&change_secret($sec);
|
|
}
|
|
else {
|
|
# Need to create a new secret
|
|
$sec = { 'client' => $newname,
|
|
'secret' => $in{'spass'},
|
|
'server' => $newremote };
|
|
&create_secret($sec);
|
|
}
|
|
|
|
&flush_file_lines();
|
|
}
|
|
&unlock_file($tunnel->{'file'});
|
|
&unlock_file($config{'pap_file'});
|
|
|
|
&webmin_log($in{'new'} ? "create" : $in{'delete'} ? "delete" : "update",
|
|
"tunnel", $tunnel->{'name'});
|
|
&redirect("");
|
|
|
|
sub check_clash
|
|
{
|
|
-r "$config{'peers_dir'}/$in{'tunnel'}" && &error($text{'save_eclash'});
|
|
}
|
|
|
|
# find_secret(client, server)
|
|
# Returns the best matching secret with the given details
|
|
sub find_secret
|
|
{
|
|
local ($exact) = grep { $_->{'client'} eq $_[0] &&
|
|
$_->{'server'} eq $_[1] } @secs;
|
|
return $exact if ($exact);
|
|
local ($client) = grep { $_->{'client'} eq $_[0] } @secs;
|
|
return $client;
|
|
}
|
|
|