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