3 # Create, update or delete a PPTP tunnel
5 require './pptp-client-lib.pl';
7 @tunnels = &list_tunnels();
8 @secs = &list_secrets();
10 ($tunnel) = grep { $_->{'name'} eq $in{'old'} } @tunnels;
11 &parse_comments($tunnel);
12 $name = &find("name", $tunnel->{'opts'});
13 $remote = &find("remotename", $tunnel->{'opts'});
14 $sec = &find_secret($name ? $name->{'value'} : &get_system_hostname(1),
15 $remote ? $remote->{'value'} : undef);
16 &lock_file($tunnel->{'file'});
19 $tunnel = { 'opts' => [ ] };
21 &error_setup($text{'save_err'});
22 &lock_file($config{'pap_file'});
25 # Just delete this tunnel and it's secret (if not used by any other)
26 unlink($tunnel->{'file'});
30 $in{'tunnel'} =~ /\S/ || &error($text{'save_ename'});
31 &to_ipaddress($in{'server'}) || &error($text{'save_eserver'});
32 $in{'login_def'} || $in{'login'} =~ /^\S+$/ ||
33 &error($text{'save_elogin'});
34 $in{'remote_def'} || $in{'remote'} =~ /^\S+$/ ||
35 &error($text{'save_eremote'});
36 $in{'file_def'} < 2 || -r $in{'file'} ||
37 &error($text{'save_efile'});
39 # Add default route changes
41 push(@routes, "delete default");
43 if ($in{'adddef'} == 1) {
44 push(@routes, "add default dev TUNNEL_DEV");
46 elsif ($in{'adddef'} == 2) {
47 &to_ipaddress($in{'def'}) || &error($text{'save_edef'});
48 push(@routes, "add default gw ".$in{'def'});
51 # Parse and add extra route commands
52 $in{'unknown'} =~ s/\r//g;
53 push(@routes, grep { /\S/ } split(/\n/, $in{'unknown'}));
55 # Parse and add static routes
56 for($i=0; defined($t = $in{"type_$i"}); $i++) {
59 &check_ipaddress($in{"net_$i"}) ||
60 &error(&text('save_enet', $i+1));
61 &check_ipaddress($in{"mask_$i"}) ||
62 &error(&text('save_emask', $i+1));
63 $in{"gw_def_$i"} || &check_ipaddress($in{"gw_$i"}) ||
64 &error(&text('save_egw', $i+1));
65 if ($in{"gw_def_$i"}) {
67 sprintf("add -net %s dev %s netmask %s",
68 $in{"net_$i"}, 'TUNNEL_DEV',
73 sprintf("add -net %s gw %s netmask %s",
74 $in{"net_$i"}, $in{"gw_$i"},
79 &check_ipaddress($in{"net_$i"}) ||
80 &error(&text('save_ehost', $i+1));
81 $in{"mask_$i"} && &error(&text('save_emask2', $i+1));
82 $in{"gw_def_$i"} || &check_ipaddress($in{"gw_$i"}) ||
83 &error(&text('save_egw2', $i+1));
84 if ($in{"gw_def_$i"}) {
86 sprintf("add -host %s dev %s",
87 $in{"net_$i"}, 'TUNNEL_DEV'));
91 sprintf("add -host %s gw %s",
92 $in{"net_$i"}, $in{"gw_$i"}));
98 mkdir($config{'peers_dir'}, 0755);
102 # Create file and set default options
103 $tunnel->{'name'} = $in{'tunnel'};
104 $tunnel->{'file'} = "$config{'peers_dir'}/$in{'tunnel'}";
105 &lock_file($tunnel->{'file'});
106 &save_ppp_option($tunnel->{'opts'}, $tunnel->{'file'}, undef,
107 { 'comment' => "PPTP Tunnel configuration for tunnel $in{'tunnel'}" });
110 # Check for a re-name
111 if ($in{'tunnel'} ne $tunnel->{'name'}) {
113 $tunnel->{'name'} = $in{'tunnel'};
114 $nf = "$config{'peers_dir'}/$in{'tunnel'}";
115 rename($tunnel->{'file'}, $nf) ||
116 &error($text{'save_erename'});
117 $tunnel->{'file'} = $nf;
122 &save_ppp_option($tunnel->{'opts'}, $tunnel->{'file'},
123 $tunnel->{'server_c'},
124 { 'comment' => "Server IP: $in{'server'}" } );
127 @or = @{$tunnel->{'routes_c'}};
128 for($i=0; $i<@routes || $i<@or; $i++) {
129 &save_ppp_option($tunnel->{'opts'}, $tunnel->{'file'},
130 $or[$i], $routes[$i] ?
131 { 'comment' => "Route: $routes[$i]" } : undef);
135 &save_ppp_option($tunnel->{'opts'}, $tunnel->{'file'}, "name",
136 $in{'login_def'} ? undef :
137 { 'name' => 'name', 'value' => $in{'login'} } );
138 &save_ppp_option($tunnel->{'opts'}, $tunnel->{'file'}, "remotename",
139 $in{'remote_def'} ? undef :
140 { 'name' => 'remotename','value' => $in{'remote'} } );
141 &save_ppp_option($tunnel->{'opts'}, $tunnel->{'file'}, "file",
142 $in{'file_def'} == 0 ? undef :
143 $in{'file_def'} == 1 ?
145 'value' => $config{'pptp_options'} } :
147 'value' => $in{'file'} });
148 &parse_mppe_options($tunnel->{'opts'}, $tunnel->{'file'});
150 # Update or add to the secrets file
151 $newname = $in{'login_def'} ? &get_system_hostname(1) : $in{'login'};
152 $newremote = $in{'remote_def'} ? "*" : $in{'remote'};
154 # No old secret was found, so look for one matching the new
156 $sec = &find_secret($newname, $newremote);
159 # Just update the secret for our login name with the new login
160 # and password. This can happen when re-naming, or if a secret
161 # for the name already exists
162 $sec->{'client'} = $newname;
163 if ($sec->{'server'} ne '*' && $newremote ne '*') {
164 $sec->{'server'} = $newremote;
166 $sec->{'secret'} = $in{'pass'};
167 &change_secret($sec);
170 # Need to create a new secret
171 $sec = { 'client' => $newname,
172 'secret' => $in{'pass'},
173 'server' => $newremote };
174 &create_secret($sec);
179 &unlock_file($tunnel->{'file'});
180 &unlock_file($config{'pap_file'});
182 &webmin_log($in{'new'} ? "create" : $in{'delete'} ? "delete" : "update",
183 "tunnel", $tunnel->{'name'});
188 -r "$config{'peers_dir'}/$in{'tunnel'}" && &error($text{'save_eclash'});
191 # find_secret(client, server)
192 # Returns the best matching secret with the given details
195 local ($exact) = grep { $_->{'client'} eq $_[0] &&
196 $_->{'server'} eq $_[1] } @secs;
197 return $exact if ($exact);
198 local ($client) = grep { $_->{'client'} eq $_[0] } @secs;