]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - html/cgi-bin/ovpnmain.cgi
Am Pakfire weitergearbeitet.
[people/pmueller/ipfire-2.x.git] / html / cgi-bin / ovpnmain.cgi
CommitLineData
6e13d0a5 1#!/usr/bin/perl
6e13d0a5
MT
2#
3# This code is distributed under the terms of the GPL
c6c9630e 4# (c) 2007 Ufuk Altinkaynak
6e13d0a5
MT
5#
6
7use CGI;
8use CGI qw/:standard/;
9use Net::DNS;
10use File::Copy;
11use File::Temp qw/ tempfile tempdir /;
12use strict;
13use Archive::Zip qw(:ERROR_CODES :CONSTANTS);
6e13d0a5 14require '/var/ipfire/general-functions.pl';
6e13d0a5
MT
15require "${General::swroot}/lang.pl";
16require "${General::swroot}/header.pl";
17require "${General::swroot}/countries.pl";
18
19# enable only the following on debugging purpose
20#use warnings;
21#use CGI::Carp 'fatalsToBrowser';
22#workaround to suppress a warning when a variable is used only once
23my @dummy = ( ${Header::colourgreen} );
24undef (@dummy);
25
f2fdd0c1
CS
26my %color = ();
27my %mainsettings = ();
28&General::readhash("${General::swroot}/main/settings", \%mainsettings);
29&General::readhash("/srv/web/ipfire/html/themes/".$mainsettings{'THEME'}."/include/colors.txt", \%color);
6e13d0a5
MT
30
31###
32### Initialize variables
33###
34my %netsettings=();
35my %cgiparams=();
36my %vpnsettings=();
37my %checked=();
38my %confighash=();
39my %cahash=();
40my %selected=();
41my $warnmessage = '';
42my $errormessage = '';
43my %settings=();
6e13d0a5
MT
44&General::readhash("${General::swroot}/ethernet/settings", \%netsettings);
45$cgiparams{'ENABLED'} = 'off';
46$cgiparams{'ENABLED_BLUE'} = 'off';
47$cgiparams{'ENABLED_ORANGE'} = 'off';
48$cgiparams{'EDIT_ADVANCED'} = 'off';
49$cgiparams{'NAT'} = 'off';
50$cgiparams{'COMPRESSION'} = 'off';
51$cgiparams{'ONLY_PROPOSED'} = 'off';
52$cgiparams{'ACTION'} = '';
53$cgiparams{'CA_NAME'} = '';
54$cgiparams{'DHCP_DOMAIN'} = '';
55$cgiparams{'DHCP_DNS'} = '';
56$cgiparams{'DHCP_WINS'} = '';
57$cgiparams{'DCOMPLZO'} = 'off';
58&Header::getcgihash(\%cgiparams, {'wantfile' => 1, 'filevar' => 'FH'});
59
60# prepare openvpn config file
61###
62### Useful functions
63###
c6c9630e
MT
64sub haveOrangeNet
65{
13211b21
CS
66 if ($netsettings{'CONFIG_TYPE'} == 2) {return 1;}
67 if ($netsettings{'CONFIG_TYPE'} == 4) {return 1;}
c6c9630e
MT
68 return 0;
69}
70
71sub haveBlueNet
72{
13211b21 73 if ($netsettings{'CONFIG_TYPE'} == 3) {return 1;}
c6c9630e 74 if ($netsettings{'CONFIG_TYPE'} == 4) {return 1;}
c6c9630e
MT
75 return 0;
76}
77
78sub sizeformat{
79 my $bytesize = shift;
80 my $i = 0;
81
82 while(abs($bytesize) >= 1024){
83 $bytesize=$bytesize/1024;
84 $i++;
85 last if($i==6);
86 }
87
88 my @units = ("Bytes","KB","MB","GB","TB","PB","EB");
89 my $newsize=(int($bytesize*100 +0.5))/100;
90 return("$newsize $units[$i]");
91}
92
93sub valid_dns_host {
94 my $hostname = $_[0];
95 unless ($hostname) { return "No hostname"};
96 my $res = new Net::DNS::Resolver;
97 my $query = $res->search("$hostname");
98 if ($query) {
99 foreach my $rr ($query->answer) {
100 ## Potential bug - we are only looking at A records:
101 return 0 if $rr->type eq "A";
102 }
103 } else {
104 return $res->errorstring;
105 }
106}
107
108sub cleanssldatabase
109{
110 if (open(FILE, ">${General::swroot}/ovpn/certs/serial")) {
111 print FILE "01";
112 close FILE;
113 }
114 if (open(FILE, ">${General::swroot}/ovpn/certs/index.txt")) {
115 print FILE "";
116 close FILE;
117 }
118 unlink ("${General::swroot}/ovpn/certs/index.txt.old");
119 unlink ("${General::swroot}/ovpn/certs/serial.old");
120 unlink ("${General::swroot}/ovpn/certs/01.pem");
121}
122
123sub newcleanssldatabase
124{
125 if (! -s "${General::swroot}/ovpn/certs/serial" ) {
126 open(FILE, ">${General::swroot}(ovpn/certs/serial");
127 print FILE "01";
128 close FILE;
129 }
130 if (! -s ">${General::swroot}/ovpn/certs/index.txt") {
131 system ("touch ${General::swroot}/ovpn/certs/index.txt");
132 }
133 unlink ("${General::swroot}/ovpn/certs/index.txt.old");
134 unlink ("${General::swroot}/ovpn/certs/serial.old");
135}
136
137sub deletebackupcert
138{
139 if (open(FILE, "${General::swroot}/ovpn/certs/serial.old")) {
140 my $hexvalue = <FILE>;
141 chomp $hexvalue;
142 close FILE;
143 unlink ("${General::swroot}/ovpn/certs/$hexvalue.pem");
144 }
145}
146
147sub checkportfw {
148 my $KEY2 = $_[0]; # key2
149 my $SRC_PORT = $_[1]; # src_port
150 my $PROTOCOL = $_[2]; # protocol
151 my $SRC_IP = $_[3]; # sourceip
152
153 my $pfwfilename = "${General::swroot}/portfw/config";
154 open(FILE, $pfwfilename) or die 'Unable to open config file.';
155 my @pfwcurrent = <FILE>;
156 close(FILE);
157 my $pfwkey1 = 0; # used for finding last sequence number used
158 foreach my $pfwline (@pfwcurrent)
159 {
160 my @pfwtemp = split(/\,/,$pfwline);
161
162 chomp ($pfwtemp[8]);
163 if ($KEY2 eq "0"){ # if key2 is 0 then it is a portfw addition
164 if ( $SRC_PORT eq $pfwtemp[3] &&
165 $PROTOCOL eq $pfwtemp[2] &&
166 $SRC_IP eq $pfwtemp[7])
167 {
168 $errormessage = "$Lang::tr{'source port in use'} $SRC_PORT";
169 }
170 # Check if key2 = 0, if it is then it is a port forward entry and we want the sequence number
171 if ( $pfwtemp[1] eq "0") {
172 $pfwkey1=$pfwtemp[0];
173 }
174 # Darren Critchley - Duplicate or overlapping Port range check
175 if ($pfwtemp[1] eq "0" &&
176 $PROTOCOL eq $pfwtemp[2] &&
177 $SRC_IP eq $pfwtemp[7] &&
178 $errormessage eq '')
179 {
180 &portchecks($SRC_PORT, $pfwtemp[5]);
181# &portchecks($pfwtemp[3], $pfwtemp[5]);
182# &portchecks($pfwtemp[3], $SRC_IP);
183 }
184 }
185 }
186# $errormessage="$KEY2 $SRC_PORT $PROTOCOL $SRC_IP";
187
188 return;
189}
190
191sub checkportoverlap
192{
193 my $portrange1 = $_[0]; # New port range
194 my $portrange2 = $_[1]; # existing port range
195 my @tempr1 = split(/\:/,$portrange1);
196 my @tempr2 = split(/\:/,$portrange2);
197
198 unless (&checkportinc($tempr1[0], $portrange2)){ return 0;}
199 unless (&checkportinc($tempr1[1], $portrange2)){ return 0;}
200
201 unless (&checkportinc($tempr2[0], $portrange1)){ return 0;}
202 unless (&checkportinc($tempr2[1], $portrange1)){ return 0;}
203
204 return 1; # Everything checks out!
205}
206
207# Darren Critchley - we want to make sure that a port entry is not within an already existing range
208sub checkportinc
209{
210 my $port1 = $_[0]; # Port
211 my $portrange2 = $_[1]; # Port range
212 my @tempr1 = split(/\:/,$portrange2);
213
214 if ($port1 < $tempr1[0] || $port1 > $tempr1[1]) {
215 return 1;
216 } else {
217 return 0;
218 }
219}
220# Darren Critchley - Duplicate or overlapping Port range check
221sub portchecks
222{
223 my $p1 = $_[0]; # New port range
224 my $p2 = $_[1]; # existing port range
225# $_ = $_[0];
226 our ($prtrange1, $prtrange2);
227 $prtrange1 = 0;
228# if (m/:/ && $prtrange1 == 1) { # comparing two port ranges
229# unless (&checkportoverlap($p1,$p2)) {
230# $errormessage = "$Lang::tr{'source port overlaps'} $p1";
231# }
232# }
233 if (m/:/ && $prtrange1 == 0 && $errormessage eq '') { # compare one port to a range
234 unless (&checkportinc($p2,$p1)) {
235 $errormessage = "$Lang::tr{'srcprt within existing'} $p1";
236 }
237 }
238 $prtrange1 = 1;
239 if (! m/:/ && $prtrange1 == 1 && $errormessage eq '') { # compare one port to a range
240 unless (&checkportinc($p1,$p2)) {
241 $errormessage = "$Lang::tr{'srcprt range overlaps'} $p2";
242 }
243 }
244 return;
245}
246
247# Darren Critchley - certain ports are reserved for IPFire
248# TCP 67,68,81,222,445
249# UDP 67,68
250# Params passed in -> port, rangeyn, protocol
251sub disallowreserved
252{
253 # port 67 and 68 same for tcp and udp, don't bother putting in an array
254 my $msg = "";
255 my @tcp_reserved = (81,222,445);
256 my $prt = $_[0]; # the port or range
257 my $ryn = $_[1]; # tells us whether or not it is a port range
258 my $prot = $_[2]; # protocol
259 my $srcdst = $_[3]; # source or destination
260 if ($ryn) { # disect port range
261 if ($srcdst eq "src") {
262 $msg = "$Lang::tr{'rsvd src port overlap'}";
263 } else {
264 $msg = "$Lang::tr{'rsvd dst port overlap'}";
265 }
266 my @tmprng = split(/\:/,$prt);
267 unless (67 < $tmprng[0] || 67 > $tmprng[1]) { $errormessage="$msg 67"; return; }
268 unless (68 < $tmprng[0] || 68 > $tmprng[1]) { $errormessage="$msg 68"; return; }
269 if ($prot eq "tcp") {
270 foreach my $prange (@tcp_reserved) {
271 unless ($prange < $tmprng[0] || $prange > $tmprng[1]) { $errormessage="$msg $prange"; return; }
272 }
273 }
274 } else {
275 if ($srcdst eq "src") {
276 $msg = "$Lang::tr{'reserved src port'}";
277 } else {
278 $msg = "$Lang::tr{'reserved dst port'}";
279 }
280 if ($prt == 67) { $errormessage="$msg 67"; return; }
281 if ($prt == 68) { $errormessage="$msg 68"; return; }
282 if ($prot eq "tcp") {
283 foreach my $prange (@tcp_reserved) {
284 if ($prange == $prt) { $errormessage="$msg $prange"; return; }
285 }
286 }
287 }
288 return;
289}
290
291sub writeserverconf {
292 my %sovpnsettings = ();
293 &General::readhash("${General::swroot}/ovpn/settings", \%sovpnsettings);
294
295 open(CONF, ">${General::swroot}/ovpn/server.conf") or die "Unable to open ${General::swroot}/ovpn/server.conf: $!";
296 flock CONF, 2;
297 print CONF "#OpenVPN Server conf\n";
298 print CONF "\n";
299 print CONF "daemon openvpnserver\n";
300 print CONF "writepid /var/run/openvpn.pid\n";
afabe9f7 301 print CONF "#DAN prepare OpenVPN for listening on blue and orange\n";
c6c9630e
MT
302 print CONF ";local $sovpnsettings{'VPN_IP'}\n";
303 print CONF "dev $sovpnsettings{'DDEVICE'}\n";
304 print CONF "$sovpnsettings{'DDEVICE'}-mtu $sovpnsettings{'DMTU'}\n";
305 print CONF "proto $sovpnsettings{'DPROTOCOL'}\n";
306 print CONF "port $sovpnsettings{'DDEST_PORT'}\n";
307 print CONF "tls-server\n";
308 print CONF "ca /var/ipfire/ovpn/ca/cacert.pem\n";
309 print CONF "cert /var/ipfire/ovpn/certs/servercert.pem\n";
310 print CONF "key /var/ipfire/ovpn/certs/serverkey.pem\n";
311 print CONF "dh /var/ipfire/ovpn/ca/dh1024.pem\n";
312 my @tempovpnsubnet = split("\/",$sovpnsettings{'DOVPN_SUBNET'});
313 print CONF "server $tempovpnsubnet[0] $tempovpnsubnet[1]\n";
314 print CONF "push \"route $netsettings{'GREEN_NETADDRESS'} $netsettings{'GREEN_NETMASK'}\"\n";
315 if ($sovpnsettings{CLIENT2CLIENT} eq 'on') {
316 print CONF "client-to-client\n";
317 }
318 if ($sovpnsettings{KEEPALIVE_1} > 0 && $sovpnsettings{KEEPALIVE_2} > 0) {
319 print CONF "keepalive $sovpnsettings{'KEEPALIVE_1'} $sovpnsettings{'KEEPALIVE_2'}\n";
320 }
321 print CONF "status-version 1\n";
4e17adad 322 print CONF "status /var/log/ovpnserver.log 30\n";
c6c9630e
MT
323 print CONF "cipher $sovpnsettings{DCIPHER}\n";
324 if ($sovpnsettings{DCOMPLZO} eq 'on') {
325 print CONF "comp-lzo\n";
326 }
327 if ($sovpnsettings{REDIRECT_GW_DEF1} eq 'on') {
328 print CONF "push \"redirect-gateway def1\"\n";
329 }
330 if ($sovpnsettings{DHCP_DOMAIN} ne '') {
331 print CONF "push \"dhcp-option DOMAIN $sovpnsettings{DHCP_DOMAIN}\"\n";
332 }
333
334 if ($sovpnsettings{DHCP_DNS} ne '') {
335 print CONF "push \"dhcp-option DNS $sovpnsettings{DHCP_DNS}\"\n";
336 }
337
338 if ($sovpnsettings{DHCP_WINS} ne '') {
339 print CONF "push \"dhcp-option WINS $sovpnsettings{DHCP_WINS}\"\n";
340 }
341
342 if ($sovpnsettings{DHCP_WINS} eq '') {
343 print CONF "max-clients 100\n";
344 }
345
346 if ($sovpnsettings{DHCP_WINS} ne '') {
347 print CONF "max-clients $sovpnsettings{MAX_CLIENTS}\n";
348 }
349 print CONF "tls-verify /var/ipfire/ovpn/verify\n";
350 print CONF "crl-verify /var/ipfire/ovpn/crls/cacrl.pem\n";
351 print CONF "user nobody\n";
352 print CONF "group nobody\n";
353 print CONF "persist-key\n";
354 print CONF "persist-tun\n";
355 if ($sovpnsettings{LOG_VERB} ne '') {
356 print CONF "verb $sovpnsettings{LOG_VERB}\n";
357 } else {
358 print CONF "verb 3\n";
359 }
360 print CONF "\n";
361
362 close(CONF);
363}
364#
365sub emptyserverlog{
4e17adad 366 if (open(FILE, ">/var/log/ovpnserver.log")) {
c6c9630e
MT
367 flock FILE, 2;
368 print FILE "";
369 close FILE;
370 }
371
372}
373
374#hier die refresh page
375if ( -e "${General::swroot}/ovpn/gencanow") {
376 my $refresh = '';
377 $refresh = "<meta http-equiv='refresh' content='15;' />";
378 &Header::showhttpheaders();
379 &Header::openpage($Lang::tr{'OVPN'}, 1, $refresh);
380 &Header::openbigbox('100%', 'center');
381 &Header::openbox('100%', 'left', "$Lang::tr{'generate root/host certificates'}:");
382 print "<tr>\n<td align='center'><img src='/images/clock.gif' alt='' /></td>\n";
383 print "<td colspan='2'><font color='red'>Please be patient this realy can take some time on older hardware...</font></td></tr>\n";
384 &Header::closebox();
385 &Header::closebigbox();
386 &Header::closepage();
387 exit (0);
388}
389##hier die refresh page
390
6e13d0a5
MT
391
392###
393### OpenVPN Server Control
394###
395if ($cgiparams{'ACTION'} eq $Lang::tr{'start ovpn server'} ||
396 $cgiparams{'ACTION'} eq $Lang::tr{'stop ovpn server'} ||
397 $cgiparams{'ACTION'} eq $Lang::tr{'restart ovpn server'}) {
6e13d0a5
MT
398 #start openvpn server
399 if ($cgiparams{'ACTION'} eq $Lang::tr{'start ovpn server'}){
c6c9630e 400 &emptyserverlog();
6e13d0a5
MT
401 system('/usr/local/bin/openvpnctrl', '-s');
402 }
403 #stop openvpn server
404 if ($cgiparams{'ACTION'} eq $Lang::tr{'stop ovpn server'}){
6e13d0a5 405 system('/usr/local/bin/openvpnctrl', '-k');
c6c9630e 406 &emptyserverlog();
6e13d0a5
MT
407 }
408# #restart openvpn server
409 if ($cgiparams{'ACTION'} eq $Lang::tr{'restart ovpn server'}){
410#workarund, till SIGHUP also works when running as nobody
c6c9630e
MT
411 system('/usr/local/bin/openvpnctrl', '-r');
412 &emptyserverlog();
6e13d0a5
MT
413 }
414}
415
416###
417### Save Advanced options
418###
419
420if ($cgiparams{'ACTION'} eq $Lang::tr{'save-adv-options'}) {
421 &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings);
422 #DAN do we really need (to to check) this value? Besides if we listen on blue and orange too,
423 #DAN this value has to leave.
424#new settings for daemon
425 $vpnsettings{'LOG_VERB'} = $cgiparams{'LOG_VERB'};
426 $vpnsettings{'KEEPALIVE_1'} = $cgiparams{'KEEPALIVE_1'};
427 $vpnsettings{'KEEPALIVE_2'} = $cgiparams{'KEEPALIVE_2'};
428 $vpnsettings{'MAX_CLIENTS'} = $cgiparams{'MAX_CLIENTS'};
429 $vpnsettings{'REDIRECT_GW_DEF1'} = $cgiparams{'REDIRECT_GW_DEF1'};
430 $vpnsettings{'CLIENT2CLIENT'} = $cgiparams{'CLIENT2CLIENT'};
431 $vpnsettings{'DHCP_DOMAIN'} = $cgiparams{'DHCP_DOMAIN'};
432 $vpnsettings{'DHCP_DNS'} = $cgiparams{'DHCP_DNS'};
433 $vpnsettings{'DHCP_WINS'} = $cgiparams{'DHCP_WINS'};
6e13d0a5
MT
434
435 if ($cgiparams{'DHCP_DOMAIN'} ne ''){
436 unless (&General::validfqdn($cgiparams{'DHCP_DOMAIN'}) || &General::validip($cgiparams{'DHCP_DOMAIN'})) {
437 $errormessage = $Lang::tr{'invalid input for dhcp domain'};
438 goto ADV_ERROR;
439 }
440 }
441 if ($cgiparams{'DHCP_DNS'} ne ''){
442 unless (&General::validfqdn($cgiparams{'DHCP_DNS'}) || &General::validip($cgiparams{'DHCP_DNS'})) {
443 $errormessage = $Lang::tr{'invalid input for dhcp dns'};
444 goto ADV_ERROR;
445 }
446 }
447 if ($cgiparams{'DHCP_WINS'} ne ''){
448 unless (&General::validfqdn($cgiparams{'DHCP_WINS'}) || &General::validip($cgiparams{'DHCP_WINS'})) {
449 $errormessage = $Lang::tr{'invalid input for dhcp wins'};
450 goto ADV_ERROR;
451 }
452 }
6e13d0a5
MT
453 if ((length($cgiparams{'MAX_CLIENTS'}) == 0) || (($cgiparams{'MAX_CLIENTS'}) < 1 ) || (($cgiparams{'MAX_CLIENTS'}) > 255 )) {
454 $errormessage = $Lang::tr{'invalid input for max clients'};
455 goto ADV_ERROR;
456 }
457 if ($cgiparams{'KEEPALIVE_1'} ne '') {
458 if ($cgiparams{'KEEPALIVE_1'} !~ /^[0-9]+$/) {
459 $errormessage = $Lang::tr{'invalid input for keepalive 1'};
460 goto ADV_ERROR;
461 }
462 }
463 if ($cgiparams{'KEEPALIVE_2'} ne ''){
464 if ($cgiparams{'KEEPALIVE_2'} !~ /^[0-9]+$/) {
465 $errormessage = $Lang::tr{'invalid input for keepalive 2'};
466 goto ADV_ERROR;
467 }
468 }
469 if ($cgiparams{'KEEPALIVE_2'} < ($cgiparams{'KEEPALIVE_1'} * 2)){
470 $errormessage = $Lang::tr{'invalid input for keepalive 1:2'};
471 goto ADV_ERROR;
472 }
473
474 &General::writehash("${General::swroot}/ovpn/settings", \%vpnsettings);
c6c9630e 475 &writeserverconf();#hier ok
6e13d0a5
MT
476}
477
c6c9630e
MT
478
479
480
6e13d0a5
MT
481###
482### Save main settings
483###
484if ($cgiparams{'ACTION'} eq $Lang::tr{'save'} && $cgiparams{'TYPE'} eq '' && $cgiparams{'KEY'} eq '') {
485 &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings);
6e13d0a5
MT
486 #DAN do we really need (to to check) this value? Besides if we listen on blue and orange too,
487 #DAN this value has to leave.
488 if ($cgiparams{'ENABLED'} eq 'on'){
489 unless (&General::validfqdn($cgiparams{'VPN_IP'}) || &General::validip($cgiparams{'VPN_IP'})) {
490 $errormessage = $Lang::tr{'invalid input for hostname'};
c6c9630e 491 goto SETTINGS_ERROR;
6e13d0a5
MT
492 }
493 }
494 if ($cgiparams{'ENABLED'} eq 'on'){
c6c9630e 495 &disallowreserved($cgiparams{'DDEST_PORT'},0,$cgiparams{'DPROTOCOL'},"dest");
6e13d0a5
MT
496 }
497 if ($errormessage) { goto SETTINGS_ERROR; }
498
499
500 if ($cgiparams{'ENABLED'} eq 'on'){
c6c9630e 501 &checkportfw(0,$cgiparams{'DDEST_PORT'},$cgiparams{'DPROTOCOL'},'0.0.0.0');
6e13d0a5
MT
502 }
503
504 if ($errormessage) { goto SETTINGS_ERROR; }
505
506 if (! &General::validipandmask($cgiparams{'DOVPN_SUBNET'})) {
c6c9630e
MT
507 $errormessage = $Lang::tr{'ovpn subnet is invalid'};
508 goto SETTINGS_ERROR;
509 }
510 my @tmpovpnsubnet = split("\/",$cgiparams{'DOVPN_SUBNET'});
511
512 if (&General::IpInSubnet ( $netsettings{'RED_ADDRESS'},
513 $tmpovpnsubnet[0], $tmpovpnsubnet[1])) {
514 $errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire RED Network $netsettings{'RED_ADDRESS'}";
515 goto SETTINGS_ERROR;
516 }
517
518 if (&General::IpInSubnet ( $netsettings{'GREEN_ADDRESS'},
519 $tmpovpnsubnet[0], $tmpovpnsubnet[1])) {
520 $errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire Green Network $netsettings{'GREEN_ADDRESS'}";
521 goto SETTINGS_ERROR;
522 }
523
524 if (&General::IpInSubnet ( $netsettings{'BLUE_ADDRESS'},
525 $tmpovpnsubnet[0], $tmpovpnsubnet[1])) {
526 $errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire Blue Network $netsettings{'BLUE_ADDRESS'}";
527 goto SETTINGS_ERROR;
528 }
529
530 if (&General::IpInSubnet ( $netsettings{'ORANGE_ADDRESS'},
531 $tmpovpnsubnet[0], $tmpovpnsubnet[1])) {
532 $errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire Orange Network $netsettings{'ORANGE_ADDRESS'}";
533 goto SETTINGS_ERROR;
534 }
535 open(ALIASES, "${General::swroot}/ethernet/aliases") or die 'Unable to open aliases file.';
536 while (<ALIASES>)
537 {
538 chomp($_);
539 my @tempalias = split(/\,/,$_);
540 if ($tempalias[1] eq 'on') {
541 if (&General::IpInSubnet ($tempalias[0] ,
542 $tmpovpnsubnet[0], $tmpovpnsubnet[1])) {
543 $errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire alias entry $tempalias[0]";
544 }
545 }
546 }
547 close(ALIASES);
6e13d0a5 548 if ($errormessage ne ''){
c6c9630e 549 goto SETTINGS_ERROR;
6e13d0a5
MT
550 }
551 if ($cgiparams{'ENABLED'} !~ /^(on|off)$/) {
552 $errormessage = $Lang::tr{'invalid input'};
553 goto SETTINGS_ERROR;
554 }
555 if ((length($cgiparams{'DMTU'})==0) || (($cgiparams{'DMTU'}) < 1000 )) {
556 $errormessage = $Lang::tr{'invalid mtu input'};
557 goto SETTINGS_ERROR;
558 }
559
560 unless (&General::validport($cgiparams{'DDEST_PORT'})) {
c6c9630e
MT
561 $errormessage = $Lang::tr{'invalid port'};
562 goto SETTINGS_ERROR;
6e13d0a5 563 }
6e13d0a5
MT
564 $vpnsettings{'ENABLED_BLUE'} = $cgiparams{'ENABLED_BLUE'};
565 $vpnsettings{'ENABLED_ORANGE'} =$cgiparams{'ENABLED_ORANGE'};
566 $vpnsettings{'ENABLED'} = $cgiparams{'ENABLED'};
567 $vpnsettings{'VPN_IP'} = $cgiparams{'VPN_IP'};
568#new settings for daemon
569 $vpnsettings{'DOVPN_SUBNET'} = $cgiparams{'DOVPN_SUBNET'};
570 $vpnsettings{'DDEVICE'} = $cgiparams{'DDEVICE'};
571 $vpnsettings{'DPROTOCOL'} = $cgiparams{'DPROTOCOL'};
572 $vpnsettings{'DDEST_PORT'} = $cgiparams{'DDEST_PORT'};
573 $vpnsettings{'DMTU'} = $cgiparams{'DMTU'};
574 $vpnsettings{'DCOMPLZO'} = $cgiparams{'DCOMPLZO'};
575 $vpnsettings{'DCIPHER'} = $cgiparams{'DCIPHER'};
576#new settings for daemon
577 &General::writehash("${General::swroot}/ovpn/settings", \%vpnsettings);
c6c9630e 578 &writeserverconf();#hier ok
6e13d0a5
MT
579SETTINGS_ERROR:
580###
581### Reset all step 2
582###
583}elsif ($cgiparams{'ACTION'} eq $Lang::tr{'reset'} && $cgiparams{'AREUSURE'} eq 'yes') {
584 my $file = '';
585 &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
586
587 foreach my $key (keys %confighash) {
c6c9630e
MT
588 if ($confighash{$key}[4] eq 'cert') {
589 delete $confighash{$cgiparams{'$key'}};
590 }
6e13d0a5
MT
591 }
592 while ($file = glob("${General::swroot}/ovpn/ca/*")) {
c6c9630e 593 unlink $file
6e13d0a5
MT
594 }
595 while ($file = glob("${General::swroot}/ovpn/certs/*")) {
c6c9630e 596 unlink $file
6e13d0a5
MT
597 }
598 while ($file = glob("${General::swroot}/ovpn/crls/*")) {
c6c9630e 599 unlink $file
6e13d0a5 600 }
c6c9630e 601 &cleanssldatabase();
6e13d0a5
MT
602 if (open(FILE, ">${General::swroot}/ovpn/caconfig")) {
603 print FILE "";
604 close FILE;
605 }
606 &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
c6c9630e 607 #&writeserverconf();
6e13d0a5
MT
608###
609### Reset all step 1
610###
611}elsif ($cgiparams{'ACTION'} eq $Lang::tr{'reset'}) {
612 &Header::showhttpheaders();
613 &Header::openpage($Lang::tr{'vpn configuration main'}, 1, '');
614 &Header::openbigbox('100%', 'LEFT', '', '');
615 &Header::openbox('100%', 'LEFT', $Lang::tr{'are you sure'});
616 print <<END
617 <table><form method='post'><input type='hidden' name='AREUSURE' value='yes' />
618 <tr><td align='center'>
619 <b><font color='${Header::colourred}'>$Lang::tr{'capswarning'}</font></b>:
620 $Lang::tr{'resetting the vpn configuration will remove the root ca, the host certificate and all certificate based connections'}
621 <tr><td align='center'><input type='submit' name='ACTION' value='$Lang::tr{'reset'}' />
622 <input type='submit' name='ACTION' value='$Lang::tr{'cancel'}' /></td></tr>
623 </form></table>
624END
625 ;
626 &Header::closebox();
627 &Header::closebigbox();
628 &Header::closepage();
629 exit (0);
630
631###
632### Upload CA Certificate
633###
634} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'upload ca certificate'}) {
635 &General::readhasharray("${General::swroot}/ovpn/caconfig", \%cahash);
636
637 if ($cgiparams{'CA_NAME'} !~ /^[a-zA-Z0-9]+$/) {
638 $errormessage = $Lang::tr{'name must only contain characters'};
639 goto UPLOADCA_ERROR;
640 }
641
642 if (length($cgiparams{'CA_NAME'}) >60) {
643 $errormessage = $Lang::tr{'name too long'};
644 goto VPNCONF_ERROR;
645 }
646
647 if ($cgiparams{'CA_NAME'} eq 'ca') {
648 $errormessage = $Lang::tr{'name is invalid'};
649 goto UPLOAD_CA_ERROR;
650 }
651
652 # Check if there is no other entry with this name
653 foreach my $key (keys %cahash) {
c6c9630e
MT
654 if ($cahash{$key}[0] eq $cgiparams{'CA_NAME'}) {
655 $errormessage = $Lang::tr{'a ca certificate with this name already exists'};
656 goto UPLOADCA_ERROR;
657 }
6e13d0a5
MT
658 }
659
660 if (ref ($cgiparams{'FH'}) ne 'Fh') {
c6c9630e
MT
661 $errormessage = $Lang::tr{'there was no file upload'};
662 goto UPLOADCA_ERROR;
6e13d0a5
MT
663 }
664 # Move uploaded ca to a temporary file
665 (my $fh, my $filename) = tempfile( );
666 if (copy ($cgiparams{'FH'}, $fh) != 1) {
c6c9630e
MT
667 $errormessage = $!;
668 goto UPLOADCA_ERROR;
6e13d0a5
MT
669 }
670 my $temp = `/usr/bin/openssl x509 -text -in $filename`;
c6c9630e
MT
671 if ($temp !~ /CA:TRUE/i) {
672 $errormessage = $Lang::tr{'not a valid ca certificate'};
673 unlink ($filename);
674 goto UPLOADCA_ERROR;
6e13d0a5 675 } else {
c6c9630e
MT
676 move($filename, "${General::swroot}/ovpn/ca/$cgiparams{'CA_NAME'}cert.pem");
677 if ($? ne 0) {
678 $errormessage = "$Lang::tr{'certificate file move failed'}: $!";
679 unlink ($filename);
680 goto UPLOADCA_ERROR;
681 }
6e13d0a5
MT
682 }
683
684 my $casubject = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/ca/$cgiparams{'CA_NAME'}cert.pem`;
685 $casubject =~ /Subject: (.*)[\n]/;
686 $casubject = $1;
687 $casubject =~ s+/Email+, E+;
688 $casubject =~ s/ ST=/ S=/;
689 $casubject = &Header::cleanhtml($casubject);
690
691 my $key = &General::findhasharraykey (\%cahash);
692 $cahash{$key}[0] = $cgiparams{'CA_NAME'};
693 $cahash{$key}[1] = $casubject;
694 &General::writehasharray("${General::swroot}/ovpn/caconfig", \%cahash);
c6c9630e
MT
695# system('/usr/local/bin/ipsecctrl', 'R');
696
6e13d0a5
MT
697 UPLOADCA_ERROR:
698
699###
700### Display ca certificate
701###
702} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'show ca certificate'}) {
c6c9630e
MT
703 &General::readhasharray("${General::swroot}/ovpn/caconfig", \%cahash);
704
705 if ( -f "${General::swroot}/ovpn/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem") {
706 &Header::showhttpheaders();
707 &Header::openpage($Lang::tr{'vpn configuration main'}, 1, '');
708 &Header::openbigbox('100%', 'LEFT', '', $errormessage);
709 &Header::openbox('100%', 'LEFT', "$Lang::tr{'ca certificate'}:");
710 my $output = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem`;
711 $output = &Header::cleanhtml($output,"y");
712 print "<pre>$output</pre>\n";
713 &Header::closebox();
714 print "<div align='center'><a href='/cgi-bin/ovpnmain.cgi'>$Lang::tr{'back'}</a></div>";
715 &Header::closebigbox();
716 &Header::closepage();
717 exit(0);
718 } else {
719 $errormessage = $Lang::tr{'invalid key'};
720 }
721
6e13d0a5
MT
722###
723### Download ca certificate
724###
725} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'download ca certificate'}) {
726 &General::readhasharray("${General::swroot}/ovpn/caconfig", \%cahash);
727
728 if ( -f "${General::swroot}/ovpn/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem" ) {
729 print "Content-Type: application/octet-stream\r\n";
730 print "Content-Disposition: filename=$cahash{$cgiparams{'KEY'}}[0]cert.pem\r\n\r\n";
731 print `/usr/bin/openssl x509 -in ${General::swroot}/ovpn/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem`;
732 exit(0);
733 } else {
734 $errormessage = $Lang::tr{'invalid key'};
735 }
736
737###
738### Remove ca certificate (step 2)
739###
740} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'remove ca certificate'} && $cgiparams{'AREUSURE'} eq 'yes') {
741 &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
742 &General::readhasharray("${General::swroot}/ovpn/caconfig", \%cahash);
743
744 if ( -f "${General::swroot}/ovpn/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem" ) {
745 foreach my $key (keys %confighash) {
746 my $test = `/usr/bin/openssl verify -CAfile ${General::swroot}/ovpn/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem ${General::swroot}/ovpn/certs/$confighash{$key}[1]cert.pem`;
747 if ($test =~ /: OK/) {
c6c9630e
MT
748 # Delete connection
749# if ($vpnsettings{'ENABLED'} eq 'on' ||
750# $vpnsettings{'ENABLED_BLUE'} eq 'on') {
751# system('/usr/local/bin/ipsecctrl', 'D', $key);
752# }
6e13d0a5
MT
753 unlink ("${General::swroot}/ovpn//certs/$confighash{$key}[1]cert.pem");
754 unlink ("${General::swroot}/ovpn/certs/$confighash{$key}[1].p12");
755 delete $confighash{$key};
756 &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
c6c9630e 757# &writeipsecfiles();
6e13d0a5
MT
758 }
759 }
760 unlink ("${General::swroot}/ovpn/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem");
761 delete $cahash{$cgiparams{'KEY'}};
762 &General::writehasharray("${General::swroot}/ovpn/caconfig", \%cahash);
c6c9630e 763# system('/usr/local/bin/ipsecctrl', 'R');
6e13d0a5
MT
764 } else {
765 $errormessage = $Lang::tr{'invalid key'};
766 }
767###
768### Remove ca certificate (step 1)
769###
770} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'remove ca certificate'}) {
771 &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
772 &General::readhasharray("${General::swroot}/ovpn/caconfig", \%cahash);
773
774 my $assignedcerts = 0;
775 if ( -f "${General::swroot}/ovpn/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem" ) {
776 foreach my $key (keys %confighash) {
777 my $test = `/usr/bin/openssl verify -CAfile ${General::swroot}/ovpn/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem ${General::swroot}/ovpn/certs/$confighash{$key}[1]cert.pem`;
778 if ($test =~ /: OK/) {
779 $assignedcerts++;
780 }
781 }
782 if ($assignedcerts) {
783 &Header::showhttpheaders();
784 &Header::openpage($Lang::tr{'vpn configuration main'}, 1, '');
785 &Header::openbigbox('100%', 'LEFT', '', $errormessage);
786 &Header::openbox('100%', 'LEFT', $Lang::tr{'are you sure'});
787 print <<END
788 <table><form method='post'><input type='hidden' name='AREUSURE' value='yes' />
789 <input type='hidden' name='KEY' value='$cgiparams{'KEY'}' />
790 <tr><td align='center'>
791 <b><font color='${Header::colourred}'>$Lang::tr{'capswarning'}</font></b>: $assignedcerts
792 $Lang::tr{'connections are associated with this ca. deleting the ca will delete these connections as well.'}
793 <tr><td align='center'><input type='submit' name='ACTION' value='$Lang::tr{'remove ca certificate'}' />
794 <input type='submit' name='ACTION' value='$Lang::tr{'cancel'}' /></td></tr>
795 </form></table>
796END
797 ;
798 &Header::closebox();
799 &Header::closebigbox();
800 &Header::closepage();
801 exit (0);
802 } else {
803 unlink ("${General::swroot}/ovpn/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem");
804 delete $cahash{$cgiparams{'KEY'}};
805 &General::writehasharray("${General::swroot}/ovpn/caconfig", \%cahash);
806# system('/usr/local/bin/ipsecctrl', 'R');
807 }
808 } else {
809 $errormessage = $Lang::tr{'invalid key'};
810 }
811
812###
813### Display root certificate
814###
c6c9630e
MT
815}elsif ($cgiparams{'ACTION'} eq $Lang::tr{'show root certificate'} ||
816 $cgiparams{'ACTION'} eq $Lang::tr{'show host certificate'}) {
817 my $output;
818 &Header::showhttpheaders();
819 &Header::openpage($Lang::tr{'vpn configuration main'}, 1, '');
820 &Header::openbigbox('100%', 'LEFT', '', '');
821 if ($cgiparams{'ACTION'} eq $Lang::tr{'show root certificate'}) {
822 &Header::openbox('100%', 'LEFT', "$Lang::tr{'root certificate'}:");
823 $output = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/ca/cacert.pem`;
824 } else {
825 &Header::openbox('100%', 'LEFT', "$Lang::tr{'host certificate'}:");
826 $output = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/certs/servercert.pem`;
827 }
828 $output = &Header::cleanhtml($output,"y");
829 print "<pre>$output</pre>\n";
830 &Header::closebox();
831 print "<div align='center'><a href='/cgi-bin/ovpnmain.cgi'>$Lang::tr{'back'}</a></div>";
832 &Header::closebigbox();
833 &Header::closepage();
834 exit(0);
835
6e13d0a5
MT
836###
837### Download root certificate
838###
839}elsif ($cgiparams{'ACTION'} eq $Lang::tr{'download root certificate'}) {
840 if ( -f "${General::swroot}/ovpn/ca/cacert.pem" ) {
841 print "Content-Type: application/octet-stream\r\n";
842 print "Content-Disposition: filename=cacert.pem\r\n\r\n";
843 print `/usr/bin/openssl x509 -in ${General::swroot}/ovpn/ca/cacert.pem`;
844 exit(0);
845 }
846
847###
848### Download host certificate
849###
850}elsif ($cgiparams{'ACTION'} eq $Lang::tr{'download host certificate'}) {
851 if ( -f "${General::swroot}/ovpn/certs/servercert.pem" ) {
852 print "Content-Type: application/octet-stream\r\n";
853 print "Content-Disposition: filename=servercert.pem\r\n\r\n";
854 print `/usr/bin/openssl x509 -in ${General::swroot}/ovpn/certs/servercert.pem`;
855 exit(0);
856 }
857###
858### Form for generating a root certificate
859###
860}elsif ($cgiparams{'ACTION'} eq $Lang::tr{'generate root/host certificates'} ||
861 $cgiparams{'ACTION'} eq $Lang::tr{'upload p12 file'}) {
862
863 &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings);
864 if (-f "${General::swroot}/ovpn/ca/cacert.pem") {
865 $errormessage = $Lang::tr{'valid root certificate already exists'};
866 $cgiparams{'ACTION'} = '';
867 goto ROOTCERT_ERROR;
868 }
869
870 if (($cgiparams{'ROOTCERT_HOSTNAME'} eq '') && -e "${General::swroot}/red/active") {
871 if (open(IPADDR, "${General::swroot}/red/local-ipaddress")) {
872 my $ipaddr = <IPADDR>;
873 close IPADDR;
874 chomp ($ipaddr);
875 $cgiparams{'ROOTCERT_HOSTNAME'} = (gethostbyaddr(pack("C4", split(/\./, $ipaddr)), 2))[0];
876 if ($cgiparams{'ROOTCERT_HOSTNAME'} eq '') {
877 $cgiparams{'ROOTCERT_HOSTNAME'} = $ipaddr;
878 }
879 }
880 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'upload p12 file'}) {
881
882 if (ref ($cgiparams{'FH'}) ne 'Fh') {
883 $errormessage = $Lang::tr{'there was no file upload'};
884 goto ROOTCERT_ERROR;
885 }
886
887 # Move uploaded certificate request to a temporary file
888 (my $fh, my $filename) = tempfile( );
889 if (copy ($cgiparams{'FH'}, $fh) != 1) {
890 $errormessage = $!;
891 goto ROOTCERT_ERROR;
892 }
893
894 # Create a temporary dirctory
895 my $tempdir = tempdir( CLEANUP => 1 );
896
897 # Extract the CA certificate from the file
898 my $pid = open(OPENSSL, "|-");
899 $SIG{ALRM} = sub { $errormessage = $Lang::tr{'broken pipe'}; goto ROOTCERT_ERROR;};
900 if ($pid) { # parent
901 if ($cgiparams{'P12_PASS'} ne '') {
902 print OPENSSL "$cgiparams{'P12_PASS'}\n";
903 }
904 close (OPENSSL);
905 if ($?) {
906 $errormessage = "$Lang::tr{'openssl produced an error'}: $?";
907 unlink ($filename);
908 goto ROOTCERT_ERROR;
909 }
910 } else { # child
911 unless (exec ('/usr/bin/openssl', 'pkcs12', '-cacerts', '-nokeys',
912 '-in', $filename,
913 '-out', "$tempdir/cacert.pem")) {
914 $errormessage = "$Lang::tr{'cant start openssl'}: $!";
915 unlink ($filename);
916 goto ROOTCERT_ERROR;
917 }
918 }
919
920 # Extract the Host certificate from the file
921 $pid = open(OPENSSL, "|-");
922 $SIG{ALRM} = sub { $errormessage = $Lang::tr{'broken pipe'}; goto ROOTCERT_ERROR;};
923 if ($pid) { # parent
924 if ($cgiparams{'P12_PASS'} ne '') {
925 print OPENSSL "$cgiparams{'P12_PASS'}\n";
926 }
927 close (OPENSSL);
928 if ($?) {
929 $errormessage = "$Lang::tr{'openssl produced an error'}: $?";
930 unlink ($filename);
931 goto ROOTCERT_ERROR;
932 }
933 } else { # child
934 unless (exec ('/usr/bin/openssl', 'pkcs12', '-clcerts', '-nokeys',
935 '-in', $filename,
936 '-out', "$tempdir/hostcert.pem")) {
937 $errormessage = "$Lang::tr{'cant start openssl'}: $!";
938 unlink ($filename);
939 goto ROOTCERT_ERROR;
940 }
941 }
942
943 # Extract the Host key from the file
944 $pid = open(OPENSSL, "|-");
945 $SIG{ALRM} = sub { $errormessage = $Lang::tr{'broken pipe'}; goto ROOTCERT_ERROR;};
946 if ($pid) { # parent
947 if ($cgiparams{'P12_PASS'} ne '') {
948 print OPENSSL "$cgiparams{'P12_PASS'}\n";
949 }
950 close (OPENSSL);
951 if ($?) {
952 $errormessage = "$Lang::tr{'openssl produced an error'}: $?";
953 unlink ($filename);
954 goto ROOTCERT_ERROR;
955 }
956 } else { # child
957 unless (exec ('/usr/bin/openssl', 'pkcs12', '-nocerts',
958 '-nodes',
959 '-in', $filename,
960 '-out', "$tempdir/serverkey.pem")) {
961 $errormessage = "$Lang::tr{'cant start openssl'}: $!";
962 unlink ($filename);
963 goto ROOTCERT_ERROR;
964 }
965 }
966
967 move("$tempdir/cacert.pem", "${General::swroot}/ovpn/ca/cacert.pem");
968 if ($? ne 0) {
969 $errormessage = "$Lang::tr{'certificate file move failed'}: $!";
970 unlink ($filename);
971 unlink ("${General::swroot}/ovpn/ca/cacert.pem");
972 unlink ("${General::swroot}/ovpn/certs/servercert.pem");
973 unlink ("${General::swroot}/ovpn/certs/serverkey.pem");
974 goto ROOTCERT_ERROR;
975 }
976
977 move("$tempdir/hostcert.pem", "${General::swroot}/ovpn/certs/servercert.pem");
978 if ($? ne 0) {
979 $errormessage = "$Lang::tr{'certificate file move failed'}: $!";
980 unlink ($filename);
981 unlink ("${General::swroot}/ovpn/ca/cacert.pem");
982 unlink ("${General::swroot}/ovpn/certs/servercert.pem");
983 unlink ("${General::swroot}/ovpn/certs/serverkey.pem");
984 goto ROOTCERT_ERROR;
985 }
986
987 move("$tempdir/serverkey.pem", "${General::swroot}/ovpn/certs/serverkey.pem");
988 if ($? ne 0) {
989 $errormessage = "$Lang::tr{'certificate file move failed'}: $!";
990 unlink ($filename);
991 unlink ("${General::swroot}/ovpn/ca/cacert.pem");
992 unlink ("${General::swroot}/ovpn/certs/servercert.pem");
993 unlink ("${General::swroot}/ovpn/certs/serverkey.pem");
994 goto ROOTCERT_ERROR;
995 }
996
997 goto ROOTCERT_SUCCESS;
998
999 } elsif ($cgiparams{'ROOTCERT_COUNTRY'} ne '') {
1000
1001 # Validate input since the form was submitted
1002 if ($cgiparams{'ROOTCERT_ORGANIZATION'} eq ''){
1003 $errormessage = $Lang::tr{'organization cant be empty'};
1004 goto ROOTCERT_ERROR;
1005 }
1006 if (length($cgiparams{'ROOTCERT_ORGANIZATION'}) >60) {
1007 $errormessage = $Lang::tr{'organization too long'};
1008 goto ROOTCERT_ERROR;
1009 }
1010 if ($cgiparams{'ROOTCERT_ORGANIZATION'} !~ /^[a-zA-Z0-9 ,\.\-_]*$/) {
1011 $errormessage = $Lang::tr{'invalid input for organization'};
1012 goto ROOTCERT_ERROR;
1013 }
1014 if ($cgiparams{'ROOTCERT_HOSTNAME'} eq ''){
1015 $errormessage = $Lang::tr{'hostname cant be empty'};
1016 goto ROOTCERT_ERROR;
1017 }
1018 unless (&General::validfqdn($cgiparams{'ROOTCERT_HOSTNAME'}) || &General::validip($cgiparams{'ROOTCERT_HOSTNAME'})) {
1019 $errormessage = $Lang::tr{'invalid input for hostname'};
1020 goto ROOTCERT_ERROR;
1021 }
1022 if ($cgiparams{'ROOTCERT_EMAIL'} ne '' && (! &General::validemail($cgiparams{'ROOTCERT_EMAIL'}))) {
1023 $errormessage = $Lang::tr{'invalid input for e-mail address'};
1024 goto ROOTCERT_ERROR;
1025 }
1026 if (length($cgiparams{'ROOTCERT_EMAIL'}) > 40) {
1027 $errormessage = $Lang::tr{'e-mail address too long'};
1028 goto ROOTCERT_ERROR;
1029 }
1030 if ($cgiparams{'ROOTCERT_OU'} ne '' && $cgiparams{'ROOTCERT_OU'} !~ /^[a-zA-Z0-9 ,\.\-_]*$/) {
1031 $errormessage = $Lang::tr{'invalid input for department'};
1032 goto ROOTCERT_ERROR;
1033 }
1034 if ($cgiparams{'ROOTCERT_CITY'} ne '' && $cgiparams{'ROOTCERT_CITY'} !~ /^[a-zA-Z0-9 ,\.\-_]*$/) {
1035 $errormessage = $Lang::tr{'invalid input for city'};
1036 goto ROOTCERT_ERROR;
1037 }
1038 if ($cgiparams{'ROOTCERT_STATE'} ne '' && $cgiparams{'ROOTCERT_STATE'} !~ /^[a-zA-Z0-9 ,\.\-_]*$/) {
1039 $errormessage = $Lang::tr{'invalid input for state or province'};
1040 goto ROOTCERT_ERROR;
1041 }
1042 if ($cgiparams{'ROOTCERT_COUNTRY'} !~ /^[A-Z]*$/) {
1043 $errormessage = $Lang::tr{'invalid input for country'};
1044 goto ROOTCERT_ERROR;
1045 }
1046
1047 # Copy the cgisettings to vpnsettings and save the configfile
1048 $vpnsettings{'ROOTCERT_ORGANIZATION'} = $cgiparams{'ROOTCERT_ORGANIZATION'};
1049 $vpnsettings{'ROOTCERT_HOSTNAME'} = $cgiparams{'ROOTCERT_HOSTNAME'};
1050 $vpnsettings{'ROOTCERT_EMAIL'} = $cgiparams{'ROOTCERT_EMAIL'};
1051 $vpnsettings{'ROOTCERT_OU'} = $cgiparams{'ROOTCERT_OU'};
1052 $vpnsettings{'ROOTCERT_CITY'} = $cgiparams{'ROOTCERT_CITY'};
1053 $vpnsettings{'ROOTCERT_STATE'} = $cgiparams{'ROOTCERT_STATE'};
1054 $vpnsettings{'ROOTCERT_COUNTRY'} = $cgiparams{'ROOTCERT_COUNTRY'};
1055 &General::writehash("${General::swroot}/ovpn/settings", \%vpnsettings);
1056
1057 # Replace empty strings with a .
1058 (my $ou = $cgiparams{'ROOTCERT_OU'}) =~ s/^\s*$/\./;
1059 (my $city = $cgiparams{'ROOTCERT_CITY'}) =~ s/^\s*$/\./;
1060 (my $state = $cgiparams{'ROOTCERT_STATE'}) =~ s/^\s*$/\./;
1061
1062 # refresh
c6c9630e 1063 #system ('/bin/touch', "${General::swroot}/ovpn/gencanow");
6e13d0a5
MT
1064
1065 # Create the CA certificate
1066 my $pid = open(OPENSSL, "|-");
1067 $SIG{ALRM} = sub { $errormessage = $Lang::tr{'broken pipe'}; goto ROOTCERT_ERROR;};
1068 if ($pid) { # parent
1069 print OPENSSL "$cgiparams{'ROOTCERT_COUNTRY'}\n";
1070 print OPENSSL "$state\n";
1071 print OPENSSL "$city\n";
1072 print OPENSSL "$cgiparams{'ROOTCERT_ORGANIZATION'}\n";
1073 print OPENSSL "$ou\n";
1074 print OPENSSL "$cgiparams{'ROOTCERT_ORGANIZATION'} CA\n";
1075 print OPENSSL "$cgiparams{'ROOTCERT_EMAIL'}\n";
1076 close (OPENSSL);
1077 if ($?) {
1078 $errormessage = "$Lang::tr{'openssl produced an error'}: $?";
1079 unlink ("${General::swroot}/ovpn/ca/cakey.pem");
1080 unlink ("${General::swroot}/ovpn/ca/cacert.pem");
1081 goto ROOTCERT_ERROR;
1082 }
1083 } else { # child
1084 unless (exec ('/usr/bin/openssl', 'req', '-x509', '-nodes', '-rand', '/proc/interrupts:/proc/net/rt_cache',
1085 '-days', '999999', '-newkey', 'rsa:2048',
1086 '-keyout', "${General::swroot}/ovpn/ca/cakey.pem",
1087 '-out', "${General::swroot}/ovpn/ca/cacert.pem",
1088 '-config',"${General::swroot}/ovpn/openssl/ovpn.cnf")) {
1089 $errormessage = "$Lang::tr{'cant start openssl'}: $!";
1090 goto ROOTCERT_ERROR;
1091 }
1092 }
1093
1094 # Create the Host certificate request
1095 $pid = open(OPENSSL, "|-");
1096 $SIG{ALRM} = sub { $errormessage = $Lang::tr{'broken pipe'}; goto ROOTCERT_ERROR;};
1097 if ($pid) { # parent
1098 print OPENSSL "$cgiparams{'ROOTCERT_COUNTRY'}\n";
1099 print OPENSSL "$state\n";
1100 print OPENSSL "$city\n";
1101 print OPENSSL "$cgiparams{'ROOTCERT_ORGANIZATION'}\n";
1102 print OPENSSL "$ou\n";
1103 print OPENSSL "$cgiparams{'ROOTCERT_HOSTNAME'}\n";
1104 print OPENSSL "$cgiparams{'ROOTCERT_EMAIL'}\n";
1105 print OPENSSL ".\n";
1106 print OPENSSL ".\n";
1107 close (OPENSSL);
1108 if ($?) {
1109 $errormessage = "$Lang::tr{'openssl produced an error'}: $?";
1110 unlink ("${General::swroot}/ovpn/certs/serverkey.pem");
1111 unlink ("${General::swroot}/ovpn/certs/serverreq.pem");
1112 goto ROOTCERT_ERROR;
1113 }
1114 } else { # child
1115 unless (exec ('/usr/bin/openssl', 'req', '-nodes', '-rand', '/proc/interrupts:/proc/net/rt_cache',
1116 '-newkey', 'rsa:1024',
1117 '-keyout', "${General::swroot}/ovpn/certs/serverkey.pem",
1118 '-out', "${General::swroot}/ovpn/certs/serverreq.pem",
1119 '-extensions', 'server',
1120 '-config', "${General::swroot}/ovpn/openssl/ovpn.cnf" )) {
1121 $errormessage = "$Lang::tr{'cant start openssl'}: $!";
1122 unlink ("${General::swroot}/ovpn/certs/serverkey.pem");
1123 unlink ("${General::swroot}/ovpn/certs/serverreq.pem");
1124 unlink ("${General::swroot}/ovpn/ca/cakey.pem");
1125 unlink ("${General::swroot}/ovpn/ca/cacert.pem");
1126 goto ROOTCERT_ERROR;
1127 }
1128 }
1129
1130 # Sign the host certificate request
1131 system('/usr/bin/openssl', 'ca', '-days', '999999',
1132 '-batch', '-notext',
1133 '-in', "${General::swroot}/ovpn/certs/serverreq.pem",
1134 '-out', "${General::swroot}/ovpn/certs/servercert.pem",
1135 '-extensions', 'server',
1136 '-config', "${General::swroot}/ovpn/openssl/ovpn.cnf");
1137 if ($?) {
1138 $errormessage = "$Lang::tr{'openssl produced an error'}: $?";
1139 unlink ("${General::swroot}/ovpn/ca/cakey.pem");
1140 unlink ("${General::swroot}/ovpn/ca/cacert.pem");
1141 unlink ("${General::swroot}/ovpn/serverkey.pem");
1142 unlink ("${General::swroot}/ovpn/certs/serverreq.pem");
1143 unlink ("${General::swroot}/ovpn/certs/servercert.pem");
c6c9630e 1144 &newcleanssldatabase();
6e13d0a5
MT
1145 goto ROOTCERT_ERROR;
1146 } else {
1147 unlink ("${General::swroot}/ovpn/certs/serverreq.pem");
c6c9630e 1148 &deletebackupcert();
6e13d0a5
MT
1149 }
1150
1151 # Create an empty CRL
1152 system('/usr/bin/openssl', 'ca', '-gencrl',
1153 '-out', "${General::swroot}/ovpn/crls/cacrl.pem",
1154 '-config', "${General::swroot}/ovpn/openssl/ovpn.cnf" );
1155 if ($?) {
1156 $errormessage = "$Lang::tr{'openssl produced an error'}: $?";
1157 unlink ("${General::swroot}/ovpn/certs/serverkey.pem");
1158 unlink ("${General::swroot}/ovpn/certs/servercert.pem");
1159 unlink ("${General::swroot}/ovpn/ca/cacert.pem");
1160 unlink ("${General::swroot}/ovpn/crls/cacrl.pem");
c6c9630e 1161 &cleanssldatabase();
6e13d0a5 1162 goto ROOTCERT_ERROR;
c6c9630e
MT
1163# } else {
1164# &cleanssldatabase();
6e13d0a5
MT
1165 }
1166 # Create Diffie Hellmann Parameter
1167 system('/usr/bin/openssl', 'dhparam', '-rand', '/proc/interrupts:/proc/net/rt_cache',
1168 '-out', "${General::swroot}/ovpn/ca/dh1024.pem",
1169 '1024' );
1170 if ($?) {
1171 $errormessage = "$Lang::tr{'openssl produced an error'}: $?";
1172 unlink ("${General::swroot}/ovpn/certs/serverkey.pem");
1173 unlink ("${General::swroot}/ovpn/certs/servercert.pem");
1174 unlink ("${General::swroot}/ovpn/ca/cacert.pem");
1175 unlink ("${General::swroot}/ovpn/crls/cacrl.pem");
1176 unlink ("${General::swroot}/ovpn/ca/dh1024.pem");
c6c9630e 1177 &cleanssldatabase();
6e13d0a5 1178 goto ROOTCERT_ERROR;
c6c9630e
MT
1179# } else {
1180# &cleanssldatabase();
6e13d0a5
MT
1181 }
1182 goto ROOTCERT_SUCCESS;
1183 }
1184 ROOTCERT_ERROR:
1185 if ($cgiparams{'ACTION'} ne '') {
1186 &Header::showhttpheaders();
1187 &Header::openpage($Lang::tr{'vpn configuration main'}, 1, '');
1188 &Header::openbigbox('100%', 'LEFT', '', '');
1189 if ($errormessage) {
1190 &Header::openbox('100%', 'LEFT', $Lang::tr{'error messages'});
1191 print "<class name='base'>$errormessage";
1192 print "&nbsp;</class>";
1193 &Header::closebox();
1194 }
1195 &Header::openbox('100%', 'LEFT', "$Lang::tr{'generate root/host certificates'}:");
1196 print <<END
1197 <form method='post' enctype='multipart/form-data'>
1198 <table width='100%' border='0' cellspacing='1' cellpadding='0'>
1199 <tr><td width='30%' class='base'>$Lang::tr{'organization name'}:</td>
1200 <td width='35%' class='base' nowrap='nowrap'><input type='text' name='ROOTCERT_ORGANIZATION' value='$cgiparams{'ROOTCERT_ORGANIZATION'}' size='32' /></td>
1201 <td width='35%' colspan='2'>&nbsp;</td></tr>
1202 <tr><td class='base'>$Lang::tr{'ipfires hostname'}:</td>
1203 <td class='base' nowrap='nowrap'><input type='text' name='ROOTCERT_HOSTNAME' value='$cgiparams{'ROOTCERT_HOSTNAME'}' size='32' /></td>
1204 <td colspan='2'>&nbsp;</td></tr>
1205 <tr><td class='base'>$Lang::tr{'your e-mail'}:&nbsp;<img src='/blob.gif' alt'*' /></td>
1206 <td class='base' nowrap='nowrap'><input type='text' name='ROOTCERT_EMAIL' value='$cgiparams{'ROOTCERT_EMAIL'}' size='32' /></td>
1207 <td colspan='2'>&nbsp;</td></tr>
1208 <tr><td class='base'>$Lang::tr{'your department'}:&nbsp;<img src='/blob.gif' alt'*' /></td>
1209 <td class='base' nowrap='nowrap'><input type='text' name='ROOTCERT_OU' value='$cgiparams{'ROOTCERT_OU'}' size='32' /></td>
1210 <td colspan='2'>&nbsp;</td></tr>
1211 <tr><td class='base'>$Lang::tr{'city'}:&nbsp;<img src='/blob.gif' alt'*' /></td>
1212 <td class='base' nowrap='nowrap'><input type='text' name='ROOTCERT_CITY' value='$cgiparams{'ROOTCERT_CITY'}' size='32' /></td>
1213 <td colspan='2'>&nbsp;</td></tr>
1214 <tr><td class='base'>$Lang::tr{'state or province'}:&nbsp;<img src='/blob.gif' alt'*' /></td>
1215 <td class='base' nowrap='nowrap'><input type='text' name='ROOTCERT_STATE' value='$cgiparams{'ROOTCERT_STATE'}' size='32' /></td>
1216 <td colspan='2'>&nbsp;</td></tr>
1217 <tr><td class='base'>$Lang::tr{'country'}:</td>
1218 <td class='base'><select name='ROOTCERT_COUNTRY'>
1219
1220END
1221 ;
1222 foreach my $country (sort keys %{Countries::countries}) {
1223 print "<option value='$Countries::countries{$country}'";
1224 if ( $Countries::countries{$country} eq $cgiparams{'ROOTCERT_COUNTRY'} ) {
1225 print " selected='selected'";
1226 }
1227 print ">$country</option>";
1228 }
1229 print <<END
1230 </select></td>
1231 <td colspan='2'>&nbsp;</td></tr>
1232 <tr><td>&nbsp;</td>
1233 <td><input type='submit' name='ACTION' value='$Lang::tr{'generate root/host certificates'}' /></td>
1234 <td>&nbsp;</td><td>&nbsp;</td></tr>
1235 <tr><td class='base' colspan='4' align='left'>
1236 <img src='/blob.gif' valign='top' alt='*' />&nbsp;$Lang::tr{'this field may be blank'}</td></tr>
1237 <tr><td class='base' colspan='4' align='left'>
1238 <b><font color='${Header::colourred}'>$Lang::tr{'capswarning'}</font></b>:
1239 $Lang::tr{'generating the root and host certificates may take a long time. it can take up to several minutes on older hardware. please be patient'}
1240 </td></tr>
1241 <tr><td colspan='4' bgcolor='#000000'><img src='/images/null.gif' width='1' height='1' border='0' /></td></tr>
1242 <tr><td class='base' nowrap='nowrap'>$Lang::tr{'upload p12 file'}:</td>
1243 <td nowrap='nowrap'><input type='file' name='FH' size='32'></td>
1244 <td colspan='2'>&nbsp;</td></tr>
1245 <tr><td class='base'>$Lang::tr{'pkcs12 file password'}:&nbsp;<img src='/blob.gif' alt='*' ></td>
1246 <td class='base' nowrap='nowrap'><input type='password' name='P12_PASS' value='$cgiparams{'P12_PASS'}' size='32' /></td>
1247 <td colspan='2'>&nbsp;</td></tr>
1248 <tr><td>&nbsp;</td>
1249 <td><input type='submit' name='ACTION' value='$Lang::tr{'upload p12 file'}' /></td>
1250 <td colspan='2'>&nbsp;</td></tr>
1251 <tr><td class='base' colspan='4' align='left'>
1252 <img src='/blob.gif' valign='top' al='*' >&nbsp;$Lang::tr{'this field may be blank'}</td></tr>
1253 </form></table>
1254END
1255 ;
1256 &Header::closebox();
1257
1258 &Header::closebigbox();
1259 &Header::closepage();
1260 exit(0)
1261 }
1262
1263 ROOTCERT_SUCCESS:
1264 system ("chmod 600 ${General::swroot}/ovpn/certs/serverkey.pem");
c6c9630e
MT
1265# if ($vpnsettings{'ENABLED'} eq 'on' ||
1266# $vpnsettings{'ENABLE_BLUE'} eq 'on') {
1267# system('/usr/local/bin/ipsecctrl', 'S');
1268# }
6e13d0a5
MT
1269
1270###
1271### Enable/Disable connection
1272###
1273}elsif ($cgiparams{'ACTION'} eq $Lang::tr{'toggle enable disable'}) {
c6c9630e
MT
1274
1275 &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings);
6e13d0a5 1276 &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
c6c9630e 1277
6e13d0a5 1278 if ($confighash{$cgiparams{'KEY'}}) {
c6c9630e
MT
1279 if ($confighash{$cgiparams{'KEY'}}[0] eq 'off') {
1280 $confighash{$cgiparams{'KEY'}}[0] = 'on';
1281 &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
1282 #&writeserverconf();
1283# if ($vpnsettings{'ENABLED'} eq 'on' ||
1284# $vpnsettings{'ENABLED_BLUE'} eq 'on') {
1285# system('/usr/local/bin/ipsecctrl', 'S', $cgiparams{'KEY'});
1286# }
1287 } else {
1288 $confighash{$cgiparams{'KEY'}}[0] = 'off';
1289# if ($vpnsettings{'ENABLED'} eq 'on' ||
1290# $vpnsettings{'ENABLED_BLUE'} eq 'on') {
1291# system('/usr/local/bin/ipsecctrl', 'D', $cgiparams{'KEY'});
1292# }
1293 &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
1294 #&writeserverconf();
6e13d0a5 1295 }
c6c9630e
MT
1296 } else {
1297 $errormessage = $Lang::tr{'invalid key'};
1298 }
6e13d0a5
MT
1299
1300###
1301### Download OpenVPN client package
1302###
1303} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'dl client arch'}) {
1304 &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings);
1305 &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
1306 my $file = '';
1307 my $clientovpn = '';
1308 my @fileholder;
1309 my $tempdir = tempdir( CLEANUP => 1 );
1310 my $zippath = "$tempdir/";
c6c9630e 1311 my $zipname = "$confighash{$cgiparams{'KEY'}}[1]-TO-IPFire.zip";
6e13d0a5 1312 my $zippathname = "$zippath$zipname";
c6c9630e
MT
1313 $clientovpn = "$confighash{$cgiparams{'KEY'}}[1]-TO-IPFire.ovpn";
1314 open(CLIENTCONF, ">$tempdir/$clientovpn") or die "Unable to open tempfile: $!";
6e13d0a5
MT
1315 flock CLIENTCONF, 2;
1316
1317 my $zip = Archive::Zip->new();
1318
c6c9630e 1319 print CLIENTCONF "#OpenVPN Server conf\r\n";
6e13d0a5
MT
1320 print CLIENTCONF "tls-client\r\n";
1321 print CLIENTCONF "client\r\n";
1322 print CLIENTCONF "dev $vpnsettings{'DDEVICE'}\r\n";
c6c9630e 1323 print CLIENTCONF "proto $vpnsettings{'DPROTOCOL'}\r\n";
6e13d0a5
MT
1324 print CLIENTCONF "$vpnsettings{'DDEVICE'}-mtu $vpnsettings{'DMTU'}\r\n";
1325 if ( $vpnsettings{'ENABLED'} eq 'on'){
1326 print CLIENTCONF "remote $vpnsettings{'VPN_IP'} $vpnsettings{'DDEST_PORT'}\r\n";
c6c9630e
MT
1327 if ( $vpnsettings{'ENABLED_BLUE'} eq 'on' && (&haveBlueNet())){
1328 print CLIENTCONF "#Coment the above line and uncoment the next line, if you want to connect on the Blue interface\r\n";
1329 print CLIENTCONF ";remote $netsettings{'BLUE_ADDRESS'} $vpnsettings{'DDEST_PORT'}\r\n";
1330 }
1331 if ( $vpnsettings{'ENABLED_ORANGE'} eq 'on' && (&haveOrangeNet())){
1332 print CLIENTCONF "#Coment the above line and uncoment the next line, if you want to connect on the Orange interface\r\n";
1333 print CLIENTCONF ";remote $netsettings{'ORANGE_ADDRESS'} $vpnsettings{'DDEST_PORT'}\r\n";
1334 }
1335 } elsif ( $vpnsettings{'ENABLED_BLUE'} eq 'on' && (&haveBlueNet())){
1336 print CLIENTCONF "remote $netsettings{'BLUE_ADDRESS'} $vpnsettings{'DDEST_PORT'}\r\n";
1337 if ( $vpnsettings{'ENABLED_ORANGE'} eq 'on' && (&haveOrangeNet())){
1338 print CLIENTCONF "#Coment the above line and uncoment the next line, if you want to connect on the Orange interface\r\n";
1339 print CLIENTCONF ";remote $netsettings{'ORANGE_ADDRESS'} $vpnsettings{'DDEST_PORT'}\r\n";
1340 }
1341 } elsif ( $vpnsettings{'ENABLED_ORANGE'} eq 'on' && (&haveOrangeNet())){
1342 print CLIENTCONF "remote $netsettings{'ORANGE_ADDRESS'} $vpnsettings{'DDEST_PORT'}\r\n";
6e13d0a5
MT
1343 }
1344
1345 if ($confighash{$cgiparams{'KEY'}}[4] eq 'cert' && -f "${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12") {
c6c9630e
MT
1346 print CLIENTCONF "pkcs12 $confighash{$cgiparams{'KEY'}}[1].p12\r\n";
1347 $zip->addFile( "${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12", "$confighash{$cgiparams{'KEY'}}[1].p12") or die "Can't add file $confighash{$cgiparams{'KEY'}}[1].p12\n";
6e13d0a5 1348 } else {
c6c9630e
MT
1349 print CLIENTCONF "ca cacert.pem\r\n";
1350 print CLIENTCONF "cert $confighash{$cgiparams{'KEY'}}[1]cert.pem\r\n";
1351 print CLIENTCONF "key $confighash{$cgiparams{'KEY'}}[1].key\r\n";
1352 $zip->addFile( "${General::swroot}/ovpn/ca/cacert.pem", "cacert.pem") or die "Can't add file cacert.pem\n";
1353 $zip->addFile( "${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem", "$confighash{$cgiparams{'KEY'}}[1]cert.pem") or die "Can't add file $confighash{$cgiparams{'KEY'}}[1]cert.pem\n";
6e13d0a5
MT
1354 }
1355 print CLIENTCONF "cipher $vpnsettings{DCIPHER}\r\n";
1356 if ($vpnsettings{DCOMPLZO} eq 'on') {
1357 print CLIENTCONF "comp-lzo\r\n";
1358 }
1359 print CLIENTCONF "verb 3\r\n";
1360 print CLIENTCONF "ns-cert-type server\r\n";
1361 close(CLIENTCONF);
1362 $zip->addFile( "$tempdir/$clientovpn", $clientovpn) or die "Can't add file $clientovpn\n";
1363 my $status = $zip->writeToFileNamed($zippathname);
1364
1365 open(DLFILE, "<$zippathname") or die "Unable to open $zippathname: $!";
1366 @fileholder = <DLFILE>;
1367 print "Content-Type:application/x-download\n";
1368 print "Content-Disposition:attachment;filename=$zipname\n\n";
1369 print @fileholder;
1370 exit (0);
1371
1372###
1373### Remove connection
1374###
1375} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'remove'}) {
1376 &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings);
1377 &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
c6c9630e
MT
1378
1379 if ($confighash{$cgiparams{'KEY'}}) {
1380# if ($vpnsettings{'ENABLED'} eq 'on' ||
1381# $vpnsettings{'ENABLED_BLUE'} eq 'on') {
1382# system('/usr/local/bin/ipsecctrl', 'D', $cgiparams{'KEY'});
1383# }
1384#
1385 my $temp = `/usr/bin/openssl ca -revoke ${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem -config ${General::swroot}/ovpn/openssl/ovpn.cnf`;
1386 unlink ("${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem");
1387 unlink ("${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12");
1388 delete $confighash{$cgiparams{'KEY'}};
1389 my $temp2 = `/usr/bin/openssl ca -gencrl -out ${General::swroot}/ovpn/crls/cacrl.pem -config ${General::swroot}/ovpn/openssl/ovpn.cnf`;
1390 &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
1391 #&writeserverconf();
6e13d0a5 1392 } else {
c6c9630e 1393 $errormessage = $Lang::tr{'invalid key'};
6e13d0a5
MT
1394 }
1395###
1396### Download PKCS12 file
1397###
1398} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'download pkcs12 file'}) {
1399 &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
1400
1401 print "Content-Disposition: filename=" . $confighash{$cgiparams{'KEY'}}[1] . ".p12\r\n";
1402 print "Content-Type: application/octet-stream\r\n\r\n";
1403 print `/bin/cat ${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12`;
1404 exit (0);
1405
1406###
1407### Display certificate
1408###
1409} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'show certificate'}) {
1410 &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
1411
1412 if ( -f "${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem") {
c6c9630e
MT
1413 &Header::showhttpheaders();
1414 &Header::openpage($Lang::tr{'vpn configuration main'}, 1, '');
1415 &Header::openbigbox('100%', 'LEFT', '', '');
1416 &Header::openbox('100%', 'LEFT', "$Lang::tr{'certificate'}:");
1417 my $output = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem`;
1418 $output = &Header::cleanhtml($output,"y");
1419 print "<pre>$output</pre>\n";
1420 &Header::closebox();
1421 print "<div align='center'><a href='/cgi-bin/ovpnmain.cgi'>$Lang::tr{'back'}</a></div>";
1422 &Header::closebigbox();
1423 &Header::closepage();
1424 exit(0);
6e13d0a5
MT
1425 }
1426###
1427### Display Certificate Revoke List
1428###
1429} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'show crl'}) {
c6c9630e
MT
1430# &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
1431
6e13d0a5 1432 if ( -f "${General::swroot}/ovpn/crls/cacrl.pem") {
c6c9630e
MT
1433 &Header::showhttpheaders();
1434 &Header::openpage($Lang::tr{'vpn configuration main'}, 1, '');
1435 &Header::openbigbox('100%', 'LEFT', '', '');
1436 &Header::openbox('100%', 'LEFT', "$Lang::tr{'crl'}:");
1437 my $output = `/usr/bin/openssl crl -text -noout -in ${General::swroot}/ovpn/crls/cacrl.pem`;
1438 $output = &Header::cleanhtml($output,"y");
1439 print "<pre>$output</pre>\n";
1440 &Header::closebox();
1441 print "<div align='center'><a href='/cgi-bin/ovpnmain.cgi'>$Lang::tr{'back'}</a></div>";
1442 &Header::closebigbox();
1443 &Header::closepage();
1444 exit(0);
6e13d0a5
MT
1445 }
1446
1447###
1448### Advanced Server Settings
1449###
1450
1451} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'advanced server'}) {
1452 %cgiparams = ();
1453 %cahash = ();
1454 %confighash = ();
1455 &General::readhash("${General::swroot}/ovpn/settings", \%cgiparams);
1456
c6c9630e
MT
1457# if ($cgiparams{'CLIENT2CLIENT'} eq '') {
1458# $cgiparams{'CLIENT2CLIENT'} = 'on';
1459# }
6e13d0a5
MT
1460ADV_ERROR:
1461 if ($cgiparams{'MAX_CLIENTS'} eq '') {
c6c9630e 1462 $cgiparams{'MAX_CLIENTS'} = '100';
6e13d0a5
MT
1463 }
1464
1465 if ($cgiparams{'KEEPALIVE_1'} eq '') {
c6c9630e 1466 $cgiparams{'KEEPALIVE_1'} = '10';
6e13d0a5
MT
1467 }
1468 if ($cgiparams{'KEEPALIVE_2'} eq '') {
c6c9630e 1469 $cgiparams{'KEEPALIVE_2'} = '60';
6e13d0a5
MT
1470 }
1471 if ($cgiparams{'LOG_VERB'} eq '') {
c6c9630e 1472 $cgiparams{'LOG_VERB'} = '3';
6e13d0a5 1473 }
6e13d0a5
MT
1474 $checked{'CLIENT2CLIENT'}{'off'} = '';
1475 $checked{'CLIENT2CLIENT'}{'on'} = '';
1476 $checked{'CLIENT2CLIENT'}{$cgiparams{'CLIENT2CLIENT'}} = 'CHECKED';
1477 $checked{'REDIRECT_GW_DEF1'}{'off'} = '';
1478 $checked{'REDIRECT_GW_DEF1'}{'on'} = '';
1479 $checked{'REDIRECT_GW_DEF1'}{$cgiparams{'REDIRECT_GW_DEF1'}} = 'CHECKED';
1480 $selected{'LOG_VERB'}{'1'} = '';
1481 $selected{'LOG_VERB'}{'2'} = '';
1482 $selected{'LOG_VERB'}{'3'} = '';
1483 $selected{'LOG_VERB'}{'4'} = '';
1484 $selected{'LOG_VERB'}{'5'} = '';
1485 $selected{'LOG_VERB'}{'6'} = '';
1486 $selected{'LOG_VERB'}{'7'} = '';
1487 $selected{'LOG_VERB'}{'8'} = '';
1488 $selected{'LOG_VERB'}{'9'} = '';
1489 $selected{'LOG_VERB'}{'10'} = '';
1490 $selected{'LOG_VERB'}{'11'} = '';
1491 $selected{'LOG_VERB'}{'0'} = '';
1492 $selected{'LOG_VERB'}{$cgiparams{'LOG_VERB'}} = 'SELECTED';
6e13d0a5
MT
1493
1494 &Header::showhttpheaders();
1495 &Header::openpage($Lang::tr{'status ovpn'}, 1, '');
1496 &Header::openbigbox('100%', 'LEFT', '', $errormessage);
1497 if ($errormessage) {
c6c9630e
MT
1498 &Header::openbox('100%', 'LEFT', $Lang::tr{'error messages'});
1499 print "<class name='base'>$errormessage\n";
1500 print "&nbsp;</class>\n";
1501 &Header::closebox();
6e13d0a5
MT
1502 }
1503 &Header::openbox('100%', 'LEFT', $Lang::tr{'advanced server'});
1504 print <<END
1505 <form method='post' enctype='multipart/form-data'>
1506 <table width='100%'>
1507 <tr>
1508 <td colspan='4'><b>$Lang::tr{'dhcp-options'}</b></td>
1509 </tr>
1510 <tr>
1511 <td width='25%'></td> <td width='20%'> </td><td width='25%'> </td><td width='30%'></td>
1512 </tr>
1513 <tr>
1514 <td class='base'>Domain</td>
1515 <td><input type='TEXT' name='DHCP_DOMAIN' value='$cgiparams{'DHCP_DOMAIN'}' size='30' /></td>
1516 </tr>
1517 <tr>
1518 <td class='base'>DNS</td>
1519 <td><input type='TEXT' name='DHCP_DNS' value='$cgiparams{'DHCP_DNS'}' size='30' /></td>
1520 </tr>
1521 <tr>
1522 <td class='base'>WINS</td>
1523 <td><input type='TEXT' name='DHCP_WINS' value='$cgiparams{'DHCP_WINS'}' size='30' /></td>
1524 </tr>
1525</table>
1526<hr size='1'>
6e13d0a5
MT
1527 <table width='100%'>
1528 <tr>
1529 <td class'base'><b>$Lang::tr{'misc-options'}</b></td>
1530 </tr>
1531 <tr>
1532 <td width='25%'></td> <td width='20%'> </td><td width='25%'> </td><td width='30%'></td>
1533 </tr>
1534 <tr>
1535 <td class='base'>Client-To-Client</td>
1536 <td><input type='checkbox' name='CLIENT2CLIENT' $checked{'CLIENT2CLIENT'}{'on'} /></td>
1537 </tr>
1538 <tr>
1539 <td class='base'>Redirect-Gateway def1</td>
1540 <td><input type='checkbox' name='REDIRECT_GW_DEF1' $checked{'REDIRECT_GW_DEF1'}{'on'} /></td>
1541 </tr>
1542 <tr>
1543 <td class='base'>Max-Clients</td>
1544 <td><input type='text' name='MAX_CLIENTS' value='$cgiparams{'MAX_CLIENTS'}' size='30' /></td>
1545 </tr>
1546 <td class='base'>Keppalive (ping/ping-restart)</td>
1547 <td><input type='TEXT' name='KEEPALIVE_1' value='$cgiparams{'KEEPALIVE_1'}' size='30' /></td>
1548 <td><input type='TEXT' name='KEEPALIVE_2' value='$cgiparams{'KEEPALIVE_2'}' size='30' /></td>
1549 </tr>
6e13d0a5
MT
1550</table>
1551<hr size='1'>
1552 <table width='100%'>
1553 <tr>
1554 <td class'base'><b>$Lang::tr{'log-options'}</b></td>
1555 </tr>
1556 <tr>
1557 <td width='25%'></td> <td width='20%'> </td><td width='25%'> </td><td width='30%'></td>
1558 </tr>
1559
1560 <tr><td class='base'>VERB</td>
1561 <td><select name='LOG_VERB'><option value='1' $selected{'LOG_VERB'}{'1'}>1</option>
1562 <option value='2' $selected{'LOG_VERB'}{'2'}>2</option>
1563 <option value='3' $selected{'LOG_VERB'}{'3'}>3</option>
1564 <option value='4' $selected{'LOG_VERB'}{'4'}>4</option>
1565 <option value='5' $selected{'LOG_VERB'}{'5'}>5</option>
1566 <option value='6' $selected{'LOG_VERB'}{'6'}>6</option>
1567 <option value='7' $selected{'LOG_VERB'}{'7'}>7</option>
1568 <option value='8' $selected{'LOG_VERB'}{'8'}>8</option>
1569 <option value='9' $selected{'LOG_VERB'}{'9'}>9</option>
1570 <option value='10' $selected{'LOG_VERB'}{'10'}>10</option>
1571 <option value='11' $selected{'LOG_VERB'}{'11'}>11</option>
c6c9630e 1572 <option value='0' $selected{'LOG_VERB'}{'0'}>0</option></select></td>
6e13d0a5
MT
1573</table>
1574<hr size='1'>
1575<table width='100%'>
1576<tr>
1577 <td>&nbsp;</td>
1578 <td allign='center'><input type='submit' name='ACTION' value='$Lang::tr{'save-adv-options'}' /></td>
1579 <td allign='center'><input type='submit' name='ACTION' value='$Lang::tr{'cancel-adv-options'}' /></td>
1580 <td>&nbsp;</td>
1581</tr>
1582</table>
1583</form>
1584END
1585;
1586
1587 &Header::closebox();
c6c9630e 1588# print "<div align='center'><a href='/cgi-bin/ovpnmain.cgi'>$Lang::tr{'back'}</a></div>";
6e13d0a5
MT
1589 &Header::closebigbox();
1590 &Header::closepage();
1591 exit(0);
1592
1593###
1594### Openvpn Connections Statistics
1595###
1596} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'ovpn con stat'}) {
1597 &Header::showhttpheaders();
1598 &Header::openpage($Lang::tr{'ovpn con stat'}, 1, '');
1599 &Header::openbigbox('100%', 'LEFT', '', '');
1600 &Header::openbox('100%', 'LEFT', $Lang::tr{'ovpn con stat'});
1601
1602#
1603# <td><b>$Lang::tr{'protocol'}</b></td>
1604# protocol temp removed
1605 print <<END
1606 <table width='100%' border='0' cellpadding='2' cellspacing='0'>
1607 <tr>
1608 <td><b>$Lang::tr{'common name'}</b></td>
1609 <td><b>$Lang::tr{'real address'}</b></td>
1610 <td><b>$Lang::tr{'virtual address'}</b></td>
1611 <td><b>$Lang::tr{'loged in at'}</b></td>
1612 <td><b>$Lang::tr{'bytes sent'}</b></td>
1613 <td><b>$Lang::tr{'bytes received'}</b></td>
1614 <td><b>$Lang::tr{'last activity'}</b></td>
1615 </tr>
1616END
1617;
4e17adad 1618 my $filename = "/var/log/ovpnserver.log";
6e13d0a5
MT
1619 open(FILE, $filename) or die 'Unable to open config file.';
1620 my @current = <FILE>;
1621 close(FILE);
1622 my @users =();
1623 my $status;
1624 my $uid = 0;
1625 my $cn;
1626 my @match = ();
1627 my $proto = "udp";
1628 my $address;
1629 my %userlookup = ();
1630 foreach my $line (@current)
1631 {
1632 chomp($line);
1633 if ( $line =~ /^Updated,(.+)/){
1634 @match = split( /^Updated,(.+)/, $line);
1635 $status = $match[1];
1636 }
c6c9630e 1637#gian
6e13d0a5
MT
1638 if ( $line =~ /^(.+),(\d+\.\d+\.\d+\.\d+\:\d+),(\d+),(\d+),(.+)/) {
1639 @match = split(m/^(.+),(\d+\.\d+\.\d+\.\d+\:\d+),(\d+),(\d+),(.+)/, $line);
1640 if ($match[1] ne "Common Name") {
1641 $cn = $match[1];
1642 $userlookup{$match[2]} = $uid;
1643 $users[$uid]{'CommonName'} = $match[1];
1644 $users[$uid]{'RealAddress'} = $match[2];
c6c9630e
MT
1645 $users[$uid]{'BytesReceived'} = &sizeformat($match[3]);
1646 $users[$uid]{'BytesSent'} = &sizeformat($match[4]);
6e13d0a5
MT
1647 $users[$uid]{'Since'} = $match[5];
1648 $users[$uid]{'Proto'} = $proto;
1649 $uid++;
1650 }
1651 }
1652 if ( $line =~ /^(\d+\.\d+\.\d+\.\d+),(.+),(\d+\.\d+\.\d+\.\d+\:\d+),(.+)/) {
1653 @match = split(m/^(\d+\.\d+\.\d+\.\d+),(.+),(\d+\.\d+\.\d+\.\d+\:\d+),(.+)/, $line);
1654 if ($match[1] ne "Virtual Address") {
1655 $address = $match[3];
1656 #find the uid in the lookup table
1657 $uid = $userlookup{$address};
1658 $users[$uid]{'VirtualAddress'} = $match[1];
1659 $users[$uid]{'LastRef'} = $match[4];
1660 }
1661 }
1662 }
1663 my $user2 = @users;
1664 if ($user2 >= 1){
1665 for (my $idx = 1; $idx <= $user2; $idx++){
1666 if ($idx % 2) {
4e17adad 1667 print "<tr bgcolor='$color{'color20'}'>\n";
6e13d0a5 1668 } else {
4e17adad 1669 print "<tr bgcolor='$color{'color22'}'>\n";
6e13d0a5
MT
1670 }
1671 print "<td align='left'>$users[$idx-1]{'CommonName'}</td>";
1672 print "<td align='left'>$users[$idx-1]{'RealAddress'}</td>";
1673 print "<td align='left'>$users[$idx-1]{'VirtualAddress'}</td>";
1674 print "<td align='left'>$users[$idx-1]{'Since'}</td>";
1675 print "<td align='left'>$users[$idx-1]{'BytesSent'}</td>";
1676 print "<td align='left'>$users[$idx-1]{'BytesReceived'}</td>";
1677 print "<td align='left'>$users[$idx-1]{'LastRef'}</td>";
1678# print "<td align='left'>$users[$idx-1]{'Proto'}</td>";
1679 }
1680 }
1681
1682 print "</table>";
1683 print <<END
1684 <table width='100%' border='0' cellpadding='2' cellspacing='0'>
1685 <tr><td></td></tr>
1686 <tr><td></td></tr>
1687 <tr><td></td></tr>
1688 <tr><td></td></tr>
1689 <tr><td align='center' >$Lang::tr{'the statistics were last updated at'} <b>$status</b></td></tr>
1690 </table>
1691END
1692;
1693 &Header::closebox();
1694 print "<div align='center'><a href='/cgi-bin/ovpnmain.cgi'>$Lang::tr{'back'}</a></div>";
1695 &Header::closebigbox();
1696 &Header::closepage();
1697 exit(0);
1698
1699###
1700### Download Certificate
1701###
1702} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'download certificate'}) {
1703 &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
c6c9630e 1704
6e13d0a5 1705 if ( -f "${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem") {
c6c9630e
MT
1706 print "Content-Disposition: filename=" . $confighash{$cgiparams{'KEY'}}[1] . "cert.pem\r\n";
1707 print "Content-Type: application/octet-stream\r\n\r\n";
1708 print `/bin/cat ${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem`;
1709 exit (0);
1710 }
1711
1712###
1713### Enable/Disable connection
1714###
1715} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'toggle enable disable'}) {
1716
1717 &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings);
1718 &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
1719
1720 if ($confighash{$cgiparams{'KEY'}}) {
1721 if ($confighash{$cgiparams{'KEY'}}[0] eq 'off') {
1722 $confighash{$cgiparams{'KEY'}}[0] = 'on';
1723 &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
1724 #&writeserverconf();
1725# if ($vpnsettings{'ENABLED'} eq 'on' ||
1726# $vpnsettings{'ENABLED_BLUE'} eq 'on') {
1727# system('/usr/local/bin/ipsecctrl', 'S', $cgiparams{'KEY'});
1728# }
1729 } else {
1730 $confighash{$cgiparams{'KEY'}}[0] = 'off';
1731# if ($vpnsettings{'ENABLED'} eq 'on' ||
1732# $vpnsettings{'ENABLED_BLUE'} eq 'on') {
1733# system('/usr/local/bin/ipsecctrl', 'D', $cgiparams{'KEY'});
1734# }
1735 &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
1736 #&writeserverconf();
1737 }
1738 } else {
1739 $errormessage = $Lang::tr{'invalid key'};
6e13d0a5
MT
1740 }
1741
1742###
1743### Restart connection
1744###
1745} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'restart'}) {
1746 &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings);
1747 &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
1748
1749 if ($confighash{$cgiparams{'KEY'}}) {
c6c9630e
MT
1750# if ($vpnsettings{'ENABLED'} eq 'on' ||
1751# $vpnsettings{'ENABLED_BLUE'} eq 'on') {
1752# system('/usr/local/bin/ipsecctrl', 'S', $cgiparams{'KEY'});
1753# }
6e13d0a5 1754 } else {
c6c9630e 1755 $errormessage = $Lang::tr{'invalid key'};
6e13d0a5
MT
1756 }
1757
1758###
c6c9630e 1759### Remove connection
6e13d0a5 1760###
c6c9630e
MT
1761} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'remove'}) {
1762 &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings);
1763 &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
1764
1765 if ($confighash{$cgiparams{'KEY'}}) {
1766# if ($vpnsettings{'ENABLED'} eq 'on' ||
1767# $vpnsettings{'ENABLED_BLUE'} eq 'on') {
1768# system('/usr/local/bin/ipsecctrl', 'D', $cgiparams{'KEY'});
1769# }
1770 unlink ("${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem");
1771 unlink ("${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12");
1772 delete $confighash{$cgiparams{'KEY'}};
1773 &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
1774 #&writeserverconf();
1775 } else {
1776 $errormessage = $Lang::tr{'invalid key'};
1777 }
1778#test33
1779
1780###
1781### Choose between adding a host-net or net-net connection
1782###
1783} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'add'} && $cgiparams{'TYPE'} eq '') {
1784 &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings);
1785 &Header::showhttpheaders();
6e13d0a5
MT
1786 &Header::openpage($Lang::tr{'vpn configuration main'}, 1, '');
1787 &Header::openbigbox('100%', 'LEFT', '', '');
c6c9630e 1788 &Header::openbox('100%', 'LEFT', $Lang::tr{'connection type'});
6e13d0a5
MT
1789 print <<END
1790 <b>$Lang::tr{'connection type'}:</b><br />
c6c9630e
MT
1791 <table><form method='post'>
1792 <tr><td><input type='radio' name='TYPE' value='host' checked /></td>
1793 <td class='base'>$Lang::tr{'host to net vpn'}</td></tr>
1794 <tr><td><input type='radio' name='TYPE' value='net' disabled='disabled' /></td>
6e13d0a5 1795 <td class='base'>$Lang::tr{'net to net vpn'}</td></tr>
c6c9630e 1796 <tr><td align='center' colspan='2'><input type='submit' name='ACTION' value='$Lang::tr{'add'}' /></td></tr>
6e13d0a5
MT
1797 </form></table>
1798END
1799 ;
1800 &Header::closebox();
1801 &Header::closebigbox();
1802 &Header::closepage();
1803 exit (0);
6e13d0a5
MT
1804###
1805### Adding a new connection
1806###
1807} elsif (($cgiparams{'ACTION'} eq $Lang::tr{'add'}) ||
1808 ($cgiparams{'ACTION'} eq $Lang::tr{'edit'}) ||
1809 ($cgiparams{'ACTION'} eq $Lang::tr{'save'} && $cgiparams{'ADVANCED'} eq '')) {
1810
1811 &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings);
1812 &General::readhasharray("${General::swroot}/ovpn/caconfig", \%cahash);
1813 &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
1814
1815 if ($cgiparams{'ACTION'} eq $Lang::tr{'edit'}) {
c6c9630e
MT
1816 if (! $confighash{$cgiparams{'KEY'}}[0]) {
1817 $errormessage = $Lang::tr{'invalid key'};
1818 goto VPNCONF_END;
1819 }
1820 $cgiparams{'ENABLED'} = $confighash{$cgiparams{'KEY'}}[0];
1821 $cgiparams{'NAME'} = $confighash{$cgiparams{'KEY'}}[1];
1822 $cgiparams{'TYPE'} = $confighash{$cgiparams{'KEY'}}[3];
1823 $cgiparams{'AUTH'} = $confighash{$cgiparams{'KEY'}}[4];
1824 $cgiparams{'PSK'} = $confighash{$cgiparams{'KEY'}}[5];
1825 $cgiparams{'SIDE'} = $confighash{$cgiparams{'KEY'}}[6];
1826 $cgiparams{'LOCAL_SUBNET'} = $confighash{$cgiparams{'KEY'}}[8];
1827 $cgiparams{'REMOTE'} = $confighash{$cgiparams{'KEY'}}[10];
1828 $cgiparams{'REMOTE_SUBNET'} = $confighash{$cgiparams{'KEY'}}[11];
1829 $cgiparams{'REMARK'} = $confighash{$cgiparams{'KEY'}}[25];
1830 $cgiparams{'INTERFACE'} = $confighash{$cgiparams{'KEY'}}[26];
1831#new fields
1832 $cgiparams{'OVPN_SUBNET'} = $confighash{$cgiparams{'KEY'}}[27];
1833 $cgiparams{'PROTOCOL'} = $confighash{$cgiparams{'KEY'}}[28];
1834 $cgiparams{'DEST_PORT'} = $confighash{$cgiparams{'KEY'}}[29];
1835 $cgiparams{'COMPLZO'} = $confighash{$cgiparams{'KEY'}}[30];
1836 $cgiparams{'MTU'} = $confighash{$cgiparams{'KEY'}}[31];
1837#new fields
1838#ab hiere error uebernehmen
1839 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'save'}) {
1840 $cgiparams{'REMARK'} = &Header::cleanhtml($cgiparams{'REMARK'});
1841 if ($cgiparams{'TYPE'} !~ /^(host|net)$/) {
1842 $errormessage = $Lang::tr{'connection type is invalid'};
1843 goto VPNCONF_ERROR;
1844 }
1845
1846
1847 if ($cgiparams{'NAME'} !~ /^[a-zA-Z0-9]+$/) {
1848 $errormessage = $Lang::tr{'name must only contain characters'};
1849 goto VPNCONF_ERROR;
1850 }
1851
1852 if ($cgiparams{'NAME'} =~ /^(host|01|block|private|clear|packetdefault)$/) {
1853 $errormessage = $Lang::tr{'name is invalid'};
1854 goto VPNCONF_ERROR;
1855 }
1856
1857 if (length($cgiparams{'NAME'}) >60) {
1858 $errormessage = $Lang::tr{'name too long'};
1859 goto VPNCONF_ERROR;
1860 }
1861
1862# if (($cgiparams{'TYPE'} eq 'net') && ($cgiparams{'SIDE'} !~ /^(left|right)$/)) {
1863# $errormessage = $Lang::tr{'ipfire side is invalid'};
1864# goto VPNCONF_ERROR;
1865# }
1866
1867 # Check if there is no other entry with this name
1868 if (! $cgiparams{'KEY'}) {
1869 foreach my $key (keys %confighash) {
1870 if ($confighash{$key}[1] eq $cgiparams{'NAME'}) {
1871 $errormessage = $Lang::tr{'a connection with this name already exists'};
1872 goto VPNCONF_ERROR;
6e13d0a5 1873 }
c6c9630e
MT
1874 }
1875 }
1876
1877 if (($cgiparams{'TYPE'} eq 'net') && (! $cgiparams{'REMOTE'})) {
1878 $errormessage = $Lang::tr{'invalid input for remote host/ip'};
1879 goto VPNCONF_ERROR;
1880 }
1881
1882 if ($cgiparams{'REMOTE'}) {
1883 if (! &General::validip($cgiparams{'REMOTE'})) {
1884 if (! &General::validfqdn ($cgiparams{'REMOTE'})) {
1885 $errormessage = $Lang::tr{'invalid input for remote host/ip'};
1886 goto VPNCONF_ERROR;
6e13d0a5 1887 } else {
c6c9630e
MT
1888 if (&valid_dns_host($cgiparams{'REMOTE'})) {
1889 $warnmessage = "$Lang::tr{'check vpn lr'} $cgiparams{'REMOTE'}. $Lang::tr{'dns check failed'}";
1890 }
6e13d0a5 1891 }
c6c9630e
MT
1892 }
1893 }
1894 if ($cgiparams{'TYPE'} ne 'host') {
1895 unless (&General::validipandmask($cgiparams{'LOCAL_SUBNET'})) {
1896 $errormessage = $Lang::tr{'local subnet is invalid'};
1897 goto VPNCONF_ERROR;}
1898 }
1899 # Check if there is no other entry without IP-address and PSK
1900 if ($cgiparams{'REMOTE'} eq '') {
1901 foreach my $key (keys %confighash) {
1902 if(($cgiparams{'KEY'} ne $key) &&
1903 ($confighash{$key}[4] eq 'psk' || $cgiparams{'AUTH'} eq 'psk') &&
1904 $confighash{$key}[10] eq '') {
1905 $errormessage = $Lang::tr{'you can only define one roadwarrior connection when using pre-shared key authentication'};
1906 goto VPNCONF_ERROR;
6e13d0a5 1907 }
c6c9630e
MT
1908 }
1909 }
1910 if (($cgiparams{'TYPE'} eq 'net') && (! &General::validipandmask($cgiparams{'REMOTE_SUBNET'}))) {
1911 $errormessage = $Lang::tr{'remote subnet is invalid'};
1912 goto VPNCONF_ERROR;
1913 }
1914
1915 if ($cgiparams{'ENABLED'} !~ /^(on|off)$/) {
1916 $errormessage = $Lang::tr{'invalid input'};
1917 goto VPNCONF_ERROR;
1918 }
1919 if ($cgiparams{'EDIT_ADVANCED'} !~ /^(on|off)$/) {
1920 $errormessage = $Lang::tr{'invalid input'};
1921 goto VPNCONF_ERROR;
1922 }
1923
1924#fixplausi
1925 if ($cgiparams{'AUTH'} eq 'psk') {
1926# if (! length($cgiparams{'PSK'}) ) {
1927# $errormessage = $Lang::tr{'pre-shared key is too short'};
1928# goto VPNCONF_ERROR;
1929# }
1930# if ($cgiparams{'PSK'} =~ /['",&]/) {
1931# $errormessage = $Lang::tr{'invalid characters found in pre-shared key'};
1932# goto VPNCONF_ERROR;
1933# }
1934 } elsif ($cgiparams{'AUTH'} eq 'certreq') {
1935 if ($cgiparams{'KEY'}) {
1936 $errormessage = $Lang::tr{'cant change certificates'};
1937 goto VPNCONF_ERROR;
1938 }
1939 if (ref ($cgiparams{'FH'}) ne 'Fh') {
1940 $errormessage = $Lang::tr{'there was no file upload'};
1941 goto VPNCONF_ERROR;
1942 }
1943
1944 # Move uploaded certificate request to a temporary file
1945 (my $fh, my $filename) = tempfile( );
1946 if (copy ($cgiparams{'FH'}, $fh) != 1) {
1947 $errormessage = $!;
1948 goto VPNCONF_ERROR;
1949 }
6e13d0a5 1950
c6c9630e
MT
1951 # Sign the certificate request and move it
1952 # Sign the host certificate request
1953 system('/usr/bin/openssl', 'ca', '-days', '999999',
1954 '-batch', '-notext',
1955 '-in', $filename,
1956 '-out', "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem",
1957 '-config',"${General::swroot}/ovpn/openssl/ovpn.cnf");
1958 if ($?) {
1959 $errormessage = "$Lang::tr{'openssl produced an error'}: $?";
1960 unlink ($filename);
1961 unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem");
1962 &newcleanssldatabase();
1963 goto VPNCONF_ERROR;
1964 } else {
1965 unlink ($filename);
1966 &deletebackupcert();
1967 }
1968
1969 my $temp = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem`;
1970 $temp =~ /Subject:.*CN=(.*)[\n]/;
1971 $temp = $1;
1972 $temp =~ s+/Email+, E+;
1973 $temp =~ s/ ST=/ S=/;
1974 $cgiparams{'CERT_NAME'} = $temp;
1975 $cgiparams{'CERT_NAME'} =~ s/,//g;
1976 $cgiparams{'CERT_NAME'} =~ s/\'//g;
1977 if ($cgiparams{'CERT_NAME'} eq '') {
1978 $errormessage = $Lang::tr{'could not retrieve common name from certificate'};
1979 goto VPNCONF_ERROR;
1980 }
1981 } elsif ($cgiparams{'AUTH'} eq 'certfile') {
1982 if ($cgiparams{'KEY'}) {
1983 $errormessage = $Lang::tr{'cant change certificates'};
1984 goto VPNCONF_ERROR;
1985 }
1986 if (ref ($cgiparams{'FH'}) ne 'Fh') {
1987 $errormessage = $Lang::tr{'there was no file upload'};
1988 goto VPNCONF_ERROR;
1989 }
1990 # Move uploaded certificate to a temporary file
1991 (my $fh, my $filename) = tempfile( );
1992 if (copy ($cgiparams{'FH'}, $fh) != 1) {
1993 $errormessage = $!;
1994 goto VPNCONF_ERROR;
1995 }
1996
1997 # Verify the certificate has a valid CA and move it
1998 my $validca = 0;
1999 my $test = `/usr/bin/openssl verify -CAfile ${General::swroot}/ovpn/ca/cacert.pem $filename`;
2000 if ($test =~ /: OK/) {
2001 $validca = 1;
2002 } else {
2003 foreach my $key (keys %cahash) {
2004 $test = `/usr/bin/openssl verify -CAfile ${General::swroot}/ovpn/ca/$cahash{$key}[0]cert.pem $filename`;
2005 if ($test =~ /: OK/) {
2006 $validca = 1;
2007 }
6e13d0a5 2008 }
c6c9630e
MT
2009 }
2010 if (! $validca) {
2011 $errormessage = $Lang::tr{'certificate does not have a valid ca associated with it'};
2012 unlink ($filename);
2013 goto VPNCONF_ERROR;
2014 } else {
2015 move($filename, "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem");
2016 if ($? ne 0) {
2017 $errormessage = "$Lang::tr{'certificate file move failed'}: $!";
2018 unlink ($filename);
2019 goto VPNCONF_ERROR;
6e13d0a5 2020 }
c6c9630e
MT
2021 }
2022
2023 my $temp = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem`;
2024 $temp =~ /Subject:.*CN=(.*)[\n]/;
2025 $temp = $1;
2026 $temp =~ s+/Email+, E+;
2027 $temp =~ s/ ST=/ S=/;
2028 $cgiparams{'CERT_NAME'} = $temp;
2029 $cgiparams{'CERT_NAME'} =~ s/,//g;
2030 $cgiparams{'CERT_NAME'} =~ s/\'//g;
2031 if ($cgiparams{'CERT_NAME'} eq '') {
2032 unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem");
2033 $errormessage = $Lang::tr{'could not retrieve common name from certificate'};
2034 goto VPNCONF_ERROR;
2035 }
2036 } elsif ($cgiparams{'AUTH'} eq 'certgen') {
2037 if ($cgiparams{'KEY'}) {
2038 $errormessage = $Lang::tr{'cant change certificates'};
2039 goto VPNCONF_ERROR;
2040 }
2041 # Validate input since the form was submitted
2042 if (length($cgiparams{'CERT_NAME'}) >60) {
2043 $errormessage = $Lang::tr{'name too long'};
2044 goto VPNCONF_ERROR;
2045 }
2046 if ($cgiparams{'CERT_NAME'} !~ /^[a-zA-Z0-9 ,\.\-_]+$/) {
2047 $errormessage = $Lang::tr{'invalid input for name'};
2048 goto VPNCONF_ERROR;
2049 }
2050 if ($cgiparams{'CERT_EMAIL'} ne '' && (! &General::validemail($cgiparams{'CERT_EMAIL'}))) {
2051 $errormessage = $Lang::tr{'invalid input for e-mail address'};
2052 goto VPNCONF_ERROR;
2053 }
2054 if (length($cgiparams{'CERT_EMAIL'}) > 40) {
2055 $errormessage = $Lang::tr{'e-mail address too long'};
2056 goto VPNCONF_ERROR;
2057 }
2058 if ($cgiparams{'CERT_OU'} ne '' && $cgiparams{'CERT_OU'} !~ /^[a-zA-Z0-9 ,\.\-_]*$/) {
2059 $errormessage = $Lang::tr{'invalid input for department'};
2060 goto VPNCONF_ERROR;
2061 }
2062 if (length($cgiparams{'CERT_ORGANIZATION'}) >60) {
2063 $errormessage = $Lang::tr{'organization too long'};
2064 goto VPNCONF_ERROR;
2065 }
2066 if ($cgiparams{'CERT_ORGANIZATION'} !~ /^[a-zA-Z0-9 ,\.\-_]+$/) {
2067 $errormessage = $Lang::tr{'invalid input for organization'};
2068 goto VPNCONF_ERROR;
2069 }
2070 if ($cgiparams{'CERT_CITY'} ne '' && $cgiparams{'CERT_CITY'} !~ /^[a-zA-Z0-9 ,\.\-_]*$/) {
2071 $errormessage = $Lang::tr{'invalid input for city'};
2072 goto VPNCONF_ERROR;
2073 }
2074 if ($cgiparams{'CERT_STATE'} ne '' && $cgiparams{'CERT_STATE'} !~ /^[a-zA-Z0-9 ,\.\-_]*$/) {
2075 $errormessage = $Lang::tr{'invalid input for state or province'};
2076 goto VPNCONF_ERROR;
2077 }
2078 if ($cgiparams{'CERT_COUNTRY'} !~ /^[A-Z]*$/) {
2079 $errormessage = $Lang::tr{'invalid input for country'};
2080 goto VPNCONF_ERROR;
2081 }
2082 if ($cgiparams{'CERT_PASS1'} ne '' && $cgiparams{'CERT_PASS2'} ne ''){
2083 if (length($cgiparams{'CERT_PASS1'}) < 5) {
2084 $errormessage = $Lang::tr{'password too short'};
2085 goto VPNCONF_ERROR;
6e13d0a5 2086 }
c6c9630e
MT
2087 }
2088 if ($cgiparams{'CERT_PASS1'} ne $cgiparams{'CERT_PASS2'}) {
2089 $errormessage = $Lang::tr{'passwords do not match'};
2090 goto VPNCONF_ERROR;
2091 }
2092
2093 # Replace empty strings with a .
2094 (my $ou = $cgiparams{'CERT_OU'}) =~ s/^\s*$/\./;
2095 (my $city = $cgiparams{'CERT_CITY'}) =~ s/^\s*$/\./;
2096 (my $state = $cgiparams{'CERT_STATE'}) =~ s/^\s*$/\./;
2097
2098 # Create the Host certificate request client
2099 my $pid = open(OPENSSL, "|-");
2100 $SIG{ALRM} = sub { $errormessage = $Lang::tr{'broken pipe'}; goto VPNCONF_ERROR;};
2101 if ($pid) { # parent
2102 print OPENSSL "$cgiparams{'CERT_COUNTRY'}\n";
2103 print OPENSSL "$state\n";
2104 print OPENSSL "$city\n";
2105 print OPENSSL "$cgiparams{'CERT_ORGANIZATION'}\n";
2106 print OPENSSL "$ou\n";
2107 print OPENSSL "$cgiparams{'CERT_NAME'}\n";
2108 print OPENSSL "$cgiparams{'CERT_EMAIL'}\n";
2109 print OPENSSL ".\n";
2110 print OPENSSL ".\n";
2111 close (OPENSSL);
2112 if ($?) {
2113 $errormessage = "$Lang::tr{'openssl produced an error'}: $?";
2114 unlink ("${General::swroot}ovpn/certs/$cgiparams{'NAME'}key.pem");
2115 unlink ("${General::swroot}ovpn/certs/$cgiparams{'NAME'}req.pem");
2116 goto VPNCONF_ERROR;
6e13d0a5 2117 }
c6c9630e
MT
2118 } else { # child
2119 unless (exec ('/usr/bin/openssl', 'req', '-nodes', '-rand', '/proc/interrupts:/proc/net/rt_cache',
2120 '-newkey', 'rsa:1024',
2121 '-keyout', "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}key.pem",
2122 '-out', "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}req.pem",
2123 '-config',"${General::swroot}/ovpn/openssl/ovpn.cnf")) {
2124 $errormessage = "$Lang::tr{'cant start openssl'}: $!";
2125 unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}key.pem");
2126 unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}req.pem");
2127 goto VPNCONF_ERROR;
6e13d0a5 2128 }
c6c9630e
MT
2129 }
2130
2131 # Sign the host certificate request
2132 system('/usr/bin/openssl', 'ca', '-days', '999999',
2133 '-batch', '-notext',
2134 '-in', "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}req.pem",
2135 '-out', "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem",
2136 '-config',"${General::swroot}/ovpn/openssl/ovpn.cnf");
2137 if ($?) {
2138 $errormessage = "$Lang::tr{'openssl produced an error'}: $?";
2139 unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}key.pem");
2140 unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}req.pem");
2141 unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem");
2142 &newcleanssldatabase();
2143 goto VPNCONF_ERROR;
2144 } else {
2145 unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}req.pem");
2146 &deletebackupcert();
2147 }
2148
2149 # Create the pkcs12 file
2150 system('/usr/bin/openssl', 'pkcs12', '-export',
2151 '-inkey', "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}key.pem",
2152 '-in', "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem",
2153 '-name', $cgiparams{'NAME'},
2154 '-passout', "pass:$cgiparams{'CERT_PASS1'}",
2155 '-certfile', "${General::swroot}/ovpn/ca/cacert.pem",
2156 '-caname', "$vpnsettings{'ROOTCERT_ORGANIZATION'} CA",
2157 '-out', "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}.p12");
2158 if ($?) {
2159 $errormessage = "$Lang::tr{'openssl produced an error'}: $?";
2160 unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}key.pem");
2161 unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem");
2162 unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}.p12");
2163 goto VPNCONF_ERROR;
2164 } else {
2165 unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}key.pem");
2166 }
2167 } elsif ($cgiparams{'AUTH'} eq 'cert') {
2168 ;# Nothing, just editing
2169 } else {
2170 $errormessage = $Lang::tr{'invalid input for authentication method'};
2171 goto VPNCONF_ERROR;
2172 }
2173
2174 # Check if there is no other entry with this common name
2175 if ((! $cgiparams{'KEY'}) && ($cgiparams{'AUTH'} ne 'psk')) {
2176 foreach my $key (keys %confighash) {
2177 if ($confighash{$key}[2] eq $cgiparams{'CERT_NAME'}) {
2178 $errormessage = $Lang::tr{'a connection with this common name already exists'};
2179 goto VPNCONF_ERROR;
6e13d0a5 2180 }
c6c9630e
MT
2181 }
2182 }
2183
2184 # Save the config
2185 my $key = $cgiparams{'KEY'};
2186 if (! $key) {
2187 $key = &General::findhasharraykey (\%confighash);
2188 foreach my $i (0 .. 31) { $confighash{$key}[$i] = "";}
2189 }
2190 $confighash{$key}[0] = $cgiparams{'ENABLED'};
2191 $confighash{$key}[1] = $cgiparams{'NAME'};
2192 if ((! $cgiparams{'KEY'}) && $cgiparams{'AUTH'} ne 'psk') {
2193 $confighash{$key}[2] = $cgiparams{'CERT_NAME'};
2194 }
2195 $confighash{$key}[3] = $cgiparams{'TYPE'};
2196 if ($cgiparams{'AUTH'} eq 'psk') {
2197 $confighash{$key}[4] = 'psk';
2198 $confighash{$key}[5] = $cgiparams{'PSK'};
2199 } else {
2200 $confighash{$key}[4] = 'cert';
2201 }
2202 if ($cgiparams{'TYPE'} eq 'net') {
2203 $confighash{$key}[6] = $cgiparams{'SIDE'};
2204 $confighash{$key}[11] = $cgiparams{'REMOTE_SUBNET'};
2205 }
2206 $confighash{$key}[8] = $cgiparams{'LOCAL_SUBNET'};
2207 $confighash{$key}[10] = $cgiparams{'REMOTE'};
2208 $confighash{$key}[25] = $cgiparams{'REMARK'};
2209 $confighash{$key}[26] = $cgiparams{'INTERFACE'};
2210# new fields
2211 $confighash{$key}[27] = $cgiparams{'OVPN_SUBNET'};
2212 $confighash{$key}[28] = $cgiparams{'PROTOCOL'};
2213 $confighash{$key}[29] = $cgiparams{'DEST_PORT'};
2214 $confighash{$key}[30] = $cgiparams{'COMPLZO'};
2215 $confighash{$key}[31] = $cgiparams{'MTU'};
2216# new fileds
2217 &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
2218 if ($cgiparams{'EDIT_ADVANCED'} eq 'on') {
2219 $cgiparams{'KEY'} = $key;
2220 $cgiparams{'ACTION'} = $Lang::tr{'advanced'};
2221 }
2222 goto VPNCONF_END;
6e13d0a5 2223 } else {
c6c9630e
MT
2224 $cgiparams{'ENABLED'} = 'on';
2225 $cgiparams{'SIDE'} = 'left';
2226 if ( ! -f "${General::swroot}/ovpn/ca/cakey.pem" ) {
2227 $cgiparams{'AUTH'} = 'psk';
2228 } elsif ( ! -f "${General::swroot}/ovpn/ca/cacert.pem") {
2229 $cgiparams{'AUTH'} = 'certfile';
2230 } else {
6e13d0a5 2231 $cgiparams{'AUTH'} = 'certgen';
c6c9630e
MT
2232 }
2233 $cgiparams{'LOCAL_SUBNET'} ="$netsettings{'GREEN_NETADDRESS'}/$netsettings{'GREEN_NETMASK'}";
2234 $cgiparams{'CERT_ORGANIZATION'} = $vpnsettings{'ROOTCERT_ORGANIZATION'};
2235 $cgiparams{'CERT_CITY'} = $vpnsettings{'ROOTCERT_CITY'};
2236 $cgiparams{'CERT_STATE'} = $vpnsettings{'ROOTCERT_STATE'};
2237 $cgiparams{'CERT_COUNTRY'} = $vpnsettings{'ROOTCERT_COUNTRY'};
6e13d0a5 2238 }
c6c9630e 2239
6e13d0a5 2240 VPNCONF_ERROR:
6e13d0a5
MT
2241 $checked{'ENABLED'}{'off'} = '';
2242 $checked{'ENABLED'}{'on'} = '';
2243 $checked{'ENABLED'}{$cgiparams{'ENABLED'}} = 'CHECKED';
2244 $checked{'ENABLED_BLUE'}{'off'} = '';
2245 $checked{'ENABLED_BLUE'}{'on'} = '';
2246 $checked{'ENABLED_BLUE'}{$cgiparams{'ENABLED_BLUE'}} = 'CHECKED';
2247 $checked{'ENABLED_ORANGE'}{'off'} = '';
2248 $checked{'ENABLED_ORANGE'}{'on'} = '';
2249 $checked{'ENABLED_ORANGE'}{$cgiparams{'ENABLED_ORANGE'}} = 'CHECKED';
c6c9630e
MT
2250
2251
6e13d0a5
MT
2252 $checked{'EDIT_ADVANCED'}{'off'} = '';
2253 $checked{'EDIT_ADVANCED'}{'on'} = '';
2254 $checked{'EDIT_ADVANCED'}{$cgiparams{'EDIT_ADVANCED'}} = 'CHECKED';
c6c9630e 2255
6e13d0a5
MT
2256 $selected{'SIDE'}{'server'} = '';
2257 $selected{'SIDE'}{'client'} = '';
2258 $selected{'SIDE'}{$cgiparams{'SIDE'}} = 'SELECTED';
c6c9630e 2259
6e13d0a5
MT
2260 $checked{'AUTH'}{'psk'} = '';
2261 $checked{'AUTH'}{'certreq'} = '';
2262 $checked{'AUTH'}{'certgen'} = '';
2263 $checked{'AUTH'}{'certfile'} = '';
2264 $checked{'AUTH'}{$cgiparams{'AUTH'}} = 'CHECKED';
c6c9630e 2265
6e13d0a5 2266 $selected{'INTERFACE'}{$cgiparams{'INTERFACE'}} = 'SELECTED';
c6c9630e 2267
6e13d0a5
MT
2268 $checked{'COMPLZO'}{'off'} = '';
2269 $checked{'COMPLZO'}{'on'} = '';
2270 $checked{'COMPLZO'}{$cgiparams{'COMPLZO'}} = 'CHECKED';
c6c9630e 2271
6e13d0a5
MT
2272
2273 if (1) {
2274 &Header::showhttpheaders();
2275 &Header::openpage($Lang::tr{'vpn configuration main'}, 1, '');
2276 &Header::openbigbox('100%', 'LEFT', '', $errormessage);
2277 if ($errormessage) {
2278 &Header::openbox('100%', 'LEFT', $Lang::tr{'error messages'});
2279 print "<class name='base'>$errormessage";
2280 print "&nbsp;</class>";
2281 &Header::closebox();
2282 }
c6c9630e 2283
6e13d0a5
MT
2284 if ($warnmessage) {
2285 &Header::openbox('100%', 'LEFT', "$Lang::tr{'warning messages'}:");
2286 print "<class name='base'>$warnmessage";
2287 print "&nbsp;</class>";
2288 &Header::closebox();
2289 }
c6c9630e 2290
6e13d0a5
MT
2291 print "<form method='post' enctype='multipart/form-data'>";
2292 print "<input type='hidden' name='TYPE' value='$cgiparams{'TYPE'}' />";
c6c9630e 2293
6e13d0a5
MT
2294 if ($cgiparams{'KEY'}) {
2295 print "<input type='hidden' name='KEY' value='$cgiparams{'KEY'}' />";
2296 print "<input type='hidden' name='AUTH' value='$cgiparams{'AUTH'}' />";
6e13d0a5 2297 }
c6c9630e 2298
6e13d0a5
MT
2299 &Header::openbox('100%', 'LEFT', "$Lang::tr{'connection'}:");
2300 print "<table width='100%'>\n";
2301 print "<tr><td width='25%' class='boldbase'>$Lang::tr{'name'}:</td>";
2302 if ($cgiparams{'TYPE'} eq 'host') {
2303 if ($cgiparams{'KEY'}) {
2304 print "<td width='35%' class='base'><input type='hidden' name='NAME' value='$cgiparams{'NAME'}' />$cgiparams{'NAME'}</td>\n";
2305 } else {
2306 print "<td width='35%'><input type='text' name='NAME' value='$cgiparams{'NAME'}' maxlength='20' size='30' /></td>";
2307 }
c6c9630e
MT
2308# print "<tr><td>$Lang::tr{'interface'}</td>";
2309# print "<td><select name='INTERFACE'>";
2310# print "<option value='RED' $selected{'INTERFACE'}{'RED'}>RED</option>";
2311# if ($netsettings{'BLUE_DEV'} ne '') {
2312# print "<option value='BLUE' $selected{'INTERFACE'}{'BLUE'}>BLUE</option>";
2313# }
2314# print "<option value='GREEN' $selected{'INTERFACE'}{'GREEN'}>GREEN</option>";
2315# print "<option value='ORANGE' $selected{'INTERFACE'}{'ORANGE'}>ORANGE</option>";
2316# print "</select></td></tr>";
2317# print <<END
6e13d0a5
MT
2318 } else {
2319 print "<input type='hidden' name='INTERFACE' value='red' />";
2320 if ($cgiparams{'KEY'}) {
c6c9630e 2321 print "<td width='25%' class='base' nowrap='nowrap'><input type='hidden' name='NAME' value='$cgiparams{'NAME'}' />$cgiparams{'NAME'}</td>";
6e13d0a5 2322 } else {
c6c9630e 2323 print "<td width='25%'><input type='text' name='NAME' value='$cgiparams{'NAME'}' maxlength='20' /></td>";
6e13d0a5 2324 }
c6c9630e
MT
2325 print <<END
2326 <td width='25%'>&nbsp;</td>
2327 <td width='25%'>&nbsp;</td></tr>
2328 <tr><td class='boldbase' nowrap='nowrap'>$Lang::tr{'Act as'}</td>
2329 <td><select name='SIDE'><option value='server' $selected{'SIDE'}{'server'}>OpenVPN Server</option>
2330 <option value='client' $selected{'SIDE'}{'client'}>OpenVPN Client</option></select></td>
2331 <td class='boldbase'>$Lang::tr{'remote host/ip'}:</td>
2332 <td><input type='TEXT' name='REMOTE' value='$cgiparams{'REMOTE'}' /></td></tr>
2333 <tr><td class='boldbase' nowrap='nowrap'>$Lang::tr{'local subnet'}</td>
2334 <td><input type='TEXT' name='LOCAL_SUBNET' value='$cgiparams{'LOCAL_SUBNET'}' /></td>
2335 <td class='boldbase' nowrap='nowrap'>$Lang::tr{'remote subnet'}</td>
2336 <td><input type='text' name='REMOTE_SUBNET' value='$cgiparams{'REMOTE_SUBNET'}' /></td></tr>
2337ttt
2338 <tr><td class='boldbase' nowrap='nowrap'>$Lang::tr{'ovpn subnet'}</td>
2339 <td><input type='TEXT' name='OVPN_SUBNET' value='$cgiparams{'OVPN_SUBNET'}' /></td></tr>
2340 <tr><td class='boldbase' nowrap='nowrap'>$Lang::tr{'protocol'}</td>
2341 <td><select name='PROTOCOL'><option value='udp' $selected{'PROTOCOL'}{'udp'}>UDP</option>
2342 <option value='tcp' $selected{'PROTOCOL'}{'tcp'}>TCP</option></select></td>
2343 <td class='boldbase'>$Lang::tr{'destination port'}:</td>
2344 <td><input type='TEXT' name='DEST_PORT' value='$cgiparams{'DEST_PORT'}' size='5' /></td></tr>
2345 <tr><td class='boldbase' nowrap='nowrap'>$Lang::tr{'comp-lzo'}</td>
2346 <td><input type='checkbox' name='COMPLZO' $checked{'COMPLZO'}{'on'} /></td>
2347 <tr><td class='boldbase' nowrap='nowrap'>$Lang::tr{'MTU'}&nbsp;<img src='/blob.gif' /></td>
2348 <td> <input type='TEXT' name='MTU' VALUE='$cgiparams{'MTU'}'size='5' /></TD>
2349
2350
2351END
2352 ;
6e13d0a5
MT
2353 }
2354 print "<tr><td class='boldbase'>$Lang::tr{'remark title'}&nbsp;<img src='/blob.gif' /></td>";
2355 print "<td colspan='3'><input type='text' name='REMARK' value='$cgiparams{'REMARK'}' size='55' maxlength='50' /></td></tr>";
c6c9630e 2356
6e13d0a5
MT
2357# if ($cgiparams{'TYPE'} eq 'net') {
2358 print "<tr><td>$Lang::tr{'enabled'} <input type='checkbox' name='ENABLED' $checked{'ENABLED'}{'on'} /></td>\n";
2359
c6c9630e
MT
2360# if ($cgiparams{'KEY'}) {
2361# print "<td colspan='3'>&nbsp;</td></tr></table>";
2362# } else {
2363# print "<td colspan='3'><input type='checkbox' name='EDIT_ADVANCED' $checked{'EDIT_ADVANCED'}{'on'} /> $Lang::tr{'edit advanced settings when done'}</tr></table>";
2364# }
2365# }else{
6e13d0a5 2366 print "<td colspan='3'>&nbsp;</td></tr></table>";
c6c9630e
MT
2367# }
2368
6e13d0a5
MT
2369
2370
2371 &Header::closebox();
c6c9630e 2372
6e13d0a5 2373 if ($cgiparams{'KEY'} && $cgiparams{'AUTH'} eq 'psk') {
c6c9630e
MT
2374 # &Header::openbox('100%', 'LEFT', $Lang::tr{'authentication'});
2375 # print <<END
2376 # <table width='100%' cellpadding='0' cellspacing='5' border='0'>
2377 # <tr><td class='base' width='50%'>$Lang::tr{'use a pre-shared key'}</td>
2378 # <td class='base' width='50%'><input type='text' name='PSK' size='30' value='$cgiparams{'PSK'}' /></td></tr>
2379 # </table>
2380END
2381 # ;
2382 # &Header::closebox();
6e13d0a5
MT
2383 } elsif (! $cgiparams{'KEY'}) {
2384 my $disabled='';
2385 my $cakeydisabled='';
2386 my $cacrtdisabled='';
2387 if ( ! -f "${General::swroot}/ovpn/ca/cakey.pem" ) { $cakeydisabled = "disabled='disabled'" } else { $cakeydisabled = "" };
2388 if ( ! -f "${General::swroot}/ovpn/ca/cacert.pem" ) { $cacrtdisabled = "disabled='disabled'" } else { $cacrtdisabled = "" };
2389 &Header::openbox('100%', 'LEFT', $Lang::tr{'authentication'});
2390 print <<END
2391 <table width='100%' cellpadding='0' cellspacing='5' border='0'>
2392 <tr><td colspan='3' bgcolor='#000000'><img src='/images/null.gif' width='1' height='1' border='0' /></td></tr>
2393 <tr><td><input type='radio' name='AUTH' value='certreq' $checked{'AUTH'}{'certreq'} $cakeydisabled /></td>
2394 <td class='base'>$Lang::tr{'upload a certificate request'}</td>
2395 <td class='base' rowspan='2'><input type='file' name='FH' size='30' $cacrtdisabled></td></tr>
2396 <tr><td><input type='radio' name='AUTH' value='certfile' $checked{'AUTH'}{'certfile'} $cacrtdisabled /></td>
2397 <td class='base'>$Lang::tr{'upload a certificate'}</td></tr>
2398 <tr><td colspan='3' bgcolor='#000000'><img src='/images/null.gif' width='1' height='1' BORDER='0' /></td></tr>
2399 <tr><td><input type='radio' name='AUTH' value='certgen' $checked{'AUTH'}{'certgen'} $cakeydisabled /></td>
2400 <td class='base'>$Lang::tr{'generate a certificate'}</td><td>&nbsp;</td></tr>
2401 <tr><td>&nbsp;</td>
2402 <td class='base'>$Lang::tr{'users fullname or system hostname'}:</td>
2403 <td class='base' nowrap='nowrap'><input type='text' name='CERT_NAME' value='$cgiparams{'CERT_NAME'}' SIZE='32' $cakeydisabled /></td></tr>
2404 <tr><td>&nbsp;</td>
2405 <td class='base'>$Lang::tr{'users email'}:&nbsp;<img src='/blob.gif' /></td>
2406 <td class='base' nowrap='nowrap'><input type='text' name='CERT_EMAIL' value='$cgiparams{'CERT_EMAIL'}' SIZE='32' $cakeydisabled /></td></tr>
2407 <tr><td>&nbsp;</td>
2408 <td class='base'>$Lang::tr{'users department'}:&nbsp;<img src='/blob.gif' /></td>
2409 <td class='base' nowrap='nowrap'><input type='text' name='CERT_OU' value='$cgiparams{'CERT_OU'}' SIZE='32' $cakeydisabled /></td></tr>
2410 <tr><td>&nbsp;</td>
2411 <td class='base'>$Lang::tr{'organization name'}:&nbsp;<img src='/blob.gif' /></td>
2412 <td class='base' nowrap='nowrap'><input type='text' name='CERT_ORGANIZATION' value='$cgiparams{'CERT_ORGANIZATION'}' SIZE='32' $cakeydisabled /></td></tr>
2413 <tr><td>&nbsp;</td>
2414 <td class='base'>$Lang::tr{'city'}:&nbsp;<img src='/blob.gif'></td>
2415 <td class='base' nowrap='nowrap'><input type='text' name='CERT_CITY' value='$cgiparams{'CERT_CITY'}' SIZE='32' $cakeydisabled /></td></tr>
2416 <tr><td>&nbsp;</td>
2417 <td class='base'>$Lang::tr{'state or province'}:&nbsp;<img src='/blob.gif' /></td>
2418 <td class='base' nowrap='nowrap'><input type='text' name='CERT_STATE' value='$cgiparams{'CERT_STATE'}' SIZE='32' $cakeydisabled /></td></tr>
2419 <tr><td>&nbsp;</td>
2420 <td class='base'>$Lang::tr{'country'}:</td>
2421 <td class='base'><select name='CERT_COUNTRY' $cakeydisabled>
2422END
c6c9630e 2423
6e13d0a5
MT
2424 ;
2425 foreach my $country (sort keys %{Countries::countries}) {
2426 print "<option value='$Countries::countries{$country}'";
2427 if ( $Countries::countries{$country} eq $cgiparams{'CERT_COUNTRY'} ) {
2428 print " selected='selected'";
2429 }
2430 print ">$country</option>";
2431 }
2432 print <<END
2433 </select></td></tr>
2434 <tr><td>&nbsp;</td>
2435 <td class='base'>$Lang::tr{'pkcs12 file password'}:</td>
2436 <td class='base' nowrap='nowrap'><input type='password' name='CERT_PASS1' value='$cgiparams{'CERT_PASS1'}' size='32' $cakeydisabled /></td></tr>
2437 <tr><td>&nbsp;</td><td class='base'>$Lang::tr{'pkcs12 file password'}:<BR>($Lang::tr{'confirmation'})</td>
2438 <td class='base' nowrap='nowrap'><input type='password' name='CERT_PASS2' value='$cgiparams{'CERT_PASS2'}' size='32' $cakeydisabled /></td></tr>
c6c9630e
MT
2439 </table>
2440END
2441 ;
2442 &Header::closebox();
2443 }
6e13d0a5 2444
c6c9630e
MT
2445 print "<div align='center'><input type='submit' name='ACTION' value='$Lang::tr{'save'}' />";
2446 if ($cgiparams{'KEY'}) {
2447# print "<input type='submit' name='ACTION' value='$Lang::tr{'advanced'}' />";
2448 }
2449 print "<input type='submit' name='ACTION' value='$Lang::tr{'cancel'}' /></div></form>";
2450 &Header::closebigbox();
2451 &Header::closepage();
2452 exit (0);
6e13d0a5 2453 }
c6c9630e 2454 VPNCONF_END:
6e13d0a5 2455}
c6c9630e
MT
2456
2457# SETTINGS_ERROR:
6e13d0a5
MT
2458###
2459### Default status page
2460###
c6c9630e
MT
2461 %cgiparams = ();
2462 %cahash = ();
2463 %confighash = ();
2464 &General::readhash("${General::swroot}/ovpn/settings", \%cgiparams);
2465 &General::readhasharray("${General::swroot}/ovpn/caconfig", \%cahash);
2466 &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
2467
4e17adad 2468 my @status = `/bin/cat /var/log/ovpnserver.log`;
c6c9630e
MT
2469
2470 if ($cgiparams{'VPN_IP'} eq '' && -e "${General::swroot}/red/active") {
6e13d0a5
MT
2471 if (open(IPADDR, "${General::swroot}/red/local-ipaddress")) {
2472 my $ipaddr = <IPADDR>;
2473 close IPADDR;
2474 chomp ($ipaddr);
2475 $cgiparams{'VPN_IP'} = (gethostbyaddr(pack("C4", split(/\./, $ipaddr)), 2))[0];
2476 if ($cgiparams{'VPN_IP'} eq '') {
c6c9630e 2477 $cgiparams{'VPN_IP'} = $ipaddr;
6e13d0a5
MT
2478 }
2479 }
c6c9630e
MT
2480 }
2481
6e13d0a5 2482#default setzen
c6c9630e 2483 if ($cgiparams{'DCIPHER'} eq '') {
6e13d0a5 2484 $cgiparams{'DCIPHER'} = 'BF-CBC';
c6c9630e 2485 }
6e13d0a5
MT
2486# if ($cgiparams{'DCOMPLZO'} eq '') {
2487# $cgiparams{'DCOMPLZO'} = 'on';
2488# }
c6c9630e 2489 if ($cgiparams{'DDEST_PORT'} eq '') {
6e13d0a5 2490 $cgiparams{'DDEST_PORT'} = '1194';
c6c9630e
MT
2491 }
2492 if ($cgiparams{'DMTU'} eq '') {
6e13d0a5 2493 $cgiparams{'DMTU'} = '1400';
c6c9630e
MT
2494 }
2495 if ($cgiparams{'DOVPN_SUBNET'} eq '') {
6e13d0a5 2496 $cgiparams{'DOVPN_SUBNET'} = '10.' . int(rand(256)) . '.' . int(rand(256)) . '.0/255.255.255.0';
c6c9630e
MT
2497 }
2498
2499 $checked{'ENABLED'}{'off'} = '';
2500 $checked{'ENABLED'}{'on'} = '';
2501 $checked{'ENABLED'}{$cgiparams{'ENABLED'}} = 'CHECKED';
2502 $checked{'ENABLED_BLUE'}{'off'} = '';
2503 $checked{'ENABLED_BLUE'}{'on'} = '';
2504 $checked{'ENABLED_BLUE'}{$cgiparams{'ENABLED_BLUE'}} = 'CHECKED';
2505 $checked{'ENABLED_ORANGE'}{'off'} = '';
2506 $checked{'ENABLED_ORANGE'}{'on'} = '';
2507 $checked{'ENABLED_ORANGE'}{$cgiparams{'ENABLED_ORANGE'}} = 'CHECKED';
2508
2509
6e13d0a5 2510#new settings
c6c9630e
MT
2511 $selected{'DDEVICE'}{'tun'} = '';
2512 $selected{'DDEVICE'}{'tap'} = '';
2513 $selected{'DDEVICE'}{$cgiparams{'DDEVICE'}} = 'SELECTED';
2514
2515 $selected{'DPROTOCOL'}{'udp'} = '';
2516 $selected{'DPROTOCOL'}{'tcp'} = '';
2517 $selected{'DPROTOCOL'}{$cgiparams{'DPROTOCOL'}} = 'SELECTED';
2518
2519 $selected{'DCIPHER'}{'DES-CBC'} = '';
2520 $selected{'DCIPHER'}{'DES-EDE-CBC'} = '';
2521 $selected{'DCIPHER'}{'DES-EDE3-CBC'} = '';
2522 $selected{'DCIPHER'}{'DESX-CBC'} = '';
2523 $selected{'DCIPHER'}{'RC2-CBC'} = '';
2524 $selected{'DCIPHER'}{'RC2-40-CBC'} = '';
2525 $selected{'DCIPHER'}{'RC2-64-CBC'} = '';
2526 $selected{'DCIPHER'}{'BF-CBC'} = '';
2527 $selected{'DCIPHER'}{'CAST5-CBC'} = '';
2528 $selected{'DCIPHER'}{'AES-128-CBC'} = '';
2529 $selected{'DCIPHER'}{'AES-192-CBC'} = '';
2530 $selected{'DCIPHER'}{'AES-256-CBC'} = '';
2531 $selected{'DCIPHER'}{$cgiparams{'DCIPHER'}} = 'SELECTED';
2532 $checked{'DCOMPLZO'}{'off'} = '';
2533 $checked{'DCOMPLZO'}{'on'} = '';
2534 $checked{'DCOMPLZO'}{$cgiparams{'DCOMPLZO'}} = 'CHECKED';
6e13d0a5
MT
2535
2536#new settings
c6c9630e
MT
2537 &Header::showhttpheaders();
2538 &Header::openpage($Lang::tr{'status ovpn'}, 1, '');
2539 &Header::openbigbox('100%', 'LEFT', '', $errormessage);
6e13d0a5 2540
c6c9630e 2541 if ($errormessage) {
6e13d0a5
MT
2542 &Header::openbox('100%', 'LEFT', $Lang::tr{'error messages'});
2543 print "<class name='base'>$errormessage\n";
2544 print "&nbsp;</class>\n";
2545 &Header::closebox();
c6c9630e 2546 }
6e13d0a5 2547
c6c9630e
MT
2548 my $sactive = "<table cellpadding='2' cellspacing='0' bgcolor='${Header::colourred}' width='50%'><tr><td align='center'><b><font color='#FFFFFF'>$Lang::tr{'stopped'}</font></b></td></tr></table>";
2549 my $srunning = "no";
2550 my $activeonrun = "";
2551 if ( -e "/var/run/openvpn.pid"){
6e13d0a5
MT
2552 $sactive = "<table cellpadding='2' cellspacing='0' bgcolor='${Header::colourgreen}' width='50%'><tr><td align='center'><b><font color='#FFFFFF'>$Lang::tr{'running'}</font></b></td></tr></table>";
2553 $srunning ="yes";
2554 $activeonrun = "";
c6c9630e 2555 } else {
6e13d0a5 2556 $activeonrun = "disabled='disabled'";
c6c9630e 2557 }
afabe9f7 2558 &Header::openbox('100%', 'LEFT', $Lang::tr{'global settings'});
c6c9630e
MT
2559 print <<END
2560 <table width='100%'>
2561 <form method='post'>
2562 <td width='25%'>&nbsp;</td>
2563 <td width='25%'>&nbsp;</td>
2564 <td width='25%'>&nbsp;</td></tr>
2565 <tr><td class='boldbase'>$Lang::tr{'ovpn server status'}</td>
2566 <td align='left'>$sactive</td>
2567 <tr><td class='boldbase'>$Lang::tr{'ovpn on red'}</td>
2568 <td><input type='checkbox' name='ENABLED' $checked{'ENABLED'}{'on'} /></td>
2569END
2570;
2571 if (&haveBlueNet()) {
2572 print "<tr><td class='boldbase'>$Lang::tr{'ovpn on blue'}</td>";
2573 print "<td><input type='checkbox' name='ENABLED_BLUE' $checked{'ENABLED_BLUE'}{'on'} /></td>";
2574 }
2575 if (&haveOrangeNet()) {
2576 print "<tr><td class='boldbase'>$Lang::tr{'ovpn on orange'}</td>";
2577 print "<td><input type='checkbox' name='ENABLED_ORANGE' $checked{'ENABLED_ORANGE'}{'on'} /></td>";
2578 }
2579 print <<END
4e17adad
CS
2580 <tr><td class='base' nowrap='nowrap' colspan='2'>$Lang::tr{'local vpn hostname/ip'}:<br /><input type='text' name='VPN_IP' value='$cgiparams{'VPN_IP'}' size='30' /></td>
2581 <td class='boldbase' nowrap='nowrap' colspan='2'>$Lang::tr{'ovpn subnet'}<br /><input type='TEXT' name='DOVPN_SUBNET' value='$cgiparams{'DOVPN_SUBNET'}' size='30' /></td></tr>
c6c9630e
MT
2582 <tr><td class='boldbase' nowrap='nowrap'>$Lang::tr{'ovpn device'}</td>
2583 <td><select name='DDEVICE' ><option value='tun' $selected{'DDEVICE'}{'tun'}>TUN</option>
2584 <option value='tap' $selected{'DDEVICE'}{'tap'}>TAP</option></select></td>
2585 <tr><td class='boldbase' nowrap='nowrap'>$Lang::tr{'protocol'}</td>
2586 <td><select name='DPROTOCOL'><option value='udp' $selected{'DPROTOCOL'}{'udp'}>UDP</option>
2587 <option value='tcp' $selected{'DPROTOCOL'}{'tcp'}>TCP</option></select></td>
2588 <td class='boldbase'>$Lang::tr{'destination port'}:</td>
2589 <td><input type='TEXT' name='DDEST_PORT' value='$cgiparams{'DDEST_PORT'}' size='5' /></td></tr>
2590 <tr><td class='boldbase' nowrap='nowrap'>$Lang::tr{'MTU'}&nbsp;</td>
2591 <td> <input type='TEXT' name='DMTU' VALUE='$cgiparams{'DMTU'}'size='5' /></TD>
2592 <tr><td class='boldbase' nowrap='nowrap'>$Lang::tr{'comp-lzo'}</td>
2593 <td><input type='checkbox' name='DCOMPLZO' $checked{'DCOMPLZO'}{'on'} /></td>
2594 <td class='boldbase' nowrap='nowrap'>$Lang::tr{'cipher'}</td>
2595 <td><select name='DCIPHER'><option value='DES-CBC' $selected{'DCIPHER'}{'DES-CBC'}>DES-CBC</option>
2596 <option value='DES-EDE-CBC' $selected{'DCIPHER'}{'DES-EDE-CBC'}>DES-EDE-CBC</option>
2597 <option value='DES-EDE3-CBC' $selected{'DCIPHER'}{'DES-EDE3-CBC'}>DES-EDE3-CBC</option>
2598 <option value='DESX-CBC' $selected{'DCIPHER'}{'DESX-CBC'}>DESX-CBC</option>
2599 <option value='RC2-CBC' $selected{'DCIPHER'}{'RC2-CBC'}>RC2-CBC</option>
2600 <option value='RC2-40-CBC' $selected{'DCIPHER'}{'RC2-40-CBC'}>RC2-40-CBC</option>
2601 <option value='RC2-64-CBC' $selected{'DCIPHER'}{'RC2-64-CBC'}>RC2-64-CBC</option>
2602 <option value='BF-CBC' $selected{'DCIPHER'}{'BF-CBC'}>BF-CBC</option>
2603 <option value='CAST5-CBC' $selected{'DCIPHER'}{'CAST5-CBC'}>CAST5-CBC</option>
2604 <option value='AES-128-CBC' $selected{'DCIPHER'}{'AES-128-CBC'}>AES-128-CBC</option>
2605 <option value='AES-192-CBC' $selected{'DCIPHER'}{'AES-192-CBC'}>AES-192-CBC</option>
2606 <option value='AES-256-CBC' $selected{'DCIPHER'}{'AES-256-CBC'}>AES-256-CBC</option></select></td>
2607END
2608;
2609
2610 if ( $srunning eq "yes" ) {
2611 print "<tr><td align='left'><input type='submit' name='ACTION' value='$Lang::tr{'save'}' disabled='disabled' /></td>";
2612 print "<td><input type='submit' name='ACTION' value='$Lang::tr{'advanced server'}' disabled='disabled'/></td>";
2613 print "<td><input type='submit' name='ACTION' value='$Lang::tr{'stop ovpn server'}' /></td>";
2614 print "<td><input type='submit' name='ACTION' value='$Lang::tr{'restart ovpn server'}' /></td></tr>";
2615 } else{
2616 print "<tr><td align='left'><input type='submit' name='ACTION' value='$Lang::tr{'save'}' /></td>";
2617 print "<td><input type='submit' name='ACTION' value='$Lang::tr{'advanced server'}' /></td>";
2618 if (( -e "${General::swroot}/ovpn/ca/cacert.pem" &&
2619 -e "${General::swroot}/ovpn/ca/dh1024.pem" &&
2620 -e "${General::swroot}/ovpn/certs/servercert.pem" &&
2621 -e "${General::swroot}/ovpn/certs/serverkey.pem") &&
2622 (( $cgiparams{'ENABLED'} eq 'on') ||
2623 ( $cgiparams{'ENABLED_BLUE'} eq 'on') ||
2624 ( $cgiparams{'ENABLED_ORANGE'} eq 'on'))){
2625 print "<td><input type='submit' name='ACTION' value='$Lang::tr{'start ovpn server'}' /></td>";
2626 print "<td><input type='submit' name='ACTION' value='$Lang::tr{'restart ovpn server'}' /></td></tr>";
2627 } else {
2628 print "<td><input type='submit' name='ACTION' value='$Lang::tr{'start ovpn server'}' disabled='disabled' /></td>";
2629 print "<td><input type='submit' name='ACTION' value='$Lang::tr{'restart ovpn server'}' disabled='disabled' /></td></tr>";
2630 }
2631 }
2632 print "</form></table>";
2633 &Header::closebox();
2634 &Header::openbox('100%', 'LEFT', "$Lang::tr{'certificate authorities'}:");
2635 print <<EOF#'
2636 <table width='100%' border='0' cellspacing='1' cellpadding='0'>
2637 <tr>
2638 <td width='25%' class='boldbase' align='center'><b>$Lang::tr{'name'}</b></td>
6e13d0a5
MT
2639 <td width='65%' class='boldbase' align='center'><b>$Lang::tr{'subject'}</b></td>
2640 <td width='10%' class='boldbase' colspan='3' align='center'><b>$Lang::tr{'action'}</b></td>
c6c9630e 2641 </tr>
6e13d0a5
MT
2642EOF
2643 ;
c6c9630e 2644 if (-f "${General::swroot}/ovpn/ca/cacert.pem") {
6e13d0a5
MT
2645 my $casubject = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/ca/cacert.pem`;
2646 $casubject =~ /Subject: (.*)[\n]/;
2647 $casubject = $1;
2648 $casubject =~ s+/Email+, E+;
2649 $casubject =~ s/ ST=/ S=/;
c6c9630e 2650
6e13d0a5 2651 print <<END
4e17adad 2652 <tr bgcolor='$color{'color22'}'>
c6c9630e
MT
2653 <td class='base'>$Lang::tr{'root certificate'}</td>
2654 <td class='base'>$casubject</td>
2655 <form method='post' name='frmrootcrta'><td width='3%' align='center'>
2656 <input type='hidden' name='ACTION' value='$Lang::tr{'show root certificate'}' />
2657 <input type='image' name='$Lang::tr{'edit'}' src='/images/info.gif' alt='$Lang::tr{'show root certificate'}' title='$Lang::tr{'show root certificate'}' width='20' height='20' border='0' />
2658 </td></form>
2659 <form method='post' name='frmrootcrtb'><td width='3%' align='center'>
6e13d0a5
MT
2660 <input type='image' name='$Lang::tr{'download root certificate'}' src='/images/floppy.gif' alt='$Lang::tr{'download root certificate'}' title='$Lang::tr{'download root certificate'}' border='0' />
2661 <input type='hidden' name='ACTION' value='$Lang::tr{'download root certificate'}' />
c6c9630e
MT
2662 </td></form>
2663 <td width='4%'>&nbsp;</td></tr>
6e13d0a5
MT
2664END
2665 ;
c6c9630e 2666 } else {
6e13d0a5
MT
2667 # display rootcert generation buttons
2668 print <<END
4e17adad 2669 <tr bgcolor='$color{'color22'}'>
6e13d0a5
MT
2670 <td class='base'>$Lang::tr{'root certificate'}:</td>
2671 <td class='base'>$Lang::tr{'not present'}</td>
2672 <td colspan='3'>&nbsp;</td></tr>
2673END
2674 ;
c6c9630e 2675 }
6e13d0a5 2676
c6c9630e 2677 if (-f "${General::swroot}/ovpn/certs/servercert.pem") {
6e13d0a5
MT
2678 my $hostsubject = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/certs/servercert.pem`;
2679 $hostsubject =~ /Subject: (.*)[\n]/;
2680 $hostsubject = $1;
2681 $hostsubject =~ s+/Email+, E+;
2682 $hostsubject =~ s/ ST=/ S=/;
c6c9630e 2683
6e13d0a5 2684 print <<END
4e17adad 2685 <tr bgcolor='$color{'color20'}'>
6e13d0a5
MT
2686 <td class='base'>$Lang::tr{'host certificate'}</td>
2687 <td class='base'>$hostsubject</td>
2688 <form method='post' name='frmhostcrta'><td width='3%' align='center'>
c6c9630e
MT
2689 <input type='hidden' name='ACTION' value='$Lang::tr{'show host certificate'}' />
2690 <input type='image' name='$Lang::tr{'show host certificate'}' src='/images/info.gif' alt='$Lang::tr{'show host certificate'}' title='$Lang::tr{'show host certificate'}' width='20' height='20' border='0' />
6e13d0a5
MT
2691 </td></form>
2692 <form method='post' name='frmhostcrtb'><td width='3%' align='center'>
c6c9630e
MT
2693 <input type='image' name='$Lang::tr{'download host certificate'}' src='/images/floppy.gif' alt='$Lang::tr{'download host certificate'}' title='$Lang::tr{'download host certificate'}' border='0' />
2694 <input type='hidden' name='ACTION' value='$Lang::tr{'download host certificate'}' />
6e13d0a5
MT
2695 </td></form>
2696 <td width='4%'>&nbsp;</td></tr>
2697END
2698 ;
c6c9630e 2699 } else {
6e13d0a5
MT
2700 # Nothing
2701 print <<END
4e17adad 2702 <tr bgcolor='$color{'color20'}'>
6e13d0a5
MT
2703 <td width='25%' class='base'>$Lang::tr{'host certificate'}:</td>
2704 <td class='base'>$Lang::tr{'not present'}</td>
2705 </td><td colspan='3'>&nbsp;</td></tr>
2706END
2707 ;
c6c9630e 2708 }
6e13d0a5 2709
c6c9630e
MT
2710 if (! -f "${General::swroot}/ovpn/ca/cacert.pem") {
2711 print "<tr><td colspan='5' align='center'><form method='post'>";
6e13d0a5 2712 print "<input type='submit' name='ACTION' value='$Lang::tr{'generate root/host certificates'}' />";
c6c9630e
MT
2713 print "</form></td></tr>\n";
2714 }
6e13d0a5 2715
c6c9630e 2716 if (keys %cahash > 0) {
6e13d0a5 2717 foreach my $key (keys %cahash) {
c6c9630e 2718 if (($key + 1) % 2) {
4e17adad 2719 print "<tr bgcolor='$color{'color20'}'>\n";
c6c9630e 2720 } else {
4e17adad 2721 print "<tr bgcolor='$color{'color22'}'>\n";
c6c9630e
MT
2722 }
2723 print "<td class='base'>$cahash{$key}[0]</td>\n";
2724 print "<td class='base'>$cahash{$key}[1]</td>\n";
2725 print <<END
2726 <form method='post' name='cafrm${key}a'><td align='center'>
6e13d0a5
MT
2727 <input type='image' name='$Lang::tr{'show ca certificate'}' src='/images/info.gif' alt='$Lang::tr{'show ca certificate'}' title='$Lang::tr{'show ca certificate'}' border='0' />
2728 <input type='hidden' name='ACTION' value='$Lang::tr{'show ca certificate'}' />
2729 <input type='hidden' name='KEY' value='$key' />
c6c9630e
MT
2730 </td></form>
2731 <form method='post' name='cafrm${key}b'><td align='center'>
6e13d0a5
MT
2732 <input type='image' name='$Lang::tr{'download ca certificate'}' src='/images/floppy.gif' alt='$Lang::tr{'download ca certificate'}' title='$Lang::tr{'download ca certificate'}' border='0' />
2733 <input type='hidden' name='ACTION' value='$Lang::tr{'download ca certificate'}' />
2734 <input type='hidden' name='KEY' value='$key' />
c6c9630e
MT
2735 </td></form>
2736 <form method='post' name='cafrm${key}c'><td align='center'>
6e13d0a5
MT
2737 <input type='hidden' name='ACTION' value='$Lang::tr{'remove ca certificate'}' />
2738 <input type='image' name='$Lang::tr{'remove ca certificate'}' src='/images/delete.gif' alt='$Lang::tr{'remove ca certificate'}' title='$Lang::tr{'remove ca certificate'}' width='20' height='20' border='0' />
2739 <input type='hidden' name='KEY' value='$key' />
c6c9630e 2740 </td></form></tr>
6e13d0a5
MT
2741END
2742 ;
2743 }
c6c9630e
MT
2744 }
2745
2746 print "</table>";
2747
2748 # If the file contains entries, print Key to action icons
2749 if ( -f "${General::swroot}/ovpn/ca/cacert.pem") {
2750 print <<END
2751 <table>
2752 <tr>
6e13d0a5
MT
2753 <td class='boldbase'>&nbsp; <b>$Lang::tr{'legend'}:</b></td>
2754 <td>&nbsp; &nbsp; <img src='/images/info.gif' alt='$Lang::tr{'show certificate'}' /></td>
2755 <td class='base'>$Lang::tr{'show certificate'}</td>
2756 <td>&nbsp; &nbsp; <img src='/images/floppy.gif' alt='$Lang::tr{'download certificate'}' /></td>
2757 <td class='base'>$Lang::tr{'download certificate'}</td>
c6c9630e
MT
2758 </tr>
2759 </table>
6e13d0a5
MT
2760END
2761 ;
c6c9630e
MT
2762 }
2763 print <<END
2764 <form method='post' enctype='multipart/form-data'>
2765 <table width='100%' border='0' cellspacing='1' cellpadding='0'>
2766 <tr><td class='base' nowrap='nowrap'>$Lang::tr{'ca name'}:</td>
2767 <td nowrap='nowrap'><input type='text' name='CA_NAME' value='$cgiparams{'CA_NAME'}' size='15' />
2768 <td nowrap='nowrap'><input type='file' name='FH' size='30' /></td>
4e17adad 2769 <td nowrap='nowrap'><input type='submit' name='ACTION' value='$Lang::tr{'upload ca certificate'}' /><br /><input type='submit' name='ACTION' value='$Lang::tr{'show crl'}' /></td>
c6c9630e 2770 </tr></table></form>
6e13d0a5
MT
2771END
2772 ;
c6c9630e
MT
2773
2774 &Header::closebox();
2775 if ( $srunning eq "yes" ) {
6e13d0a5 2776 print "<div align='center'><form method='post'><input type='submit' name='ACTION' value='$Lang::tr{'reset'}' disabled='disabled' /></div></form>\n";
c6c9630e
MT
2777 }else{
2778 print "<div align='center'><form method='post'><input type='submit' name='ACTION' value='$Lang::tr{'reset'}' /></div></form>\n";
2779 }
2780 if ( -f "${General::swroot}/ovpn/ca/cacert.pem" ) {
2781 &Header::openbox('100%', 'LEFT', $Lang::tr{'Client status and controlc' });
2782 print <<END
2783 <table width='100%' border='0' cellspacing='1' cellpadding='0'>
2784<tr>
2785 <td width='10%' class='boldbase' align='center'><b>$Lang::tr{'name'}</b></td>
2786 <td width='15%' class='boldbase' align='center'><b>$Lang::tr{'type'}</b></td>
2787 <td width='18%' class='boldbase' align='center'><b>$Lang::tr{'common name'}</b></td>
2788 <td width='17%' class='boldbase' align='center'><b>$Lang::tr{'valid till'}</b></td>
2789 <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>
2790 <td width='10%' class='boldbase' align='center'><b>$Lang::tr{'status'}</b></td>
2791 <td width='5%' class='boldbase' colspan='6' align='center'><b>$Lang::tr{'action'}</b></td>
2792</tr>
6e13d0a5 2793END
c6c9630e
MT
2794 ;
2795 my $id = 0;
2796 my $gif;
2797 foreach my $key (keys %confighash) {
2798 if ($confighash{$key}[0] eq 'on') { $gif = 'on.gif'; } else { $gif = 'off.gif'; }
2799
2800 if ($id % 2) {
4e17adad 2801 print "<tr bgcolor='$color{'color20'}'>\n";
bb89e92a 2802 } else {
4e17adad 2803 print "<tr bgcolor='$color{'color22'}'>\n";
c6c9630e
MT
2804 }
2805 print "<td align='center' nowrap='nowrap'>$confighash{$key}[1]</td>";
2806 print "<td align='center' nowrap='nowrap'>" . $Lang::tr{"$confighash{$key}[3]"} . " (" . $Lang::tr{"$confighash{$key}[4]"} . ")</td>";
2807 if ($confighash{$key}[4] eq 'cert') {
2808 print "<td align='left' nowrap='nowrap'>$confighash{$key}[2]</td>";
2809 } else {
2810 print "<td align='left'>&nbsp;</td>";
2811 }
2812 my $cavalid = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/certs/$confighash{$key}[1]cert.pem`;
2813 $cavalid =~ /Not After : (.*)[\n]/;
2814 $cavalid = $1;
2815 print "<td align='center'>$cavalid</td>";
2816 print "<td align='center'>$confighash{$key}[25]</td>";
2817 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>";
2818 if ($confighash{$key}[0] eq 'off') {
2819 $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>";
2820 } else {
2821 my $cn;
2822 my @match = ();
2823 foreach my $line (@status) {
2824 chomp($line);
2825 if ( $line =~ /^(.+),(\d+\.\d+\.\d+\.\d+\:\d+),(\d+),(\d+),(.+)/) {
2826 @match = split(m/^(.+),(\d+\.\d+\.\d+\.\d+\:\d+),(\d+),(\d+),(.+)/, $line);
2827 if ($match[1] ne "Common Name") {
2828 $cn = $match[1];
2829 }
2830 $cn =~ s/[_]/ /g;
2831 if ($cn eq "$confighash{$key}[2]") {
2832 $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>";
2833 }
2834 }
2835 }
2836 }
2837 my $disable_clientdl = "disabled='disabled'";
2838 if (( $cgiparams{'ENABLED'} eq 'on') ||
2839 ( $cgiparams{'ENABLED_BLUE'} eq 'on') ||
2840 ( $cgiparams{'ENABLED_ORANGE'} eq 'on')){
2841 $disable_clientdl = "";
2842 }
2843 print <<END
2844 <td align='center'>$active</td>
2845
2846 <form method='post' name='frm${key}a'><td align='center'>
2847 <input type='image' name='$Lang::tr{'dl client arch'}' $disable_clientdl src='/images/openvpn.png' alt='$Lang::tr{'dl client arch'}' title='$Lang::tr{'dl client arch'}' border='0' />
2848 <input type='hidden' name='ACTION' value='$Lang::tr{'dl client arch'}' $disable_clientdl />
2849 <input type='hidden' name='KEY' value='$key' $disable_clientdl />
2850 </td></form>
2851END
2852 ;
2853 if ($confighash{$key}[4] eq 'cert') {
2854 print <<END
2855 <form method='post' name='frm${key}b'><td align='center'>
2856 <input type='image' name='$Lang::tr{'show certificate'}' src='/images/info.gif' alt='$Lang::tr{'show certificate'}' title='$Lang::tr{'show certificate'}' border='0' />
2857 <input type='hidden' name='ACTION' value='$Lang::tr{'show certificate'}' />
2858 <input type='hidden' name='KEY' value='$key' />
2859 </td></form>
2860END
2861 ; } else {
2862 print "<td>&nbsp;</td>";
2863 }
2864 if ($confighash{$key}[4] eq 'cert' && -f "${General::swroot}/ovpn/certs/$confighash{$key}[1].p12") {
2865 print <<END
2866 <form method='post' name='frm${key}c'><td align='center'>
2867 <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' />
2868 <input type='hidden' name='ACTION' value='$Lang::tr{'download pkcs12 file'}' />
2869 <input type='hidden' name='KEY' value='$key' />
2870 </td></form>
2871END
2872 ; } elsif ($confighash{$key}[4] eq 'cert') {
2873 print <<END
2874 <form method='post' name='frm${key}c'><td align='center'>
2875 <input type='image' name='$Lang::tr{'download certificate'}' src='/images/floppy.gif' alt='$Lang::tr{'download certificate'}' title='$Lang::tr{'download certificate'}' border='0' />
2876 <input type='hidden' name='ACTION' value='$Lang::tr{'download certificate'}' />
2877 <input type='hidden' name='KEY' value='$key' />
2878 </td></form>
2879END
2880 ; } else {
2881 print "<td>&nbsp;</td>";
2882 }
2883 print <<END
2884 <form method='post' name='frm${key}d'><td align='center'>
2885 <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' />
2886 <input type='hidden' name='ACTION' value='$Lang::tr{'toggle enable disable'}' />
2887 <input type='hidden' name='KEY' value='$key' />
2888 </td></form>
2889
2890 <form method='post' name='frm${key}e'><td align='center'>
2891 <input type='hidden' name='ACTION' value='$Lang::tr{'edit'}' />
2892 <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'/>
2893 <input type='hidden' name='KEY' value='$key' />
2894 </td></form>
2895 <form method='post' name='frm${key}f'><td align='center'>
2896 <input type='hidden' name='ACTION' value='$Lang::tr{'remove'}' />
2897 <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' />
2898 <input type='hidden' name='KEY' value='$key' />
2899 </td></form>
2900 </tr>
2901END
2902 ;
2903 $id++;
2904 }
2905 ;
2906
2907 # If the config file contains entries, print Key to action icons
2908 if ( $id ) {
2909 print <<END
2910 <table>
2911 <tr>
2912 <td class='boldbase'>&nbsp; <b>$Lang::tr{'legend'}:</b></td>
2913 <td>&nbsp; <img src='/images/on.gif' alt='$Lang::tr{'click to disable'}' /></td>
2914 <td class='base'>$Lang::tr{'click to disable'}</td>
2915 <td>&nbsp; &nbsp; <img src='/images/info.gif' alt='$Lang::tr{'show certificate'}' /></td>
2916 <td class='base'>$Lang::tr{'show certificate'}</td>
2917 <td>&nbsp; &nbsp; <img src='/images/edit.gif' alt='$Lang::tr{'edit'}' /></td>
2918 <td class='base'>$Lang::tr{'edit'}</td>
2919 <td>&nbsp; &nbsp; <img src='/images/delete.gif' alt='$Lang::tr{'remove'}' /></td>
2920 <td class='base'>$Lang::tr{'remove'}</td>
2921 </tr>
2922 <tr>
2923 <td>&nbsp; </td>
2924 <td>&nbsp; <img src='/images/off.gif' alt='?OFF' /></td>
2925 <td class='base'>$Lang::tr{'click to enable'}</td>
2926 <td>&nbsp; &nbsp; <img src='/images/floppy.gif' alt='?FLOPPY' /></td>
2927 <td class='base'>$Lang::tr{'download certificate'}</td>
2928 <td>&nbsp; &nbsp; <img src='/images/openvpn.png' alt='?RELOAD'/></td>
2929 <td class='base'>$Lang::tr{'dl client arch'}</td>
2930 </tr>
2931 </table>
2932END
2933 ;
2934 }
2935
2936 print <<END
2937 <table width='100%'>
2938 <form method='post'>
2939 <tr><td width='50%' ><input type='submit' name='ACTION' value='$Lang::tr{'add'}' /></td>
2940 <td width='50%' ><input type='submit' name='ACTION' value='$Lang::tr{'ovpn con stat'}' $activeonrun /></td></tr>
2941 </form>
2942 </table>
2943END
2944 ;
2945 &Header::closebox();
bb89e92a 2946}
115340d2 2947&Header::closepage();