2 # Common functions for PPTP server configuration
5 BEGIN { push(@INC, ".."); };
9 %access = &get_module_acl();
11 $options_pptp = $config{'pptp_ppp_options'} || "/etc/ppp/options.pptp";
14 # Returns the PPTP configuration
19 open(FILE, $config{'file'});
22 if (/^\s*(#?)\s*(\S+)\s*(\S*)\s*$/) {
23 push(@rv, { 'name' => $2,
27 'index' => scalar(@rv) });
35 # find_conf(name, &config)
39 foreach $c (@{$_[1]}) {
40 if (lc($c->{'name'}) eq lc($_[0]) && $c->{'enabled'}) {
47 # save_directive(&config, name, [value])
50 local $lref = &read_file_lines($config{'file'});
51 local ($old) = grep { lc($_->{'name'}) eq lc($_[1]) } @{$_[0]};
54 # Can just update old one
55 $lref->[$old->{'line'}] = "$_[1]\t$_[2]";
57 elsif ($old->{'enabled'}) {
59 $lref->[$old->{'line'}] = "#$old->{'name'}\t$old->{'value'}";
62 elsif (defined($_[2])) {
64 push(@$lref, "$_[1]\t$_[2]");
69 # Returns the PID of the running PPTP server process
72 open(PID, $config{'pid_file'}) || return undef;
80 # Returns the hostname that this server uses for authentication
83 local $conf = &get_config();
84 local $option = &find_conf("option", $conf);
85 $option ||= $config{'ppp_options'};
86 local @opts = &parse_ppp_options($option);
87 local $name = &find("name", \@opts);
88 return $name ? $name->{'value'} : &get_system_hostname(1);
91 # parse_ppp_options(file)
100 if (/^([0-9\.]+):([0-9\.]+)/) {
101 push(@rv, { 'local' => $1,
105 'index' => scalar(@rv) });
107 elsif (/^(\S+)\s*(.*)/) {
108 push(@rv, { 'name' => $1,
112 'index' => scalar(@rv) });
120 # find(name, &config)
123 local @rv = grep { lc($_->{'name'}) eq lc($_[0]) } @{$_[1]};
124 return wantarray ? @rv : $rv[0];
127 # save_ppp_option(&config, file, &old|name, &new)
130 local $ol = ref($_[2]) || !defined($_[2]) ? $_[2] : &find($_[2], $_[0]);
132 local $lref = &read_file_lines($_[1]);
135 if ($nw->{'local'}) {
136 $line = $nw->{'local'}.":".$nw->{'remote'};
139 $line = $nw->{'name'};
140 $line .= " $nw->{'value'}" if ($nw->{'value'} ne "");
144 $lref->[$ol->{'line'}] = $line;
147 splice(@$lref, $ol->{'line'}, 1);
149 foreach $c (@{$_[0]}) {
150 $c->{'line'}-- if ($c->{'line'} > $ol->{'line'});
159 # Returns a list of active PPTP connections by checking the process list.
160 # Each element of the list is an array containing the PPP PID, PPTP PID,
161 # client IP, interface, local IP and remote IP, start time and username
166 # Look in the log file for connection messages
167 local (%pppuser, %localip, %remoteip);
168 &open_readfile(LOG, $config{'log_file'});
170 if (/pppd\[(\d+)\].*authentication\s+succeeded\s+for\s+(\S+)/i) {
173 elsif (/pppd\[(\d+)\].*local\s+IP\s+address\s+(\S+)/) {
176 elsif (/pppd\[(\d+)\].*remote\s+IP\s+address\s+(\S+)/) {
182 # Check for running pptpd and pppd processes
183 &foreign_require("proc", "proc-lib.pl");
184 &foreign_require("net", "net-lib.pl");
185 local @procs = &proc::list_processes();
186 local @ifaces = &net::active_interfaces();
187 foreach $p (@procs) {
188 if ($p->{'args'} =~ /pptpd\s*\[([0-9\.]+)/) {
189 # Found a PPTP connection process .. get the child PPP proc
191 local ($ppp) = grep { $_->{'ppid'} == $p->{'pid'} } @procs;
192 local $user = $ppp ? $pppuser{$ppp->{'pid'}} : undef;
194 if ($ppp && ($lip=$localip{$ppp->{'pid'}})) {
195 # We got the local and remote IPs from the log file
196 local $rip2 = $remoteip{$ppp->{'pid'}};
197 local ($iface) = grep { $_->{'address'} eq $lip &&
198 $_->{'ptp'} eq $rip } @ifaces;
199 push(@rv, [ $ppp->{'pid'}, $p->{'pid'},
200 $rip, $iface ? $iface->{'fullname'} : undef,
202 $ppp->{'_stime'}, $user ] );
204 elsif ($ppp && $ppp->{'args'} =~ /([0-9\.]+):([0-9\.]+)/) {
205 # Find the matching interface
206 local ($iface) = grep { $_->{'address'} eq $1 &&
207 $_->{'ptp'} eq $2 } @ifaces;
209 push(@rv, [ $ppp->{'pid'}, $p->{'pid'},
210 $rip, $iface->{'fullname'},
211 $1, $iface->{'ptp'} || $2,
212 $ppp->{'_stime'}, $user ] );
215 push(@rv, [ $ppp->{'pid'}, $p->{'pid'},
217 $ppp->{'_stime'}, $user ] );
221 # PPP process doesn't include IPs
222 push(@rv, [ $ppp->{'pid'}, $p->{'pid'},
223 $rip, undef, undef, undef,
224 $ppp->{'_stime'}, $user ] );
231 # get_pptpd_version(&out)
232 sub get_pptpd_version
234 local $out = `$config{'pptpd'} -v 2>&1`;
236 return $out =~ /(PoPToP|pptpd)\s+v?(\S+)/i ? $2 : undef;
239 # apply_configuration()
240 # Attempts to apply the PPTP server configuration, and returns undef on
241 # success or an error message on failure
242 sub apply_configuration
245 if ($config{'stop_cmd'}) {
246 local $out = &backquote_logged("$config{'stop_cmd'} 2>&1 </dev/null");
247 return "<pre>$out</pre>" if ($?);
250 local $pid = &get_pptpd_pid();
251 if (!$pid || !&kill_logged('TERM', $pid)) {
252 return $text{'stop_egone'};
257 local $cmd = $config{'start_cmd'} || $config{'pptpd'};
258 local $temp = &tempname();
259 local $rv = &system_logged("$cmd >$temp 2>&1 </dev/null");
260 local $out = `cat $temp`;
263 return "<pre>$out</pre>";