]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blob - html/cgi-bin/ovpnfunc.pl
OpenVPN/ZERINA-Update.
[people/teissler/ipfire-2.x.git] / html / cgi-bin / ovpnfunc.pl
1 #!/usr/bin/perl -w
2 package Ovpnfunc;
3 use Archive::Zip qw(:ERROR_CODES :CONSTANTS);
4 use Net::DNS;
5 use File::Copy;
6 use File::Temp qw/ tempfile tempdir /;
7 use strict;
8 require '/var/ipfire/general-functions.pl';
9 my %netsettings=();
10 my $errormessage = '';
11 my $errormessage2 = '';
12 my @subnets; # array of anonymous hashes {cn, from, to}
13 my @subnets2; # array of anonymous hashes {cn, from, to}
14 my %overlaps; # hash {cn} of anonymous arrays of subnets
15 my ($subnet, $from, $to, $i, $j);
16 &General::readhash("${General::swroot}/ethernet/settings", \%netsettings);
17 sub haveOrangeNet
18 {
19 if ($netsettings{'CONFIG_TYPE'} == 1) {return 1;}
20 if ($netsettings{'CONFIG_TYPE'} == 3) {return 1;}
21 if ($netsettings{'CONFIG_TYPE'} == 5) {return 1;}
22 if ($netsettings{'CONFIG_TYPE'} == 7) {return 1;}
23 return 0;
24 }
25
26 sub haveBlueNet
27 {
28 if ($netsettings{'CONFIG_TYPE'} == 4) {return 1;}
29 if ($netsettings{'CONFIG_TYPE'} == 5) {return 1;}
30 if ($netsettings{'CONFIG_TYPE'} == 6) {return 1;}
31 if ($netsettings{'CONFIG_TYPE'} == 7) {return 1;}
32 return 0;
33 }
34
35 sub sizeformat{
36 my $bytesize = $_[0];
37 my $i = 0;
38
39 while(abs($bytesize) >= 1024){
40 $bytesize=$bytesize/1024;
41 $i++;
42 last if($i==6);
43 }
44
45 my @units = ("Bytes","KB","MB","GB","TB","PB","EB");
46 my $newsize=(int($bytesize*100 +0.5))/100;
47 return("$newsize $units[$i]");
48 }
49
50 sub valid_dns_host {
51 my $hostname = $_[0];
52 unless ($hostname) { return "No hostname"};
53 my $res = new Net::DNS::Resolver;
54 my $query = $res->search("$hostname");
55 if ($query) {
56 foreach my $rr ($query->answer) {
57 ## Potential bug - we are only looking at A records:
58 return 0 if $rr->type eq "A";
59 }
60 } else {
61 return $res->errorstring;
62 }
63 }
64
65 sub cleanssldatabase
66 {
67 if (open(FILE, ">${General::swroot}/ovpn/certs/serial")) {
68 print FILE "01";
69 close FILE;
70 }
71 if (open(FILE, ">${General::swroot}/ovpn/certs/index.txt")) {
72 print FILE "";
73 close FILE;
74 }
75 unlink ("${General::swroot}/ovpn/certs/index.txt.old");
76 unlink ("${General::swroot}/ovpn/certs/serial.old");
77 unlink ("${General::swroot}/ovpn/certs/01.pem");
78 }
79
80 sub newcleanssldatabase
81 {
82 if (! -s "${General::swroot}/ovpn/certs/serial" ) {
83 open(FILE, ">${General::swroot}(ovpn/certs/serial");
84 print FILE "01";
85 close FILE;
86 }
87 if (! -s ">${General::swroot}/ovpn/certs/index.txt") {
88 system ("touch ${General::swroot}/ovpn/certs/index.txt");
89 }
90 unlink ("${General::swroot}/ovpn/certs/index.txt.old");
91 unlink ("${General::swroot}/ovpn/certs/serial.old");
92 }
93
94 sub deletebackupcert
95 {
96 if (open(FILE, "${General::swroot}/ovpn/certs/serial.old")) {
97 my $hexvalue = <FILE>;
98 chomp $hexvalue;
99 close FILE;
100 unlink ("${General::swroot}/ovpn/certs/$hexvalue.pem");
101 }
102 }
103
104 sub checkportfw {
105 my $KEY2 = $_[0]; # key2
106 my $SRC_PORT = $_[1]; # src_port
107 my $PROTOCOL = $_[2]; # protocol
108 my $SRC_IP = $_[3]; # sourceip
109 my $pfwfilename = "${General::swroot}/portfw/config";
110 open(FILE, $pfwfilename) or die 'Unable to open config file.';
111 my @pfwcurrent = <FILE>;
112 close(FILE);
113 my $pfwkey1 = 0; # used for finding last sequence number used
114 foreach my $pfwline (@pfwcurrent)
115 {
116 my @pfwtemp = split(/\,/,$pfwline);
117
118 chomp ($pfwtemp[8]);
119 if ($KEY2 eq "0"){ # if key2 is 0 then it is a portfw addition
120 if ( $SRC_PORT eq $pfwtemp[3] &&
121 $PROTOCOL eq $pfwtemp[2] &&
122 $SRC_IP eq $pfwtemp[7])
123 {
124 $errormessage = "$Lang::tr{'source port in use'} $SRC_PORT";
125 }
126 # Check if key2 = 0, if it is then it is a port forward entry and we want the sequence number
127 if ( $pfwtemp[1] eq "0") {
128 $pfwkey1=$pfwtemp[0];
129 }
130 # Darren Critchley - Duplicate or overlapping Port range check
131 if ($pfwtemp[1] eq "0" &&
132 $PROTOCOL eq $pfwtemp[2] &&
133 $SRC_IP eq $pfwtemp[7] &&
134 $errormessage eq '')
135 {
136 &portchecks($SRC_PORT, $pfwtemp[5]);
137 # &portchecks($pfwtemp[3], $pfwtemp[5]);
138 # &portchecks($pfwtemp[3], $SRC_IP);
139 }
140 }
141 }
142 # $errormessage="$KEY2 $SRC_PORT $PROTOCOL $SRC_IP";
143
144 return $errormessage;
145 }
146
147 sub checkportoverlap
148 {
149 my $portrange1 = $_[0]; # New port range
150 my $portrange2 = $_[1]; # existing port range
151 my @tempr1 = split(/\:/,$portrange1);
152 my @tempr2 = split(/\:/,$portrange2);
153
154 unless (&checkportinc($tempr1[0], $portrange2)){ return 0;}
155 unless (&checkportinc($tempr1[1], $portrange2)){ return 0;}
156
157 unless (&checkportinc($tempr2[0], $portrange1)){ return 0;}
158 unless (&checkportinc($tempr2[1], $portrange1)){ return 0;}
159
160 return 1; # Everything checks out!
161 }
162
163 # Darren Critchley - we want to make sure that a port entry is not within an already existing range
164 sub checkportinc
165 {
166 my $port1 = $_[0]; # Port
167 my $portrange2 = $_[1]; # Port range
168 my @tempr1 = split(/\:/,$portrange2);
169
170 if ($port1 < $tempr1[0] || $port1 > $tempr1[1]) {
171 return 1;
172 } else {
173 return 0;
174 }
175 }
176 # Darren Critchley - Duplicate or overlapping Port range check
177 sub portchecks
178 {
179 my $p1 = $_[0]; # New port range
180 my $p2 = $_[1]; # existing port range
181 # $_ = $_[0];
182 our ($prtrange1, $prtrange2);
183 $prtrange1 = 0;
184 # if (m/:/ && $prtrange1 == 1) { # comparing two port ranges
185 # unless (&checkportoverlap($p1,$p2)) {
186 # $errormessage = "$Lang::tr{'source port overlaps'} $p1";
187 # }
188 # }
189 if (m/:/ && $prtrange1 == 0 && $errormessage eq '') { # compare one port to a range
190 unless (&checkportinc($p2,$p1)) {
191 $errormessage = "$Lang::tr{'srcprt within existing'} $p1";
192 }
193 }
194 $prtrange1 = 1;
195 if (! m/:/ && $prtrange1 == 1 && $errormessage eq '') { # compare one port to a range
196 unless (&checkportinc($p1,$p2)) {
197 $errormessage = "$Lang::tr{'srcprt range overlaps'} $p2";
198 }
199 }
200 return;
201 }
202
203 # Darren Critchley - certain ports are reserved for IPFire
204 # TCP 67,68,81,222,444
205 # UDP 67,68
206 # Params passed in -> port, rangeyn, protocol
207 sub disallowreserved
208 {
209 # port 67 and 68 same for tcp and udp, don't bother putting in an array
210 my $msg = "";
211 my @tcp_reserved = (81,222,444);
212 my $prt = $_[0]; # the port or range
213 my $ryn = $_[1]; # tells us whether or not it is a port range
214 my $prot = $_[2]; # protocol
215 my $srcdst = $_[3]; # source or destination
216 if ($ryn) { # disect port range
217 if ($srcdst eq "src") {
218 $msg = "$Lang::tr{'rsvd src port overlap'}";
219 } else {
220 $msg = "$Lang::tr{'rsvd dst port overlap'}";
221 }
222 my @tmprng = split(/\:/,$prt);
223 unless (67 < $tmprng[0] || 67 > $tmprng[1]) { $errormessage="$msg 67"; return; }
224 unless (68 < $tmprng[0] || 68 > $tmprng[1]) { $errormessage="$msg 68"; return; }
225 if ($prot eq "tcp") {
226 foreach my $prange (@tcp_reserved) {
227 unless ($prange < $tmprng[0] || $prange > $tmprng[1]) { $errormessage="$msg $prange"; return; }
228 }
229 }
230 } else {
231 if ($srcdst eq "src") {
232 $msg = "$Lang::tr{'reserved src port'}";
233 } else {
234 $msg = "$Lang::tr{'reserved dst port'}";
235 }
236 if ($prt == 67) { $errormessage="$msg 67"; return; }
237 if ($prt == 68) { $errormessage="$msg 68"; return; }
238 if ($prot eq "tcp") {
239 foreach my $prange (@tcp_reserved) {
240 if ($prange == $prt) {
241 $errormessage = "$msg $prange";
242 return $errormessage; }
243 }
244 }
245 }
246 return $errormessage;
247 }
248
249 sub writeserverconf {
250 my %sovpnsettings = ();
251 &General::readhash("${General::swroot}/ovpn/settings", \%sovpnsettings);
252
253 open(CONF, ">${General::swroot}/ovpn/server.conf") or die "Unable to open ${General::swroot}/ovpn/server.conf: $!";
254 flock CONF, 2;
255 print CONF "#OpenVPN Server conf\n";
256 print CONF "\n";
257 print CONF "daemon openvpnserver\n";
258 print CONF "writepid /var/run/openvpn.pid\n";
259 print CONF "#DAN prepare ZERINA for listening on blue and orange\n";
260 print CONF ";local $sovpnsettings{'VPN_IP'}\n";
261 print CONF "dev $sovpnsettings{'DDEVICE'}\n";
262 print CONF "$sovpnsettings{'DDEVICE'}-mtu $sovpnsettings{'DMTU'}\n";
263 if ($sovpnsettings{'DPROTOCOL'} eq 'tcp') {
264 print CONF "proto $sovpnsettings{'DPROTOCOL'}-server\n";
265 } else {
266 print CONF "proto $sovpnsettings{'DPROTOCOL'}\n";
267 }
268 print CONF "port $sovpnsettings{'DDEST_PORT'}\n";
269 print CONF "tls-server\n";
270 print CONF "ca /var/ipfire/ovpn/ca/cacert.pem\n";
271 print CONF "cert /var/ipfire/ovpn/certs/servercert.pem\n";
272 print CONF "key /var/ipfire/ovpn/certs/serverkey.pem\n";
273 print CONF "dh /var/ipfire/ovpn/ca/dh1024.pem\n";
274 my @tempovpnsubnet = split("\/",$sovpnsettings{'DOVPN_SUBNET'});
275 print CONF "server $tempovpnsubnet[0] $tempovpnsubnet[1]\n";
276 print CONF "push \"route $netsettings{'GREEN_NETADDRESS'} $netsettings{'GREEN_NETMASK'}\"\n";
277 if ($sovpnsettings{AD_ROUTE1} ne '') {
278 my @tempovpnsubnet = split("\/",$sovpnsettings{'AD_ROUTE1'});
279 print CONF "push \"route $tempovpnsubnet[0] $tempovpnsubnet[1]\"\n";
280 }
281 if ($sovpnsettings{AD_ROUTE2} ne '') {
282 my @tempovpnsubnet = split("\/",$sovpnsettings{'AD_ROUTE2'});
283 print CONF "push \"route $tempovpnsubnet[0] $tempovpnsubnet[1]\"\n";
284 }
285 if ($sovpnsettings{AD_ROUTE3} ne '') {
286 my @tempovpnsubnet = split("\/",$sovpnsettings{'AD_ROUTE3'});
287 print CONF "push \"route $tempovpnsubnet[0] $tempovpnsubnet[1]\"\n";
288 }
289 if ($sovpnsettings{CLIENT2CLIENT} eq 'on') {
290 print CONF "client-to-client\n";
291 }
292 if ($sovpnsettings{KEEPALIVE_1} > 0 && $sovpnsettings{KEEPALIVE_2} > 0) {
293 print CONF "keepalive $sovpnsettings{'KEEPALIVE_1'} $sovpnsettings{'KEEPALIVE_2'}\n";
294 }
295 print CONF "status-version 1\n";
296 print CONF "status /var/log/ovpnserver.log 30\n";
297 print CONF "cipher $sovpnsettings{DCIPHER}\n";
298 if ($sovpnsettings{DCOMPLZO} eq 'on') {
299 print CONF "comp-lzo\n";
300 }
301 if ($sovpnsettings{REDIRECT_GW_DEF1} eq 'on') {
302 print CONF "push \"redirect-gateway def1\"\n";
303 }
304 if ($sovpnsettings{DHCP_DOMAIN} ne '') {
305 print CONF "push \"dhcp-option DOMAIN $sovpnsettings{DHCP_DOMAIN}\"\n";
306 }
307
308 if ($sovpnsettings{DHCP_DNS} ne '') {
309 print CONF "push \"dhcp-option DNS $sovpnsettings{DHCP_DNS}\"\n";
310 }
311
312 if ($sovpnsettings{DHCP_WINS} ne '') {
313 print CONF "push \"dhcp-option WINS $sovpnsettings{DHCP_WINS}\"\n";
314 }
315
316 if ($sovpnsettings{DHCP_WINS} eq '') {
317 print CONF "max-clients 100\n";
318 }
319
320 if ($sovpnsettings{DHCP_WINS} ne '') {
321 print CONF "max-clients $sovpnsettings{MAX_CLIENTS}\n";
322 }
323
324 #################################################################################
325 # Added by Philipp Jenni #
326 # #
327 # Contact: philipp.jenni-at-gmx.ch #
328 # Date: 2006-04-22 #
329 # Description: Add the FAST-IO Parameter from OpenVPN to der Server.Config. #
330 # Add the NICE Parameter from OpenVPN to der Server.Config. #
331 # Add the MTU-DISC Parameter from OpenVPN to der Server.Config. #
332 # Add the MSSFIX Parameter from OpenVPN to der Server.Config. #
333 # Add the FRAMGMENT Parameter from OpenVPN to der Server.Config. #
334 #################################################################################
335 if ($sovpnsettings{EXTENDED_FASTIO} eq 'on') {
336 print CONF "fast-io\n";
337 }
338 if ($sovpnsettings{EXTENDED_NICE} != 0) {
339 print CONF "nice $sovpnsettings{EXTENDED_NICE}\n";
340 }
341 if ($sovpnsettings{EXTENDED_MTUDISC} eq 'on') {
342 print CONF "mtu-disc yes\n";
343 }
344 if ($sovpnsettings{EXTENDED_MSSFIX} ne '') {
345 print CONF "mssfix $sovpnsettings{EXTENDED_MSSFIX}\n";
346 }
347 if ($sovpnsettings{EXTENDED_FRAGMENT} ne '') {
348 print CONF "fragment $sovpnsettings{EXTENDED_FRAGMENT}\n";
349 }
350 #################################################################################
351 # End of Inserted Data #
352 #################################################################################
353
354 print CONF "tls-verify /var/ipfire/ovpn/verify\n";
355 print CONF "crl-verify /var/ipfire/ovpn/crls/cacrl.pem\n";
356 print CONF "user nobody\n";
357 print CONF "group nobody\n";
358 print CONF "persist-key\n";
359 print CONF "persist-tun\n";
360 if ($sovpnsettings{LOG_VERB} ne '') {
361 print CONF "verb $sovpnsettings{LOG_VERB}\n";
362 } else {
363 print CONF "verb 3\n";
364 }
365 print CONF "\n";
366
367 close(CONF);
368 }
369
370 sub writenet2netconf {
371 my $n2nkey = $_[0];
372 my $zerinaclient = $_[1];
373 my %n2nconfighash = ();
374 my $file = '';
375 # my $file = '';
376 my $clientovpn = '';
377 my @fileholder;
378 my $tempdir = tempdir( CLEANUP => 1 );
379 my $zippath = "$tempdir/";
380 &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%n2nconfighash);
381 if (! $n2nkey) {
382 $n2nkey = &General::findhasharraykey (\%n2nconfighash);
383 foreach my $i (0 .. 25) { $n2nconfighash{$n2nkey}[$i] = "";}
384 }
385 my $zipname = "$n2nconfighash{$n2nkey}[1].zip";
386 my $zippathname = "$zippath$zipname";
387 if ($n2nconfighash{$n2nkey}[3] eq 'net') {
388 if ($zerinaclient eq '') {
389 if ( -d "${General::swroot}/ovpn/n2nconf/$n2nconfighash{$n2nkey}[1]"){
390 while ($file = glob("${General::swroot}/ovpn/n2nconf/$n2nconfighash{$n2nkey}[1]/*.conf")) {
391 unlink $file
392 }
393 } else {
394 mkdir("${General::swroot}/ovpn/n2nconf/$n2nconfighash{$n2nkey}[1]", 0770);
395 }
396 open(CONF, ">${General::swroot}/ovpn/n2nconf/$n2nconfighash{$n2nkey}[1]/$n2nconfighash{$n2nkey}[1].conf") or die "Unable to open ${General::swroot}/ovpn/n2nconf/$n2nconfighash{$n2nkey}[1]/$n2nconfighash{$n2nkey}[1].conf: $!";
397 } else {
398 $clientovpn = "$n2nconfighash{$n2nkey}[1].conf";
399 open(CONF, ">$tempdir/$clientovpn") or die "Unable to open $tempdir/$clientovpn: $!";
400 }
401 flock CONF, 2;
402 print CONF "dev tun\n";
403 print CONF "tun-mtu $n2nconfighash{$n2nkey}[17]\n";
404 if ($n2nconfighash{$n2nkey}[14] eq 'udp') {
405 print CONF "proto $n2nconfighash{$n2nkey}[14]\n";
406 } elsif ((($zerinaclient eq '') && ($n2nconfighash{$n2nkey}[6] eq 'server'))) {
407 print CONF "proto $n2nconfighash{$n2nkey}[14]-server\n";
408 } else {
409 print CONF "proto $n2nconfighash{$n2nkey}[14]-client\n";
410 }
411 print CONF "port $n2nconfighash{$n2nkey}[15]\n";
412 my @tempovpnsubnet = split("\/",$n2nconfighash{$n2nkey}[13]);
413 my @ovpnip = split /\./,$tempovpnsubnet[0];
414 # if ((($zerinaclient eq '') && ($n2nconfighash{$n2nkey}[19] eq 'no'))) {
415 if ((($zerinaclient eq '') && ($n2nconfighash{$n2nkey}[6] eq 'server'))) {
416 print CONF "ifconfig $ovpnip[0].$ovpnip[1].$ovpnip[2].1 $ovpnip[0].$ovpnip[1].$ovpnip[2].2\n";
417 print CONF "remote $n2nconfighash{$n2nkey}[10]\n";
418 print CONF "tls-server\n";
419 print CONF "ca /var/ipfire/ovpn/ca/cacert.pem\n";
420 print CONF "cert /var/ipfire/ovpn/certs/servercert.pem\n";
421 print CONF "key /var/ipfire/ovpn/certs/serverkey.pem\n";
422 print CONF "dh /var/ipfire/ovpn/ca/dh1024.pem\n";
423 my @tempremotesubnet = split("\/",$n2nconfighash{$n2nkey}[11]);
424 print CONF "route $tempremotesubnet[0] $tempremotesubnet[1]\n";
425 } else {
426 print CONF "ifconfig $ovpnip[0].$ovpnip[1].$ovpnip[2].2 $ovpnip[0].$ovpnip[1].$ovpnip[2].1\n";
427 #print CONF "$zerinaclient ufuk 10=$n2nconfighash{$n2nkey}[10] 18=$n2nconfighash{$n2nkey}[18] 19=$n2nconfighash{$n2nkey}[19] \n";
428 if ($zerinaclient ne 'true'){
429 if ($n2nconfighash{$n2nkey}[19] eq 'no'){
430 print CONF "remote $n2nconfighash{$n2nkey}[10]\n";
431 } else {
432 print CONF "remote $n2nconfighash{$n2nkey}[10]\n";
433 }
434 } else {
435 print CONF "remote $n2nconfighash{$n2nkey}[18]\n";
436 }
437 print CONF "tls-client\n";
438 if ($zerinaclient ne 'true'){
439 print CONF "pkcs12 ${General::swroot}/ovpn/n2nconf/$n2nconfighash{$n2nkey}[1]/$n2nconfighash{$n2nkey}[1].p12\n";
440 } else {
441 print CONF "pkcs12 $n2nconfighash{$n2nkey}[1].p12\n";
442 }
443 if ($n2nconfighash{$n2nkey}[19] eq 'no'){
444 my @tempremotesubnet = split("\/",$n2nconfighash{$n2nkey}[8]);
445 print CONF "route $tempremotesubnet[0] $tempremotesubnet[1]\n";
446 } else {
447 my @tempremotesubnet = split("\/",$n2nconfighash{$n2nkey}[11]);
448 print CONF "route $tempremotesubnet[0] $tempremotesubnet[1]\n";
449 }
450 }
451 if ($n2nconfighash{$n2nkey}[26] > 0 && $n2nconfighash{$n2nkey}[27] > 0) {
452 print CONF "keepalive $n2nconfighash{$n2nkey}[26] $n2nconfighash{$n2nkey}[27]\n";
453 } else {
454 print CONF "keepalive 10 60\n";
455 }
456 print CONF "cipher $n2nconfighash{$n2nkey}[20]\n";
457 if ($n2nconfighash{$n2nkey}[16] eq 'on') {
458 print CONF "comp-lzo\n";
459 }
460 if ($n2nconfighash{$n2nkey}[42] ne '') {
461 print CONF "verb $n2nconfighash{$n2nkey}[42]\n";
462 } else {
463 print CONF "verb 3\n";
464 }
465 if ($n2nconfighash{$n2nkey}[19] eq 'no'){
466 print CONF "#$n2nconfighash{$n2nkey}[11]\n";
467 } else {
468 print CONF "#$n2nconfighash{$n2nkey}[8]\n";
469 }
470 if ($zerinaclient ne 'true') {
471 print CONF "daemon OVPN_$n2nconfighash{$n2nkey}[1]\n";
472 print CONF "#status ${General::swroot}/ovpn/n2nconf/$n2nconfighash{$n2nkey}[1]/$n2nconfighash{$n2nkey}[1].log 2\n";
473 }
474 close(CONF);
475 if ($zerinaclient eq 'true') {
476 my $zip = Archive::Zip->new();
477 $zip->addFile( "${General::swroot}/ovpn/certs/$n2nconfighash{$n2nkey}[1].p12", "$n2nconfighash{$n2nkey}[1].p12") or die "Can't add file ${General::swroot}/ovpn/certs/$n2nconfighash{$n2nkey}[1].p12\n";
478 $zip->addFile( "$tempdir/$clientovpn", $clientovpn) or die "Can't add file $clientovpn\n";
479 my $status = $zip->writeToFileNamed($zippathname);
480 open(DLFILE, "<$zippathname") or die "Unable to open $zippathname: $!";
481 @fileholder = <DLFILE>;
482 print "Content-Type:application/x-download\n";
483 print "Content-Disposition:attachment;filename=$zipname\n\n";
484 print @fileholder;
485 exit (0);
486 }
487 }
488 }
489
490 sub removenet2netconf {
491 my %n2nconfighash = ();
492 my $key = $_[0];
493 my $file = '';
494 &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%n2nconfighash);
495 if ($n2nconfighash{$key}[3] eq 'net') {
496 if ( -d "${General::swroot}/ovpn/n2nconf/$n2nconfighash{$key}[1]"){
497 while ($file = glob("${General::swroot}/ovpn/n2nconf/$n2nconfighash{$key}[1]/*")) {
498 unlink $file
499 }
500 rmdir("${General::swroot}/ovpn/n2nconf/$n2nconfighash{$key}[1]");
501 }
502 }
503 }
504
505 sub emptyserverlog{
506 if (open(FILE, ">/var/log/ovpnserver.log")) {
507 flock FILE, 2;
508 print FILE "";
509 close FILE;
510 }
511 }
512
513 sub displayca {
514 my $key = $_[0];
515 my %cahash = ();
516 &General::readhasharray("${General::swroot}/ovpn/caconfig", \%cahash);
517 if ( -f "${General::swroot}/ovpn/ca/$cahash{$key}[0]cert.pem") {
518 &Header::showhttpheaders();
519 &Header::openpage($Lang::tr{'vpn configuration main'}, 1, '');
520 &Header::openbigbox('100%', 'LEFT', '', $errormessage);
521 &Header::openbox('100%', 'LEFT', "$Lang::tr{'ca certificate'}:");
522 my $output = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/ca/$cahash{$key}[0]cert.pem`;
523 $output = &Header::cleanhtml($output,"y");
524 print "<pre>$output</pre>\n";
525 &Header::closebox();
526 print "<div align='center'><a href='/cgi-bin/ovpnmain.cgi'>$Lang::tr{'back'}</a></div>";
527 &Header::closebigbox();
528 &Header::closepage();
529 exit(0);
530 } else {
531 $errormessage = $Lang::tr{'invalid key'};
532 }
533 }
534 sub displayroothost {
535 my $roothost = $_[0];
536 my $output;
537 &Header::showhttpheaders();
538 &Header::openpage($Lang::tr{'vpn configuration main'}, 1, '');
539 &Header::openbigbox('100%', 'LEFT', '', '');
540 if ($roothost eq $Lang::tr{'show root certificate'}) {
541 &Header::openbox('100%', 'LEFT', "$Lang::tr{'root certificate'}:");
542 $output = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/ca/cacert.pem`;
543 } else {
544 &Header::openbox('100%', 'LEFT', "$Lang::tr{'host certificate'}:");
545 $output = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/certs/servercert.pem`;
546 }
547 $output = &Header::cleanhtml($output,"y");
548 print "<pre>$output</pre>\n";
549 &Header::closebox();
550 print "<div align='center'><a href='/cgi-bin/ovpnmain.cgi'>$Lang::tr{'back'}</a></div>";
551 &Header::closebigbox();
552 &Header::closepage();
553 exit(0);
554 }
555
556 sub killconnection {
557 my $key = $_[0];
558 my %n2nconfighash = ();
559 &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%n2nconfighash);
560 my $n2nactive = `/bin/ps ax|grep $n2nconfighash{$key}[1].conf|grep -v grep|awk \'{print \$1}\'`;
561 if ($n2nactive ne ''){
562 system('/usr/local/bin/openvpnctrl', '-kn2n', $n2nactive);
563 }
564 }
565
566 sub cidrormask {
567 my $cidrmask = $_[0];
568 my $cidrmask2 = $cidrmask;
569 if ("/$cidrmask" =~ /^\/(\d+)/){#cidr
570 if ($cidrmask2 = &cidr2mask("/$cidrmask")) {
571 return $cidrmask2;
572 } else {
573 if ($cidrmask =~ /^\d+\.\d+\.\d+\.\d+/){#mask
574 return $cidrmask;
575 }
576 }
577 } else {
578 if ($cidrmask =~ /^\d+\.\d+\.\d+\.\d+/){#mask
579 return $cidrmask;
580 }
581 }
582 }
583 sub cidr2mask {
584 my( $cidr ) = @_;
585 my( $one32 ) = 0xffffffff;
586 my( @d, $n, $bits );
587
588 if ( $cidr eq "/0" ) {
589 return "0.0.0.0";
590 }
591
592 if ( $cidr !~ /\/(\d+)/ ) {
593 return undef;
594 }
595 $bits = $1;
596
597 if ( $bits > 32 ) {
598 return undef;
599 }
600
601 #-- convert to subnet-style mask
602 $n = $one32 << (32 - $bits);
603 $d[3] = $n % 256; $n = int( $n / 256);
604 $d[2] = $n % 256; $n = int( $n / 256);
605 $d[1] = $n % 256; $n = int( $n / 256);
606 $d[0] = $n;
607 return join '.', @d;
608 }
609
610
611 # ----------------------------------------------------------------------------
612 # $cidr = &mask2cidr( $mask )
613 # ----------------------------------------------------------------------------
614
615 sub mask2cidr {
616 my( $mask ) = @_;
617 my( @d, $n, $bits );
618
619 if ( $mask eq "0.0.0.0" ) {
620 return "/0";
621 }
622
623 if ( ! &validMask( $mask ) ) {
624 return undef;
625 }
626
627 @d = split /\./, $mask;
628 $n = ((((($d[0] * 256) + $d[1]) * 256) + $d[2]) * 256) + $d[3];
629 $bits = 32;
630 while ( ($n % 2) == 0 ) {
631 $n >>= 1;
632 $bits -= 1;
633 }
634 return "/$bits";
635 }
636
637
638 # ----------------------------------------------------------------------------
639 # $yesno = &validMask( $mask )
640 # ----------------------------------------------------------------------------
641
642 sub validMask {
643 my( $mask ) = @_;
644 my( @d, $n, $str );
645
646 @d = split /\./, $mask;
647 $n = ((((($d[0] * 256) + $d[1]) * 256) + $d[2]) * 256) + $d[3];
648 $str = sprintf "%b", $n;
649 return ( $str =~ /^1+0*$/ );
650 }
651
652 sub overlapping {
653 # read all subnets from AD, convert to integer range, and sort.
654 foreach $subnet (@subnets2) {
655 ($from, $to) = &subnet2range ($subnet);
656 push @subnets, { cn => $subnet, from => $from, to => $to };
657 }
658 @subnets = sort { $a->{from} <=> $b->{from} } @subnets;
659
660 # compare all possible subnets for overlap; depend on sort order.
661 for ($i=0; $i<=$#subnets; $i++) {
662 for ($j=$i+1; $j<=$#subnets; $j++) {
663 last if $subnets[$i]->{to} < $subnets[$j]->{from}; # no possible overlap anymore;
664 push @{$overlaps{$subnets[$i]->{cn}}}, $subnets[$j]->{cn} if $subnets[$i]->{to} >= $subnets[$j]->{from};
665 }
666 }
667
668 if (scalar (keys %overlaps)) {
669 foreach $subnet (sort keys %overlaps) {
670 #$errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire IPSEC : %s\n", $subnet, join (", ", sort @{$overlaps{$subnet}});
671 $errormessage = "$subnet : $overlaps{$subnet}[0]";
672 last;
673 }
674 }
675 return $errormessage;
676 }
677
678 # &subnet2range ($subnet)
679 # convert subnets to integers in order to compare them later.
680 # A subnet looks like this: 10.1.2.0/24
681 # returns beginning and end of subnet as integer
682 #
683 sub subnet2range {
684 my $subnet = shift (@_);
685 my ($from, $to);
686
687 $subnet =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)\/(\d+)$/ || die "bad subnet $subnet\n";
688 $from = $1*2**24 + $2*2**16 + $3*2**8 + $4;
689 $to = $from + 2**(32-$5) - 1;
690 return ($from, $to);
691 }
692
693 sub ovelapplausi {
694 my $tmpovpnsubnet0 = $_[0];
695 my $tmpovpnsubnet1 = $_[1];
696 my %vpnconfighash = ();
697 my $tmpcidr = '';
698 my @tmpremotevpnsubnet;
699 &General::readhasharray("${General::swroot}/vpn/config", \%vpnconfighash);
700
701 if (&General::IpInSubnet ( $netsettings{'GREEN_ADDRESS'},
702 $tmpovpnsubnet0, $tmpovpnsubnet1)) {
703 $errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire Green Network $netsettings{'GREEN_ADDRESS'}";
704 return $errormessage;
705 }
706
707 if (&haveBlueNet()) {
708 if (&General::IpInSubnet ( $netsettings{'BLUE_ADDRESS'},
709 $tmpovpnsubnet0, $tmpovpnsubnet1)) {
710 $errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire Blue Network $netsettings{'BLUE_ADDRESS'}";
711 return $errormessage;
712 }
713 }
714 if (&haveOrangeNet()) {
715 if (&General::IpInSubnet ( $netsettings{'ORANGE_ADDRESS'},
716 $tmpovpnsubnet0, $tmpovpnsubnet1)) {
717 $errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire Orange Network $netsettings{'ORANGE_ADDRESS'}";
718 return $errormessage;
719 }
720 }
721 open(ALIASES, "${General::swroot}/ethernet/aliases") or die 'Unable to open aliases file.';
722 while (<ALIASES>)
723 {
724 chomp($_);
725 my @tempalias = split(/\,/,$_);
726 if ($tempalias[1] eq 'on') {
727 if (&General::IpInSubnet ($tempalias[0] ,
728 $tmpovpnsubnet0, $tmpovpnsubnet1)) {
729 $errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire alias entry $tempalias[0]";
730 exit $errormessage;
731 }
732 }
733 }
734 close(ALIASES);
735
736 #check against ipsec connections
737 foreach my $key (keys %vpnconfighash) {
738 #$confighash{$key}[8] = $cgiparams{'LOCAL_SUBNET'};
739 #$confighash{$key}[3]#host or net
740 #$confighash{$key}[11] = $cgiparams{'REMOTE_SUBNET'};
741 #$confighash{$key}[10] = $cgiparams{'REMOTE'};
742 &emptyarray();
743 $tmpcidr = &mask2cidr($tmpovpnsubnet1);
744 push @subnets2, "$tmpovpnsubnet0$tmpcidr";
745 @tmpremotevpnsubnet = split("\/",$vpnconfighash{$key}[8]);
746 $tmpcidr = &mask2cidr($tmpremotevpnsubnet[1]);
747 push @subnets2, "$tmpremotevpnsubnet[0]$tmpcidr";
748 $errormessage2 = &overlapping();
749 if ($errormessage2 ne '') {
750 $errormessage = "$Lang::tr{'ovpn subnet overlap'}IPSCEC Connection=$vpnconfighash{$key}[1] $Lang::tr{'local subnet'} $errormessage2 ";
751 last;
752 }
753 &emptyarray();
754 if ($vpnconfighash{$key}[3] eq 'net'){
755 if (&General::IpInSubnet ($vpnconfighash{$key}[10],$tmpovpnsubnet0, $tmpovpnsubnet1)) {
756 $errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire IPSEC Connection/IP: $vpnconfighash{$key}[1]/$vpnconfighash{$key}[10]";
757 last;
758 }
759 #check agains ipsec local subent
760 push @subnets2, "$tmpovpnsubnet0$tmpcidr";
761 @tmpremotevpnsubnet = split("\/",$vpnconfighash{$key}[11]);
762 $tmpcidr = &mask2cidr($tmpremotevpnsubnet[1]);
763 push @subnets2, "$tmpremotevpnsubnet[0]$tmpcidr";
764 $errormessage2 = &overlapping();
765 if ($errormessage2 ne '') {
766 $errormessage = "$Lang::tr{'ovpn subnet overlap'}IPSCEC Connection=$vpnconfighash{$key}[1] $Lang::tr{'remote subnet'} $errormessage2 ";
767 last;
768 }
769 &emptyarray();
770 push @subnets2, "$tmpovpnsubnet0$tmpcidr";
771 @tmpremotevpnsubnet = split("\/",$vpnconfighash{$key}[8]);
772 $tmpcidr = &mask2cidr($tmpremotevpnsubnet[1]);
773 push @subnets2, "$tmpremotevpnsubnet[0]$tmpcidr";
774 $errormessage2 = &overlapping();
775 if ($errormessage2 ne '') {
776 $errormessage = "$Lang::tr{'ovpn subnet overlap'}IPSCEC Connection=$vpnconfighash{$key}[1] $Lang::tr{'local subnet'} $errormessage2 ";
777 last;
778 }
779 &emptyarray();
780 }
781 }
782 #check against OpenVPN Connections (aware check against itself)
783 return $errormessage;
784 }
785 sub emptyarray {
786 @subnets2 = ();
787 @subnets = ();
788 }
789 sub rwclientstatus {
790 my $activeonrun = $_[0];
791 my @status = `/bin/cat /var/log/ovpnserver.log`;
792 my %confighash = ();
793 my $dis = ''
794 &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
795 if ( -f "${General::swroot}/ovpn/ca/cacert.pem" ) {
796 $dis = '';
797 } else {
798 $dis = "disabled='disabled'";
799 }
800
801 &Header::openbox('100%', 'LEFT', "Roadwarrior $Lang::tr{'Client status and controlc'}");
802 print <<END
803 <table width='100%' border='0' cellspacing='1' cellpadding='0'>
804 <tr>
805 <td width='10%' class='boldbase' align='center'><b>$Lang::tr{'name'}</b></td>
806 <td width='15%' class='boldbase' align='center'><b>$Lang::tr{'type'}</b></td>
807 <td width='18%' class='boldbase' align='center'><b>$Lang::tr{'common name'}</b></td>
808 <td width='17%' class='boldbase' align='center'><b>$Lang::tr{'valid till'}</b></td>
809 <td width='25%' class='boldbase' align='center'><b>$Lang::tr{'remark'}</b><br /><img src='/images/null.gif' width='125' height='1' border='0' alt='L2089' /></td>
810 <td width='10%' class='boldbase' align='center'><b>$Lang::tr{'status'}</b></td>
811 <td width='5%' class='boldbase' colspan='6' align='center'><b>$Lang::tr{'action'}</b></td>
812 </tr>
813 END
814 ;
815 my $id = 0;
816 my $gif;
817 foreach my $key (keys %confighash) {
818 if ($confighash{$key}[3] eq 'host') {
819 if ($confighash{$key}[0] eq 'on') { $gif = 'on.gif'; } else { $gif = 'off.gif'; }
820 if ($id % 2) {
821 print "<tr bgcolor='${Header::table1colour}'>\n";
822 } else {
823 print "<tr bgcolor='${Header::table2colour}'>\n";
824 }
825 print "<td align='center' nowrap='nowrap'>$confighash{$key}[1]</td>";
826 print "<td align='center' nowrap='nowrap'>" . $Lang::tr{"$confighash{$key}[3]"} . " (" . $Lang::tr{"$confighash{$key}[4]"} . ")</td>";
827 if ($confighash{$key}[4] eq 'cert') {
828 print "<td align='left' nowrap='nowrap'>$confighash{$key}[2]</td>";
829 } else {
830 print "<td align='left'>&nbsp;</td>";
831 }
832 if ($confighash{$key}[19] ne 'yes') {
833 my $cavalid = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/certs/$confighash{$key}[1]cert.pem`;
834 $cavalid =~ /Not After : (.*)[\n]/;
835 $cavalid = $1;
836 print "<td align='center'>$cavalid</td>";
837 } else {
838 print "<td>&nbsp;</td>";
839 }
840 print "<td align='center'>$confighash{$key}[25]</td>";
841 my $active = "<table cellpadding='2' cellspacing='0' bgcolor='${Header::colourred}' width='100%'><tr><td align='center'><b><font color='#FFFFFF'>$Lang::tr{'capsclosed'}</font></b></td></tr></table>";
842 if ($confighash{$key}[0] eq 'off') {
843 $active = "<table cellpadding='2' cellspacing='0' bgcolor='${Header::colourblue}' width='100%'><tr><td align='center'><b><font color='#FFFFFF'>$Lang::tr{'capsclosed'}</font></b></td></tr></table>";
844 } else {
845 my $cn;
846 my @match = ();
847 foreach my $line (@status) {
848 chomp($line);
849 if ( $line =~ /^(.+),(\d+\.\d+\.\d+\.\d+\:\d+),(\d+),(\d+),(.+)/) {
850 @match = split(m/^(.+),(\d+\.\d+\.\d+\.\d+\:\d+),(\d+),(\d+),(.+)/, $line);
851 if ($match[1] ne "Common Name") {
852 $cn = $match[1];
853 }
854 $cn =~ s/[_]/ /g;
855 if ($cn eq "$confighash{$key}[2]") {
856 $active = "<table cellpadding='2' cellspacing='0' bgcolor='${Header::colourgreen}' width='100%'><tr><td align='center'><b><font color='#FFFFFF'>$Lang::tr{'capsopen'}</font></b></td></tr></table>";
857 }
858 }
859 }
860 }
861 print "<td align='center'>$active</td>";
862 my $disable_clientdl = "";
863 if ($confighash{$key}[6] ne 'client') {
864 print <<END
865 <form method='post' name='frm${key}a'><td align='center'>
866 <input type='image' name='$Lang::tr{'dl client arch'}' $disable_clientdl src='/images/openvpn.gif' alt='$Lang::tr{'dl client arch'}' title='$Lang::tr{'dl client arch'}' border='0' />
867 <input type='hidden' name='ACTION' value='$Lang::tr{'dl client arch'}' $disable_clientdl />
868 <input type='hidden' name='KEY' value='$key' $disable_clientdl />
869 </td></form>
870 END
871 ; } else {
872 print "<td>&nbsp;</td>";
873 }
874 if ($confighash{$key}[4] eq 'cert' && $confighash{$key}[19] ne 'yes') {
875 print <<END
876 <form method='post' name='frm${key}b'><td align='center'>
877 <input type='image' name='$Lang::tr{'show certificate'}' src='/images/info.gif' alt='$Lang::tr{'show certificate'}' title='$Lang::tr{'show certificate'}' border='0' />
878 <input type='hidden' name='ACTION' value='$Lang::tr{'show certificate'}' />
879 <input type='hidden' name='KEY' value='$key' />
880 </td></form>
881 END
882 ; } else {
883 print "<td>&nbsp;</td>";
884 }
885 if ($confighash{$key}[4] eq 'cert' && -f "${General::swroot}/ovpn/certs/$confighash{$key}[1].p12") {
886 print <<END
887 <form method='post' name='frm${key}c'><td align='center'>
888 <input type='image' name='$Lang::tr{'download pkcs12 file'}' src='/images/floppy.gif' alt='$Lang::tr{'download pkcs12 file'}' title='$Lang::tr{'download pkcs12 file'}' border='0' />
889 <input type='hidden' name='ACTION' value='$Lang::tr{'download pkcs12 file'}' />
890 <input type='hidden' name='KEY' value='$key' />
891 </td></form>
892 END
893 ; } elsif ($confighash{$key}[4] eq 'cert' && $confighash{$key}[19] ne 'yes') {
894 print <<END
895 <form method='post' name='frm${key}c'><td align='center'>
896 <input type='image' name='$Lang::tr{'download certificate'}' src='/images/floppy.gif' alt='$Lang::tr{'download certificate'}' title='$Lang::tr{'download certificate'}' border='0' />
897 <input type='hidden' name='ACTION' value='$Lang::tr{'download certificate'}' />
898 <input type='hidden' name='KEY' value='$key' />
899 </td></form>
900 END
901 ; } else {
902 print "<td>&nbsp;</td>";
903 }
904 print <<END
905 <form method='post' name='frm${key}d'><td align='center'>
906 <input type='image' name='$Lang::tr{'toggle enable disable'}' src='/images/$gif' alt='$Lang::tr{'toggle enable disable'}' title='$Lang::tr{'toggle enable disable'}' border='0' />
907 <input type='hidden' name='ACTION' value='$Lang::tr{'toggle enable disable'}' />
908 <input type='hidden' name='KEY' value='$key' />
909 </td></form>
910 <form method='post' name='frm${key}e'><td align='center'>
911 <input type='hidden' name='ACTION' value='$Lang::tr{'edit'}' />
912 <input type='image' name='$Lang::tr{'edit'}' src='/images/edit.gif' alt='$Lang::tr{'edit'}' title='$Lang::tr{'edit'}' width='20' height='20' border='0'/>
913 <input type='hidden' name='KEY' value='$key' />
914 </td></form>
915 <form method='post' name='frm${key}f'><td align='center'>
916 <input type='hidden' name='ACTION' value='$Lang::tr{'remove'}' />
917 <input type='image' name='$Lang::tr{'remove'}' src='/images/delete.gif' alt='$Lang::tr{'remove'}' title='$Lang::tr{'remove'}' width='20' height='20' border='0' />
918 <input type='hidden' name='KEY' value='$key' />
919 </td></form>
920 </tr>
921 END
922 ;
923 $id++;
924 }
925 }
926 ;
927 # If the config file contains entries, print Key to action icons
928 if ( $id ) {
929 print <<END
930 <table>
931 <tr>
932 <td class='boldbase'>&nbsp; <b>$Lang::tr{'legend'}:</b></td>
933 <td>&nbsp; <img src='/images/on.gif' alt='$Lang::tr{'click to disable'}' /></td>
934 <td class='base'>$Lang::tr{'click to disable'}</td>
935 <td>&nbsp; &nbsp; <img src='/images/info.gif' alt='$Lang::tr{'show certificate'}' /></td>
936 <td class='base'>$Lang::tr{'show certificate'}</td>
937 <td>&nbsp; &nbsp; <img src='/images/edit.gif' alt='$Lang::tr{'edit'}' /></td>
938 <td class='base'>$Lang::tr{'edit'}</td>
939 <td>&nbsp; &nbsp; <img src='/images/delete.gif' alt='$Lang::tr{'remove'}' /></td>
940 <td class='base'>$Lang::tr{'remove'}</td>
941 </tr>
942 <tr>
943 <td>&nbsp; </td>
944 <td>&nbsp; <img src='/images/off.gif' alt='?OFF' /></td>
945 <td class='base'>$Lang::tr{'click to enable'}</td>
946 <td>&nbsp; &nbsp; <img src='/images/floppy.gif' alt='?FLOPPY' /></td>
947 <td class='base'>$Lang::tr{'download certificate'}</td>
948 <td>&nbsp; &nbsp; <img src='/images/openvpn.gif' alt='?RELOAD'/></td>
949 <td class='base'>$Lang::tr{'dl client arch'}</td>
950 </tr>
951 </table>
952 END
953 ;
954 }
955 print <<END
956 <table width='100%'>
957 <form method='post'>
958 <tr><td width='50%' ><input type='submit' name='ACTION' value='$Lang::tr{'add'}' $dis />
959 <input type='hidden' name='TYPE' value='host' /></td>
960 <td width='50%' ><input type='submit' name='ACTION' value='$Lang::tr{'ovpn con stat'}' $activeonrun /></td></tr>
961 </form>
962 </table>
963 END
964 ;
965 &Header::closebox();
966 #}
967 }
968 sub net2netstatus {
969 #net2net connections
970 my $activeonrun = $_[0];
971 my @status = `/bin/cat /var/log/ovpnserver.log`;
972 my %confighash = ();
973 my $dis = ''
974 &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
975 if ( -f "${General::swroot}/ovpn/ca/cacert.pem" ) {
976 $dis = '';
977 } else {
978 $dis = "disabled='disabled'";
979 }
980 &Header::openbox('100%', 'LEFT', "Net to Net Connection status and control:");
981 print <<END
982 <table width='100%' border='0' cellspacing='1' cellpadding='0'>
983 <tr>
984 <td width='10%' class='boldbase' align='center'><b>$Lang::tr{'name'}</b></td>
985 <td width='15%' class='boldbase' align='center'><b>$Lang::tr{'type'}</b></td>
986 <td width='18%' class='boldbase' align='center'><b>$Lang::tr{'common name'}</b></td>
987 <td width='17%' class='boldbase' align='center'><b>$Lang::tr{'valid till'}</b></td>
988 <td width='25%' class='boldbase' align='center'><b>$Lang::tr{'remark'}</b><br /><img src='/images/null.gif' width='125' height='1' border='0' alt='L2089' /></td>
989 <td width='10%' class='boldbase' align='center'><b>$Lang::tr{'status'}</b></td>
990 <td width='5%' class='boldbase' colspan='6' align='center'><b>$Lang::tr{'action'}</b></td>
991 </tr>
992 END
993 ;
994 my $id = 0;
995 my $gif;
996 foreach my $key (keys %confighash) {
997 if ($confighash{$key}[3] eq 'net') {
998 if ($confighash{$key}[0] eq 'on') { $gif = 'on.gif'; } else { $gif = 'off.gif'; }
999 if ($id % 2) {
1000 print "<tr bgcolor='${Header::table1colour}'>\n";
1001 } else {
1002 print "<tr bgcolor='${Header::table2colour}'>\n";
1003 }
1004 print "<td align='center' nowrap='nowrap'>$confighash{$key}[1]</td>";
1005 print "<td align='center' nowrap='nowrap'>" . $confighash{$key}[6] . "-" . $Lang::tr{"$confighash{$key}[3]"} . " (" . $Lang::tr{"$confighash{$key}[4]"} . ")</td>";
1006 if ($confighash{$key}[4] eq 'cert') {
1007 print "<td align='left' nowrap='nowrap'>$confighash{$key}[2]</td>";
1008 } else {
1009 print "<td align='left'>&nbsp;</td>";
1010 }
1011 if ($confighash{$key}[19] ne 'yes') {
1012 my $cavalid = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/certs/$confighash{$key}[1]cert.pem`;
1013 $cavalid =~ /Not After : (.*)[\n]/;
1014 $cavalid = $1;
1015 print "<td align='center'>$cavalid</td>";
1016 } else {
1017 print "<td>&nbsp;</td>";
1018 }
1019 print "<td align='center'>$confighash{$key}[25]</td>";
1020 my $active = "<table cellpadding='2' cellspacing='0' bgcolor='${Header::colourred}' width='100%'><tr><td align='center'><b><font color='#FFFFFF'>$Lang::tr{'capsclosed'}</font></b></td></tr></table>";
1021 if ($confighash{$key}[0] eq 'off') {
1022 $active = "<table cellpadding='2' cellspacing='0' bgcolor='${Header::colourblue}' width='100%'><tr><td align='center'><b><font color='#FFFFFF'>$Lang::tr{'capsclosed'}</font></b></td></tr></table>";
1023 } else {
1024 my @tempovpnsubnet = split("\/",$confighash{$key}[13]);
1025 my @ovpnip = split /\./,$tempovpnsubnet[0];
1026 my $pingip = "";
1027 if ($confighash{$key}[6] eq 'server') {
1028 $pingip = "$ovpnip[0].$ovpnip[1].$ovpnip[2].2";
1029 } else {
1030 $pingip = "$ovpnip[0].$ovpnip[1].$ovpnip[2].1";
1031 }
1032 my $p = Net::Ping->new("udp",1);
1033 if ($p->ping($pingip)) {
1034 $active = "<table cellpadding='2' cellspacing='0' bgcolor='${Header::colourgreen}' width='100%'><tr><td align='center'><b><font color='#FFFFFF'>$Lang::tr{'capsopen'}</font></b></td></tr></table>";
1035 }
1036 $p->close();
1037 }
1038 print "<td align='center'>$active</td>";
1039 my $disable_clientdl = "";
1040 if ($confighash{$key}[6] ne 'client') {
1041 print <<END
1042 <form method='post' name='frm${key}a'><td align='center'>
1043 <input type='image' name='$Lang::tr{'dl client arch'}' $disable_clientdl src='/images/openvpn.gif' alt='$Lang::tr{'dl client arch'}' title='$Lang::tr{'dl client arch'}' border='0' />
1044 <input type='hidden' name='ACTION' value='$Lang::tr{'dl client arch'}' $disable_clientdl />
1045 <input type='hidden' name='KEY' value='$key' $disable_clientdl />
1046 </td></form>
1047 END
1048 ; } else {
1049 print "<td>&nbsp;</td>";
1050 }
1051 if ($confighash{$key}[4] eq 'cert' && $confighash{$key}[19] ne 'yes') {
1052 print <<END
1053 <form method='post' name='frm${key}b'><td align='center'>
1054 <input type='image' name='$Lang::tr{'show certificate'}' src='/images/info.gif' alt='$Lang::tr{'show certificate'}' title='$Lang::tr{'show certificate'}' border='0' />
1055 <input type='hidden' name='ACTION' value='$Lang::tr{'show certificate'}' />
1056 <input type='hidden' name='KEY' value='$key' />
1057 </td></form>
1058 END
1059 ; } else {
1060 print "<td>&nbsp;</td>";
1061 }
1062 if ($confighash{$key}[4] eq 'cert' && -f "${General::swroot}/ovpn/certs/$confighash{$key}[1].p12") {
1063 print <<END
1064 <form method='post' name='frm${key}c'><td align='center'>
1065 <input type='image' name='$Lang::tr{'download pkcs12 file'}' src='/images/floppy.gif' alt='$Lang::tr{'download pkcs12 file'}' title='$Lang::tr{'download pkcs12 file'}' border='0' />
1066 <input type='hidden' name='ACTION' value='$Lang::tr{'download pkcs12 file'}' />
1067 <input type='hidden' name='KEY' value='$key' />
1068 </td></form>
1069 END
1070 ; } elsif ($confighash{$key}[4] eq 'cert' && $confighash{$key}[19] ne 'yes') {
1071 print <<END
1072 <form method='post' name='frm${key}c'><td align='center'>
1073 <input type='image' name='$Lang::tr{'download certificate'}' src='/images/floppy.gif' alt='$Lang::tr{'download certificate'}' title='$Lang::tr{'download certificate'}' border='0' />
1074 <input type='hidden' name='ACTION' value='$Lang::tr{'download certificate'}' />
1075 <input type='hidden' name='KEY' value='$key' />
1076 </td></form>
1077 END
1078 ; } else {
1079 print "<td>&nbsp;</td>";
1080 }
1081
1082 print <<END
1083 <form method='post' name='frm${key}d'><td align='center'>
1084 <input type='image' name='$Lang::tr{'toggle enable disable'}' src='/images/$gif' alt='$Lang::tr{'toggle enable disable'}' title='$Lang::tr{'toggle enable disable'}' border='0' />
1085 <input type='hidden' name='ACTION' value='$Lang::tr{'toggle enable disable'}' />
1086 <input type='hidden' name='KEY' value='$key' />
1087 </td></form>
1088 <form method='post' name='frm${key}e'><td align='center'>
1089 <input type='hidden' name='ACTION' value='$Lang::tr{'edit'}' />
1090 <input type='image' name='$Lang::tr{'edit'}' src='/images/edit.gif' alt='$Lang::tr{'edit'}' title='$Lang::tr{'edit'}' width='20' height='20' border='0'/>
1091 <input type='hidden' name='KEY' value='$key' />
1092 </td></form>
1093 <form method='post' name='frm${key}f'><td align='center'>
1094 <input type='hidden' name='ACTION' value='$Lang::tr{'remove'}' />
1095 <input type='image' name='$Lang::tr{'remove'}' src='/images/delete.gif' alt='$Lang::tr{'remove'}' title='$Lang::tr{'remove'}' width='20' height='20' border='0' />
1096 <input type='hidden' name='KEY' value='$key' />
1097 </td></form>
1098 </tr>
1099 END
1100 ;
1101 $id++;
1102 }
1103 }
1104 ;
1105
1106 # If the config file contains entries, print Key to action icons
1107 if ( $id ) {
1108 print <<END
1109 <table>
1110 <tr>
1111 <td class='boldbase'>&nbsp; <b>$Lang::tr{'legend'}:</b></td>
1112 <td>&nbsp; <img src='/images/on.gif' alt='$Lang::tr{'click to disable'}' /></td>
1113 <td class='base'>$Lang::tr{'click to disable'}</td>
1114 <td>&nbsp; &nbsp; <img src='/images/info.gif' alt='$Lang::tr{'show certificate'}' /></td>
1115 <td class='base'>$Lang::tr{'show certificate'}</td>
1116 <td>&nbsp; &nbsp; <img src='/images/edit.gif' alt='$Lang::tr{'edit'}' /></td>
1117 <td class='base'>$Lang::tr{'edit'}</td>
1118 <td>&nbsp; &nbsp; <img src='/images/delete.gif' alt='$Lang::tr{'remove'}' /></td>
1119 <td class='base'>$Lang::tr{'remove'}</td>
1120 </tr>
1121 <tr>
1122 <td>&nbsp; </td>
1123 <td>&nbsp; <img src='/images/off.gif' alt='?OFF' /></td>
1124 <td class='base'>$Lang::tr{'click to enable'}</td>
1125 <td>&nbsp; &nbsp; <img src='/images/floppy.gif' alt='?FLOPPY' /></td>
1126 <td class='base'>$Lang::tr{'download certificate'}</td>
1127 <td>&nbsp; &nbsp; <img src='/images/openvpn.gif' alt='?RELOAD'/></td>
1128 <td class='base'>$Lang::tr{'dl client arch'}</td>
1129 </tr>
1130 </table>
1131 END
1132 ;
1133 }
1134 print <<END
1135 <table width='100%'>
1136 <form method='post'>
1137 <tr><td width='50%' ><input type='submit' name='ACTION' value='$Lang::tr{'add'}' $ dis /></td></tr>
1138 </form>
1139 </table>
1140 END
1141 ;
1142 &Header::closebox();
1143 #}
1144 #net2net connections
1145 }