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