]> git.ipfire.org Git - ipfire-2.x.git/blob - html/cgi-bin/ovpnmain.cgi
ovpnmain.cgi: Fix remote IP address validation.
[ipfire-2.x.git] / html / cgi-bin / ovpnmain.cgi
1 #!/usr/bin/perl
2 ###############################################################################
3 # #
4 # IPFire.org - A linux based firewall #
5 # Copyright (C) 2007-2013 IPFire Team <info@ipfire.org> #
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 ###############################################################################
21 ###
22 # Based on IPFireCore 55
23 ###
24 use CGI;
25 use CGI qw/:standard/;
26 use Net::DNS;
27 use Net::Ping;
28 use Net::Telnet;
29 use File::Copy;
30 use File::Temp qw/ tempfile tempdir /;
31 use strict;
32 use Archive::Zip qw(:ERROR_CODES :CONSTANTS);
33 require '/var/ipfire/general-functions.pl';
34 require "${General::swroot}/lang.pl";
35 require "${General::swroot}/header.pl";
36 require "${General::swroot}/countries.pl";
37
38 # enable only the following on debugging purpose
39 #use warnings;
40 #use CGI::Carp 'fatalsToBrowser';
41 #workaround to suppress a warning when a variable is used only once
42 my @dummy = ( ${Header::colourgreen}, ${Header::colourblue} );
43 undef (@dummy);
44
45 my %color = ();
46 my %mainsettings = ();
47 &General::readhash("${General::swroot}/main/settings", \%mainsettings);
48 &General::readhash("/srv/web/ipfire/html/themes/".$mainsettings{'THEME'}."/include/colors.txt", \%color);
49
50 ###
51 ### Initialize variables
52 ###
53 my %ccdconfhash=();
54 my %ccdroutehash=();
55 my %ccdroute2hash=();
56 my %netsettings=();
57 my %cgiparams=();
58 my %vpnsettings=();
59 my %checked=();
60 my %confighash=();
61 my %cahash=();
62 my %selected=();
63 my $warnmessage = '';
64 my $errormessage = '';
65 my %settings=();
66 my $routes_push_file = '';
67 my $confighost="${General::swroot}/fwhosts/customhosts";
68 my $configgrp="${General::swroot}/fwhosts/customgroups";
69 my $customnet="${General::swroot}/fwhosts/customnetworks";
70 my $name;
71 &General::readhash("${General::swroot}/ethernet/settings", \%netsettings);
72 $cgiparams{'ENABLED'} = 'off';
73 $cgiparams{'ENABLED_BLUE'} = 'off';
74 $cgiparams{'ENABLED_ORANGE'} = 'off';
75 $cgiparams{'EDIT_ADVANCED'} = 'off';
76 $cgiparams{'NAT'} = 'off';
77 $cgiparams{'COMPRESSION'} = 'off';
78 $cgiparams{'ONLY_PROPOSED'} = 'off';
79 $cgiparams{'ACTION'} = '';
80 $cgiparams{'CA_NAME'} = '';
81 $cgiparams{'DHCP_DOMAIN'} = '';
82 $cgiparams{'DHCP_DNS'} = '';
83 $cgiparams{'DHCP_WINS'} = '';
84 $cgiparams{'ROUTES_PUSH'} = '';
85 $cgiparams{'DCOMPLZO'} = 'off';
86 $cgiparams{'MSSFIX'} = '';
87 $cgiparams{'number'} = '';
88 $cgiparams{'PMTU_DISCOVERY'} = '';
89 $routes_push_file = "${General::swroot}/ovpn/routes_push";
90 unless (-e $routes_push_file) { system("touch $routes_push_file"); }
91 unless (-e "${General::swroot}/ovpn/ccd.conf") { system("touch ${General::swroot}/ovpn/ccd.conf"); }
92 unless (-e "${General::swroot}/ovpn/ccdroute") { system("touch ${General::swroot}/ovpn/ccdroute"); }
93 unless (-e "${General::swroot}/ovpn/ccdroute2") { system("touch ${General::swroot}/ovpn/ccdroute2"); }
94
95 &Header::getcgihash(\%cgiparams, {'wantfile' => 1, 'filevar' => 'FH'});
96
97 # prepare openvpn config file
98 ###
99 ### Useful functions
100 ###
101 sub haveOrangeNet
102 {
103 if ($netsettings{'CONFIG_TYPE'} == 2) {return 1;}
104 if ($netsettings{'CONFIG_TYPE'} == 4) {return 1;}
105 return 0;
106 }
107
108 sub haveBlueNet
109 {
110 if ($netsettings{'CONFIG_TYPE'} == 3) {return 1;}
111 if ($netsettings{'CONFIG_TYPE'} == 4) {return 1;}
112 return 0;
113 }
114
115 sub sizeformat{
116 my $bytesize = shift;
117 my $i = 0;
118
119 while(abs($bytesize) >= 1024){
120 $bytesize=$bytesize/1024;
121 $i++;
122 last if($i==6);
123 }
124
125 my @units = ("Bytes","KB","MB","GB","TB","PB","EB");
126 my $newsize=(int($bytesize*100 +0.5))/100;
127 return("$newsize $units[$i]");
128 }
129
130 sub cleanssldatabase
131 {
132 if (open(FILE, ">${General::swroot}/ovpn/certs/serial")) {
133 print FILE "01";
134 close FILE;
135 }
136 if (open(FILE, ">${General::swroot}/ovpn/certs/index.txt")) {
137 print FILE "";
138 close FILE;
139 }
140 unlink ("${General::swroot}/ovpn/certs/index.txt.old");
141 unlink ("${General::swroot}/ovpn/certs/serial.old");
142 unlink ("${General::swroot}/ovpn/certs/01.pem");
143 }
144
145 sub newcleanssldatabase
146 {
147 if (! -s "${General::swroot}/ovpn/certs/serial" ) {
148 open(FILE, ">${General::swroot}(ovpn/certs/serial");
149 print FILE "01";
150 close FILE;
151 }
152 if (! -s ">${General::swroot}/ovpn/certs/index.txt") {
153 system ("touch ${General::swroot}/ovpn/certs/index.txt");
154 }
155 unlink ("${General::swroot}/ovpn/certs/index.txt.old");
156 unlink ("${General::swroot}/ovpn/certs/serial.old");
157 }
158
159 sub deletebackupcert
160 {
161 if (open(FILE, "${General::swroot}/ovpn/certs/serial.old")) {
162 my $hexvalue = <FILE>;
163 chomp $hexvalue;
164 close FILE;
165 unlink ("${General::swroot}/ovpn/certs/$hexvalue.pem");
166 }
167 }
168
169 sub checkportfw {
170 my $KEY2 = $_[0]; # key2
171 my $SRC_PORT = $_[1]; # src_port
172 my $PROTOCOL = $_[2]; # protocol
173 my $SRC_IP = $_[3]; # sourceip
174
175 my $pfwfilename = "${General::swroot}/portfw/config";
176 open(FILE, $pfwfilename) or die 'Unable to open config file.';
177 my @pfwcurrent = <FILE>;
178 close(FILE);
179 my $pfwkey1 = 0; # used for finding last sequence number used
180 foreach my $pfwline (@pfwcurrent)
181 {
182 my @pfwtemp = split(/\,/,$pfwline);
183
184 chomp ($pfwtemp[8]);
185 if ($KEY2 eq "0"){ # if key2 is 0 then it is a portfw addition
186 if ( $SRC_PORT eq $pfwtemp[3] &&
187 $PROTOCOL eq $pfwtemp[2] &&
188 $SRC_IP eq $pfwtemp[7])
189 {
190 $errormessage = "$Lang::tr{'source port in use'} $SRC_PORT";
191 }
192 # Check if key2 = 0, if it is then it is a port forward entry and we want the sequence number
193 if ( $pfwtemp[1] eq "0") {
194 $pfwkey1=$pfwtemp[0];
195 }
196 # Darren Critchley - Duplicate or overlapping Port range check
197 if ($pfwtemp[1] eq "0" &&
198 $PROTOCOL eq $pfwtemp[2] &&
199 $SRC_IP eq $pfwtemp[7] &&
200 $errormessage eq '')
201 {
202 &portchecks($SRC_PORT, $pfwtemp[5]);
203 # &portchecks($pfwtemp[3], $pfwtemp[5]);
204 # &portchecks($pfwtemp[3], $SRC_IP);
205 }
206 }
207 }
208 # $errormessage="$KEY2 $SRC_PORT $PROTOCOL $SRC_IP";
209
210 return;
211 }
212
213 sub checkportoverlap
214 {
215 my $portrange1 = $_[0]; # New port range
216 my $portrange2 = $_[1]; # existing port range
217 my @tempr1 = split(/\:/,$portrange1);
218 my @tempr2 = split(/\:/,$portrange2);
219
220 unless (&checkportinc($tempr1[0], $portrange2)){ return 0;}
221 unless (&checkportinc($tempr1[1], $portrange2)){ return 0;}
222
223 unless (&checkportinc($tempr2[0], $portrange1)){ return 0;}
224 unless (&checkportinc($tempr2[1], $portrange1)){ return 0;}
225
226 return 1; # Everything checks out!
227 }
228
229 # Darren Critchley - we want to make sure that a port entry is not within an already existing range
230 sub checkportinc
231 {
232 my $port1 = $_[0]; # Port
233 my $portrange2 = $_[1]; # Port range
234 my @tempr1 = split(/\:/,$portrange2);
235
236 if ($port1 < $tempr1[0] || $port1 > $tempr1[1]) {
237 return 1;
238 } else {
239 return 0;
240 }
241 }
242 # Darren Critchley - Duplicate or overlapping Port range check
243 sub portchecks
244 {
245 my $p1 = $_[0]; # New port range
246 my $p2 = $_[1]; # existing port range
247 # $_ = $_[0];
248 our ($prtrange1, $prtrange2);
249 $prtrange1 = 0;
250 # if (m/:/ && $prtrange1 == 1) { # comparing two port ranges
251 # unless (&checkportoverlap($p1,$p2)) {
252 # $errormessage = "$Lang::tr{'source port overlaps'} $p1";
253 # }
254 # }
255 if (m/:/ && $prtrange1 == 0 && $errormessage eq '') { # compare one port to a range
256 unless (&checkportinc($p2,$p1)) {
257 $errormessage = "$Lang::tr{'srcprt within existing'} $p1";
258 }
259 }
260 $prtrange1 = 1;
261 if (! m/:/ && $prtrange1 == 1 && $errormessage eq '') { # compare one port to a range
262 unless (&checkportinc($p1,$p2)) {
263 $errormessage = "$Lang::tr{'srcprt range overlaps'} $p2";
264 }
265 }
266 return;
267 }
268
269 # Darren Critchley - certain ports are reserved for IPFire
270 # TCP 67,68,81,222,445
271 # UDP 67,68
272 # Params passed in -> port, rangeyn, protocol
273 sub disallowreserved
274 {
275 # port 67 and 68 same for tcp and udp, don't bother putting in an array
276 my $msg = "";
277 my @tcp_reserved = (81,222,445);
278 my $prt = $_[0]; # the port or range
279 my $ryn = $_[1]; # tells us whether or not it is a port range
280 my $prot = $_[2]; # protocol
281 my $srcdst = $_[3]; # source or destination
282 if ($ryn) { # disect port range
283 if ($srcdst eq "src") {
284 $msg = "$Lang::tr{'rsvd src port overlap'}";
285 } else {
286 $msg = "$Lang::tr{'rsvd dst port overlap'}";
287 }
288 my @tmprng = split(/\:/,$prt);
289 unless (67 < $tmprng[0] || 67 > $tmprng[1]) { $errormessage="$msg 67"; return; }
290 unless (68 < $tmprng[0] || 68 > $tmprng[1]) { $errormessage="$msg 68"; return; }
291 if ($prot eq "tcp") {
292 foreach my $prange (@tcp_reserved) {
293 unless ($prange < $tmprng[0] || $prange > $tmprng[1]) { $errormessage="$msg $prange"; return; }
294 }
295 }
296 } else {
297 if ($srcdst eq "src") {
298 $msg = "$Lang::tr{'reserved src port'}";
299 } else {
300 $msg = "$Lang::tr{'reserved dst port'}";
301 }
302 if ($prt == 67) { $errormessage="$msg 67"; return; }
303 if ($prt == 68) { $errormessage="$msg 68"; return; }
304 if ($prot eq "tcp") {
305 foreach my $prange (@tcp_reserved) {
306 if ($prange == $prt) { $errormessage="$msg $prange"; return; }
307 }
308 }
309 }
310 return;
311 }
312
313 sub writeserverconf {
314 my %sovpnsettings = ();
315 my @temp = ();
316 &General::readhash("${General::swroot}/ovpn/settings", \%sovpnsettings);
317 &read_routepushfile;
318
319 open(CONF, ">${General::swroot}/ovpn/server.conf") or die "Unable to open ${General::swroot}/ovpn/server.conf: $!";
320 flock CONF, 2;
321 print CONF "#OpenVPN Server conf\n";
322 print CONF "\n";
323 print CONF "daemon openvpnserver\n";
324 print CONF "writepid /var/run/openvpn.pid\n";
325 print CONF "#DAN prepare OpenVPN for listening on blue and orange\n";
326 print CONF ";local $sovpnsettings{'VPN_IP'}\n";
327 print CONF "dev $sovpnsettings{'DDEVICE'}\n";
328 print CONF "proto $sovpnsettings{'DPROTOCOL'}\n";
329 print CONF "port $sovpnsettings{'DDEST_PORT'}\n";
330 print CONF "script-security 3 system\n";
331 print CONF "ifconfig-pool-persist /var/ipfire/ovpn/ovpn-leases.db 3600\n";
332 print CONF "client-config-dir /var/ipfire/ovpn/ccd\n";
333 print CONF "tls-server\n";
334 print CONF "ca /var/ipfire/ovpn/ca/cacert.pem\n";
335 print CONF "cert /var/ipfire/ovpn/certs/servercert.pem\n";
336 print CONF "key /var/ipfire/ovpn/certs/serverkey.pem\n";
337 print CONF "dh /var/ipfire/ovpn/ca/dh1024.pem\n";
338 my @tempovpnsubnet = split("\/",$sovpnsettings{'DOVPN_SUBNET'});
339 print CONF "server $tempovpnsubnet[0] $tempovpnsubnet[1]\n";
340 #print CONF "push \"route $netsettings{'GREEN_NETADDRESS'} $netsettings{'GREEN_NETMASK'}\"\n";
341
342 # Check if we are using mssfix, fragment or mtu-disc and set the corretct mtu of 1500.
343 # If we doesn't use one of them, we can use the configured mtu value.
344 if ($sovpnsettings{'MSSFIX'} eq 'on')
345 { print CONF "$sovpnsettings{'DDEVICE'}-mtu 1500\n"; }
346 elsif ($sovpnsettings{'FRAGMENT'} ne '' && $sovpnsettings{'DPROTOCOL'} ne 'tcp')
347 { print CONF "$sovpnsettings{'DDEVICE'}-mtu 1500\n"; }
348 elsif (($sovpnsettings{'PMTU_DISCOVERY'} eq 'yes') ||
349 ($sovpnsettings{'PMTU_DISCOVERY'} eq 'maybe') ||
350 ($sovpnsettings{'PMTU_DISCOVERY'} eq 'no' ))
351 { print CONF "$sovpnsettings{'DDEVICE'}-mtu 1500\n"; }
352 else
353 { print CONF "$sovpnsettings{'DDEVICE'}-mtu $sovpnsettings{'DMTU'}\n"; }
354
355 if ($vpnsettings{'ROUTES_PUSH'} ne '') {
356 @temp = split(/\n/,$vpnsettings{'ROUTES_PUSH'});
357 foreach (@temp)
358 {
359 @tempovpnsubnet = split("\/",&General::ipcidr2msk($_));
360 print CONF "push \"route " . $tempovpnsubnet[0]. " " . $tempovpnsubnet[1] . "\"\n";
361 }
362 }
363 # a.marx ccd
364 my %ccdconfhash=();
365 &General::readhasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash);
366 foreach my $key (keys %ccdconfhash) {
367 my $a=$ccdconfhash{$key}[1];
368 my ($b,$c) = split (/\//, $a);
369 print CONF "route $b ".&General::cidrtosub($c)."\n";
370 }
371 my %ccdroutehash=();
372 &General::readhasharray("${General::swroot}/ovpn/ccdroute", \%ccdroutehash);
373 foreach my $key (keys %ccdroutehash) {
374 foreach my $i ( 1 .. $#{$ccdroutehash{$key}}){
375 my ($a,$b)=split (/\//,$ccdroutehash{$key}[$i]);
376 print CONF "route $a $b\n";
377 }
378 }
379 # ccd end
380
381 if ($sovpnsettings{CLIENT2CLIENT} eq 'on') {
382 print CONF "client-to-client\n";
383 }
384 if ($sovpnsettings{MSSFIX} eq 'on') {
385 print CONF "mssfix\n";
386 }
387 if ($sovpnsettings{FRAGMENT} ne '' && $sovpnsettings{'DPROTOCOL'} ne 'tcp') {
388 print CONF "fragment $sovpnsettings{'FRAGMENT'}\n";
389 }
390
391 # Check if a valid operating mode has been choosen and use it.
392 if (($sovpnsettings{'PMTU_DISCOVERY'} eq 'yes') ||
393 ($sovpnsettings{'PMTU_DISCOVERY'} eq 'maybe') ||
394 ($sovpnsettings{'PMTU_DISCOVERY'} eq 'no' )) {
395 print CONF "mtu-disc $sovpnsettings{'PMTU_DISCOVERY'}\n";
396 }
397
398 if ($sovpnsettings{KEEPALIVE_1} > 0 && $sovpnsettings{KEEPALIVE_2} > 0) {
399 print CONF "keepalive $sovpnsettings{'KEEPALIVE_1'} $sovpnsettings{'KEEPALIVE_2'}\n";
400 }
401 print CONF "status-version 1\n";
402 print CONF "status /var/log/ovpnserver.log 30\n";
403 print CONF "cipher $sovpnsettings{DCIPHER}\n";
404 if ($sovpnsettings{DCOMPLZO} eq 'on') {
405 print CONF "comp-lzo\n";
406 }
407 if ($sovpnsettings{REDIRECT_GW_DEF1} eq 'on') {
408 print CONF "push \"redirect-gateway def1\"\n";
409 }
410 if ($sovpnsettings{DHCP_DOMAIN} ne '') {
411 print CONF "push \"dhcp-option DOMAIN $sovpnsettings{DHCP_DOMAIN}\"\n";
412 }
413
414 if ($sovpnsettings{DHCP_DNS} ne '') {
415 print CONF "push \"dhcp-option DNS $sovpnsettings{DHCP_DNS}\"\n";
416 }
417
418 if ($sovpnsettings{DHCP_WINS} ne '') {
419 print CONF "push \"dhcp-option WINS $sovpnsettings{DHCP_WINS}\"\n";
420 }
421
422 if ($sovpnsettings{DHCP_WINS} eq '') {
423 print CONF "max-clients 100\n";
424 }
425 if ($sovpnsettings{DHCP_WINS} ne '') {
426 print CONF "max-clients $sovpnsettings{MAX_CLIENTS}\n";
427 }
428 print CONF "tls-verify /var/ipfire/ovpn/verify\n";
429 print CONF "crl-verify /var/ipfire/ovpn/crls/cacrl.pem\n";
430 print CONF "user nobody\n";
431 print CONF "group nobody\n";
432 print CONF "persist-key\n";
433 print CONF "persist-tun\n";
434 if ($sovpnsettings{LOG_VERB} ne '') {
435 print CONF "verb $sovpnsettings{LOG_VERB}\n";
436 } else {
437 print CONF "verb 3\n";
438 }
439 print CONF "\n";
440
441 close(CONF);
442 }
443
444 sub emptyserverlog{
445 if (open(FILE, ">/var/log/ovpnserver.log")) {
446 flock FILE, 2;
447 print FILE "";
448 close FILE;
449 }
450
451 }
452
453 sub delccdnet
454 {
455 my %ccdconfhash = ();
456 my %ccdhash = ();
457 my $ccdnetname=$_[0];
458 if (-f "${General::swroot}/ovpn/ovpnconfig"){
459 &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%ccdhash);
460 foreach my $key (keys %ccdhash) {
461 if ($ccdhash{$key}[32] eq $ccdnetname) {
462 $errormessage=$Lang::tr{'ccd err hostinnet'};
463 return;
464 }
465 }
466 }
467 &General::readhasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash);
468 foreach my $key (keys %ccdconfhash) {
469 if ($ccdconfhash{$key}[0] eq $ccdnetname){
470 delete $ccdconfhash{$key};
471 }
472 }
473 &General::writehasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash);
474
475 &writeserverconf;
476 return 0;
477 }
478
479 sub addccdnet
480 {
481 my %ccdconfhash=();
482 my @ccdconf=();
483 my $ccdname=$_[0];
484 my $ccdnet=$_[1];
485 my $subcidr;
486 my @ip2=();
487 my $checkup;
488 my $ccdip;
489 my $baseaddress;
490
491
492 #check name
493 if ($ccdname eq '')
494 {
495 $errormessage=$errormessage.$Lang::tr{'ccd err name'}."<br>";
496 return
497 }
498
499 if(!&General::validhostname($ccdname))
500 {
501 $errormessage=$Lang::tr{'ccd err invalidname'};
502 return;
503 }
504
505 ($ccdip,$subcidr) = split (/\//,$ccdnet);
506 $subcidr=&General::iporsubtocidr($subcidr);
507 #check subnet
508 if ($subcidr > 30)
509 {
510 $errormessage=$Lang::tr{'ccd err invalidnet'};
511 return;
512 }
513 #check ip
514 if (!&General::validipandmask($ccdnet)){
515 $errormessage=$Lang::tr{'ccd err invalidnet'};
516 return;
517 }
518
519 $errormessage=&General::checksubnets($ccdname,$ccdnet);
520
521
522 if (!$errormessage) {
523 my %ccdconfhash=();
524 $baseaddress=&General::getnetworkip($ccdip,$subcidr);
525 &General::readhasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash);
526 my $key = &General::findhasharraykey (\%ccdconfhash);
527 foreach my $i (0 .. 1) { $ccdconfhash{$key}[$i] = "";}
528 $ccdconfhash{$key}[0] = $ccdname;
529 $ccdconfhash{$key}[1] = $baseaddress."/".$subcidr;
530 &General::writehasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash);
531 &writeserverconf;
532 $cgiparams{'ccdname'}='';
533 $cgiparams{'ccdsubnet'}='';
534 return 1;
535 }
536 }
537
538 sub modccdnet
539 {
540
541 my $newname=$_[0];
542 my $oldname=$_[1];
543 my %ccdconfhash=();
544 my %ccdhash=();
545 &General::readhasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash);
546 foreach my $key (keys %ccdconfhash) {
547 if ($ccdconfhash{$key}[0] eq $oldname) {
548 foreach my $key1 (keys %ccdconfhash) {
549 if ($ccdconfhash{$key1}[0] eq $newname){
550 $errormessage=$errormessage.$Lang::tr{'ccd err netadrexist'};
551 return;
552 }else{
553 $ccdconfhash{$key}[0]= $newname;
554 &General::writehasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash);
555 last;
556 }
557 }
558 }
559 }
560
561 &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%ccdhash);
562 foreach my $key (keys %ccdhash) {
563 if ($ccdhash{$key}[32] eq $oldname) {
564 $ccdhash{$key}[32]=$newname;
565 &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%ccdhash);
566 last;
567 }
568 }
569
570 return 0;
571 }
572 sub ccdmaxclients
573 {
574 my $ccdnetwork=$_[0];
575 my @octets=();
576 my @subnet=();
577 @octets=split("\/",$ccdnetwork);
578 @subnet= split /\./, &General::cidrtosub($octets[1]);
579 my ($a,$b,$c,$d,$e);
580 $a=256-$subnet[0];
581 $b=256-$subnet[1];
582 $c=256-$subnet[2];
583 $d=256-$subnet[3];
584 $e=($a*$b*$c*$d)/4;
585 return $e-1;
586 }
587
588 sub getccdadresses
589 {
590 my $ipin=$_[0];
591 my ($ip1,$ip2,$ip3,$ip4)=split /\./, $ipin;
592 my $cidr=$_[1];
593 chomp($cidr);
594 my $count=$_[2];
595 my $hasip=$_[3];
596 chomp($hasip);
597 my @iprange=();
598 my %ccdhash=();
599 &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%ccdhash);
600 $iprange[0]=$ip1.".".$ip2.".".$ip3.".".2;
601 for (my $i=1;$i<=$count;$i++) {
602 my $tmpip=$iprange[$i-1];
603 my $stepper=$i*4;
604 $iprange[$i]= &General::getnextip($tmpip,4);
605 }
606 my $r=0;
607 foreach my $key (keys %ccdhash) {
608 $r=0;
609 foreach my $tmp (@iprange){
610 my ($net,$sub) = split (/\//,$ccdhash{$key}[33]);
611 if ($net eq $tmp) {
612 if ( $hasip ne $ccdhash{$key}[33] ){
613 splice (@iprange,$r,1);
614 }
615 }
616 $r++;
617 }
618 }
619 return @iprange;
620 }
621
622 sub fillselectbox
623 {
624 my $boxname=$_[1];
625 my ($ccdip,$subcidr) = split("/",$_[0]);
626 my $tz=$_[2];
627 my @allccdips=&getccdadresses($ccdip,$subcidr,&ccdmaxclients($ccdip."/".$subcidr),$tz);
628 print"<select name='$boxname' STYLE='font-family : arial; font-size : 9pt; width:130px;' >";
629 foreach (@allccdips) {
630 my $ip=$_."/30";
631 chomp($ip);
632 print "<option value='$ip' ";
633 if ( $ip eq $cgiparams{$boxname} ){
634 print"selected";
635 }
636 print ">$ip</option>";
637 }
638 print "</select>";
639 }
640
641 sub hostsinnet
642 {
643 my $name=$_[0];
644 my %ccdhash=();
645 my $i=0;
646 &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%ccdhash);
647 foreach my $key (keys %ccdhash) {
648 if ($ccdhash{$key}[32] eq $name){ $i++;}
649 }
650 return $i;
651 }
652
653 sub check_routes_push
654 {
655 my $val=$_[0];
656 my ($ip,$cidr) = split (/\//, $val);
657 ##check for existing routes in routes_push
658 if (-e "${General::swroot}/ovpn/routes_push") {
659 open(FILE,"${General::swroot}/ovpn/routes_push");
660 while (<FILE>) {
661 $_=~s/\s*$//g;
662
663 my ($ip2,$cidr2) = split (/\//,"$_");
664 my $val2=$ip2."/".&General::iporsubtodec($cidr2);
665
666 if($val eq $val2){
667 return 0;
668 }
669 #subnetcheck
670 if (&General::IpInSubnet ($ip,$ip2,&General::iporsubtodec($cidr2))){
671 return 0;
672 }
673 };
674 close(FILE);
675 }
676 return 1;
677 }
678
679 sub check_ccdroute
680 {
681 my %ccdroutehash=();
682 my $val=$_[0];
683 my ($ip,$cidr) = split (/\//, $val);
684 #check for existing routes in ccdroute
685 &General::readhasharray("${General::swroot}/ovpn/ccdroute", \%ccdroutehash);
686 foreach my $key (keys %ccdroutehash) {
687 foreach my $i (1 .. $#{$ccdroutehash{$key}}) {
688 if (&General::iporsubtodec($val) eq $ccdroutehash{$key}[$i] && $ccdroutehash{$key}[0] ne $cgiparams{'NAME'}){
689 return 0;
690 }
691 my ($ip2,$cidr2) = split (/\//,$ccdroutehash{$key}[$i]);
692 #subnetcheck
693 if (&General::IpInSubnet ($ip,$ip2,$cidr2)&& $ccdroutehash{$key}[0] ne $cgiparams{'NAME'} ){
694 return 0;
695 }
696 }
697 }
698 return 1;
699 }
700 sub check_ccdconf
701 {
702 my %ccdconfhash=();
703 my $val=$_[0];
704 my ($ip,$cidr) = split (/\//, $val);
705 #check for existing routes in ccdroute
706 &General::readhasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash);
707 foreach my $key (keys %ccdconfhash) {
708 if (&General::iporsubtocidr($val) eq $ccdconfhash{$key}[1]){
709 return 0;
710 }
711 my ($ip2,$cidr2) = split (/\//,$ccdconfhash{$key}[1]);
712 #subnetcheck
713 if (&General::IpInSubnet ($ip,$ip2,&General::cidrtosub($cidr2))){
714 return 0;
715 }
716
717 }
718 return 1;
719 }
720
721 ###
722 # m.a.d net2net
723 ###
724
725 sub validdotmask
726 {
727 my $ipdotmask = $_[0];
728 if (&General::validip($ipdotmask)) { return 0; }
729 if (!($ipdotmask =~ /^(.*?)\/(.*?)$/)) { }
730 my $mask = $2;
731 if (($mask =~ /\./ )) { return 0; }
732 return 1;
733 }
734
735 # -------------------------------------------------------------------
736
737 sub write_routepushfile
738 {
739 open(FILE, ">$routes_push_file");
740 flock(FILE, 2);
741 if ($vpnsettings{'ROUTES_PUSH'} ne '') {
742 print FILE $vpnsettings{'ROUTES_PUSH'};
743 }
744 close(FILE);
745 }
746
747 sub read_routepushfile
748 {
749 if (-e "$routes_push_file") {
750 open(FILE,"$routes_push_file");
751 delete $vpnsettings{'ROUTES_PUSH'};
752 while (<FILE>) { $vpnsettings{'ROUTES_PUSH'} .= $_ };
753 close(FILE);
754 $cgiparams{'ROUTES_PUSH'} = $vpnsettings{'ROUTES_PUSH'};
755
756 }
757 }
758
759
760 #hier die refresh page
761 if ( -e "${General::swroot}/ovpn/gencanow") {
762 my $refresh = '';
763 $refresh = "<meta http-equiv='refresh' content='15;' />";
764 &Header::showhttpheaders();
765 &Header::openpage($Lang::tr{'OVPN'}, 1, $refresh);
766 &Header::openbigbox('100%', 'center');
767 &Header::openbox('100%', 'left', "$Lang::tr{'generate root/host certificates'}:");
768 print "<tr>\n<td align='center'><img src='/images/clock.gif' alt='' /></td>\n";
769 print "<td colspan='2'><font color='red'>Please be patient this realy can take some time on older hardware...</font></td></tr>\n";
770 &Header::closebox();
771 &Header::closebigbox();
772 &Header::closepage();
773 exit (0);
774 }
775 ##hier die refresh page
776
777
778 ###
779 ### OpenVPN Server Control
780 ###
781 if ($cgiparams{'ACTION'} eq $Lang::tr{'start ovpn server'} ||
782 $cgiparams{'ACTION'} eq $Lang::tr{'stop ovpn server'} ||
783 $cgiparams{'ACTION'} eq $Lang::tr{'restart ovpn server'}) {
784 #start openvpn server
785 if ($cgiparams{'ACTION'} eq $Lang::tr{'start ovpn server'}){
786 &emptyserverlog();
787 system('/usr/local/bin/openvpnctrl', '-s');
788 }
789 #stop openvpn server
790 if ($cgiparams{'ACTION'} eq $Lang::tr{'stop ovpn server'}){
791 system('/usr/local/bin/openvpnctrl', '-k');
792 &emptyserverlog();
793 }
794 # #restart openvpn server
795 # if ($cgiparams{'ACTION'} eq $Lang::tr{'restart ovpn server'}){
796 #workarund, till SIGHUP also works when running as nobody
797 # system('/usr/local/bin/openvpnctrl', '-r');
798 # &emptyserverlog();
799 # }
800 }
801
802 ###
803 ### Save Advanced options
804 ###
805
806 if ($cgiparams{'ACTION'} eq $Lang::tr{'save-adv-options'}) {
807 &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings);
808 #DAN do we really need (to to check) this value? Besides if we listen on blue and orange too,
809 #DAN this value has to leave.
810 #new settings for daemon
811 $vpnsettings{'LOG_VERB'} = $cgiparams{'LOG_VERB'};
812 $vpnsettings{'KEEPALIVE_1'} = $cgiparams{'KEEPALIVE_1'};
813 $vpnsettings{'KEEPALIVE_2'} = $cgiparams{'KEEPALIVE_2'};
814 $vpnsettings{'MAX_CLIENTS'} = $cgiparams{'MAX_CLIENTS'};
815 $vpnsettings{'REDIRECT_GW_DEF1'} = $cgiparams{'REDIRECT_GW_DEF1'};
816 $vpnsettings{'CLIENT2CLIENT'} = $cgiparams{'CLIENT2CLIENT'};
817 $vpnsettings{'DHCP_DOMAIN'} = $cgiparams{'DHCP_DOMAIN'};
818 $vpnsettings{'DHCP_DNS'} = $cgiparams{'DHCP_DNS'};
819 $vpnsettings{'DHCP_WINS'} = $cgiparams{'DHCP_WINS'};
820 $vpnsettings{'ROUTES_PUSH'} = $cgiparams{'ROUTES_PUSH'};
821 $vpnsettings{'PMTU_DISCOVERY'} = $cgiparams{'PMTU_DISCOVERY'};
822 my @temp=();
823
824 if ($cgiparams{'FRAGMENT'} eq '') {
825 delete $vpnsettings{'FRAGMENT'};
826 } else {
827 if ($cgiparams{'FRAGMENT'} !~ /^[0-9]+$/) {
828 $errormessage = "Incorrect value, please insert only numbers.";
829 goto ADV_ERROR;
830 } else {
831 $vpnsettings{'FRAGMENT'} = $cgiparams{'FRAGMENT'};
832 }
833 }
834 if ($cgiparams{'MSSFIX'} ne 'on') {
835 delete $vpnsettings{'MSSFIX'};
836 } else {
837 $vpnsettings{'MSSFIX'} = $cgiparams{'MSSFIX'};
838 }
839
840 if (($cgiparams{'PMTU_DISCOVERY'} eq 'yes') ||
841 ($cgiparams{'PMTU_DISCOVERY'} eq 'maybe') ||
842 ($cgiparams{'PMTU_DISCOVERY'} eq 'no' )) {
843
844 if (($cgiparams{'MSSFIX'} eq 'on') || ($cgiparams{'FRAGMENT'} ne '')) {
845 $errormessage = $Lang::tr{'ovpn mtu-disc with mssfix or fragment'};
846 goto ADV_ERROR;
847 }
848 }
849
850 if ($cgiparams{'DHCP_DOMAIN'} ne ''){
851 unless (&General::validdomainname($cgiparams{'DHCP_DOMAIN'}) || &General::validip($cgiparams{'DHCP_DOMAIN'})) {
852 $errormessage = $Lang::tr{'invalid input for dhcp domain'};
853 goto ADV_ERROR;
854 }
855 }
856 if ($cgiparams{'DHCP_DNS'} ne ''){
857 unless (&General::validfqdn($cgiparams{'DHCP_DNS'}) || &General::validip($cgiparams{'DHCP_DNS'})) {
858 $errormessage = $Lang::tr{'invalid input for dhcp dns'};
859 goto ADV_ERROR;
860 }
861 }
862 if ($cgiparams{'DHCP_WINS'} ne ''){
863 unless (&General::validfqdn($cgiparams{'DHCP_WINS'}) || &General::validip($cgiparams{'DHCP_WINS'})) {
864 $errormessage = $Lang::tr{'invalid input for dhcp wins'};
865 goto ADV_ERROR;
866 }
867 }
868 if ($cgiparams{'ROUTES_PUSH'} ne ''){
869 @temp = split(/\n/,$cgiparams{'ROUTES_PUSH'});
870 undef $vpnsettings{'ROUTES_PUSH'};
871
872 foreach my $tmpip (@temp)
873 {
874 s/^\s+//g; s/\s+$//g;
875
876 if ($tmpip)
877 {
878 $tmpip=~s/\s*$//g;
879 unless (&General::validipandmask($tmpip)) {
880 $errormessage = "$tmpip ".$Lang::tr{'ovpn errmsg invalid ip or mask'};
881 goto ADV_ERROR;
882 }
883 my ($ip, $cidr) = split("\/",&General::ipcidr2msk($tmpip));
884
885 if ($ip eq $netsettings{'GREEN_NETADDRESS'} && $cidr eq $netsettings{'GREEN_NETMASK'}) {
886 $errormessage = $Lang::tr{'ovpn errmsg green already pushed'};
887 goto ADV_ERROR;
888 }
889 # a.marx ccd
890 my %ccdroutehash=();
891 &General::readhasharray("${General::swroot}/ovpn/ccdroute", \%ccdroutehash);
892 foreach my $key (keys %ccdroutehash) {
893 foreach my $i (1 .. $#{$ccdroutehash{$key}}) {
894 if ( $ip."/".$cidr eq $ccdroutehash{$key}[$i] ){
895 $errormessage="Route $ip\/$cidr ".$Lang::tr{'ccd err inuse'}." $ccdroutehash{$key}[0]" ;
896 goto ADV_ERROR;
897 }
898 my ($ip2,$cidr2) = split(/\//,$ccdroutehash{$key}[$i]);
899 if (&General::IpInSubnet ($ip,$ip2,$cidr2)){
900 $errormessage="Route $ip\/$cidr ".$Lang::tr{'ccd err inuse'}." $ccdroutehash{$key}[0]" ;
901 goto ADV_ERROR;
902 }
903 }
904 }
905
906 # ccd end
907
908 $vpnsettings{'ROUTES_PUSH'} .= $tmpip."\n";
909 }
910 }
911 &write_routepushfile;
912 undef $vpnsettings{'ROUTES_PUSH'};
913 }
914 else {
915 undef $vpnsettings{'ROUTES_PUSH'};
916 &write_routepushfile;
917 }
918 if ((length($cgiparams{'MAX_CLIENTS'}) == 0) || (($cgiparams{'MAX_CLIENTS'}) < 1 ) || (($cgiparams{'MAX_CLIENTS'}) > 255 )) {
919 $errormessage = $Lang::tr{'invalid input for max clients'};
920 goto ADV_ERROR;
921 }
922 if ($cgiparams{'KEEPALIVE_1'} ne '') {
923 if ($cgiparams{'KEEPALIVE_1'} !~ /^[0-9]+$/) {
924 $errormessage = $Lang::tr{'invalid input for keepalive 1'};
925 goto ADV_ERROR;
926 }
927 }
928 if ($cgiparams{'KEEPALIVE_2'} ne ''){
929 if ($cgiparams{'KEEPALIVE_2'} !~ /^[0-9]+$/) {
930 $errormessage = $Lang::tr{'invalid input for keepalive 2'};
931 goto ADV_ERROR;
932 }
933 }
934 if ($cgiparams{'KEEPALIVE_2'} < ($cgiparams{'KEEPALIVE_1'} * 2)){
935 $errormessage = $Lang::tr{'invalid input for keepalive 1:2'};
936 goto ADV_ERROR;
937 }
938
939 &General::writehash("${General::swroot}/ovpn/settings", \%vpnsettings);
940 &writeserverconf();#hier ok
941 }
942
943 ###
944 # m.a.d net2net
945 ###
946
947 if ($cgiparams{'ACTION'} eq $Lang::tr{'save'} && $cgiparams{'TYPE'} eq 'net' && $cgiparams{'SIDE'} eq 'server')
948 {
949
950 my @remsubnet = split(/\//,$cgiparams{'REMOTE_SUBNET'});
951 my @ovsubnettemp = split(/\./,$cgiparams{'OVPN_SUBNET'});
952 my $ovsubnet = "$ovsubnettemp[0].$ovsubnettemp[1].$ovsubnettemp[2]";
953 my $tunmtu = '';
954
955 unless(-d "${General::swroot}/ovpn/n2nconf/"){mkdir "${General::swroot}/ovpn/n2nconf", 0755 or die "Unable to create dir $!";}
956 unless(-d "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}", 0770 or die "Unable to create dir $!";}
957
958 open(SERVERCONF, ">${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Unable to open ${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf: $!";
959
960 flock SERVERCONF, 2;
961 print SERVERCONF "# IPFire n2n Open VPN Server Config by ummeegge und m.a.d\n";
962 print SERVERCONF "\n";
963 print SERVERCONF "# User Security\n";
964 print SERVERCONF "user nobody\n";
965 print SERVERCONF "group nobody\n";
966 print SERVERCONF "persist-tun\n";
967 print SERVERCONF "persist-key\n";
968 print SERVERCONF "script-security 2\n";
969 print SERVERCONF "# IP/DNS for remote Server Gateway\n";
970
971 if ($cgiparams{'REMOTE'} ne '') {
972 print SERVERCONF "remote $cgiparams{'REMOTE'}\n";
973 }
974
975 print SERVERCONF "float\n";
976 print SERVERCONF "# IP adresses of the VPN Subnet\n";
977 print SERVERCONF "ifconfig $ovsubnet.1 $ovsubnet.2\n";
978 print SERVERCONF "# Client Gateway Network\n";
979 print SERVERCONF "route $remsubnet[0] $remsubnet[1]\n";
980 print SERVERCONF "# tun Device\n";
981 print SERVERCONF "dev tun\n";
982 print SERVERCONF "# Port and Protokol\n";
983 print SERVERCONF "port $cgiparams{'DEST_PORT'}\n";
984
985 if ($cgiparams{'PROTOCOL'} eq 'tcp') {
986 print SERVERCONF "proto tcp-server\n";
987 print SERVERCONF "# Packet size\n";
988 if ($cgiparams{'MTU'} eq '') {$tunmtu = '1400'} else {$tunmtu = $cgiparams{'MTU'}};
989 print SERVERCONF "tun-mtu $tunmtu\n";
990 }
991
992 if ($cgiparams{'PROTOCOL'} eq 'udp') {
993 print SERVERCONF "proto udp\n";
994 print SERVERCONF "# Paketsize\n";
995 if ($cgiparams{'MTU'} eq '') {$tunmtu = '1500'} else {$tunmtu = $cgiparams{'MTU'}};
996 print SERVERCONF "tun-mtu $tunmtu\n";
997 if ($cgiparams{'FRAGMENT'} ne '') {print SERVERCONF "fragment $cgiparams{'FRAGMENT'}\n";}
998 if ($cgiparams{'MSSFIX'} eq 'on') {print SERVERCONF "mssfix\n"; };
999 }
1000
1001 # Check if a valid operating mode has been choosen and use it.
1002 if (($cgiparams{'PMTU_DISCOVERY'} eq 'yes') ||
1003 ($cgiparams{'PMTU_DISCOVERY'} eq 'maybe') ||
1004 ($cgiparams{'PMTU_DISCOVERY'} eq 'no' )) {
1005 if(($cgiparams{'MSSFIX'} ne 'on') || ($cgiparams{'FRAGMENT'} eq '')) {
1006 if($cgiparams{'MTU'} eq '1500') {
1007 print SERVERCONF "mtu-disc $cgiparams{'PMTU_DISCOVERY'}\n";
1008 }
1009 }
1010 }
1011 print SERVERCONF "# Auth. Server\n";
1012 print SERVERCONF "tls-server\n";
1013 print SERVERCONF "ca ${General::swroot}/ovpn/ca/cacert.pem\n";
1014 print SERVERCONF "cert ${General::swroot}/ovpn/certs/servercert.pem\n";
1015 print SERVERCONF "key ${General::swroot}/ovpn/certs/serverkey.pem\n";
1016 print SERVERCONF "dh ${General::swroot}/ovpn/ca/dh1024.pem\n";
1017 print SERVERCONF "# Cipher\n";
1018 print SERVERCONF "cipher AES-256-CBC\n";
1019 if ($cgiparams{'COMPLZO'} eq 'on') {
1020 print SERVERCONF "# Enable Compression\n";
1021 print SERVERCONF "comp-lzo\r\n";
1022 }
1023 print SERVERCONF "# Debug Level\n";
1024 print SERVERCONF "verb 3\n";
1025 print SERVERCONF "# Tunnel check\n";
1026 print SERVERCONF "keepalive 10 60\n";
1027 print SERVERCONF "# Start as daemon\n";
1028 print SERVERCONF "daemon $cgiparams{'NAME'}n2n\n";
1029 print SERVERCONF "writepid /var/run/$cgiparams{'NAME'}n2n.pid\n";
1030 print SERVERCONF "# Activate Management Interface and Port\n";
1031 if ($cgiparams{'OVPN_MGMT'} eq '') {print SERVERCONF "management localhost $cgiparams{'DEST_PORT'}\n"}
1032 else {print SERVERCONF "management localhost $cgiparams{'OVPN_MGMT'}\n"};
1033 close(SERVERCONF);
1034
1035 }
1036
1037 ###
1038 # m.a.d net2net
1039 ###
1040
1041 if ($cgiparams{'ACTION'} eq $Lang::tr{'save'} && $cgiparams{'TYPE'} eq 'net' && $cgiparams{'SIDE'} eq 'client')
1042 {
1043 my @ovsubnettemp = split(/\./,$cgiparams{'OVPN_SUBNET'});
1044 my $ovsubnet = "$ovsubnettemp[0].$ovsubnettemp[1].$ovsubnettemp[2]";
1045 my @remsubnet = split(/\//,$cgiparams{'REMOTE_SUBNET'});
1046 my $tunmtu = '';
1047
1048 unless(-d "${General::swroot}/ovpn/n2nconf/"){mkdir "${General::swroot}/ovpn/n2nconf", 0755 or die "Unable to create dir $!";}
1049 unless(-d "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}", 0770 or die "Unable to create dir $!";}
1050
1051 open(CLIENTCONF, ">${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Unable to open ${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf: $!";
1052
1053 flock CLIENTCONF, 2;
1054 print CLIENTCONF "# IPFire rewritten n2n Open VPN Client Config by ummeegge und m.a.d\n";
1055 print CLIENTCONF "#\n";
1056 print CLIENTCONF "# User Security\n";
1057 print CLIENTCONF "user nobody\n";
1058 print CLIENTCONF "group nobody\n";
1059 print CLIENTCONF "persist-tun\n";
1060 print CLIENTCONF "persist-key\n";
1061 print CLIENTCONF "script-security 2\n";
1062 print CLIENTCONF "# IP/DNS for remote Server Gateway\n";
1063 print CLIENTCONF "remote $cgiparams{'REMOTE'}\n";
1064 print CLIENTCONF "float\n";
1065 print CLIENTCONF "# IP adresses of the VPN Subnet\n";
1066 print CLIENTCONF "ifconfig $ovsubnet.2 $ovsubnet.1\n";
1067 print CLIENTCONF "# Server Gateway Network\n";
1068 print CLIENTCONF "route $remsubnet[0] $remsubnet[1]\n";
1069 print CLIENTCONF "# tun Device\n";
1070 print CLIENTCONF "dev tun\n";
1071 print CLIENTCONF "# Port and Protokol\n";
1072 print CLIENTCONF "port $cgiparams{'DEST_PORT'}\n";
1073
1074 if ($cgiparams{'PROTOCOL'} eq 'tcp') {
1075 print CLIENTCONF "proto tcp-client\n";
1076 print CLIENTCONF "# Packet size\n";
1077 if ($cgiparams{'MTU'} eq '') {$tunmtu = '1400'} else {$tunmtu = $cgiparams{'MTU'}};
1078 print CLIENTCONF "tun-mtu $tunmtu\n";
1079 }
1080
1081 if ($cgiparams{'PROTOCOL'} eq 'udp') {
1082 print CLIENTCONF "proto udp\n";
1083 print CLIENTCONF "# Paketsize\n";
1084 if ($cgiparams{'MTU'} eq '') {$tunmtu = '1500'} else {$tunmtu = $cgiparams{'MTU'}};
1085 print CLIENTCONF "tun-mtu $tunmtu\n";
1086 if ($cgiparams{'FRAGMENT'} ne '') {print CLIENTCONF "fragment $cgiparams{'FRAGMENT'}\n";}
1087 if ($cgiparams{'MSSFIX'} eq 'on') {print CLIENTCONF "mssfix\n"; };
1088 }
1089
1090 # Check if a valid operating mode has been choosen and use it.
1091 if (($cgiparams{'PMTU_DISCOVERY'} eq 'yes') ||
1092 ($cgiparams{'PMTU_DISCOVERY'} eq 'maybe') ||
1093 ($cgiparams{'PMTU_DISCOVERY'} eq 'no' )) {
1094 if(($cgiparams{'MSSFIX'} ne 'on') || ($cgiparams{'FRAGMENT'} eq '')) {
1095 if ($cgiparams{'MTU'} eq '1500') {
1096 print CLIENTCONF "mtu-disc $cgiparams{'PMTU_DISCOVERY'}\n";
1097 }
1098 }
1099 }
1100
1101 print CLIENTCONF "ns-cert-type server\n";
1102 print CLIENTCONF "# Auth. Client\n";
1103 print CLIENTCONF "tls-client\n";
1104 print CLIENTCONF "# Cipher\n";
1105 print CLIENTCONF "cipher AES-256-CBC\n";
1106 print CLIENTCONF "pkcs12 ${General::swroot}/ovpn/certs/$cgiparams{'NAME'}.p12\r\n";
1107 if ($cgiparams{'COMPLZO'} eq 'on') {
1108 print CLIENTCONF "# Enable Compression\n";
1109 print CLIENTCONF "comp-lzo\r\n";
1110 }
1111 print CLIENTCONF "# Debug Level\n";
1112 print CLIENTCONF "verb 3\n";
1113 print CLIENTCONF "# Tunnel check\n";
1114 print CLIENTCONF "keepalive 10 60\n";
1115 print CLIENTCONF "# Start as daemon\n";
1116 print CLIENTCONF "daemon $cgiparams{'NAME'}n2n\n";
1117 print CLIENTCONF "writepid /var/run/$cgiparams{'NAME'}n2n.pid\n";
1118 print CLIENTCONF "# Activate Management Interface and Port\n";
1119 if ($cgiparams{'OVPN_MGMT'} eq '') {print CLIENTCONF "management localhost $cgiparams{'DEST_PORT'}\n"}
1120 else {print CLIENTCONF "management localhost $cgiparams{'OVPN_MGMT'}\n"};
1121 close(CLIENTCONF);
1122
1123 }
1124
1125 ###
1126 ### Save main settings
1127 ###
1128
1129
1130 if ($cgiparams{'ACTION'} eq $Lang::tr{'save'} && $cgiparams{'TYPE'} eq '' && $cgiparams{'KEY'} eq '') {
1131 &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings);
1132 #DAN do we really need (to to check) this value? Besides if we listen on blue and orange too,
1133 #DAN this value has to leave.
1134 if ($cgiparams{'ENABLED'} eq 'on'){
1135 unless (&General::validfqdn($cgiparams{'VPN_IP'}) || &General::validip($cgiparams{'VPN_IP'})) {
1136 $errormessage = $Lang::tr{'invalid input for hostname'};
1137 goto SETTINGS_ERROR;
1138 }
1139 }
1140 if ($cgiparams{'ENABLED'} eq 'on'){
1141 &disallowreserved($cgiparams{'DDEST_PORT'},0,$cgiparams{'DPROTOCOL'},"dest");
1142 }
1143 if ($errormessage) { goto SETTINGS_ERROR; }
1144
1145
1146 if ($cgiparams{'ENABLED'} eq 'on'){
1147 &checkportfw(0,$cgiparams{'DDEST_PORT'},$cgiparams{'DPROTOCOL'},'0.0.0.0');
1148 }
1149
1150 if ($errormessage) { goto SETTINGS_ERROR; }
1151
1152 if (! &General::validipandmask($cgiparams{'DOVPN_SUBNET'})) {
1153 $errormessage = $Lang::tr{'ovpn subnet is invalid'};
1154 goto SETTINGS_ERROR;
1155 }
1156 my @tmpovpnsubnet = split("\/",$cgiparams{'DOVPN_SUBNET'});
1157
1158 if (&General::IpInSubnet ( $netsettings{'RED_ADDRESS'},
1159 $tmpovpnsubnet[0], $tmpovpnsubnet[1])) {
1160 $errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire RED Network $netsettings{'RED_ADDRESS'}";
1161 goto SETTINGS_ERROR;
1162 }
1163
1164 if (&General::IpInSubnet ( $netsettings{'GREEN_ADDRESS'},
1165 $tmpovpnsubnet[0], $tmpovpnsubnet[1])) {
1166 $errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire Green Network $netsettings{'GREEN_ADDRESS'}";
1167 goto SETTINGS_ERROR;
1168 }
1169
1170 if (&General::IpInSubnet ( $netsettings{'BLUE_ADDRESS'},
1171 $tmpovpnsubnet[0], $tmpovpnsubnet[1])) {
1172 $errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire Blue Network $netsettings{'BLUE_ADDRESS'}";
1173 goto SETTINGS_ERROR;
1174 }
1175
1176 if (&General::IpInSubnet ( $netsettings{'ORANGE_ADDRESS'},
1177 $tmpovpnsubnet[0], $tmpovpnsubnet[1])) {
1178 $errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire Orange Network $netsettings{'ORANGE_ADDRESS'}";
1179 goto SETTINGS_ERROR;
1180 }
1181 open(ALIASES, "${General::swroot}/ethernet/aliases") or die 'Unable to open aliases file.';
1182 while (<ALIASES>)
1183 {
1184 chomp($_);
1185 my @tempalias = split(/\,/,$_);
1186 if ($tempalias[1] eq 'on') {
1187 if (&General::IpInSubnet ($tempalias[0] ,
1188 $tmpovpnsubnet[0], $tmpovpnsubnet[1])) {
1189 $errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire alias entry $tempalias[0]";
1190 }
1191 }
1192 }
1193 close(ALIASES);
1194 if ($errormessage ne ''){
1195 goto SETTINGS_ERROR;
1196 }
1197 if ($cgiparams{'ENABLED'} !~ /^(on|off)$/) {
1198 $errormessage = $Lang::tr{'invalid input'};
1199 goto SETTINGS_ERROR;
1200 }
1201 if ((length($cgiparams{'DMTU'})==0) || (($cgiparams{'DMTU'}) < 1000 )) {
1202 $errormessage = $Lang::tr{'invalid mtu input'};
1203 goto SETTINGS_ERROR;
1204 }
1205
1206 unless (&General::validport($cgiparams{'DDEST_PORT'})) {
1207 $errormessage = $Lang::tr{'invalid port'};
1208 goto SETTINGS_ERROR;
1209 }
1210 $vpnsettings{'ENABLED_BLUE'} = $cgiparams{'ENABLED_BLUE'};
1211 $vpnsettings{'ENABLED_ORANGE'} =$cgiparams{'ENABLED_ORANGE'};
1212 $vpnsettings{'ENABLED'} = $cgiparams{'ENABLED'};
1213 $vpnsettings{'VPN_IP'} = $cgiparams{'VPN_IP'};
1214 #new settings for daemon
1215 $vpnsettings{'DOVPN_SUBNET'} = $cgiparams{'DOVPN_SUBNET'};
1216 $vpnsettings{'DDEVICE'} = $cgiparams{'DDEVICE'};
1217 $vpnsettings{'DPROTOCOL'} = $cgiparams{'DPROTOCOL'};
1218 $vpnsettings{'DDEST_PORT'} = $cgiparams{'DDEST_PORT'};
1219 $vpnsettings{'DMTU'} = $cgiparams{'DMTU'};
1220 $vpnsettings{'DCOMPLZO'} = $cgiparams{'DCOMPLZO'};
1221 $vpnsettings{'DCIPHER'} = $cgiparams{'DCIPHER'};
1222 #wrtie enable
1223
1224 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");}
1225 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");}
1226 if ( $vpnsettings{'ENABLED'} eq 'on' ) {system("touch ${General::swroot}/ovpn/enable 2>/dev/null");}else{system("unlink ${General::swroot}/ovpn/enable 2>/dev/null");}
1227 #new settings for daemon
1228 &General::writehash("${General::swroot}/ovpn/settings", \%vpnsettings);
1229 &writeserverconf();#hier ok
1230 SETTINGS_ERROR:
1231 ###
1232 ### Reset all step 2
1233 ###
1234 }elsif ($cgiparams{'ACTION'} eq $Lang::tr{'reset'} && $cgiparams{'AREUSURE'} eq 'yes') {
1235 my $file = '';
1236 &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
1237
1238 foreach my $key (keys %confighash) {
1239 if ($confighash{$key}[4] eq 'cert') {
1240 delete $confighash{$cgiparams{'$key'}};
1241 }
1242 }
1243 while ($file = glob("${General::swroot}/ovpn/ca/*")) {
1244 unlink $file
1245 }
1246 while ($file = glob("${General::swroot}/ovpn/certs/*")) {
1247 unlink $file
1248 }
1249 while ($file = glob("${General::swroot}/ovpn/crls/*")) {
1250 unlink $file
1251 }
1252 &cleanssldatabase();
1253 if (open(FILE, ">${General::swroot}/ovpn/caconfig")) {
1254 print FILE "";
1255 close FILE;
1256 }
1257 &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
1258 #&writeserverconf();
1259 ###
1260 ### Reset all step 1
1261 ###
1262 }elsif ($cgiparams{'ACTION'} eq $Lang::tr{'reset'}) {
1263 &Header::showhttpheaders();
1264 &Header::openpage($Lang::tr{'vpn configuration main'}, 1, '');
1265 &Header::openbigbox('100%', 'LEFT', '', '');
1266 &Header::openbox('100%', 'LEFT', $Lang::tr{'are you sure'});
1267 print <<END
1268 <table><form method='post'><input type='hidden' name='AREUSURE' value='yes' />
1269 <tr><td align='center'>
1270 <b><font color='${Header::colourred}'>$Lang::tr{'capswarning'}</font></b>:
1271 $Lang::tr{'resetting the vpn configuration will remove the root ca, the host certificate and all certificate based connections'}
1272 <tr><td align='center'><input type='submit' name='ACTION' value='$Lang::tr{'reset'}' />
1273 <input type='submit' name='ACTION' value='$Lang::tr{'cancel'}' /></td></tr>
1274 </form></table>
1275 END
1276 ;
1277 &Header::closebox();
1278 &Header::closebigbox();
1279 &Header::closepage();
1280 exit (0);
1281
1282 ###
1283 ### Upload CA Certificate
1284 ###
1285 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'upload ca certificate'}) {
1286 &General::readhasharray("${General::swroot}/ovpn/caconfig", \%cahash);
1287
1288 if ($cgiparams{'CA_NAME'} !~ /^[a-zA-Z0-9]+$/) {
1289 $errormessage = $Lang::tr{'name must only contain characters'};
1290 goto UPLOADCA_ERROR;
1291 }
1292
1293 if (length($cgiparams{'CA_NAME'}) >60) {
1294 $errormessage = $Lang::tr{'name too long'};
1295 goto VPNCONF_ERROR;
1296 }
1297
1298 if ($cgiparams{'CA_NAME'} eq 'ca') {
1299 $errormessage = $Lang::tr{'name is invalid'};
1300 goto UPLOAD_CA_ERROR;
1301 }
1302
1303 # Check if there is no other entry with this name
1304 foreach my $key (keys %cahash) {
1305 if ($cahash{$key}[0] eq $cgiparams{'CA_NAME'}) {
1306 $errormessage = $Lang::tr{'a ca certificate with this name already exists'};
1307 goto UPLOADCA_ERROR;
1308 }
1309 }
1310
1311 if (ref ($cgiparams{'FH'}) ne 'Fh') {
1312 $errormessage = $Lang::tr{'there was no file upload'};
1313 goto UPLOADCA_ERROR;
1314 }
1315 # Move uploaded ca to a temporary file
1316 (my $fh, my $filename) = tempfile( );
1317 if (copy ($cgiparams{'FH'}, $fh) != 1) {
1318 $errormessage = $!;
1319 goto UPLOADCA_ERROR;
1320 }
1321 my $temp = `/usr/bin/openssl x509 -text -in $filename`;
1322 if ($temp !~ /CA:TRUE/i) {
1323 $errormessage = $Lang::tr{'not a valid ca certificate'};
1324 unlink ($filename);
1325 goto UPLOADCA_ERROR;
1326 } else {
1327 move($filename, "${General::swroot}/ovpn/ca/$cgiparams{'CA_NAME'}cert.pem");
1328 if ($? ne 0) {
1329 $errormessage = "$Lang::tr{'certificate file move failed'}: $!";
1330 unlink ($filename);
1331 goto UPLOADCA_ERROR;
1332 }
1333 }
1334
1335 my $casubject = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/ca/$cgiparams{'CA_NAME'}cert.pem`;
1336 $casubject =~ /Subject: (.*)[\n]/;
1337 $casubject = $1;
1338 $casubject =~ s+/Email+, E+;
1339 $casubject =~ s/ ST=/ S=/;
1340 $casubject = &Header::cleanhtml($casubject);
1341
1342 my $key = &General::findhasharraykey (\%cahash);
1343 $cahash{$key}[0] = $cgiparams{'CA_NAME'};
1344 $cahash{$key}[1] = $casubject;
1345 &General::writehasharray("${General::swroot}/ovpn/caconfig", \%cahash);
1346 # system('/usr/local/bin/ipsecctrl', 'R');
1347
1348 UPLOADCA_ERROR:
1349
1350 ###
1351 ### Display ca certificate
1352 ###
1353 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'show ca certificate'}) {
1354 &General::readhasharray("${General::swroot}/ovpn/caconfig", \%cahash);
1355
1356 if ( -f "${General::swroot}/ovpn/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem") {
1357 &Header::showhttpheaders();
1358 &Header::openpage($Lang::tr{'vpn configuration main'}, 1, '');
1359 &Header::openbigbox('100%', 'LEFT', '', $errormessage);
1360 &Header::openbox('100%', 'LEFT', "$Lang::tr{'ca certificate'}:");
1361 my $output = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem`;
1362 $output = &Header::cleanhtml($output,"y");
1363 print "<pre>$output</pre>\n";
1364 &Header::closebox();
1365 print "<div align='center'><a href='/cgi-bin/ovpnmain.cgi'>$Lang::tr{'back'}</a></div>";
1366 &Header::closebigbox();
1367 &Header::closepage();
1368 exit(0);
1369 } else {
1370 $errormessage = $Lang::tr{'invalid key'};
1371 }
1372
1373 ###
1374 ### Download ca certificate
1375 ###
1376 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'download ca certificate'}) {
1377 &General::readhasharray("${General::swroot}/ovpn/caconfig", \%cahash);
1378
1379 if ( -f "${General::swroot}/ovpn/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem" ) {
1380 print "Content-Type: application/octet-stream\r\n";
1381 print "Content-Disposition: filename=$cahash{$cgiparams{'KEY'}}[0]cert.pem\r\n\r\n";
1382 print `/usr/bin/openssl x509 -in ${General::swroot}/ovpn/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem`;
1383 exit(0);
1384 } else {
1385 $errormessage = $Lang::tr{'invalid key'};
1386 }
1387
1388 ###
1389 ### Remove ca certificate (step 2)
1390 ###
1391 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'remove ca certificate'} && $cgiparams{'AREUSURE'} eq 'yes') {
1392 &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
1393 &General::readhasharray("${General::swroot}/ovpn/caconfig", \%cahash);
1394
1395 if ( -f "${General::swroot}/ovpn/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem" ) {
1396 foreach my $key (keys %confighash) {
1397 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`;
1398 if ($test =~ /: OK/) {
1399 # Delete connection
1400 # if ($vpnsettings{'ENABLED'} eq 'on' ||
1401 # $vpnsettings{'ENABLED_BLUE'} eq 'on') {
1402 # system('/usr/local/bin/ipsecctrl', 'D', $key);
1403 # }
1404 unlink ("${General::swroot}/ovpn//certs/$confighash{$key}[1]cert.pem");
1405 unlink ("${General::swroot}/ovpn/certs/$confighash{$key}[1].p12");
1406 delete $confighash{$key};
1407 &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
1408 # &writeipsecfiles();
1409 }
1410 }
1411 unlink ("${General::swroot}/ovpn/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem");
1412 delete $cahash{$cgiparams{'KEY'}};
1413 &General::writehasharray("${General::swroot}/ovpn/caconfig", \%cahash);
1414 # system('/usr/local/bin/ipsecctrl', 'R');
1415 } else {
1416 $errormessage = $Lang::tr{'invalid key'};
1417 }
1418 ###
1419 ### Remove ca certificate (step 1)
1420 ###
1421 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'remove ca certificate'}) {
1422 &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
1423 &General::readhasharray("${General::swroot}/ovpn/caconfig", \%cahash);
1424
1425 my $assignedcerts = 0;
1426 if ( -f "${General::swroot}/ovpn/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem" ) {
1427 foreach my $key (keys %confighash) {
1428 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`;
1429 if ($test =~ /: OK/) {
1430 $assignedcerts++;
1431 }
1432 }
1433 if ($assignedcerts) {
1434 &Header::showhttpheaders();
1435 &Header::openpage($Lang::tr{'vpn configuration main'}, 1, '');
1436 &Header::openbigbox('100%', 'LEFT', '', $errormessage);
1437 &Header::openbox('100%', 'LEFT', $Lang::tr{'are you sure'});
1438 print <<END
1439 <table><form method='post'><input type='hidden' name='AREUSURE' value='yes' />
1440 <input type='hidden' name='KEY' value='$cgiparams{'KEY'}' />
1441 <tr><td align='center'>
1442 <b><font color='${Header::colourred}'>$Lang::tr{'capswarning'}</font></b>: $assignedcerts
1443 $Lang::tr{'connections are associated with this ca. deleting the ca will delete these connections as well.'}
1444 <tr><td align='center'><input type='submit' name='ACTION' value='$Lang::tr{'remove ca certificate'}' />
1445 <input type='submit' name='ACTION' value='$Lang::tr{'cancel'}' /></td></tr>
1446 </form></table>
1447 END
1448 ;
1449 &Header::closebox();
1450 &Header::closebigbox();
1451 &Header::closepage();
1452 exit (0);
1453 } else {
1454 unlink ("${General::swroot}/ovpn/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem");
1455 delete $cahash{$cgiparams{'KEY'}};
1456 &General::writehasharray("${General::swroot}/ovpn/caconfig", \%cahash);
1457 # system('/usr/local/bin/ipsecctrl', 'R');
1458 }
1459 } else {
1460 $errormessage = $Lang::tr{'invalid key'};
1461 }
1462
1463 ###
1464 ### Display root certificate
1465 ###
1466 }elsif ($cgiparams{'ACTION'} eq $Lang::tr{'show root certificate'} ||
1467 $cgiparams{'ACTION'} eq $Lang::tr{'show host certificate'}) {
1468 my $output;
1469 &Header::showhttpheaders();
1470 &Header::openpage($Lang::tr{'vpn configuration main'}, 1, '');
1471 &Header::openbigbox('100%', 'LEFT', '', '');
1472 if ($cgiparams{'ACTION'} eq $Lang::tr{'show root certificate'}) {
1473 &Header::openbox('100%', 'LEFT', "$Lang::tr{'root certificate'}:");
1474 $output = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/ca/cacert.pem`;
1475 } else {
1476 &Header::openbox('100%', 'LEFT', "$Lang::tr{'host certificate'}:");
1477 $output = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/certs/servercert.pem`;
1478 }
1479 $output = &Header::cleanhtml($output,"y");
1480 print "<pre>$output</pre>\n";
1481 &Header::closebox();
1482 print "<div align='center'><a href='/cgi-bin/ovpnmain.cgi'>$Lang::tr{'back'}</a></div>";
1483 &Header::closebigbox();
1484 &Header::closepage();
1485 exit(0);
1486
1487 ###
1488 ### Download root certificate
1489 ###
1490 }elsif ($cgiparams{'ACTION'} eq $Lang::tr{'download root certificate'}) {
1491 if ( -f "${General::swroot}/ovpn/ca/cacert.pem" ) {
1492 print "Content-Type: application/octet-stream\r\n";
1493 print "Content-Disposition: filename=cacert.pem\r\n\r\n";
1494 print `/usr/bin/openssl x509 -in ${General::swroot}/ovpn/ca/cacert.pem`;
1495 exit(0);
1496 }
1497
1498 ###
1499 ### Download host certificate
1500 ###
1501 }elsif ($cgiparams{'ACTION'} eq $Lang::tr{'download host certificate'}) {
1502 if ( -f "${General::swroot}/ovpn/certs/servercert.pem" ) {
1503 print "Content-Type: application/octet-stream\r\n";
1504 print "Content-Disposition: filename=servercert.pem\r\n\r\n";
1505 print `/usr/bin/openssl x509 -in ${General::swroot}/ovpn/certs/servercert.pem`;
1506 exit(0);
1507 }
1508 ###
1509 ### Form for generating a root certificate
1510 ###
1511 }elsif ($cgiparams{'ACTION'} eq $Lang::tr{'generate root/host certificates'} ||
1512 $cgiparams{'ACTION'} eq $Lang::tr{'upload p12 file'}) {
1513
1514 &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings);
1515 if (-f "${General::swroot}/ovpn/ca/cacert.pem") {
1516 $errormessage = $Lang::tr{'valid root certificate already exists'};
1517 $cgiparams{'ACTION'} = '';
1518 goto ROOTCERT_ERROR;
1519 }
1520
1521 if (($cgiparams{'ROOTCERT_HOSTNAME'} eq '') && -e "${General::swroot}/red/active") {
1522 if (open(IPADDR, "${General::swroot}/red/local-ipaddress")) {
1523 my $ipaddr = <IPADDR>;
1524 close IPADDR;
1525 chomp ($ipaddr);
1526 $cgiparams{'ROOTCERT_HOSTNAME'} = (gethostbyaddr(pack("C4", split(/\./, $ipaddr)), 2))[0];
1527 if ($cgiparams{'ROOTCERT_HOSTNAME'} eq '') {
1528 $cgiparams{'ROOTCERT_HOSTNAME'} = $ipaddr;
1529 }
1530 }
1531 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'upload p12 file'}) {
1532
1533 if (ref ($cgiparams{'FH'}) ne 'Fh') {
1534 $errormessage = $Lang::tr{'there was no file upload'};
1535 goto ROOTCERT_ERROR;
1536 }
1537
1538 # Move uploaded certificate request to a temporary file
1539 (my $fh, my $filename) = tempfile( );
1540 if (copy ($cgiparams{'FH'}, $fh) != 1) {
1541 $errormessage = $!;
1542 goto ROOTCERT_ERROR;
1543 }
1544
1545 # Create a temporary dirctory
1546 my $tempdir = tempdir( CLEANUP => 1 );
1547
1548 # Extract the CA certificate from the file
1549 my $pid = open(OPENSSL, "|-");
1550 $SIG{ALRM} = sub { $errormessage = $Lang::tr{'broken pipe'}; goto ROOTCERT_ERROR;};
1551 if ($pid) { # parent
1552 if ($cgiparams{'P12_PASS'} ne '') {
1553 print OPENSSL "$cgiparams{'P12_PASS'}\n";
1554 }
1555 close (OPENSSL);
1556 if ($?) {
1557 $errormessage = "$Lang::tr{'openssl produced an error'}: $?";
1558 unlink ($filename);
1559 goto ROOTCERT_ERROR;
1560 }
1561 } else { # child
1562 unless (exec ('/usr/bin/openssl', 'pkcs12', '-cacerts', '-nokeys',
1563 '-in', $filename,
1564 '-out', "$tempdir/cacert.pem")) {
1565 $errormessage = "$Lang::tr{'cant start openssl'}: $!";
1566 unlink ($filename);
1567 goto ROOTCERT_ERROR;
1568 }
1569 }
1570
1571 # Extract the Host certificate from the file
1572 $pid = open(OPENSSL, "|-");
1573 $SIG{ALRM} = sub { $errormessage = $Lang::tr{'broken pipe'}; goto ROOTCERT_ERROR;};
1574 if ($pid) { # parent
1575 if ($cgiparams{'P12_PASS'} ne '') {
1576 print OPENSSL "$cgiparams{'P12_PASS'}\n";
1577 }
1578 close (OPENSSL);
1579 if ($?) {
1580 $errormessage = "$Lang::tr{'openssl produced an error'}: $?";
1581 unlink ($filename);
1582 goto ROOTCERT_ERROR;
1583 }
1584 } else { # child
1585 unless (exec ('/usr/bin/openssl', 'pkcs12', '-clcerts', '-nokeys',
1586 '-in', $filename,
1587 '-out', "$tempdir/hostcert.pem")) {
1588 $errormessage = "$Lang::tr{'cant start openssl'}: $!";
1589 unlink ($filename);
1590 goto ROOTCERT_ERROR;
1591 }
1592 }
1593
1594 # Extract the Host key from the file
1595 $pid = open(OPENSSL, "|-");
1596 $SIG{ALRM} = sub { $errormessage = $Lang::tr{'broken pipe'}; goto ROOTCERT_ERROR;};
1597 if ($pid) { # parent
1598 if ($cgiparams{'P12_PASS'} ne '') {
1599 print OPENSSL "$cgiparams{'P12_PASS'}\n";
1600 }
1601 close (OPENSSL);
1602 if ($?) {
1603 $errormessage = "$Lang::tr{'openssl produced an error'}: $?";
1604 unlink ($filename);
1605 goto ROOTCERT_ERROR;
1606 }
1607 } else { # child
1608 unless (exec ('/usr/bin/openssl', 'pkcs12', '-nocerts',
1609 '-nodes',
1610 '-in', $filename,
1611 '-out', "$tempdir/serverkey.pem")) {
1612 $errormessage = "$Lang::tr{'cant start openssl'}: $!";
1613 unlink ($filename);
1614 goto ROOTCERT_ERROR;
1615 }
1616 }
1617
1618 move("$tempdir/cacert.pem", "${General::swroot}/ovpn/ca/cacert.pem");
1619 if ($? ne 0) {
1620 $errormessage = "$Lang::tr{'certificate file move failed'}: $!";
1621 unlink ($filename);
1622 unlink ("${General::swroot}/ovpn/ca/cacert.pem");
1623 unlink ("${General::swroot}/ovpn/certs/servercert.pem");
1624 unlink ("${General::swroot}/ovpn/certs/serverkey.pem");
1625 goto ROOTCERT_ERROR;
1626 }
1627
1628 move("$tempdir/hostcert.pem", "${General::swroot}/ovpn/certs/servercert.pem");
1629 if ($? ne 0) {
1630 $errormessage = "$Lang::tr{'certificate file move failed'}: $!";
1631 unlink ($filename);
1632 unlink ("${General::swroot}/ovpn/ca/cacert.pem");
1633 unlink ("${General::swroot}/ovpn/certs/servercert.pem");
1634 unlink ("${General::swroot}/ovpn/certs/serverkey.pem");
1635 goto ROOTCERT_ERROR;
1636 }
1637
1638 move("$tempdir/serverkey.pem", "${General::swroot}/ovpn/certs/serverkey.pem");
1639 if ($? ne 0) {
1640 $errormessage = "$Lang::tr{'certificate file move failed'}: $!";
1641 unlink ($filename);
1642 unlink ("${General::swroot}/ovpn/ca/cacert.pem");
1643 unlink ("${General::swroot}/ovpn/certs/servercert.pem");
1644 unlink ("${General::swroot}/ovpn/certs/serverkey.pem");
1645 goto ROOTCERT_ERROR;
1646 }
1647
1648 goto ROOTCERT_SUCCESS;
1649
1650 } elsif ($cgiparams{'ROOTCERT_COUNTRY'} ne '') {
1651
1652 # Validate input since the form was submitted
1653 if ($cgiparams{'ROOTCERT_ORGANIZATION'} eq ''){
1654 $errormessage = $Lang::tr{'organization cant be empty'};
1655 goto ROOTCERT_ERROR;
1656 }
1657 if (length($cgiparams{'ROOTCERT_ORGANIZATION'}) >60) {
1658 $errormessage = $Lang::tr{'organization too long'};
1659 goto ROOTCERT_ERROR;
1660 }
1661 if ($cgiparams{'ROOTCERT_ORGANIZATION'} !~ /^[a-zA-Z0-9 ,\.\-_]*$/) {
1662 $errormessage = $Lang::tr{'invalid input for organization'};
1663 goto ROOTCERT_ERROR;
1664 }
1665 if ($cgiparams{'ROOTCERT_HOSTNAME'} eq ''){
1666 $errormessage = $Lang::tr{'hostname cant be empty'};
1667 goto ROOTCERT_ERROR;
1668 }
1669 unless (&General::validfqdn($cgiparams{'ROOTCERT_HOSTNAME'}) || &General::validip($cgiparams{'ROOTCERT_HOSTNAME'})) {
1670 $errormessage = $Lang::tr{'invalid input for hostname'};
1671 goto ROOTCERT_ERROR;
1672 }
1673 if ($cgiparams{'ROOTCERT_EMAIL'} ne '' && (! &General::validemail($cgiparams{'ROOTCERT_EMAIL'}))) {
1674 $errormessage = $Lang::tr{'invalid input for e-mail address'};
1675 goto ROOTCERT_ERROR;
1676 }
1677 if (length($cgiparams{'ROOTCERT_EMAIL'}) > 40) {
1678 $errormessage = $Lang::tr{'e-mail address too long'};
1679 goto ROOTCERT_ERROR;
1680 }
1681 if ($cgiparams{'ROOTCERT_OU'} ne '' && $cgiparams{'ROOTCERT_OU'} !~ /^[a-zA-Z0-9 ,\.\-_]*$/) {
1682 $errormessage = $Lang::tr{'invalid input for department'};
1683 goto ROOTCERT_ERROR;
1684 }
1685 if ($cgiparams{'ROOTCERT_CITY'} ne '' && $cgiparams{'ROOTCERT_CITY'} !~ /^[a-zA-Z0-9 ,\.\-_]*$/) {
1686 $errormessage = $Lang::tr{'invalid input for city'};
1687 goto ROOTCERT_ERROR;
1688 }
1689 if ($cgiparams{'ROOTCERT_STATE'} ne '' && $cgiparams{'ROOTCERT_STATE'} !~ /^[a-zA-Z0-9 ,\.\-_]*$/) {
1690 $errormessage = $Lang::tr{'invalid input for state or province'};
1691 goto ROOTCERT_ERROR;
1692 }
1693 if ($cgiparams{'ROOTCERT_COUNTRY'} !~ /^[A-Z]*$/) {
1694 $errormessage = $Lang::tr{'invalid input for country'};
1695 goto ROOTCERT_ERROR;
1696 }
1697
1698 # Copy the cgisettings to vpnsettings and save the configfile
1699 $vpnsettings{'ROOTCERT_ORGANIZATION'} = $cgiparams{'ROOTCERT_ORGANIZATION'};
1700 $vpnsettings{'ROOTCERT_HOSTNAME'} = $cgiparams{'ROOTCERT_HOSTNAME'};
1701 $vpnsettings{'ROOTCERT_EMAIL'} = $cgiparams{'ROOTCERT_EMAIL'};
1702 $vpnsettings{'ROOTCERT_OU'} = $cgiparams{'ROOTCERT_OU'};
1703 $vpnsettings{'ROOTCERT_CITY'} = $cgiparams{'ROOTCERT_CITY'};
1704 $vpnsettings{'ROOTCERT_STATE'} = $cgiparams{'ROOTCERT_STATE'};
1705 $vpnsettings{'ROOTCERT_COUNTRY'} = $cgiparams{'ROOTCERT_COUNTRY'};
1706 &General::writehash("${General::swroot}/ovpn/settings", \%vpnsettings);
1707
1708 # Replace empty strings with a .
1709 (my $ou = $cgiparams{'ROOTCERT_OU'}) =~ s/^\s*$/\./;
1710 (my $city = $cgiparams{'ROOTCERT_CITY'}) =~ s/^\s*$/\./;
1711 (my $state = $cgiparams{'ROOTCERT_STATE'}) =~ s/^\s*$/\./;
1712
1713 # refresh
1714 #system ('/bin/touch', "${General::swroot}/ovpn/gencanow");
1715
1716 # Create the CA certificate
1717 my $pid = open(OPENSSL, "|-");
1718 $SIG{ALRM} = sub { $errormessage = $Lang::tr{'broken pipe'}; goto ROOTCERT_ERROR;};
1719 if ($pid) { # parent
1720 print OPENSSL "$cgiparams{'ROOTCERT_COUNTRY'}\n";
1721 print OPENSSL "$state\n";
1722 print OPENSSL "$city\n";
1723 print OPENSSL "$cgiparams{'ROOTCERT_ORGANIZATION'}\n";
1724 print OPENSSL "$ou\n";
1725 print OPENSSL "$cgiparams{'ROOTCERT_ORGANIZATION'} CA\n";
1726 print OPENSSL "$cgiparams{'ROOTCERT_EMAIL'}\n";
1727 close (OPENSSL);
1728 if ($?) {
1729 $errormessage = "$Lang::tr{'openssl produced an error'}: $?";
1730 unlink ("${General::swroot}/ovpn/ca/cakey.pem");
1731 unlink ("${General::swroot}/ovpn/ca/cacert.pem");
1732 goto ROOTCERT_ERROR;
1733 }
1734 } else { # child
1735 unless (exec ('/usr/bin/openssl', 'req', '-x509', '-nodes', '-rand', '/proc/interrupts:/proc/net/rt_cache',
1736 '-days', '999999', '-newkey', 'rsa:2048',
1737 '-keyout', "${General::swroot}/ovpn/ca/cakey.pem",
1738 '-out', "${General::swroot}/ovpn/ca/cacert.pem",
1739 '-config',"${General::swroot}/ovpn/openssl/ovpn.cnf")) {
1740 $errormessage = "$Lang::tr{'cant start openssl'}: $!";
1741 goto ROOTCERT_ERROR;
1742 }
1743 }
1744
1745 # Create the Host certificate request
1746 $pid = open(OPENSSL, "|-");
1747 $SIG{ALRM} = sub { $errormessage = $Lang::tr{'broken pipe'}; goto ROOTCERT_ERROR;};
1748 if ($pid) { # parent
1749 print OPENSSL "$cgiparams{'ROOTCERT_COUNTRY'}\n";
1750 print OPENSSL "$state\n";
1751 print OPENSSL "$city\n";
1752 print OPENSSL "$cgiparams{'ROOTCERT_ORGANIZATION'}\n";
1753 print OPENSSL "$ou\n";
1754 print OPENSSL "$cgiparams{'ROOTCERT_HOSTNAME'}\n";
1755 print OPENSSL "$cgiparams{'ROOTCERT_EMAIL'}\n";
1756 print OPENSSL ".\n";
1757 print OPENSSL ".\n";
1758 close (OPENSSL);
1759 if ($?) {
1760 $errormessage = "$Lang::tr{'openssl produced an error'}: $?";
1761 unlink ("${General::swroot}/ovpn/certs/serverkey.pem");
1762 unlink ("${General::swroot}/ovpn/certs/serverreq.pem");
1763 goto ROOTCERT_ERROR;
1764 }
1765 } else { # child
1766 unless (exec ('/usr/bin/openssl', 'req', '-nodes', '-rand', '/proc/interrupts:/proc/net/rt_cache',
1767 '-newkey', 'rsa:1024',
1768 '-keyout', "${General::swroot}/ovpn/certs/serverkey.pem",
1769 '-out', "${General::swroot}/ovpn/certs/serverreq.pem",
1770 '-extensions', 'server',
1771 '-config', "${General::swroot}/ovpn/openssl/ovpn.cnf" )) {
1772 $errormessage = "$Lang::tr{'cant start openssl'}: $!";
1773 unlink ("${General::swroot}/ovpn/certs/serverkey.pem");
1774 unlink ("${General::swroot}/ovpn/certs/serverreq.pem");
1775 unlink ("${General::swroot}/ovpn/ca/cakey.pem");
1776 unlink ("${General::swroot}/ovpn/ca/cacert.pem");
1777 goto ROOTCERT_ERROR;
1778 }
1779 }
1780
1781 # Sign the host certificate request
1782 system('/usr/bin/openssl', 'ca', '-days', '999999',
1783 '-batch', '-notext',
1784 '-in', "${General::swroot}/ovpn/certs/serverreq.pem",
1785 '-out', "${General::swroot}/ovpn/certs/servercert.pem",
1786 '-extensions', 'server',
1787 '-config', "${General::swroot}/ovpn/openssl/ovpn.cnf");
1788 if ($?) {
1789 $errormessage = "$Lang::tr{'openssl produced an error'}: $?";
1790 unlink ("${General::swroot}/ovpn/ca/cakey.pem");
1791 unlink ("${General::swroot}/ovpn/ca/cacert.pem");
1792 unlink ("${General::swroot}/ovpn/serverkey.pem");
1793 unlink ("${General::swroot}/ovpn/certs/serverreq.pem");
1794 unlink ("${General::swroot}/ovpn/certs/servercert.pem");
1795 &newcleanssldatabase();
1796 goto ROOTCERT_ERROR;
1797 } else {
1798 unlink ("${General::swroot}/ovpn/certs/serverreq.pem");
1799 &deletebackupcert();
1800 }
1801
1802 # Create an empty CRL
1803 system('/usr/bin/openssl', 'ca', '-gencrl',
1804 '-out', "${General::swroot}/ovpn/crls/cacrl.pem",
1805 '-config', "${General::swroot}/ovpn/openssl/ovpn.cnf" );
1806 if ($?) {
1807 $errormessage = "$Lang::tr{'openssl produced an error'}: $?";
1808 unlink ("${General::swroot}/ovpn/certs/serverkey.pem");
1809 unlink ("${General::swroot}/ovpn/certs/servercert.pem");
1810 unlink ("${General::swroot}/ovpn/ca/cacert.pem");
1811 unlink ("${General::swroot}/ovpn/crls/cacrl.pem");
1812 &cleanssldatabase();
1813 goto ROOTCERT_ERROR;
1814 # } else {
1815 # &cleanssldatabase();
1816 }
1817 # Create Diffie Hellmann Parameter
1818 system('/usr/bin/openssl', 'dhparam', '-rand', '/proc/interrupts:/proc/net/rt_cache',
1819 '-out', "${General::swroot}/ovpn/ca/dh1024.pem",
1820 '1024' );
1821 if ($?) {
1822 $errormessage = "$Lang::tr{'openssl produced an error'}: $?";
1823 unlink ("${General::swroot}/ovpn/certs/serverkey.pem");
1824 unlink ("${General::swroot}/ovpn/certs/servercert.pem");
1825 unlink ("${General::swroot}/ovpn/ca/cacert.pem");
1826 unlink ("${General::swroot}/ovpn/crls/cacrl.pem");
1827 unlink ("${General::swroot}/ovpn/ca/dh1024.pem");
1828 &cleanssldatabase();
1829 goto ROOTCERT_ERROR;
1830 # } else {
1831 # &cleanssldatabase();
1832 }
1833 goto ROOTCERT_SUCCESS;
1834 }
1835 ROOTCERT_ERROR:
1836 if ($cgiparams{'ACTION'} ne '') {
1837 &Header::showhttpheaders();
1838 &Header::openpage($Lang::tr{'vpn configuration main'}, 1, '');
1839 &Header::openbigbox('100%', 'LEFT', '', '');
1840 if ($errormessage) {
1841 &Header::openbox('100%', 'LEFT', $Lang::tr{'error messages'});
1842 print "<class name='base'>$errormessage";
1843 print "&nbsp;</class>";
1844 &Header::closebox();
1845 }
1846 &Header::openbox('100%', 'LEFT', "$Lang::tr{'generate root/host certificates'}:");
1847 print <<END
1848 <form method='post' enctype='multipart/form-data'>
1849 <table width='100%' border='0' cellspacing='1' cellpadding='0'>
1850 <tr><td width='30%' class='base'>$Lang::tr{'organization name'}:</td>
1851 <td width='35%' class='base' nowrap='nowrap'><input type='text' name='ROOTCERT_ORGANIZATION' value='$cgiparams{'ROOTCERT_ORGANIZATION'}' size='32' /></td>
1852 <td width='35%' colspan='2'>&nbsp;</td></tr>
1853 <tr><td class='base'>$Lang::tr{'ipfires hostname'}:</td>
1854 <td class='base' nowrap='nowrap'><input type='text' name='ROOTCERT_HOSTNAME' value='$cgiparams{'ROOTCERT_HOSTNAME'}' size='32' /></td>
1855 <td colspan='2'>&nbsp;</td></tr>
1856 <tr><td class='base'>$Lang::tr{'your e-mail'}:&nbsp;<img src='/blob.gif' alt'*' /></td>
1857 <td class='base' nowrap='nowrap'><input type='text' name='ROOTCERT_EMAIL' value='$cgiparams{'ROOTCERT_EMAIL'}' size='32' /></td>
1858 <td colspan='2'>&nbsp;</td></tr>
1859 <tr><td class='base'>$Lang::tr{'your department'}:&nbsp;<img src='/blob.gif' alt'*' /></td>
1860 <td class='base' nowrap='nowrap'><input type='text' name='ROOTCERT_OU' value='$cgiparams{'ROOTCERT_OU'}' size='32' /></td>
1861 <td colspan='2'>&nbsp;</td></tr>
1862 <tr><td class='base'>$Lang::tr{'city'}:&nbsp;<img src='/blob.gif' alt'*' /></td>
1863 <td class='base' nowrap='nowrap'><input type='text' name='ROOTCERT_CITY' value='$cgiparams{'ROOTCERT_CITY'}' size='32' /></td>
1864 <td colspan='2'>&nbsp;</td></tr>
1865 <tr><td class='base'>$Lang::tr{'state or province'}:&nbsp;<img src='/blob.gif' alt'*' /></td>
1866 <td class='base' nowrap='nowrap'><input type='text' name='ROOTCERT_STATE' value='$cgiparams{'ROOTCERT_STATE'}' size='32' /></td>
1867 <td colspan='2'>&nbsp;</td></tr>
1868 <tr><td class='base'>$Lang::tr{'country'}:</td>
1869 <td class='base'><select name='ROOTCERT_COUNTRY'>
1870
1871 END
1872 ;
1873 foreach my $country (sort keys %{Countries::countries}) {
1874 print "<option value='$Countries::countries{$country}'";
1875 if ( $Countries::countries{$country} eq $cgiparams{'ROOTCERT_COUNTRY'} ) {
1876 print " selected='selected'";
1877 }
1878 print ">$country</option>";
1879 }
1880 print <<END
1881 </select></td>
1882 <td colspan='2'>&nbsp;</td></tr>
1883 <tr><td>&nbsp;</td>
1884 <td><input type='submit' name='ACTION' value='$Lang::tr{'generate root/host certificates'}' /></td>
1885 <td>&nbsp;</td><td>&nbsp;</td></tr>
1886 <tr><td class='base' colspan='4' align='left'>
1887 <img src='/blob.gif' valign='top' alt='*' />&nbsp;$Lang::tr{'this field may be blank'}</td></tr>
1888 <tr><td class='base' colspan='4' align='left'>
1889 <b><font color='${Header::colourred}'>$Lang::tr{'capswarning'}</font></b>:
1890 $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'}
1891 </td></tr>
1892 <tr><td colspan='4' bgcolor='#000000'><img src='/images/null.gif' width='1' height='1' border='0' /></td></tr>
1893 <tr><td class='base' nowrap='nowrap'>$Lang::tr{'upload p12 file'}:</td>
1894 <td nowrap='nowrap'><input type='file' name='FH' size='32'></td>
1895 <td colspan='2'>&nbsp;</td></tr>
1896 <tr><td class='base'>$Lang::tr{'pkcs12 file password'}:&nbsp;<img src='/blob.gif' alt='*' ></td>
1897 <td class='base' nowrap='nowrap'><input type='password' name='P12_PASS' value='$cgiparams{'P12_PASS'}' size='32' /></td>
1898 <td colspan='2'>&nbsp;</td></tr>
1899 <tr><td>&nbsp;</td>
1900 <td><input type='submit' name='ACTION' value='$Lang::tr{'upload p12 file'}' /></td>
1901 <td colspan='2'>&nbsp;</td></tr>
1902 <tr><td class='base' colspan='4' align='left'>
1903 <img src='/blob.gif' valign='top' al='*' >&nbsp;$Lang::tr{'this field may be blank'}</td></tr>
1904 </form></table>
1905 END
1906 ;
1907 &Header::closebox();
1908
1909 &Header::closebigbox();
1910 &Header::closepage();
1911 exit(0)
1912 }
1913
1914 ROOTCERT_SUCCESS:
1915 system ("chmod 600 ${General::swroot}/ovpn/certs/serverkey.pem");
1916 # if ($vpnsettings{'ENABLED'} eq 'on' ||
1917 # $vpnsettings{'ENABLE_BLUE'} eq 'on') {
1918 # system('/usr/local/bin/ipsecctrl', 'S');
1919 # }
1920
1921 ###
1922 ### Enable/Disable connection
1923 ###
1924
1925 ###
1926 # m.a.d net2net
1927 ###
1928
1929 }elsif ($cgiparams{'ACTION'} eq $Lang::tr{'toggle enable disable'}) {
1930
1931 &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings);
1932 &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
1933 # my $n2nactive = '';
1934 my $n2nactive = `/bin/ps ax|grep $confighash{$cgiparams{'KEY'}}[1]|grep -v grep|awk \'{print \$1}\'`;
1935
1936 if ($confighash{$cgiparams{'KEY'}}) {
1937 if ($confighash{$cgiparams{'KEY'}}[0] eq 'off') {
1938 $confighash{$cgiparams{'KEY'}}[0] = 'on';
1939 &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
1940
1941 if ($confighash{$cgiparams{'KEY'}}[3] eq 'net'){
1942 system('/usr/local/bin/openvpnctrl', '-sn2n', $confighash{$cgiparams{'KEY'}}[1]);
1943 }
1944 } else {
1945
1946 $confighash{$cgiparams{'KEY'}}[0] = 'off';
1947 &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
1948
1949 if ($confighash{$cgiparams{'KEY'}}[3] eq 'net'){
1950 if ($n2nactive ne ''){
1951 system('/usr/local/bin/openvpnctrl', '-kn2n', $confighash{$cgiparams{'KEY'}}[1]);
1952 }
1953
1954 } else {
1955 $errormessage = $Lang::tr{'invalid key'};
1956 }
1957 }
1958 }
1959
1960 ###
1961 ### Download OpenVPN client package
1962 ###
1963
1964
1965 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'dl client arch'}) {
1966 &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings);
1967 &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
1968 my $file = '';
1969 my $clientovpn = '';
1970 my @fileholder;
1971 my $tempdir = tempdir( CLEANUP => 1 );
1972 my $zippath = "$tempdir/";
1973
1974 ###
1975 # m.a.d net2net
1976 ###
1977
1978 if ($confighash{$cgiparams{'KEY'}}[3] eq 'net'){
1979
1980 my $zipname = "$confighash{$cgiparams{'KEY'}}[1]-Client.zip";
1981 my $zippathname = "$zippath$zipname";
1982 $clientovpn = "$confighash{$cgiparams{'KEY'}}[1].conf";
1983 my @ovsubnettemp = split(/\./,$confighash{$cgiparams{'KEY'}}[27]);
1984 my $ovsubnet = "$ovsubnettemp[0].$ovsubnettemp[1].$ovsubnettemp[2]";
1985 my $tunmtu = '';
1986 my @remsubnet = split(/\//,$confighash{$cgiparams{'KEY'}}[8]);
1987 my $n2nfragment = '';
1988
1989 open(CLIENTCONF, ">$tempdir/$clientovpn") or die "Unable to open tempfile: $!";
1990 flock CLIENTCONF, 2;
1991
1992 my $zip = Archive::Zip->new();
1993 print CLIENTCONF "# IPFire n2n Open VPN Client Config by ummeegge und m.a.d\n";
1994 print CLIENTCONF "# \n";
1995 print CLIENTCONF "# User Security\n";
1996 print CLIENTCONF "user nobody\n";
1997 print CLIENTCONF "group nobody\n";
1998 print CLIENTCONF "persist-tun\n";
1999 print CLIENTCONF "persist-key\n";
2000 print CLIENTCONF "script-security 2\n";
2001 print CLIENTCONF "# IP/DNS for remote Server Gateway\n";
2002 print CLIENTCONF "remote $vpnsettings{'VPN_IP'}\n";
2003 print CLIENTCONF "float\n";
2004 print CLIENTCONF "# IP adresses of the VPN Subnet\n";
2005 print CLIENTCONF "ifconfig $ovsubnet.2 $ovsubnet.1\n";
2006 print CLIENTCONF "# Server Gateway Network\n";
2007 print CLIENTCONF "route $remsubnet[0] $remsubnet[1]\n";
2008 print CLIENTCONF "# tun Device\n";
2009 print CLIENTCONF "dev $vpnsettings{'DDEVICE'}\n";
2010 print CLIENTCONF "# Port and Protokoll\n";
2011 print CLIENTCONF "port $confighash{$cgiparams{'KEY'}}[29]\n";
2012
2013 if ($confighash{$cgiparams{'KEY'}}[28] eq 'tcp') {
2014 print CLIENTCONF "proto tcp-client\n";
2015 print CLIENTCONF "# Packet size\n";
2016 if ($confighash{$cgiparams{'KEY'}}[31] eq '') {$tunmtu = '1400'} else {$tunmtu = $confighash{$cgiparams{'KEY'}}[31]};
2017 print CLIENTCONF "tun-mtu $tunmtu\n";
2018 }
2019
2020 if ($confighash{$cgiparams{'KEY'}}[28] eq 'udp') {
2021 print CLIENTCONF "proto udp\n";
2022 print CLIENTCONF "# Paketsize\n";
2023 if ($confighash{$cgiparams{'KEY'}}[31] eq '') {$tunmtu = '1500'} else {$tunmtu = $confighash{$cgiparams{'KEY'}}[31]};
2024 print CLIENTCONF "tun-mtu $tunmtu\n";
2025 if ($confighash{$cgiparams{'KEY'}}[24] ne '') {print CLIENTCONF "fragment $confighash{$cgiparams{'KEY'}}[24]\n";}
2026 if ($confighash{$cgiparams{'KEY'}}[23] eq 'on') {print CLIENTCONF "mssfix\n";}
2027 }
2028 if (($confighash{$cgiparams{'KEY'}}[38] eq 'yes') ||
2029 ($confighash{$cgiparams{'KEY'}}[38] eq 'maybe') ||
2030 ($confighash{$cgiparams{'KEY'}}[38] eq 'no' )) {
2031 if (($confighash{$cgiparams{'KEY'}}[23] ne 'on') || ($confighash{$cgiparams{'KEY'}}[24] eq '')) {
2032 if ($tunmtu eq '1500' ) {
2033 print CLIENTCONF "mtu-disc $confighash{$cgiparams{'KEY'}}[38]\n";
2034 }
2035 }
2036 }
2037 print CLIENTCONF "ns-cert-type server\n";
2038 print CLIENTCONF "# Auth. Client\n";
2039 print CLIENTCONF "tls-client\n";
2040 print CLIENTCONF "# Cipher\n";
2041 print CLIENTCONF "cipher AES-256-CBC\n";
2042 if ($confighash{$cgiparams{'KEY'}}[4] eq 'cert' && -f "${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12") {
2043 print CLIENTCONF "pkcs12 ${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12\r\n";
2044 $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";
2045 }
2046 if ($confighash{$cgiparams{'KEY'}}[30] eq 'on') {
2047 print CLIENTCONF "# Enable Compression\n";
2048 print CLIENTCONF "comp-lzo\r\n";
2049 }
2050 print CLIENTCONF "# Debug Level\n";
2051 print CLIENTCONF "verb 3\n";
2052 print CLIENTCONF "# Tunnel check\n";
2053 print CLIENTCONF "keepalive 10 60\n";
2054 print CLIENTCONF "# Start as daemon\n";
2055 print CLIENTCONF "daemon $confighash{$cgiparams{'KEY'}}[1]n2n\n";
2056 print CLIENTCONF "writepid /var/run/$confighash{$cgiparams{'KEY'}}[1]n2n.pid\n";
2057 print CLIENTCONF "# Activate Management Interface and Port\n";
2058 if ($confighash{$cgiparams{'KEY'}}[22] eq '') {print CLIENTCONF "management localhost $confighash{$cgiparams{'KEY'}}[29]\n"}
2059 else {print CLIENTCONF "management localhost $confighash{$cgiparams{'KEY'}}[22]\n"};
2060 print CLIENTCONF "# remsub $confighash{$cgiparams{'KEY'}}[11]\n";
2061
2062
2063 close(CLIENTCONF);
2064
2065 $zip->addFile( "$tempdir/$clientovpn", $clientovpn) or die "Can't add file $clientovpn\n";
2066 my $status = $zip->writeToFileNamed($zippathname);
2067
2068 open(DLFILE, "<$zippathname") or die "Unable to open $zippathname: $!";
2069 @fileholder = <DLFILE>;
2070 print "Content-Type:application/x-download\n";
2071 print "Content-Disposition:attachment;filename=$zipname\n\n";
2072 print @fileholder;
2073 exit (0);
2074 }
2075 else
2076 {
2077 my $zipname = "$confighash{$cgiparams{'KEY'}}[1]-TO-IPFire.zip";
2078 my $zippathname = "$zippath$zipname";
2079 $clientovpn = "$confighash{$cgiparams{'KEY'}}[1]-TO-IPFire.ovpn";
2080
2081 ###
2082 # m.a.d net2net
2083 ###
2084
2085 open(CLIENTCONF, ">$tempdir/$clientovpn") or die "Unable to open tempfile: $!";
2086 flock CLIENTCONF, 2;
2087
2088 my $zip = Archive::Zip->new();
2089
2090 print CLIENTCONF "#OpenVPN Client conf\r\n";
2091 print CLIENTCONF "tls-client\r\n";
2092 print CLIENTCONF "client\r\n";
2093 print CLIENTCONF "nobind\r\n";
2094 print CLIENTCONF "dev $vpnsettings{'DDEVICE'}\r\n";
2095 print CLIENTCONF "proto $vpnsettings{'DPROTOCOL'}\r\n";
2096
2097 # Check if we are using fragment, mssfix or mtu-disc and set MTU to 1500
2098 # or use configured value.
2099 if ($vpnsettings{FRAGMENT} ne '' && $vpnsettings{DPROTOCOL} ne 'tcp' )
2100 { print CLIENTCONF "$vpnsettings{'DDEVICE'}-mtu 1500\r\n"; }
2101 elsif ($vpnsettings{MSSFIX} eq 'on')
2102 { print CLIENTCONF "$vpnsettings{'DDEVICE'}-mtu 1500\r\n"; }
2103 elsif (($vpnsettings{'PMTU_DISCOVERY'} eq 'yes') ||
2104 ($vpnsettings{'PMTU_DISCOVERY'} eq 'maybe') ||
2105 ($vpnsettings{'PMTU_DISCOVERY'} eq 'no' ))
2106 { print CLIENTCONF "$vpnsettings{'DDEVICE'}-mtu 1500\r\n"; }
2107 else
2108 { print CLIENTCONF "$vpnsettings{'DDEVICE'}-mtu $vpnsettings{'DMTU'}\r\n"; }
2109
2110 if ( $vpnsettings{'ENABLED'} eq 'on'){
2111 print CLIENTCONF "remote $vpnsettings{'VPN_IP'} $vpnsettings{'DDEST_PORT'}\r\n";
2112 if ( $vpnsettings{'ENABLED_BLUE'} eq 'on' && (&haveBlueNet())){
2113 print CLIENTCONF "#Coment the above line and uncoment the next line, if you want to connect on the Blue interface\r\n";
2114 print CLIENTCONF ";remote $netsettings{'BLUE_ADDRESS'} $vpnsettings{'DDEST_PORT'}\r\n";
2115 }
2116 if ( $vpnsettings{'ENABLED_ORANGE'} eq 'on' && (&haveOrangeNet())){
2117 print CLIENTCONF "#Coment the above line and uncoment the next line, if you want to connect on the Orange interface\r\n";
2118 print CLIENTCONF ";remote $netsettings{'ORANGE_ADDRESS'} $vpnsettings{'DDEST_PORT'}\r\n";
2119 }
2120 } elsif ( $vpnsettings{'ENABLED_BLUE'} eq 'on' && (&haveBlueNet())){
2121 print CLIENTCONF "remote $netsettings{'BLUE_ADDRESS'} $vpnsettings{'DDEST_PORT'}\r\n";
2122 if ( $vpnsettings{'ENABLED_ORANGE'} eq 'on' && (&haveOrangeNet())){
2123 print CLIENTCONF "#Coment the above line and uncoment the next line, if you want to connect on the Orange interface\r\n";
2124 print CLIENTCONF ";remote $netsettings{'ORANGE_ADDRESS'} $vpnsettings{'DDEST_PORT'}\r\n";
2125 }
2126 } elsif ( $vpnsettings{'ENABLED_ORANGE'} eq 'on' && (&haveOrangeNet())){
2127 print CLIENTCONF "remote $netsettings{'ORANGE_ADDRESS'} $vpnsettings{'DDEST_PORT'}\r\n";
2128 }
2129
2130 if ($confighash{$cgiparams{'KEY'}}[4] eq 'cert' && -f "${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12") {
2131 print CLIENTCONF "pkcs12 $confighash{$cgiparams{'KEY'}}[1].p12\r\n";
2132 $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";
2133 } else {
2134 print CLIENTCONF "ca cacert.pem\r\n";
2135 print CLIENTCONF "cert $confighash{$cgiparams{'KEY'}}[1]cert.pem\r\n";
2136 print CLIENTCONF "key $confighash{$cgiparams{'KEY'}}[1].key\r\n";
2137 $zip->addFile( "${General::swroot}/ovpn/ca/cacert.pem", "cacert.pem") or die "Can't add file cacert.pem\n";
2138 $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";
2139 }
2140 print CLIENTCONF "cipher $vpnsettings{DCIPHER}\r\n";
2141 if ($vpnsettings{DCOMPLZO} eq 'on') {
2142 print CLIENTCONF "comp-lzo\r\n";
2143 }
2144 print CLIENTCONF "verb 3\r\n";
2145 print CLIENTCONF "ns-cert-type server\r\n";
2146 print CLIENTCONF "tls-remote $vpnsettings{ROOTCERT_HOSTNAME}\r\n";
2147 if ($vpnsettings{MSSFIX} eq 'on') {
2148 print CLIENTCONF "mssfix\r\n";
2149 }
2150 if ($vpnsettings{FRAGMENT} ne '' && $vpnsettings{DPROTOCOL} ne 'tcp' ) {
2151 print CLIENTCONF "fragment $vpnsettings{'FRAGMENT'}\r\n";
2152 }
2153
2154 # Check if a valid operating mode has been choosen and use it.
2155 if (($vpnsettings{'PMTU_DISCOVERY'} eq 'yes') ||
2156 ($vpnsettings{'PMTU_DISCOVERY'} eq 'maybe') ||
2157 ($vpnsettings{'PMTU_DISCOVERY'} eq 'no' )) {
2158 if(($vpnsettings{MSSFIX} ne 'on') || ($vpnsettings{FRAGMENT} eq '')) {
2159 print CLIENTCONF "mtu-disc $vpnsettings{'PMTU_DISCOVERY'}\r\n";
2160 }
2161 }
2162 close(CLIENTCONF);
2163
2164 $zip->addFile( "$tempdir/$clientovpn", $clientovpn) or die "Can't add file $clientovpn\n";
2165 my $status = $zip->writeToFileNamed($zippathname);
2166
2167 open(DLFILE, "<$zippathname") or die "Unable to open $zippathname: $!";
2168 @fileholder = <DLFILE>;
2169 print "Content-Type:application/x-download\n";
2170 print "Content-Disposition:attachment;filename=$zipname\n\n";
2171 print @fileholder;
2172 exit (0);
2173 }
2174
2175
2176
2177 ###
2178 ### Remove connection
2179 ###
2180
2181
2182 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'remove'}) {
2183 &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings);
2184 &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
2185
2186 if ($confighash{$cgiparams{'KEY'}}) {
2187 # if ($vpnsettings{'ENABLED'} eq 'on' ||
2188 # $vpnsettings{'ENABLED_BLUE'} eq 'on') {
2189 # system('/usr/local/bin/ipsecctrl', 'D', $cgiparams{'KEY'});
2190 # }
2191 #
2192 my $temp = `/usr/bin/openssl ca -revoke ${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem -config ${General::swroot}/ovpn/openssl/ovpn.cnf`;
2193
2194 ###
2195 # m.a.d net2net
2196 ###
2197
2198 if ($confighash{$cgiparams{'KEY'}}[3] eq 'net') {
2199
2200 my $conffile = glob("${General::swroot}/ovpn/n2nconf/$confighash{$cgiparams{'KEY'}}[1]/$confighash{$cgiparams{'KEY'}}[1].conf");
2201 my $certfile = glob("${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12");
2202 unlink ($certfile) or die "Removing $certfile fail: $!";
2203 unlink ($conffile) or die "Removing $conffile fail: $!";
2204 rmdir ("${General::swroot}/ovpn/n2nconf/$confighash{$cgiparams{'KEY'}}[1]") || die "Kann Verzeichnis nicht loeschen: $!";
2205
2206 }
2207
2208 unlink ("${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem");
2209 unlink ("${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12");
2210
2211 # A.Marx CCD delete ccd files and routes
2212
2213
2214 if (-f "${General::swroot}/ovpn/ccd/$confighash{$cgiparams{'KEY'}}[2]")
2215 {
2216 unlink "${General::swroot}/ovpn/ccd/$confighash{$cgiparams{'KEY'}}[2]";
2217 }
2218
2219 &General::readhasharray("${General::swroot}/ovpn/ccdroute", \%ccdroutehash);
2220 foreach my $key (keys %ccdroutehash) {
2221 if ($ccdroutehash{$key}[0] eq $confighash{$cgiparams{'KEY'}}[1]){
2222 delete $ccdroutehash{$key};
2223 }
2224 }
2225 &General::writehasharray("${General::swroot}/ovpn/ccdroute", \%ccdroutehash);
2226
2227 &General::readhasharray("${General::swroot}/ovpn/ccdroute2", \%ccdroute2hash);
2228 foreach my $key (keys %ccdroute2hash) {
2229 if ($ccdroute2hash{$key}[0] eq $confighash{$cgiparams{'KEY'}}[1]){
2230 delete $ccdroute2hash{$key};
2231 }
2232 }
2233 &General::writehasharray("${General::swroot}/ovpn/ccdroute2", \%ccdroute2hash);
2234 &writeserverconf;
2235
2236
2237 # CCD end
2238
2239
2240 delete $confighash{$cgiparams{'KEY'}};
2241 my $temp2 = `/usr/bin/openssl ca -gencrl -out ${General::swroot}/ovpn/crls/cacrl.pem -config ${General::swroot}/ovpn/openssl/ovpn.cnf`;
2242 &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
2243
2244 #&writeserverconf();
2245 } else {
2246 $errormessage = $Lang::tr{'invalid key'};
2247 }
2248
2249
2250 ###
2251 ### Download PKCS12 file
2252 ###
2253 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'download pkcs12 file'}) {
2254 &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
2255
2256 print "Content-Disposition: filename=" . $confighash{$cgiparams{'KEY'}}[1] . ".p12\r\n";
2257 print "Content-Type: application/octet-stream\r\n\r\n";
2258 print `/bin/cat ${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12`;
2259 exit (0);
2260
2261 ###
2262 ### Display certificate
2263 ###
2264 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'show certificate'}) {
2265 &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
2266
2267 if ( -f "${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem") {
2268 &Header::showhttpheaders();
2269 &Header::openpage($Lang::tr{'vpn configuration main'}, 1, '');
2270 &Header::openbigbox('100%', 'LEFT', '', '');
2271 &Header::openbox('100%', 'LEFT', "$Lang::tr{'certificate'}:");
2272 my $output = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem`;
2273 $output = &Header::cleanhtml($output,"y");
2274 print "<pre>$output</pre>\n";
2275 &Header::closebox();
2276 print "<div align='center'><a href='/cgi-bin/ovpnmain.cgi'>$Lang::tr{'back'}</a></div>";
2277 &Header::closebigbox();
2278 &Header::closepage();
2279 exit(0);
2280 }
2281 ###
2282 ### Display Certificate Revoke List
2283 ###
2284 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'show crl'}) {
2285 # &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
2286
2287 if ( -f "${General::swroot}/ovpn/crls/cacrl.pem") {
2288 &Header::showhttpheaders();
2289 &Header::openpage($Lang::tr{'vpn configuration main'}, 1, '');
2290 &Header::openbigbox('100%', 'LEFT', '', '');
2291 &Header::openbox('100%', 'LEFT', "$Lang::tr{'crl'}:");
2292 my $output = `/usr/bin/openssl crl -text -noout -in ${General::swroot}/ovpn/crls/cacrl.pem`;
2293 $output = &Header::cleanhtml($output,"y");
2294 print "<pre>$output</pre>\n";
2295 &Header::closebox();
2296 print "<div align='center'><a href='/cgi-bin/ovpnmain.cgi'>$Lang::tr{'back'}</a></div>";
2297 &Header::closebigbox();
2298 &Header::closepage();
2299 exit(0);
2300 }
2301
2302 ###
2303 ### Advanced Server Settings
2304 ###
2305
2306 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'advanced server'}) {
2307 %cgiparams = ();
2308 %cahash = ();
2309 %confighash = ();
2310 my $disabled;
2311 &General::readhash("${General::swroot}/ovpn/settings", \%cgiparams);
2312 read_routepushfile;
2313
2314
2315 # if ($cgiparams{'CLIENT2CLIENT'} eq '') {
2316 # $cgiparams{'CLIENT2CLIENT'} = 'on';
2317 # }
2318 ADV_ERROR:
2319 if ($cgiparams{'MAX_CLIENTS'} eq '') {
2320 $cgiparams{'MAX_CLIENTS'} = '100';
2321 }
2322 if ($cgiparams{'KEEPALIVE_1'} eq '') {
2323 $cgiparams{'KEEPALIVE_1'} = '10';
2324 }
2325 if ($cgiparams{'KEEPALIVE_2'} eq '') {
2326 $cgiparams{'KEEPALIVE_2'} = '60';
2327 }
2328 if ($cgiparams{'LOG_VERB'} eq '') {
2329 $cgiparams{'LOG_VERB'} = '3';
2330 }
2331 if ($cgiparams{'PMTU_DISCOVERY'} eq '') {
2332 $cgiparams{'PMTU_DISCOVERY'} = 'off';
2333 }
2334 $checked{'CLIENT2CLIENT'}{'off'} = '';
2335 $checked{'CLIENT2CLIENT'}{'on'} = '';
2336 $checked{'CLIENT2CLIENT'}{$cgiparams{'CLIENT2CLIENT'}} = 'CHECKED';
2337 $checked{'REDIRECT_GW_DEF1'}{'off'} = '';
2338 $checked{'REDIRECT_GW_DEF1'}{'on'} = '';
2339 $checked{'REDIRECT_GW_DEF1'}{$cgiparams{'REDIRECT_GW_DEF1'}} = 'CHECKED';
2340 $selected{'ENGINES'}{$cgiparams{'ENGINES'}} = 'SELECTED';
2341 $checked{'MSSFIX'}{'off'} = '';
2342 $checked{'MSSFIX'}{'on'} = '';
2343 $checked{'MSSFIX'}{$cgiparams{'MSSFIX'}} = 'CHECKED';
2344 $checked{'PMTU_DISCOVERY'}{$cgiparams{'PMTU_DISCOVERY'}} = 'checked=\'checked\'';
2345 $selected{'LOG_VERB'}{'1'} = '';
2346 $selected{'LOG_VERB'}{'2'} = '';
2347 $selected{'LOG_VERB'}{'3'} = '';
2348 $selected{'LOG_VERB'}{'4'} = '';
2349 $selected{'LOG_VERB'}{'5'} = '';
2350 $selected{'LOG_VERB'}{'6'} = '';
2351 $selected{'LOG_VERB'}{'7'} = '';
2352 $selected{'LOG_VERB'}{'8'} = '';
2353 $selected{'LOG_VERB'}{'9'} = '';
2354 $selected{'LOG_VERB'}{'10'} = '';
2355 $selected{'LOG_VERB'}{'11'} = '';
2356 $selected{'LOG_VERB'}{'0'} = '';
2357 $selected{'LOG_VERB'}{$cgiparams{'LOG_VERB'}} = 'SELECTED';
2358
2359 &Header::showhttpheaders();
2360 &Header::openpage($Lang::tr{'status ovpn'}, 1, '');
2361 &Header::openbigbox('100%', 'LEFT', '', $errormessage);
2362 if ($errormessage) {
2363 &Header::openbox('100%', 'LEFT', $Lang::tr{'error messages'});
2364 print "<class name='base'>$errormessage\n";
2365 print "&nbsp;</class>\n";
2366 &Header::closebox();
2367 }
2368 &Header::openbox('100%', 'LEFT', $Lang::tr{'advanced server'});
2369 print <<END
2370 <form method='post' enctype='multipart/form-data'>
2371 <table width='100%' border=0>
2372 <tr>
2373 <td colspan='4'><b>$Lang::tr{'dhcp-options'}</b></td>
2374 </tr>
2375 <tr>
2376 <td width='25%'></td> <td width='20%'> </td><td width='25%'> </td><td width='30%'></td>
2377 </tr>
2378 <tr>
2379 <td class='base'>Domain</td>
2380 <td><input type='TEXT' name='DHCP_DOMAIN' value='$cgiparams{'DHCP_DOMAIN'}' size='30' /></td>
2381 </tr>
2382 <tr>
2383 <td class='base'>DNS</td>
2384 <td><input type='TEXT' name='DHCP_DNS' value='$cgiparams{'DHCP_DNS'}' size='30' /></td>
2385 </tr>
2386 <tr>
2387 <td class='base'>WINS</td>
2388 <td><input type='TEXT' name='DHCP_WINS' value='$cgiparams{'DHCP_WINS'}' size='30' /></td>
2389 </tr>
2390 <tr>
2391 <td colspan='4'><b>$Lang::tr{'ovpn routes push options'}</b></td>
2392 </tr>
2393 <tr>
2394 <td class='base'>$Lang::tr{'ovpn routes push'}</td>
2395 <td colspan='2'>
2396 <textarea name='ROUTES_PUSH' cols='26' rows='6' wrap='off'>
2397 END
2398 ;
2399
2400 if ($cgiparams{'ROUTES_PUSH'} ne '')
2401 {
2402 print $cgiparams{'ROUTES_PUSH'};
2403 }
2404
2405 print <<END;
2406 </textarea></td>
2407 </tr>
2408 </tr>
2409 </table>
2410 <hr size='1'>
2411 <table width='100%'>
2412 <tr>
2413 <td class'base'><b>$Lang::tr{'misc-options'}</b></td>
2414 </tr>
2415 <tr>
2416 <td width='20%'></td> <td width='15%'> </td><td width='15%'> </td><td width='15%'></td><td width='35%'></td>
2417 </tr>
2418 <tr>
2419 <td class='base'>Client-To-Client</td>
2420 <td><input type='checkbox' name='CLIENT2CLIENT' $checked{'CLIENT2CLIENT'}{'on'} /></td>
2421 </tr>
2422 <tr>
2423 <td class='base'>Redirect-Gateway def1</td>
2424 <td><input type='checkbox' name='REDIRECT_GW_DEF1' $checked{'REDIRECT_GW_DEF1'}{'on'} /></td>
2425 </tr>
2426 <tr>
2427 <td class='base'>Max-Clients</td>
2428 <td><input type='text' name='MAX_CLIENTS' value='$cgiparams{'MAX_CLIENTS'}' size='10' /></td>
2429 </tr>
2430 <tr>
2431 <td class='base'>Keepalive <br />
2432 (ping/ping-restart)</td>
2433 <td><input type='TEXT' name='KEEPALIVE_1' value='$cgiparams{'KEEPALIVE_1'}' size='10' /></td>
2434 <td><input type='TEXT' name='KEEPALIVE_2' value='$cgiparams{'KEEPALIVE_2'}' size='10' /></td>
2435 </tr>
2436 <tr>
2437 <td class='base'>fragment <br></td>
2438 <td><input type='TEXT' name='FRAGMENT' value='$cgiparams{'FRAGMENT'}' size='10' /></td>
2439 <td>Default: <span class="base">1300</span></td>
2440 </tr>
2441 <tr>
2442 <td class='base'>mssfix</td>
2443 <td><input type='checkbox' name='MSSFIX' $checked{'MSSFIX'}{'on'} /></td>
2444 <td>Default: on</td>
2445 </tr>
2446
2447 <tr>
2448 <td class='base'>$Lang::tr{'ovpn mtu-disc'}</td>
2449 <td><input type='radio' name='PMTU_DISCOVERY' value='yes' $checked{'PMTU_DISCOVERY'}{'yes'} /> $Lang::tr{'ovpn mtu-disc yes'}</td>
2450 <td><input type='radio' name='PMTU_DISCOVERY' value='maybe' $checked{'PMTU_DISCOVERY'}{'maybe'} /> $Lang::tr{'ovpn mtu-disc maybe'}</td>
2451 <td><input type='radio' name='PMTU_DISCOVERY' value='no' $checked{'PMTU_DISCOVERY'}{'no'} /> $Lang::tr{'ovpn mtu-disc no'}</td>
2452 <td><input type='radio' name='PMTU_DISCOVERY' value='off' $checked{'PMTU_DISCOVERY'}{'off'} /> $Lang::tr{'ovpn mtu-disc off'}</td>
2453 </tr>
2454 </table>
2455
2456 <!--
2457 <hr size='1'>
2458 <table width='100%'>
2459 <tr>
2460 <td class'base'><b>Crypto-Engines</b></td>
2461 </tr>
2462 <tr>
2463 <td width='15%'></td> <td width='30%'> </td><td width='25%'> </td><td width='30%'></td>
2464 </tr>
2465 <tr><td class='base'>Engines:</td>
2466 <td><select name='ENGINES'><option value="none" $selected{'ENGINES'}{'none'}>none</option>
2467 <option value="cryptodev" $selected{'ENGINES'}{'cryptodev'}>cryptodev</option>
2468 <option value="padlock" $selected{'ENGINES'}{'padlock'}>padlock</option>
2469 </select>
2470 </td>
2471 </table>
2472 -->
2473 <hr size='1'>
2474 <table width='100%'>
2475 <tr>
2476 <td class'base'><b>$Lang::tr{'log-options'}</b></td>
2477 </tr>
2478 <tr>
2479 <td width='15%'></td> <td width='30%'> </td><td width='25%'> </td><td width='30%'></td>
2480 </tr>
2481
2482 <tr><td class='base'>VERB</td>
2483 <td><select name='LOG_VERB'><option value='1' $selected{'LOG_VERB'}{'1'}>1</option>
2484 <option value='2' $selected{'LOG_VERB'}{'2'}>2</option>
2485 <option value='3' $selected{'LOG_VERB'}{'3'}>3</option>
2486 <option value='4' $selected{'LOG_VERB'}{'4'}>4</option>
2487 <option value='5' $selected{'LOG_VERB'}{'5'}>5</option>
2488 <option value='6' $selected{'LOG_VERB'}{'6'}>6</option>
2489 <option value='7' $selected{'LOG_VERB'}{'7'}>7</option>
2490 <option value='8' $selected{'LOG_VERB'}{'8'}>8</option>
2491 <option value='9' $selected{'LOG_VERB'}{'9'}>9</option>
2492 <option value='10' $selected{'LOG_VERB'}{'10'}>10</option>
2493 <option value='11' $selected{'LOG_VERB'}{'11'}>11</option>
2494 <option value='0' $selected{'LOG_VERB'}{'0'}>0</option></select></td>
2495 </table><hr>
2496 END
2497
2498 if ( -e "/var/run/openvpn.pid"){
2499 print" <br><b><font color='#990000'>$Lang::tr{'attention'}:</b></font><br>
2500 $Lang::tr{'server restart'}<br><br>
2501 <hr>";
2502 print<<END
2503 <table width='100%'>
2504 <tr>
2505 <td>&nbsp;</td>
2506 <td allign='center'><input type='submit' name='ACTION' value='$Lang::tr{'save-adv-options'}' disabled='disabled' /></td>
2507 <td allign='center'><input type='submit' name='ACTION' value='$Lang::tr{'cancel-adv-options'}' /></td>
2508 <td>&nbsp;</td>
2509 </tr>
2510 </table>
2511 </form>
2512 END
2513 ;
2514
2515
2516 }else{
2517
2518 print<<END
2519 <table width='100%'>
2520 <tr>
2521 <td>&nbsp;</td>
2522 <td allign='center'><input type='submit' name='ACTION' value='$Lang::tr{'save-adv-options'}' /></td>
2523 <td allign='center'><input type='submit' name='ACTION' value='$Lang::tr{'cancel-adv-options'}' /></td>
2524 <td>&nbsp;</td>
2525 </tr>
2526 </table>
2527 </form>
2528 END
2529 ;
2530 }
2531 &Header::closebox();
2532 # print "<div align='center'><a href='/cgi-bin/ovpnmain.cgi'>$Lang::tr{'back'}</a></div>";
2533 &Header::closebigbox();
2534 &Header::closepage();
2535 exit(0);
2536
2537
2538 # A.Marx CCD Add,delete or edit CCD net
2539
2540 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'ccd net'} ||
2541 $cgiparams{'ACTION'} eq $Lang::tr{'ccd add'} ||
2542 $cgiparams{'ACTION'} eq "kill" ||
2543 $cgiparams{'ACTION'} eq "edit" ||
2544 $cgiparams{'ACTION'} eq 'editsave'){
2545 &Header::showhttpheaders();
2546 &Header::openpage($Lang::tr{'ccd net'}, 1, '');
2547 &Header::openbigbox('100%', 'LEFT', '', '');
2548
2549 if ($cgiparams{'ACTION'} eq "kill"){
2550 &delccdnet($cgiparams{'net'});
2551 }
2552
2553 if ($cgiparams{'ACTION'} eq 'editsave'){
2554 my ($a,$b) =split (/\|/,$cgiparams{'ccdname'});
2555 if ( $a ne $b){ &modccdnet($a,$b);}
2556 $cgiparams{'ccdname'}='';
2557 $cgiparams{'ccdsubnet'}='';
2558 }
2559
2560 if ($cgiparams{'ACTION'} eq $Lang::tr{'ccd add'}) {
2561 &addccdnet($cgiparams{'ccdname'},$cgiparams{'ccdsubnet'});
2562 }
2563 if ($errormessage) {
2564 &Header::openbox('100%', 'LEFT', $Lang::tr{'error messages'});
2565 print "<class name='base'>$errormessage";
2566 print "&nbsp;</class>";
2567 &Header::closebox();
2568 }
2569 if ($cgiparams{'ACTION'} eq "edit"){
2570
2571 &Header::openbox('100%', 'LEFT', $Lang::tr{'ccd modify'});
2572
2573 print <<END
2574 <table width='100%' border=0>
2575 <tr><form method='post'>
2576 <td width='10%' nowrap='nowrap'>$Lang::tr{'ccd name'}:</td><td><input type='TEXT' name='ccdname' value='$cgiparams{'ccdname'}' /></td>
2577 <td width='8%'>$Lang::tr{'ccd subnet'}:</td><td><input type='TEXT' name='ccdsubnet' value='$cgiparams{'ccdsubnet'}' readonly /></td></tr>
2578 <tr><td colspan='4' align='right'><hr><input type='submit' value='$Lang::tr{'save'}' /><input type='hidden' name='ACTION' value='editsave'/>
2579 <input type='hidden' name='ccdname' value='$cgiparams{'ccdname'}'/><input type='submit' value='$Lang::tr{'cancel'}' />
2580 </td></tr>
2581 </table></form>
2582 END
2583 ;
2584 &Header::closebox();
2585
2586 &Header::openbox('100%', 'LEFT',$Lang::tr{'ccd net'} );
2587 print <<END
2588 <table width='100%' border='0' cellpadding='0' cellspacing='1'>
2589 <tr>
2590 <td class='boldbase' align='center'><b>$Lang::tr{'ccd name'}</td><td class='boldbase' align='center'><b>$Lang::tr{'network'}</td><td class='boldbase' width='15%' align='center'><b>$Lang::tr{'ccd used'}</td><td width='3%'></td><td width='3%'></td></tr>
2591 END
2592 ;
2593 }
2594 else{
2595 if (! -e "/var/run/openvpn.pid"){
2596 &Header::openbox('100%', 'LEFT', $Lang::tr{'ccd add'});
2597 print <<END;
2598 <table width='100%' border='0'>
2599 <tr><form method='post'>
2600 <td colspan='4'>$Lang::tr{'ccd hint'}<br><br></td></tr>
2601 <tr>
2602 <td width='10%' nowrap='nwrap'>$Lang::tr{'ccd name'}:</td><td><input type='TEXT' name='ccdname' value='$cgiparams{'ccdname'}' /></td>
2603 <td width='8%'>$Lang::tr{'ccd subnet'}:</td><td><input type='TEXT' name='ccdsubnet' value='$cgiparams{'ccdsubnet'}' /></td></tr>
2604 <tr><td colspan=4><hr /></td></tr><tr>
2605 <td colspan='4' align='right'><input type='hidden' name='ACTION' value='$Lang::tr{'ccd add'}' /><input type='submit' value='$Lang::tr{'add'}' /><input type='hidden' name='DOVPN_SUBNET' value='$cgiparams{'DOVPN_SUBNET'}'/></td></tr>
2606 </table></form>
2607 END
2608
2609 &Header::closebox();
2610 }
2611 &Header::openbox('100%', 'LEFT',$Lang::tr{'ccd net'} );
2612 if ( -e "/var/run/openvpn.pid"){
2613 print "<b>$Lang::tr{'attention'}:</b><br>";
2614 print "$Lang::tr{'ccd noaddnet'}<br><hr>";
2615 }
2616
2617 print <<END
2618 <table width='100%' border='0' cellpadding='0' cellspacing='1'>
2619 <tr>
2620 <td class='boldbase' align='center' nowrap='nowrap' width='20%'><b>$Lang::tr{'ccd name'}</td><td class='boldbase' align='center' width='8%'><b>$Lang::tr{'network'}</td><td class='boldbase' width='8%' align='center' nowrap='nowrap'><b>$Lang::tr{'ccd used'}</td><td width='1%' align='center'></td><td width='1%' align='center'></td></tr>
2621 END
2622 ;
2623 }
2624 my %ccdconfhash=();
2625 &General::readhasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash);
2626 my @ccdconf=();
2627 my $count=0;
2628 foreach my $key (sort { uc($ccdconfhash{$a}[0]) cmp uc($ccdconfhash{$b}[0]) } keys %ccdconfhash) {
2629 @ccdconf=($ccdconfhash{$key}[0],$ccdconfhash{$key}[1]);
2630 $count++;
2631 my $ccdhosts = &hostsinnet($ccdconf[0]);
2632 if ($count % 2){ print" <tr bgcolor='$color{'color22'}'>";}
2633 else{ print" <tr bgcolor='$color{'color20'}'>";}
2634 print"<td>$ccdconf[0]</td><td align='center'>$ccdconf[1]</td><td align='center'>$ccdhosts/".(&ccdmaxclients($ccdconf[1])+1)."</td><td>";
2635 print <<END
2636 <form method='post' />
2637 <input type='image' src='/images/edit.gif' align='middle' alt=$Lang::tr{'edit'} title=$Lang::tr{'edit'} />
2638 <input type='hidden' name='ACTION' value='edit'/>
2639 <input type='hidden' name='ccdname' value='$ccdconf[0]' />
2640 <input type='hidden' name='ccdsubnet' value='$ccdconf[1]' />
2641 </form></td>
2642 <form method='post' />
2643 <td><input type='hidden' name='ACTION' value='kill'/>
2644 <input type='hidden' name='number' value='$count' />
2645 <input type='hidden' name='net' value='$ccdconf[0]' />
2646 <input type='image' src='/images/delete.gif' align='middle' alt=$Lang::tr{'remove'} title=$Lang::tr{'remove'} /></form></td></tr>
2647 END
2648 ;
2649 }
2650 print "</table></form>";
2651 &Header::closebox();
2652 print "<div align='center'><a href='/cgi-bin/ovpnmain.cgi'>$Lang::tr{'back'}</a></div>";
2653 &Header::closebigbox();
2654 &Header::closepage();
2655 exit(0);
2656
2657 #END CCD
2658
2659 ###
2660 ### Openvpn Connections Statistics
2661 ###
2662 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'ovpn con stat'}) {
2663 &Header::showhttpheaders();
2664 &Header::openpage($Lang::tr{'ovpn con stat'}, 1, '');
2665 &Header::openbigbox('100%', 'LEFT', '', '');
2666 &Header::openbox('100%', 'LEFT', $Lang::tr{'ovpn con stat'});
2667
2668 #
2669 # <td><b>$Lang::tr{'protocol'}</b></td>
2670 # protocol temp removed
2671 print <<END
2672 <table width='100%' border='0' cellpadding='2' cellspacing='0'>
2673 <tr>
2674 <td><b>$Lang::tr{'common name'}</b></td>
2675 <td><b>$Lang::tr{'real address'}</b></td>
2676 <td><b>$Lang::tr{'virtual address'}</b></td>
2677 <td><b>$Lang::tr{'loged in at'}</b></td>
2678 <td><b>$Lang::tr{'bytes sent'}</b></td>
2679 <td><b>$Lang::tr{'bytes received'}</b></td>
2680 <td><b>$Lang::tr{'last activity'}</b></td>
2681 </tr>
2682 END
2683 ;
2684 my $filename = "/var/log/ovpnserver.log";
2685 open(FILE, $filename) or die 'Unable to open config file.';
2686 my @current = <FILE>;
2687 close(FILE);
2688 my @users =();
2689 my $status;
2690 my $uid = 0;
2691 my $cn;
2692 my @match = ();
2693 my $proto = "udp";
2694 my $address;
2695 my %userlookup = ();
2696 foreach my $line (@current)
2697 {
2698 chomp($line);
2699 if ( $line =~ /^Updated,(.+)/){
2700 @match = split( /^Updated,(.+)/, $line);
2701 $status = $match[1];
2702 }
2703 #gian
2704 if ( $line =~ /^(.+),(\d+\.\d+\.\d+\.\d+\:\d+),(\d+),(\d+),(.+)/) {
2705 @match = split(m/^(.+),(\d+\.\d+\.\d+\.\d+\:\d+),(\d+),(\d+),(.+)/, $line);
2706 if ($match[1] ne "Common Name") {
2707 $cn = $match[1];
2708 $userlookup{$match[2]} = $uid;
2709 $users[$uid]{'CommonName'} = $match[1];
2710 $users[$uid]{'RealAddress'} = $match[2];
2711 $users[$uid]{'BytesReceived'} = &sizeformat($match[3]);
2712 $users[$uid]{'BytesSent'} = &sizeformat($match[4]);
2713 $users[$uid]{'Since'} = $match[5];
2714 $users[$uid]{'Proto'} = $proto;
2715 $uid++;
2716 }
2717 }
2718 if ( $line =~ /^(\d+\.\d+\.\d+\.\d+),(.+),(\d+\.\d+\.\d+\.\d+\:\d+),(.+)/) {
2719 @match = split(m/^(\d+\.\d+\.\d+\.\d+),(.+),(\d+\.\d+\.\d+\.\d+\:\d+),(.+)/, $line);
2720 if ($match[1] ne "Virtual Address") {
2721 $address = $match[3];
2722 #find the uid in the lookup table
2723 $uid = $userlookup{$address};
2724 $users[$uid]{'VirtualAddress'} = $match[1];
2725 $users[$uid]{'LastRef'} = $match[4];
2726 }
2727 }
2728 }
2729 my $user2 = @users;
2730 if ($user2 >= 1){
2731 for (my $idx = 1; $idx <= $user2; $idx++){
2732 if ($idx % 2) {
2733 print "<tr bgcolor='$color{'color20'}'>\n";
2734 } else {
2735 print "<tr bgcolor='$color{'color22'}'>\n";
2736 }
2737 print "<td align='left'>$users[$idx-1]{'CommonName'}</td>";
2738 print "<td align='left'>$users[$idx-1]{'RealAddress'}</td>";
2739 print "<td align='left'>$users[$idx-1]{'VirtualAddress'}</td>";
2740 print "<td align='left'>$users[$idx-1]{'Since'}</td>";
2741 print "<td align='left'>$users[$idx-1]{'BytesSent'}</td>";
2742 print "<td align='left'>$users[$idx-1]{'BytesReceived'}</td>";
2743 print "<td align='left'>$users[$idx-1]{'LastRef'}</td>";
2744 # print "<td align='left'>$users[$idx-1]{'Proto'}</td>";
2745 }
2746 }
2747
2748 print "</table>";
2749 print <<END
2750 <table width='100%' border='0' cellpadding='2' cellspacing='0'>
2751 <tr><td></td></tr>
2752 <tr><td></td></tr>
2753 <tr><td></td></tr>
2754 <tr><td></td></tr>
2755 <tr><td align='center' >$Lang::tr{'the statistics were last updated at'} <b>$status</b></td></tr>
2756 </table>
2757 END
2758 ;
2759 &Header::closebox();
2760 print "<div align='center'><a href='/cgi-bin/ovpnmain.cgi'>$Lang::tr{'back'}</a></div>";
2761 &Header::closebigbox();
2762 &Header::closepage();
2763 exit(0);
2764
2765 ###
2766 ### Download Certificate
2767 ###
2768 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'download certificate'}) {
2769 &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
2770
2771 if ( -f "${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem") {
2772 print "Content-Disposition: filename=" . $confighash{$cgiparams{'KEY'}}[1] . "cert.pem\r\n";
2773 print "Content-Type: application/octet-stream\r\n\r\n";
2774 print `/bin/cat ${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem`;
2775 exit (0);
2776 }
2777
2778 ###
2779 ### Enable/Disable connection
2780 ###
2781
2782 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'toggle enable disable'}) {
2783
2784 &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings);
2785 &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
2786
2787 if ($confighash{$cgiparams{'KEY'}}) {
2788 if ($confighash{$cgiparams{'KEY'}}[0] eq 'off') {
2789 $confighash{$cgiparams{'KEY'}}[0] = 'on';
2790 &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
2791 #&writeserverconf();
2792 # if ($vpnsettings{'ENABLED'} eq 'on' ||
2793 # $vpnsettings{'ENABLED_BLUE'} eq 'on') {
2794 # system('/usr/local/bin/ipsecctrl', 'S', $cgiparams{'KEY'});
2795 # }
2796 } else {
2797 $confighash{$cgiparams{'KEY'}}[0] = 'off';
2798 # if ($vpnsettings{'ENABLED'} eq 'on' ||
2799 # $vpnsettings{'ENABLED_BLUE'} eq 'on') {
2800 # system('/usr/local/bin/ipsecctrl', 'D', $cgiparams{'KEY'});
2801 # }
2802 &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
2803 #&writeserverconf();
2804 }
2805 } else {
2806 $errormessage = $Lang::tr{'invalid key'};
2807 }
2808
2809 ###
2810 ### Restart connection
2811 ###
2812 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'restart'}) {
2813 &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings);
2814 &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
2815
2816 if ($confighash{$cgiparams{'KEY'}}) {
2817 # if ($vpnsettings{'ENABLED'} eq 'on' ||
2818 # $vpnsettings{'ENABLED_BLUE'} eq 'on') {
2819 # system('/usr/local/bin/ipsecctrl', 'S', $cgiparams{'KEY'});
2820 # }
2821 } else {
2822 $errormessage = $Lang::tr{'invalid key'};
2823 }
2824
2825 ###
2826 ### Remove connection
2827 ###
2828 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'remove'}) {
2829 &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings);
2830 &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
2831
2832 if ($confighash{$cgiparams{'KEY'}}) {
2833 # if ($vpnsettings{'ENABLED'} eq 'on' ||
2834 # $vpnsettings{'ENABLED_BLUE'} eq 'on') {
2835 # system('/usr/local/bin/ipsecctrl', 'D', $cgiparams{'KEY'});
2836 # }
2837 unlink ("${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem");
2838 unlink ("${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12");
2839 delete $confighash{$cgiparams{'KEY'}};
2840 &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
2841 #&writeserverconf();
2842 } else {
2843 $errormessage = $Lang::tr{'invalid key'};
2844 }
2845 #test33
2846
2847 ###
2848 ### Choose between adding a host-net or net-net connection
2849 ###
2850
2851 ###
2852 # m.a.d net2net
2853 ###
2854
2855 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'add'} && $cgiparams{'TYPE'} eq '') {
2856 &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings);
2857 &Header::showhttpheaders();
2858 &Header::openpage($Lang::tr{'vpn configuration main'}, 1, '');
2859 &Header::openbigbox('100%', 'LEFT', '', '');
2860 &Header::openbox('100%', 'LEFT', $Lang::tr{'connection type'});
2861
2862 if ( -s "${General::swroot}/ovpn/settings") {
2863
2864 print <<END
2865 <b>$Lang::tr{'connection type'}:</b><br />
2866 <table border='0' width='100%'><form method='post' ENCTYPE="multipart/form-data">
2867 <tr><td><input type='radio' name='TYPE' value='host' checked /></td>
2868 <td class='base'>$Lang::tr{'host to net vpn'}</td></tr>
2869 <tr><td><input type='radio' name='TYPE' value='net' /></td>
2870 <td class='base'>$Lang::tr{'net to net vpn'}</td></tr>
2871 <tr><td><input type='radio' name='TYPE' value='net2net' /></td>
2872 <td class='base'>$Lang::tr{'net to net vpn'} (Upload Client Package)</td></tr>
2873 <tr><td>&nbsp;</td><td class='base'><input type='file' name='FH' size='30'></td></tr>
2874 <tr><td>&nbsp;</td><td>Import Connection Name <img src='/blob.gif' /></td></tr>
2875 <tr><td>&nbsp;</td><td class='base'><input type='text' name='n2nname' size='30'>Default : Client Packagename</td></tr>
2876 <tr><td colspan='3'><hr /></td></tr>
2877 <tr><td align='right' colspan='3'><input type='submit' name='ACTION' value='$Lang::tr{'add'}' /></td></tr>
2878 <tr><td class='base' colspan='3' align='left'><img src='/blob.gif' alt='*' />&nbsp;$Lang::tr{'this field may be blank'}</td></tr>
2879 </form></table>
2880 END
2881 ;
2882
2883
2884 } else {
2885 print <<END
2886 <b>$Lang::tr{'connection type'}:</b><br />
2887 <table border='0' width='100%'><form method='post' ENCTYPE="multipart/form-data">
2888 <tr><td><input type='radio' name='TYPE' value='host' checked /></td> <td class='base'>$Lang::tr{'host to net vpn'}</td></tr>
2889 <tr><td align='right' colspan'3'><input type='submit' name='ACTION' value='$Lang::tr{'add'}' /></td></tr>
2890 </form></table>
2891 END
2892 ;
2893
2894 }
2895
2896 &Header::closebox();
2897 &Header::closebigbox();
2898 &Header::closepage();
2899 exit (0);
2900
2901 ###
2902 # m.a.d net2net
2903 ###
2904
2905 } elsif (($cgiparams{'ACTION'} eq $Lang::tr{'add'}) && ($cgiparams{'TYPE'} eq 'net2net')){
2906
2907 my @firen2nconf;
2908 my @confdetails;
2909 my $uplconffilename ='';
2910 my $uplconffilename2 ='';
2911 my $uplp12name = '';
2912 my $uplp12name2 = '';
2913 my @rem_subnet;
2914 my @rem_subnet2;
2915 my @tmposupnet3;
2916 my $key;
2917 my @n2nname;
2918
2919 &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
2920
2921 # Check if a file is uploaded
2922
2923 if (ref ($cgiparams{'FH'}) ne 'Fh') {
2924 $errormessage = $Lang::tr{'there was no file upload'};
2925 goto N2N_ERROR;
2926 }
2927
2928 # Move uploaded IPfire n2n package to temporary file
2929
2930 (my $fh, my $filename) = tempfile( );
2931 if (copy ($cgiparams{'FH'}, $fh) != 1) {
2932 $errormessage = $!;
2933 goto N2N_ERROR;
2934 }
2935
2936 my $zip = Archive::Zip->new();
2937 my $zipName = $filename;
2938 my $status = $zip->read( $zipName );
2939 if ($status != AZ_OK) {
2940 $errormessage = "Read of $zipName failed\n";
2941 goto N2N_ERROR;
2942 }
2943
2944 my $tempdir = tempdir( CLEANUP => 1 );
2945 my @files = $zip->memberNames();
2946 for(@files) {
2947 $zip->extractMemberWithoutPaths($_,"$tempdir/$_");
2948 }
2949 my $countfiles = @files;
2950
2951 # Check if we have not more then 2 files
2952
2953 if ( $countfiles == 2){
2954 foreach (@files){
2955 if ( $_ =~ /.conf$/){
2956 $uplconffilename = $_;
2957 }
2958 if ( $_ =~ /.p12$/){
2959 $uplp12name = $_;
2960 }
2961 }
2962 if (($uplconffilename eq '') || ($uplp12name eq '')){
2963 $errormessage = "Either no *.conf or no *.p12 file found\n";
2964 goto N2N_ERROR;
2965 }
2966
2967 open(FILE, "$tempdir/$uplconffilename") or die 'Unable to open*.conf file';
2968 @firen2nconf = <FILE>;
2969 close (FILE);
2970 chomp(@firen2nconf);
2971
2972 } else {
2973
2974 $errormessage = "Filecount does not match only 2 files are allowed\n";
2975 goto N2N_ERROR;
2976 }
2977
2978 ###
2979 # m.a.d net2net
2980 ###
2981
2982 if ($cgiparams{'n2nname'} ne ''){
2983
2984 $uplconffilename2 = "$cgiparams{'n2nname'}.conf";
2985 $uplp12name2 = "$cgiparams{'n2nname'}.p12";
2986 $n2nname[0] = $cgiparams{'n2nname'};
2987 my @n2nname2 = split(/\./,$uplconffilename);
2988 $n2nname2[0] =~ s/\n|\r//g;
2989 my $input1 = "${General::swroot}/ovpn/certs/$uplp12name";
2990 my $output1 = "${General::swroot}/ovpn/certs/$uplp12name2";
2991 my $input2 = "$n2nname2[0]n2n";
2992 my $output2 = "$n2nname[0]n2n";
2993 my $filename = "$tempdir/$uplconffilename";
2994 open(FILE, "< $filename") or die 'Unable to open config file.';
2995 my @current = <FILE>;
2996 close(FILE);
2997 foreach (@current) {s/$input1/$output1/g;}
2998 foreach (@current) {s/$input2/$output2/g;}
2999 open (OUT, "> $filename") || die 'Unable to open config file.';
3000 print OUT @current;
3001 close OUT;
3002
3003 }else{
3004 $uplconffilename2 = $uplconffilename;
3005 $uplp12name2 = $uplp12name;
3006 @n2nname = split(/\./,$uplconffilename);
3007 $n2nname[0] =~ s/\n|\r//g;
3008 }
3009 unless(-d "${General::swroot}/ovpn/n2nconf/"){mkdir "${General::swroot}/ovpn/n2nconf", 0755 or die "Unable to create dir $!";}
3010 unless(-d "${General::swroot}/ovpn/n2nconf/$n2nname[0]"){mkdir "${General::swroot}/ovpn/n2nconf/$n2nname[0]", 0770 or die "Unable to create dir $!";}
3011
3012 move("$tempdir/$uplconffilename", "${General::swroot}/ovpn/n2nconf/$n2nname[0]/$uplconffilename2");
3013
3014 if ($? ne 0) {
3015 $errormessage = "*.conf move failed: $!";
3016 unlink ($filename);
3017 goto N2N_ERROR;
3018 }
3019
3020 move("$tempdir/$uplp12name", "${General::swroot}/ovpn/certs/$uplp12name2");
3021 chmod 0600, "${General::swroot}/ovpn/certs/$uplp12name";
3022
3023 if ($? ne 0) {
3024 $errormessage = "$Lang::tr{'certificate file move failed'}: $!";
3025 unlink ($filename);
3026 goto N2N_ERROR;
3027 }
3028
3029 my $complzoactive;
3030 my $mssfixactive;
3031 my $n2nfragment;
3032 my @n2nmtudisc = split(/ /, (grep { /^mtu-disc/ } @firen2nconf)[0]);;
3033 my @n2nproto2 = split(/ /, (grep { /^proto/ } @firen2nconf)[0]);
3034 my @n2nproto = split(/-/, $n2nproto2[1]);
3035 my @n2nport = split(/ /, (grep { /^port/ } @firen2nconf)[0]);
3036 my @n2ntunmtu = split(/ /, (grep { /^tun-mtu/ } @firen2nconf)[0]);
3037 my @n2ncomplzo = grep { /^comp-lzo/ } @firen2nconf;
3038 if ($n2ncomplzo[0] =~ /comp-lzo/){$complzoactive = "on";} else {$complzoactive = "off";}
3039 my @n2nmssfix = grep { /^mssfix/ } @firen2nconf;
3040 if ($n2nmssfix[0] =~ /mssfix/){$mssfixactive = "on";} else {$mssfixactive = "off";}
3041 #my @n2nmssfix = split(/ /, (grep { /^mssfix/ } @firen2nconf)[0]);
3042 my @n2nfragment = split(/ /, (grep { /^fragment/ } @firen2nconf)[0]);
3043 my @n2nremote = split(/ /, (grep { /^remote/ } @firen2nconf)[0]);
3044 my @n2novpnsuball = split(/ /, (grep { /^ifconfig/ } @firen2nconf)[0]);
3045 my @n2novpnsub = split(/\./,$n2novpnsuball[1]);
3046 my @n2nremsub = split(/ /, (grep { /^route/ } @firen2nconf)[0]);
3047 my @n2nmgmt = split(/ /, (grep { /^management/ } @firen2nconf)[0]);
3048 my @n2nlocalsub = split(/ /, (grep { /^# remsub/ } @firen2nconf)[0]);
3049
3050
3051 ###
3052 # m.a.d delete CR and LF from arrays for this chomp doesnt work
3053 ###
3054
3055 $n2nremote[1] =~ s/\n|\r//g;
3056 $n2novpnsub[0] =~ s/\n|\r//g;
3057 $n2novpnsub[1] =~ s/\n|\r//g;
3058 $n2novpnsub[2] =~ s/\n|\r//g;
3059 $n2nproto[0] =~ s/\n|\r//g;
3060 $n2nport[1] =~ s/\n|\r//g;
3061 $n2ntunmtu[1] =~ s/\n|\r//g;
3062 $n2nremsub[1] =~ s/\n|\r//g;
3063 $n2nremsub[2] =~ s/\n|\r//g;
3064 $n2nlocalsub[2] =~ s/\n|\r//g;
3065 $n2nfragment[1] =~ s/\n|\r//g;
3066 $n2nmgmt[2] =~ s/\n|\r//g;
3067 $n2nmtudisc[1] =~ s/\n|\r//g;
3068 chomp ($complzoactive);
3069 chomp ($mssfixactive);
3070
3071 ###
3072 # m.a.d net2net
3073 ###
3074
3075 ###
3076 # Check if there is no other entry with this name
3077 ###
3078
3079 foreach my $dkey (keys %confighash) {
3080 if ($confighash{$dkey}[1] eq $n2nname[0]) {
3081 $errormessage = $Lang::tr{'a connection with this name already exists'};
3082 unlink ("${General::swroot}/ovpn/n2nconf/$n2nname[0]/$n2nname[0].conf") or die "Removing Configfile fail: $!";
3083 unlink ("${General::swroot}/ovpn/certs/$n2nname[0].p12") or die "Removing Certfile fail: $!";
3084 rmdir ("${General::swroot}/ovpn/n2nconf/$n2nname[0]") || die "Removing Directory fail: $!";
3085 goto N2N_ERROR;
3086 }
3087 }
3088
3089 ###
3090 # Check if OpenVPN Subnet is valid
3091 ###
3092
3093 foreach my $dkey (keys %confighash) {
3094 if ($confighash{$dkey}[27] eq "$n2novpnsub[0].$n2novpnsub[1].$n2novpnsub[2].0/255.255.255.0") {
3095 $errormessage = 'The OpenVPN Subnet is already in use';
3096 unlink ("${General::swroot}/ovpn/n2nconf/$n2nname[0]/$n2nname[0].conf") or die "Removing Configfile fail: $!";
3097 unlink ("${General::swroot}/ovpn/certs/$n2nname[0].p12") or die "Removing Certfile fail: $!";
3098 rmdir ("${General::swroot}/ovpn/n2nconf/$n2nname[0]") || die "Removing Directory fail: $!";
3099 goto N2N_ERROR;
3100 }
3101 }
3102
3103 ###
3104 # Check im Dest Port is vaild
3105 ###
3106
3107 foreach my $dkey (keys %confighash) {
3108 if ($confighash{$dkey}[29] eq $n2nport[1] ) {
3109 $errormessage = 'The OpenVPN Port is already in use';
3110 unlink ("${General::swroot}/ovpn/n2nconf/$n2nname[0]/$n2nname[0].conf") or die "Removing Configfile fail: $!";
3111 unlink ("${General::swroot}/ovpn/certs/$n2nname[0].p12") or die "Removing Certfile fail: $!";
3112 rmdir ("${General::swroot}/ovpn/n2nconf/$n2nname[0]") || die "Removing Directory fail: $!";
3113 goto N2N_ERROR;
3114 }
3115 }
3116
3117
3118
3119 $key = &General::findhasharraykey (\%confighash);
3120
3121 foreach my $i (0 .. 39) { $confighash{$key}[$i] = "";}
3122
3123 $confighash{$key}[0] = 'off';
3124 $confighash{$key}[1] = $n2nname[0];
3125 $confighash{$key}[2] = $n2nname[0];
3126 $confighash{$key}[3] = 'net';
3127 $confighash{$key}[4] = 'cert';
3128 $confighash{$key}[6] = 'client';
3129 $confighash{$key}[8] = $n2nlocalsub[2];
3130 $confighash{$key}[10] = $n2nremote[1];
3131 $confighash{$key}[11] = "$n2nremsub[1]/$n2nremsub[2]";
3132 $confighash{$key}[22] = $n2nmgmt[2];
3133 $confighash{$key}[23] = $mssfixactive;
3134 $confighash{$key}[24] = $n2nfragment[1];
3135 $confighash{$key}[25] = 'IPFire n2n Client';
3136 $confighash{$key}[26] = 'red';
3137 $confighash{$key}[27] = "$n2novpnsub[0].$n2novpnsub[1].$n2novpnsub[2].0/255.255.255.0";
3138 $confighash{$key}[28] = $n2nproto[0];
3139 $confighash{$key}[29] = $n2nport[1];
3140 $confighash{$key}[30] = $complzoactive;
3141 $confighash{$key}[31] = $n2ntunmtu[1];
3142 $confighash{$key}[38] = $n2nmtudisc[1];
3143
3144
3145 &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
3146
3147 N2N_ERROR:
3148
3149 &Header::showhttpheaders();
3150 &Header::openpage('Validate imported configuration', 1, '');
3151 &Header::openbigbox('100%', 'LEFT', '', $errormessage);
3152 if ($errormessage) {
3153 &Header::openbox('100%', 'LEFT', $Lang::tr{'error messages'});
3154 print "<class name='base'>$errormessage";
3155 print "&nbsp;</class>";
3156 &Header::closebox();
3157
3158 } else
3159 {
3160 &Header::openbox('100%', 'LEFT', 'import ipfire net2net config');
3161 }
3162 if ($errormessage eq ''){
3163 print <<END
3164 <!-- ipfire net2net config gui -->
3165 <table width='100%'>
3166 <tr><td width='25%'>&nbsp;</td><td width='25%'>&nbsp;</td></tr>
3167 <tr><td class='boldbase'>$Lang::tr{'name'}:</td><td><b>$n2nname[0]</b></td></tr>
3168 <tr><td>&nbsp;</td><td>&nbsp;</td></tr>
3169 <tr><td class='boldbase' nowrap='nowrap'>$Lang::tr{'Act as'}</td><td><b>$confighash{$key}[6]</b></td></tr>
3170 <tr><td class='boldbase' nowrap='nowrap'>Remote Host </td><td><b>$confighash{$key}[10]</b></td></tr>
3171 <tr><td class='boldbase' nowrap='nowrap'>$Lang::tr{'local subnet'}</td><td><b>$confighash{$key}[8]</b></td></tr>
3172 <tr><td class='boldbase' nowrap='nowrap'>$Lang::tr{'remote subnet'}</td><td><b>$confighash{$key}[11]</b></td></tr>
3173 <tr><td class='boldbase' nowrap='nowrap'>$Lang::tr{'ovpn subnet'}</td><td><b>$confighash{$key}[27]</b></td></tr>
3174 <tr><td class='boldbase' nowrap='nowrap'>$Lang::tr{'protocol'}</td><td><b>$confighash{$key}[28]</b></td></tr>
3175 <tr><td class='boldbase' nowrap='nowrap'>$Lang::tr{'destination port'}:</td><td><b>$confighash{$key}[29]</b></td></tr>
3176 <tr><td class='boldbase' nowrap='nowrap'>$Lang::tr{'comp-lzo'}</td><td><b>$confighash{$key}[30]</b></td></tr>
3177 <tr><td class='boldbase' nowrap='nowrap'>MSSFIX </td><td><b>$confighash{$key}[23]</b></td></tr>
3178 <tr><td class='boldbase' nowrap='nowrap'>Fragment </td><td><b>$confighash{$key}[24]</b></td></tr>
3179 <tr><td class='boldbase' nowrap='nowrap'>$Lang::tr{'MTU'}</td><td><b>$confighash{$key}[31]</b></td></tr>
3180 <tr><td class='boldbase' nowrap='nowrap'>$Lang::tr{'ovpn mtu-disc'}</td><td><b>$confighash{$key}[38]</b></td></tr>
3181 <tr><td class='boldbase' nowrap='nowrap'>Management Port </td><td><b>$confighash{$key}[22]</b></td></tr>
3182 <tr><td>&nbsp;</td><td>&nbsp;</td></tr>
3183 </table>
3184 END
3185 ;
3186 &Header::closebox();
3187 }
3188
3189 if ($errormessage) {
3190 print "<div align='center'><a href='/cgi-bin/ovpnmain.cgi'>$Lang::tr{'back'}</a></div>";
3191 } else {
3192 print "<div align='center'><form method='post' ENCTYPE='multipart/form-data'><input type='submit' name='ACTION' value='$Lang::tr{'add'}' />";
3193 print "<input type='hidden' name='TYPE' value='net2netakn' />";
3194 print "<input type='hidden' name='KEY' value='$key' />";
3195 print "<input type='submit' name='ACTION' value='$Lang::tr{'cancel'}' /></div></form>";
3196 }
3197 &Header::closebigbox();
3198 &Header::closepage();
3199 exit(0);
3200
3201
3202 ##
3203 ### Accept IPFire n2n Package Settings
3204 ###
3205
3206 } elsif (($cgiparams{'ACTION'} eq $Lang::tr{'add'}) && ($cgiparams{'TYPE'} eq 'net2netakn')){
3207
3208 ###
3209 ### Discard and Rollback IPFire n2n Package Settings
3210 ###
3211
3212 } elsif (($cgiparams{'ACTION'} eq $Lang::tr{'cancel'}) && ($cgiparams{'TYPE'} eq 'net2netakn')){
3213
3214 &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
3215
3216 if ($confighash{$cgiparams{'KEY'}}) {
3217
3218 my $conffile = glob("${General::swroot}/ovpn/n2nconf/$confighash{$cgiparams{'KEY'}}[1]/$confighash{$cgiparams{'KEY'}}[1].conf");
3219 my $certfile = glob("${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12");
3220 unlink ($certfile) or die "Removing $certfile fail: $!";
3221 unlink ($conffile) or die "Removing $conffile fail: $!";
3222 rmdir ("${General::swroot}/ovpn/n2nconf/$confighash{$cgiparams{'KEY'}}[1]") || die "Kann Verzeichnis nicht loeschen: $!";
3223 delete $confighash{$cgiparams{'KEY'}};
3224 &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
3225
3226 } else {
3227 $errormessage = $Lang::tr{'invalid key'};
3228 }
3229
3230
3231 ###
3232 # m.a.d net2net
3233 ###
3234
3235
3236 ###
3237 ### Adding a new connection
3238 ###
3239 } elsif (($cgiparams{'ACTION'} eq $Lang::tr{'add'}) ||
3240 ($cgiparams{'ACTION'} eq $Lang::tr{'edit'}) ||
3241 ($cgiparams{'ACTION'} eq $Lang::tr{'save'} && $cgiparams{'ADVANCED'} eq '')) {
3242
3243 &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings);
3244 &General::readhasharray("${General::swroot}/ovpn/caconfig", \%cahash);
3245 &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
3246
3247 if ($cgiparams{'ACTION'} eq $Lang::tr{'edit'}) {
3248 if (! $confighash{$cgiparams{'KEY'}}[0]) {
3249 $errormessage = $Lang::tr{'invalid key'};
3250 goto VPNCONF_END;
3251 }
3252 $cgiparams{'ENABLED'} = $confighash{$cgiparams{'KEY'}}[0];
3253 $cgiparams{'NAME'} = $confighash{$cgiparams{'KEY'}}[1];
3254 $cgiparams{'TYPE'} = $confighash{$cgiparams{'KEY'}}[3];
3255 $cgiparams{'AUTH'} = $confighash{$cgiparams{'KEY'}}[4];
3256 $cgiparams{'PSK'} = $confighash{$cgiparams{'KEY'}}[5];
3257 $cgiparams{'SIDE'} = $confighash{$cgiparams{'KEY'}}[6];
3258 $cgiparams{'LOCAL_SUBNET'} = $confighash{$cgiparams{'KEY'}}[8];
3259 $cgiparams{'REMOTE'} = $confighash{$cgiparams{'KEY'}}[10];
3260 $cgiparams{'REMOTE_SUBNET'} = $confighash{$cgiparams{'KEY'}}[11];
3261 $cgiparams{'OVPN_MGMT'} = $confighash{$cgiparams{'KEY'}}[22];
3262 $cgiparams{'MSSFIX'} = $confighash{$cgiparams{'KEY'}}[23];
3263 $cgiparams{'FRAGMENT'} = $confighash{$cgiparams{'KEY'}}[24];
3264 $cgiparams{'REMARK'} = $confighash{$cgiparams{'KEY'}}[25];
3265 $cgiparams{'INTERFACE'} = $confighash{$cgiparams{'KEY'}}[26];
3266 $cgiparams{'OVPN_SUBNET'} = $confighash{$cgiparams{'KEY'}}[27];
3267 $cgiparams{'PROTOCOL'} = $confighash{$cgiparams{'KEY'}}[28];
3268 $cgiparams{'DEST_PORT'} = $confighash{$cgiparams{'KEY'}}[29];
3269 $cgiparams{'COMPLZO'} = $confighash{$cgiparams{'KEY'}}[30];
3270 $cgiparams{'MTU'} = $confighash{$cgiparams{'KEY'}}[31];
3271 $cgiparams{'CHECK1'} = $confighash{$cgiparams{'KEY'}}[32];
3272 $name=$cgiparams{'CHECK1'} ;
3273 $cgiparams{$name} = $confighash{$cgiparams{'KEY'}}[33];
3274 $cgiparams{'RG'} = $confighash{$cgiparams{'KEY'}}[34];
3275 $cgiparams{'CCD_DNS1'} = $confighash{$cgiparams{'KEY'}}[35];
3276 $cgiparams{'CCD_DNS2'} = $confighash{$cgiparams{'KEY'}}[36];
3277 $cgiparams{'CCD_WINS'} = $confighash{$cgiparams{'KEY'}}[37];
3278 $cgiparams{'PMTU_DISCOVERY'} = $confighash{$cgiparams{'KEY'}}[38];
3279 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'save'}) {
3280 $cgiparams{'REMARK'} = &Header::cleanhtml($cgiparams{'REMARK'});
3281
3282 #A.Marx CCD check iroute field and convert it to decimal
3283 if ($cgiparams{'TYPE'} eq 'host') {
3284 my @temp=();
3285 my %ccdroutehash=();
3286 my $keypoint=0;
3287 my $ip;
3288 my $cidr;
3289 if ($cgiparams{'IR'} ne ''){
3290 @temp = split("\n",$cgiparams{'IR'});
3291 &General::readhasharray("${General::swroot}/ovpn/ccdroute", \%ccdroutehash);
3292 #find key to use
3293 foreach my $key (keys %ccdroutehash) {
3294 if ($ccdroutehash{$key}[0] eq $cgiparams{'NAME'}) {
3295 $keypoint=$key;
3296 delete $ccdroutehash{$key};
3297 }else{
3298 $keypoint = &General::findhasharraykey (\%ccdroutehash);
3299 }
3300 }
3301 $ccdroutehash{$keypoint}[0]=$cgiparams{'NAME'};
3302 my $i=1;
3303 my $val=0;
3304 foreach $val (@temp){
3305 chomp($val);
3306 $val=~s/\s*$//g;
3307 #check if iroute exists in ccdroute or if new iroute is part of an existing one
3308 foreach my $key (keys %ccdroutehash) {
3309 foreach my $oldiroute ( 1 .. $#{$ccdroutehash{$key}}){
3310 if ($ccdroutehash{$key}[$oldiroute] eq "$val") {
3311 $errormessage=$errormessage.$Lang::tr{'ccd err irouteexist'};
3312 goto VPNCONF_ERROR;
3313 }
3314 my ($ip1,$cidr1) = split (/\//, $val);
3315 $ip1 = &General::getnetworkip($ip1,&General::iporsubtocidr($cidr1));
3316 my ($ip2,$cidr2) = split (/\//, $ccdroutehash{$key}[$oldiroute]);
3317 if (&General::IpInSubnet ($ip1,$ip2,$cidr2)){
3318 $errormessage=$errormessage.$Lang::tr{'ccd err irouteexist'};
3319 goto VPNCONF_ERROR;
3320 }
3321
3322 }
3323 }
3324 if (!&General::validipandmask($val)){
3325 $errormessage=$errormessage."Route ".$Lang::tr{'ccd invalid'}." ($val)";
3326 goto VPNCONF_ERROR;
3327 }else{
3328 ($ip,$cidr) = split(/\//,$val);
3329 $ip=&General::getnetworkip($ip,&General::iporsubtocidr($cidr));
3330 $cidr=&General::iporsubtodec($cidr);
3331 $ccdroutehash{$keypoint}[$i] = $ip."/".$cidr;
3332
3333 }
3334
3335 #check for existing network IP's
3336 if (&General::IpInSubnet ($ip,$netsettings{GREEN_NETADDRESS},$netsettings{GREEN_NETMASK}) && $netsettings{GREEN_NETADDRESS} ne '0.0.0.0')
3337 {
3338 $errormessage=$Lang::tr{'ccd err green'};
3339 goto VPNCONF_ERROR;
3340 }elsif(&General::IpInSubnet ($ip,$netsettings{RED_NETADDRESS},$netsettings{RED_NETMASK}) && $netsettings{RED_NETADDRESS} ne '0.0.0.0')
3341 {
3342 $errormessage=$Lang::tr{'ccd err red'};
3343 goto VPNCONF_ERROR;
3344 }elsif(&General::IpInSubnet ($ip,$netsettings{BLUE_NETADDRESS},$netsettings{BLUE_NETMASK}) && $netsettings{BLUE_NETADDRESS} ne '0.0.0.0' && $netsettings{BLUE_NETADDRESS} gt '')
3345 {
3346 $errormessage=$Lang::tr{'ccd err blue'};
3347 goto VPNCONF_ERROR;
3348 }elsif(&General::IpInSubnet ($ip,$netsettings{ORANGE_NETADDRESS},$netsettings{ORANGE_NETMASK}) && $netsettings{ORANGE_NETADDRESS} ne '0.0.0.0' && $netsettings{ORANGE_NETADDRESS} gt '' )
3349 {
3350 $errormessage=$Lang::tr{'ccd err orange'};
3351 goto VPNCONF_ERROR;
3352 }
3353
3354 if (&General::validipandmask($val)){
3355 $ccdroutehash{$keypoint}[$i] = $ip."/".$cidr;
3356 }else{
3357 $errormessage=$errormessage."Route ".$Lang::tr{'ccd invalid'}." ($ip/$cidr)";
3358 goto VPNCONF_ERROR;
3359 }
3360 $i++;
3361 }
3362 &General::writehasharray("${General::swroot}/ovpn/ccdroute", \%ccdroutehash);
3363 &writeserverconf;
3364 }else{
3365 &General::readhasharray("${General::swroot}/ovpn/ccdroute", \%ccdroutehash);
3366 foreach my $key (keys %ccdroutehash) {
3367 if ($ccdroutehash{$key}[0] eq $cgiparams{'NAME'}) {
3368 delete $ccdroutehash{$key};
3369 &General::writehasharray("${General::swroot}/ovpn/ccdroute", \%ccdroutehash);
3370 &writeserverconf;
3371 }
3372 }
3373 }
3374 undef @temp;
3375 #check route field and convert it to decimal
3376 my $val=0;
3377 my $i=1;
3378 &General::readhasharray("${General::swroot}/ovpn/ccdroute2", \%ccdroute2hash);
3379 #find key to use
3380 foreach my $key (keys %ccdroute2hash) {
3381 if ($ccdroute2hash{$key}[0] eq $cgiparams{'NAME'}) {
3382 $keypoint=$key;
3383 delete $ccdroute2hash{$key};
3384 }else{
3385 $keypoint = &General::findhasharraykey (\%ccdroute2hash);
3386 &General::writehasharray("${General::swroot}/ovpn/ccdroute", \%ccdroutehash);
3387 &writeserverconf;
3388 }
3389 }
3390 $ccdroute2hash{$keypoint}[0]=$cgiparams{'NAME'};
3391 if ($cgiparams{'IFROUTE'} eq ''){$cgiparams{'IFROUTE'} = $Lang::tr{'ccd none'};}
3392 @temp = split(/\|/,$cgiparams{'IFROUTE'});
3393 my %ownnet=();
3394 &General::readhash("${General::swroot}/ethernet/settings", \%ownnet);
3395 foreach $val (@temp){
3396 chomp($val);
3397 $val=~s/\s*$//g;
3398 if ($val eq $Lang::tr{'green'})
3399 {
3400 $val=$ownnet{GREEN_NETADDRESS}."/".$ownnet{GREEN_NETMASK};
3401 }
3402 if ($val eq $Lang::tr{'blue'})
3403 {
3404 $val=$ownnet{BLUE_NETADDRESS}."/".$ownnet{BLUE_NETMASK};
3405 }
3406 if ($val eq $Lang::tr{'orange'})
3407 {
3408 $val=$ownnet{ORANGE_NETADDRESS}."/".$ownnet{ORANGE_NETMASK};
3409 }
3410 my ($ip,$cidr) = split (/\//, $val);
3411
3412 if ($val ne $Lang::tr{'ccd none'})
3413 {
3414 if (! &check_routes_push($val)){$errormessage=$errormessage."Route $val ".$Lang::tr{'ccd err routeovpn2'}." ($val)";goto VPNCONF_ERROR;}
3415 if (! &check_ccdroute($val)){$errormessage=$errormessage."<br>Route $val ".$Lang::tr{'ccd err inuse'}." ($val)" ;goto VPNCONF_ERROR;}
3416 if (! &check_ccdconf($val)){$errormessage=$errormessage."<br>Route $val ".$Lang::tr{'ccd err routeovpn'}." ($val)";goto VPNCONF_ERROR;}
3417 if (&General::validipandmask($val)){
3418 $val=$ip."/".&General::iporsubtodec($cidr);
3419 $ccdroute2hash{$keypoint}[$i] = $val;
3420 }else{
3421 $errormessage=$errormessage."Route ".$Lang::tr{'ccd invalid'}." ($val)";
3422 goto VPNCONF_ERROR;
3423 }
3424 }else{
3425 $ccdroute2hash{$keypoint}[$i]='';
3426 }
3427 $i++;
3428 }
3429 &General::writehasharray("${General::swroot}/ovpn/ccdroute2", \%ccdroute2hash);
3430
3431 #check dns1 ip
3432 if ($cgiparams{'CCD_DNS1'} ne '' && ! &General::validip($cgiparams{'CCD_DNS1'})) {
3433 $errormessage=$errormessage."<br>".$Lang::tr{'invalid input for dhcp dns'}." 1";
3434 goto VPNCONF_ERROR;
3435 }
3436 #check dns2 ip
3437 if ($cgiparams{'CCD_DNS2'} ne '' && ! &General::validip($cgiparams{'CCD_DNS2'})) {
3438 $errormessage=$errormessage."<br>".$Lang::tr{'invalid input for dhcp dns'}." 2";
3439 goto VPNCONF_ERROR;
3440 }
3441 #check wins ip
3442 if ($cgiparams{'CCD_WINS'} ne '' && ! &General::validip($cgiparams{'CCD_WINS'})) {
3443 $errormessage=$errormessage."<br>".$Lang::tr{'invalid input for dhcp wins'};
3444 goto VPNCONF_ERROR;
3445 }
3446 }
3447
3448 #CCD End
3449
3450
3451 if ($cgiparams{'TYPE'} !~ /^(host|net)$/) {
3452 $errormessage = $Lang::tr{'connection type is invalid'};
3453 if ($cgiparams{'TYPE'} eq 'net') {
3454 unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!";
3455 rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!";
3456 }
3457 goto VPNCONF_ERROR;
3458 }
3459
3460
3461 if ($cgiparams{'NAME'} !~ /^[a-zA-Z0-9]+$/) {
3462 $errormessage = $Lang::tr{'name must only contain characters'};
3463 if ($cgiparams{'TYPE'} eq 'net') {
3464 unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!";
3465 rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!";
3466 }
3467 goto VPNCONF_ERROR;
3468 }
3469
3470 if ($cgiparams{'NAME'} =~ /^(host|01|block|private|clear|packetdefault)$/) {
3471 $errormessage = $Lang::tr{'name is invalid'};
3472 if ($cgiparams{'TYPE'} eq 'net') {
3473 unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!";
3474 rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!";
3475 }
3476 goto VPNCONF_ERROR;
3477 }
3478
3479 if (length($cgiparams{'NAME'}) >60) {
3480 $errormessage = $Lang::tr{'name too long'};
3481 if ($cgiparams{'TYPE'} eq 'net') {
3482 unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!";
3483 rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!";
3484 }
3485 goto VPNCONF_ERROR;
3486 }
3487
3488 ###
3489 # m.a.d net2net
3490 ###
3491
3492 if ($cgiparams{'TYPE'} eq 'net') {
3493 if ($cgiparams{'DEST_PORT'} eq $vpnsettings{'DDEST_PORT'}) {
3494 $errormessage = $Lang::tr{'openvpn destination port used'};
3495 unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!";
3496 rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!";
3497 goto VPNCONF_ERROR;
3498 }
3499 #Bugfix 10357
3500 foreach my $key (sort keys %confighash){
3501 if ( ($confighash{$key}[22] eq $cgiparams{'DEST_PORT'} && $cgiparams{'NAME'} ne $confighash{$key}[1]) || ($confighash{$key}[29] eq $cgiparams{'DEST_PORT'} && $cgiparams{'NAME'} ne $confighash{$key}[1])){
3502 $errormessage = $Lang::tr{'openvpn destination port used'};
3503 unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!";
3504 rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!";
3505 goto VPNCONF_ERROR;
3506 }
3507 }
3508 if ($cgiparams{'DEST_PORT'} eq '') {
3509 $errormessage = $Lang::tr{'invalid port'};
3510 unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!";
3511 rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!";
3512 goto VPNCONF_ERROR;
3513 }
3514
3515 # Check if the input for the transfer net is valid.
3516 if (!&General::validipandmask($cgiparams{'OVPN_SUBNET'})){
3517 $errormessage = $Lang::tr{'ccd err invalidnet'};
3518 unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!";
3519 rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!";
3520 goto VPNCONF_ERROR;
3521 }
3522
3523 if ($cgiparams{'OVPN_SUBNET'} eq $vpnsettings{'DOVPN_SUBNET'}) {
3524 $errormessage = $Lang::tr{'openvpn subnet is used'};
3525 unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!";
3526 rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!";
3527 goto VPNCONF_ERROR;
3528 }
3529
3530 if (($cgiparams{'PROTOCOL'} eq 'tcp') && ($cgiparams{'MSSFIX'} eq 'on')) {
3531 $errormessage = $Lang::tr{'openvpn mssfix allowed with udp'};
3532 unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!";
3533 rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!";
3534 goto VPNCONF_ERROR;
3535 }
3536
3537 if (($cgiparams{'PROTOCOL'} eq 'tcp') && ($cgiparams{'FRAGMENT'} ne '')) {
3538 $errormessage = $Lang::tr{'openvpn fragment allowed with udp'};
3539 unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!";
3540 rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!";
3541 goto VPNCONF_ERROR;
3542 }
3543
3544 if ($cgiparams{'PMTU_DISCOVERY'} ne 'off') {
3545 if (($cgiparams{'FRAGMENT'} ne '') || ($cgiparams{'MSSFIX'} eq 'on')) {
3546 $errormessage = $Lang::tr{'ovpn mtu-disc with mssfix or fragment'};
3547 unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!";
3548 rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!";
3549 goto VPNCONF_ERROR;
3550 }
3551 }
3552
3553 if (($cgiparams{'PMTU_DISCOVERY'} ne 'off') && ($cgiparams{'MTU'} ne '1500')) {
3554 $errormessage = $Lang::tr{'ovpn mtu-disc and mtu not 1500'};
3555 unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!";
3556 rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!";
3557 goto VPNCONF_ERROR;
3558 }
3559
3560 if ( &validdotmask ($cgiparams{'LOCAL_SUBNET'})) {
3561 $errormessage = $Lang::tr{'openvpn prefix local subnet'};
3562 unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!";
3563 rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!";
3564 goto VPNCONF_ERROR;
3565 }
3566
3567 if ( &validdotmask ($cgiparams{'OVPN_SUBNET'})) {
3568 $errormessage = $Lang::tr{'openvpn prefix openvpn subnet'};
3569 unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!";
3570 rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!";
3571 goto VPNCONF_ERROR;
3572 }
3573
3574 if ( &validdotmask ($cgiparams{'REMOTE_SUBNET'})) {
3575 $errormessage = $Lang::tr{'openvpn prefix remote subnet'};
3576 unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!";
3577 rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!";
3578 goto VPNCONF_ERROR;
3579 }
3580
3581 if ($cgiparams{'OVPN_MGMT'} eq '') {
3582 $cgiparams{'OVPN_MGMT'} = $cgiparams{'DEST_PORT'};
3583 }
3584
3585 }
3586
3587 # if (($cgiparams{'TYPE'} eq 'net') && ($cgiparams{'SIDE'} !~ /^(left|right)$/)) {
3588 # $errormessage = $Lang::tr{'ipfire side is invalid'};
3589 # goto VPNCONF_ERROR;
3590 # }
3591
3592 # Check if there is no other entry with this name
3593 if (! $cgiparams{'KEY'}) {
3594 foreach my $key (keys %confighash) {
3595 if ($confighash{$key}[1] eq $cgiparams{'NAME'}) {
3596 $errormessage = $Lang::tr{'a connection with this name already exists'};
3597 if ($cgiparams{'TYPE'} eq 'net') {
3598 unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!";
3599 rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!";
3600 }
3601 goto VPNCONF_ERROR;
3602 }
3603 }
3604 }
3605
3606 # Check if a remote host/IP has been set for the client.
3607 if ($cgiparams{'TYPE'} eq 'net') {
3608 if ($cgiparams{'SIDE'} ne 'server' && $cgiparams{'REMOTE'} eq '') {
3609 $errormessage = $Lang::tr{'invalid input for remote host/ip'};
3610
3611 # Check if this is a N2N connection and drop temporary config.
3612 unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!";
3613 rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!";
3614
3615 goto VPNCONF_ERROR;
3616 }
3617
3618 # Check if a remote host/IP has been configured - the field can be empty on the server side.
3619 if ($cgiparams{'REMOTE'} ne '') {
3620 # Check if the given IP is valid - otherwise check if it is a valid domain.
3621 if (! &General::validip($cgiparams{'REMOTE'})) {
3622 # Check for a valid domain.
3623 if (! &General::validfqdn ($cgiparams{'REMOTE'})) {
3624 $errormessage = $Lang::tr{'invalid input for remote host/ip'};
3625
3626 # Check if this is a N2N connection and drop temporary config.
3627 unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!";
3628 rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!";
3629
3630 goto VPNCONF_ERROR;
3631 }
3632 }
3633 }
3634 }
3635
3636 if ($cgiparams{'TYPE'} ne 'host') {
3637 unless (&General::validipandmask($cgiparams{'LOCAL_SUBNET'})) {
3638 $errormessage = $Lang::tr{'local subnet is invalid'};
3639 if ($cgiparams{'TYPE'} eq 'net') {
3640 unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!";
3641 rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!";
3642 }
3643 goto VPNCONF_ERROR;}
3644 }
3645 # Check if there is no other entry without IP-address and PSK
3646 if ($cgiparams{'REMOTE'} eq '') {
3647 foreach my $key (keys %confighash) {
3648 if(($cgiparams{'KEY'} ne $key) &&
3649 ($confighash{$key}[4] eq 'psk' || $cgiparams{'AUTH'} eq 'psk') &&
3650 $confighash{$key}[10] eq '') {
3651 $errormessage = $Lang::tr{'you can only define one roadwarrior connection when using pre-shared key authentication'};
3652 goto VPNCONF_ERROR;
3653 }
3654 }
3655 }
3656 if (($cgiparams{'TYPE'} eq 'net') && (! &General::validipandmask($cgiparams{'REMOTE_SUBNET'}))) {
3657 $errormessage = $Lang::tr{'remote subnet is invalid'};
3658 unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!";
3659 rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!";
3660 goto VPNCONF_ERROR;
3661 }
3662
3663 if ($cgiparams{'ENABLED'} !~ /^(on|off)$/) {
3664 $errormessage = $Lang::tr{'invalid input'};
3665 goto VPNCONF_ERROR;
3666 }
3667 if ($cgiparams{'EDIT_ADVANCED'} !~ /^(on|off)$/) {
3668 $errormessage = $Lang::tr{'invalid input'};
3669 goto VPNCONF_ERROR;
3670 }
3671
3672 #fixplausi
3673 if ($cgiparams{'AUTH'} eq 'psk') {
3674 # if (! length($cgiparams{'PSK'}) ) {
3675 # $errormessage = $Lang::tr{'pre-shared key is too short'};
3676 # goto VPNCONF_ERROR;
3677 # }
3678 # if ($cgiparams{'PSK'} =~ /['",&]/) {
3679 # $errormessage = $Lang::tr{'invalid characters found in pre-shared key'};
3680 # goto VPNCONF_ERROR;
3681 # }
3682 } elsif ($cgiparams{'AUTH'} eq 'certreq') {
3683 if ($cgiparams{'KEY'}) {
3684 $errormessage = $Lang::tr{'cant change certificates'};
3685 goto VPNCONF_ERROR;
3686 }
3687 if (ref ($cgiparams{'FH'}) ne 'Fh') {
3688 $errormessage = $Lang::tr{'there was no file upload'};
3689 goto VPNCONF_ERROR;
3690 }
3691
3692 # Move uploaded certificate request to a temporary file
3693 (my $fh, my $filename) = tempfile( );
3694 if (copy ($cgiparams{'FH'}, $fh) != 1) {
3695 $errormessage = $!;
3696 goto VPNCONF_ERROR;
3697 }
3698
3699 # Sign the certificate request and move it
3700 # Sign the host certificate request
3701 system('/usr/bin/openssl', 'ca', '-days', "$cgiparams{'DAYS_VALID'}",
3702 '-batch', '-notext',
3703 '-in', $filename,
3704 '-out', "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem",
3705 '-config',"${General::swroot}/ovpn/openssl/ovpn.cnf");
3706 if ($?) {
3707 $errormessage = "$Lang::tr{'openssl produced an error'}: $?";
3708 unlink ($filename);
3709 unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem");
3710 &newcleanssldatabase();
3711 goto VPNCONF_ERROR;
3712 } else {
3713 unlink ($filename);
3714 &deletebackupcert();
3715 }
3716
3717 my $temp = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem`;
3718 $temp =~ /Subject:.*CN=(.*)[\n]/;
3719 $temp = $1;
3720 $temp =~ s+/Email+, E+;
3721 $temp =~ s/ ST=/ S=/;
3722 $cgiparams{'CERT_NAME'} = $temp;
3723 $cgiparams{'CERT_NAME'} =~ s/,//g;
3724 $cgiparams{'CERT_NAME'} =~ s/\'//g;
3725 if ($cgiparams{'CERT_NAME'} eq '') {
3726 $errormessage = $Lang::tr{'could not retrieve common name from certificate'};
3727 goto VPNCONF_ERROR;
3728 }
3729 } elsif ($cgiparams{'AUTH'} eq 'certfile') {
3730 if ($cgiparams{'KEY'}) {
3731 $errormessage = $Lang::tr{'cant change certificates'};
3732 goto VPNCONF_ERROR;
3733 }
3734 if (ref ($cgiparams{'FH'}) ne 'Fh') {
3735 $errormessage = $Lang::tr{'there was no file upload'};
3736 goto VPNCONF_ERROR;
3737 }
3738 # Move uploaded certificate to a temporary file
3739 (my $fh, my $filename) = tempfile( );
3740 if (copy ($cgiparams{'FH'}, $fh) != 1) {
3741 $errormessage = $!;
3742 goto VPNCONF_ERROR;
3743 }
3744
3745 # Verify the certificate has a valid CA and move it
3746 my $validca = 0;
3747 my $test = `/usr/bin/openssl verify -CAfile ${General::swroot}/ovpn/ca/cacert.pem $filename`;
3748 if ($test =~ /: OK/) {
3749 $validca = 1;
3750 } else {
3751 foreach my $key (keys %cahash) {
3752 $test = `/usr/bin/openssl verify -CAfile ${General::swroot}/ovpn/ca/$cahash{$key}[0]cert.pem $filename`;
3753 if ($test =~ /: OK/) {
3754 $validca = 1;
3755 }
3756 }
3757 }
3758 if (! $validca) {
3759 $errormessage = $Lang::tr{'certificate does not have a valid ca associated with it'};
3760 unlink ($filename);
3761 goto VPNCONF_ERROR;
3762 } else {
3763 move($filename, "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem");
3764 if ($? ne 0) {
3765 $errormessage = "$Lang::tr{'certificate file move failed'}: $!";
3766 unlink ($filename);
3767 goto VPNCONF_ERROR;
3768 }
3769 }
3770
3771 my $temp = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem`;
3772 $temp =~ /Subject:.*CN=(.*)[\n]/;
3773 $temp = $1;
3774 $temp =~ s+/Email+, E+;
3775 $temp =~ s/ ST=/ S=/;
3776 $cgiparams{'CERT_NAME'} = $temp;
3777 $cgiparams{'CERT_NAME'} =~ s/,//g;
3778 $cgiparams{'CERT_NAME'} =~ s/\'//g;
3779 if ($cgiparams{'CERT_NAME'} eq '') {
3780 unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem");
3781 $errormessage = $Lang::tr{'could not retrieve common name from certificate'};
3782 goto VPNCONF_ERROR;
3783 }
3784 } elsif ($cgiparams{'AUTH'} eq 'certgen') {
3785 if ($cgiparams{'KEY'}) {
3786 $errormessage = $Lang::tr{'cant change certificates'};
3787 goto VPNCONF_ERROR;
3788 }
3789 # Validate input since the form was submitted
3790 if (length($cgiparams{'CERT_NAME'}) >60) {
3791 $errormessage = $Lang::tr{'name too long'};
3792 goto VPNCONF_ERROR;
3793 }
3794 if ($cgiparams{'CERT_NAME'} !~ /^[a-zA-Z0-9 ,\.\-_]+$/) {
3795 $errormessage = $Lang::tr{'invalid input for name'};
3796 goto VPNCONF_ERROR;
3797 }
3798 if ($cgiparams{'CERT_EMAIL'} ne '' && (! &General::validemail($cgiparams{'CERT_EMAIL'}))) {
3799 $errormessage = $Lang::tr{'invalid input for e-mail address'};
3800 goto VPNCONF_ERROR;
3801 }
3802 if (length($cgiparams{'CERT_EMAIL'}) > 40) {
3803 $errormessage = $Lang::tr{'e-mail address too long'};
3804 goto VPNCONF_ERROR;
3805 }
3806 if ($cgiparams{'CERT_OU'} ne '' && $cgiparams{'CERT_OU'} !~ /^[a-zA-Z0-9 ,\.\-_]*$/) {
3807 $errormessage = $Lang::tr{'invalid input for department'};
3808 goto VPNCONF_ERROR;
3809 }
3810 if (length($cgiparams{'CERT_ORGANIZATION'}) >60) {
3811 $errormessage = $Lang::tr{'organization too long'};
3812 goto VPNCONF_ERROR;
3813 }
3814 if ($cgiparams{'CERT_ORGANIZATION'} !~ /^[a-zA-Z0-9 ,\.\-_]+$/) {
3815 $errormessage = $Lang::tr{'invalid input for organization'};
3816 goto VPNCONF_ERROR;
3817 }
3818 if ($cgiparams{'CERT_CITY'} ne '' && $cgiparams{'CERT_CITY'} !~ /^[a-zA-Z0-9 ,\.\-_]*$/) {
3819 $errormessage = $Lang::tr{'invalid input for city'};
3820 goto VPNCONF_ERROR;
3821 }
3822 if ($cgiparams{'CERT_STATE'} ne '' && $cgiparams{'CERT_STATE'} !~ /^[a-zA-Z0-9 ,\.\-_]*$/) {
3823 $errormessage = $Lang::tr{'invalid input for state or province'};
3824 goto VPNCONF_ERROR;
3825 }
3826 if ($cgiparams{'CERT_COUNTRY'} !~ /^[A-Z]*$/) {
3827 $errormessage = $Lang::tr{'invalid input for country'};
3828 goto VPNCONF_ERROR;
3829 }
3830 if ($cgiparams{'CERT_PASS1'} ne '' && $cgiparams{'CERT_PASS2'} ne ''){
3831 if (length($cgiparams{'CERT_PASS1'}) < 5) {
3832 $errormessage = $Lang::tr{'password too short'};
3833 goto VPNCONF_ERROR;
3834 }
3835 }
3836 if ($cgiparams{'CERT_PASS1'} ne $cgiparams{'CERT_PASS2'}) {
3837 $errormessage = $Lang::tr{'passwords do not match'};
3838 goto VPNCONF_ERROR;
3839 }
3840
3841 # Replace empty strings with a .
3842 (my $ou = $cgiparams{'CERT_OU'}) =~ s/^\s*$/\./;
3843 (my $city = $cgiparams{'CERT_CITY'}) =~ s/^\s*$/\./;
3844 (my $state = $cgiparams{'CERT_STATE'}) =~ s/^\s*$/\./;
3845
3846 # Create the Host certificate request client
3847 my $pid = open(OPENSSL, "|-");
3848 $SIG{ALRM} = sub { $errormessage = $Lang::tr{'broken pipe'}; goto VPNCONF_ERROR;};
3849 if ($pid) { # parent
3850 print OPENSSL "$cgiparams{'CERT_COUNTRY'}\n";
3851 print OPENSSL "$state\n";
3852 print OPENSSL "$city\n";
3853 print OPENSSL "$cgiparams{'CERT_ORGANIZATION'}\n";
3854 print OPENSSL "$ou\n";
3855 print OPENSSL "$cgiparams{'CERT_NAME'}\n";
3856 print OPENSSL "$cgiparams{'CERT_EMAIL'}\n";
3857 print OPENSSL ".\n";
3858 print OPENSSL ".\n";
3859 close (OPENSSL);
3860 if ($?) {
3861 $errormessage = "$Lang::tr{'openssl produced an error'}: $?";
3862 unlink ("${General::swroot}ovpn/certs/$cgiparams{'NAME'}key.pem");
3863 unlink ("${General::swroot}ovpn/certs/$cgiparams{'NAME'}req.pem");
3864 goto VPNCONF_ERROR;
3865 }
3866 } else { # child
3867 unless (exec ('/usr/bin/openssl', 'req', '-nodes', '-rand', '/proc/interrupts:/proc/net/rt_cache',
3868 '-newkey', 'rsa:1024',
3869 '-keyout', "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}key.pem",
3870 '-out', "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}req.pem",
3871 '-config',"${General::swroot}/ovpn/openssl/ovpn.cnf")) {
3872 $errormessage = "$Lang::tr{'cant start openssl'}: $!";
3873 unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}key.pem");
3874 unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}req.pem");
3875 goto VPNCONF_ERROR;
3876 }
3877 }
3878
3879 # Sign the host certificate request
3880 system('/usr/bin/openssl', 'ca', '-days', "$cgiparams{'DAYS_VALID'}",
3881 '-batch', '-notext',
3882 '-in', "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}req.pem",
3883 '-out', "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem",
3884 '-config',"${General::swroot}/ovpn/openssl/ovpn.cnf");
3885 if ($?) {
3886 $errormessage = "$Lang::tr{'openssl produced an error'}: $?";
3887 unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}key.pem");
3888 unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}req.pem");
3889 unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem");
3890 &newcleanssldatabase();
3891 goto VPNCONF_ERROR;
3892 } else {
3893 unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}req.pem");
3894 &deletebackupcert();
3895 }
3896
3897 # Create the pkcs12 file
3898 system('/usr/bin/openssl', 'pkcs12', '-export',
3899 '-inkey', "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}key.pem",
3900 '-in', "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem",
3901 '-name', $cgiparams{'NAME'},
3902 '-passout', "pass:$cgiparams{'CERT_PASS1'}",
3903 '-certfile', "${General::swroot}/ovpn/ca/cacert.pem",
3904 '-caname', "$vpnsettings{'ROOTCERT_ORGANIZATION'} CA",
3905 '-out', "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}.p12");
3906 if ($?) {
3907 $errormessage = "$Lang::tr{'openssl produced an error'}: $?";
3908 unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}key.pem");
3909 unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem");
3910 unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}.p12");
3911 goto VPNCONF_ERROR;
3912 } else {
3913 unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}key.pem");
3914 }
3915 } elsif ($cgiparams{'AUTH'} eq 'cert') {
3916 ;# Nothing, just editing
3917 } else {
3918 $errormessage = $Lang::tr{'invalid input for authentication method'};
3919 goto VPNCONF_ERROR;
3920 }
3921
3922 # Check if there is no other entry with this common name
3923 if ((! $cgiparams{'KEY'}) && ($cgiparams{'AUTH'} ne 'psk')) {
3924 foreach my $key (keys %confighash) {
3925 if ($confighash{$key}[2] eq $cgiparams{'CERT_NAME'}) {
3926 $errormessage = $Lang::tr{'a connection with this common name already exists'};
3927 goto VPNCONF_ERROR;
3928 }
3929 }
3930 }
3931
3932 # Save the config
3933 my $key = $cgiparams{'KEY'};
3934
3935 if (! $key) {
3936 $key = &General::findhasharraykey (\%confighash);
3937 foreach my $i (0 .. 38) { $confighash{$key}[$i] = "";}
3938 }
3939 $confighash{$key}[0] = $cgiparams{'ENABLED'};
3940 $confighash{$key}[1] = $cgiparams{'NAME'};
3941 if ((! $cgiparams{'KEY'}) && $cgiparams{'AUTH'} ne 'psk') {
3942 $confighash{$key}[2] = $cgiparams{'CERT_NAME'};
3943 }
3944
3945 $confighash{$key}[3] = $cgiparams{'TYPE'};
3946 if ($cgiparams{'AUTH'} eq 'psk') {
3947 $confighash{$key}[4] = 'psk';
3948 $confighash{$key}[5] = $cgiparams{'PSK'};
3949 } else {
3950 $confighash{$key}[4] = 'cert';
3951 }
3952 if ($cgiparams{'TYPE'} eq 'net') {
3953 $confighash{$key}[6] = $cgiparams{'SIDE'};
3954 $confighash{$key}[11] = $cgiparams{'REMOTE_SUBNET'};
3955 }
3956 $confighash{$key}[8] = $cgiparams{'LOCAL_SUBNET'};
3957 $confighash{$key}[10] = $cgiparams{'REMOTE'};
3958 if ($cgiparams{'OVPN_MGMT'} eq '') {
3959 $confighash{$key}[22] = $confighash{$key}[29];
3960 } else {
3961 $confighash{$key}[22] = $cgiparams{'OVPN_MGMT'};
3962 }
3963 $confighash{$key}[23] = $cgiparams{'MSSFIX'};
3964 $confighash{$key}[24] = $cgiparams{'FRAGMENT'};
3965 $confighash{$key}[25] = $cgiparams{'REMARK'};
3966 $confighash{$key}[26] = $cgiparams{'INTERFACE'};
3967 # new fields
3968 $confighash{$key}[27] = $cgiparams{'OVPN_SUBNET'};
3969 $confighash{$key}[28] = $cgiparams{'PROTOCOL'};
3970 $confighash{$key}[29] = $cgiparams{'DEST_PORT'};
3971 $confighash{$key}[30] = $cgiparams{'COMPLZO'};
3972 $confighash{$key}[31] = $cgiparams{'MTU'};
3973 $confighash{$key}[32] = $cgiparams{'CHECK1'};
3974 $name=$cgiparams{'CHECK1'};
3975 $confighash{$key}[33] = $cgiparams{$name};
3976 $confighash{$key}[34] = $cgiparams{'RG'};
3977 $confighash{$key}[35] = $cgiparams{'CCD_DNS1'};
3978 $confighash{$key}[36] = $cgiparams{'CCD_DNS2'};
3979 $confighash{$key}[37] = $cgiparams{'CCD_WINS'};
3980 $confighash{$key}[38] = $cgiparams{'PMTU_DISCOVERY'};
3981
3982
3983 &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
3984
3985 if ($cgiparams{'CHECK1'} ){
3986
3987 my ($ccdip,$ccdsub)=split "/",$cgiparams{$name};
3988 my ($a,$b,$c,$d) = split (/\./,$ccdip);
3989 if ( -e "${General::swroot}/ovpn/ccd/$confighash{$key}[2]"){
3990 unlink "${General::swroot}/ovpn/ccd/$cgiparams{'CERT_NAME'}";
3991 }
3992 $confighash{$key}[2] =~ s/ /_/gi;
3993 open ( CCDRWCONF,'>',"${General::swroot}/ovpn/ccd/$confighash{$key}[2]") or die "Unable to create clientconfigfile $!";
3994 print CCDRWCONF "# OpenVPN clientconfig from ccd extension by Copymaster#\n\n";
3995 if($cgiparams{'CHECK1'} eq 'dynamic'){
3996 print CCDRWCONF "#This client uses the dynamic pool\n";
3997 }else{
3998 print CCDRWCONF "#Ip address client and server\n";
3999 print CCDRWCONF "ifconfig-push $ccdip ".&General::getlastip($ccdip,1)."\n";
4000 }
4001 if ($confighash{$key}[34] eq 'on'){
4002 print CCDRWCONF "\n#Redirect Gateway: \n#All IP traffic is redirected through the vpn \n";
4003 print CCDRWCONF "push redirect-gateway\n";
4004 }
4005 &General::readhasharray("${General::swroot}/ovpn/ccdroute", \%ccdroutehash);
4006 if ($cgiparams{'IR'} ne ''){
4007 print CCDRWCONF "\n#Client routes these networks (behind Client)\n";
4008 foreach my $key (keys %ccdroutehash){
4009 if ($ccdroutehash{$key}[0] eq $cgiparams{'NAME'}){
4010 foreach my $i ( 1 .. $#{$ccdroutehash{$key}}){
4011 my ($a,$b)=split (/\//,$ccdroutehash{$key}[$i]);
4012 print CCDRWCONF "iroute $a $b\n";
4013 }
4014 }
4015 }
4016 }
4017 if ($cgiparams{'IFROUTE'} eq $Lang::tr{'ccd none'} ){$cgiparams{'IFROUTE'}='';}
4018 if ($cgiparams{'IFROUTE'} ne ''){
4019 print CCDRWCONF "\n#Client gets routes to these networks (behind IPFire)\n";
4020 foreach my $key (keys %ccdroute2hash){
4021 if ($ccdroute2hash{$key}[0] eq $cgiparams{'NAME'}){
4022 foreach my $i ( 1 .. $#{$ccdroute2hash{$key}}){
4023 if($ccdroute2hash{$key}[$i] eq $Lang::tr{'blue'}){
4024 my %blue=();
4025 &General::readhash("${General::swroot}/ethernet/settings", \%blue);
4026 print CCDRWCONF "push \"route $blue{BLUE_ADDRESS} $blue{BLUE_NETMASK}\n";
4027 }elsif($ccdroute2hash{$key}[$i] eq $Lang::tr{'orange'}){
4028 my %orange=();
4029 &General::readhash("${General::swroot}/ethernet/settings", \%orange);
4030 print CCDRWCONF "push \"route $orange{ORANGE_ADDRESS} $orange{ORANGE_NETMASK}\n";
4031 }else{
4032 my ($a,$b)=split (/\//,$ccdroute2hash{$key}[$i]);
4033 print CCDRWCONF "push \"route $a $b\"\n";
4034 }
4035 }
4036 }
4037 }
4038 }
4039 if(($cgiparams{'CCD_DNS1'} eq '') && ($cgiparams{'CCD_DNS1'} ne '')){ $cgiparams{'CCD_DNS1'} = $cgiparams{'CCD_DNS2'};$cgiparams{'CCD_DNS2'}='';}
4040 if($cgiparams{'CCD_DNS1'} ne ''){
4041 print CCDRWCONF "\n#Client gets these nameservers\n";
4042 print CCDRWCONF "push \"dhcp-option DNS $cgiparams{'CCD_DNS1'}\" \n";
4043 }
4044 if($cgiparams{'CCD_DNS2'} ne ''){
4045 print CCDRWCONF "push \"dhcp-option DNS $cgiparams{'CCD_DNS2'}\" \n";
4046 }
4047 if($cgiparams{'CCD_WINS'} ne ''){
4048 print CCDRWCONF "\n#Client gets this WINS server\n";
4049 print CCDRWCONF "push \"dhcp-option WINS $cgiparams{'CCD_WINS'}\" \n";
4050 }
4051 close CCDRWCONF;
4052 }
4053
4054 ###
4055 # m.a.d n2n begin
4056 ###
4057
4058 if ($cgiparams{'TYPE'} eq 'net') {
4059
4060 if (-e "/var/run/$confighash{$key}[1]n2n.pid") {
4061 system('/usr/local/bin/openvpnctrl', '-kn2n', $confighash{$cgiparams{'KEY'}}[1]);
4062
4063 &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
4064 my $key = $cgiparams{'KEY'};
4065 if (! $key) {
4066 $key = &General::findhasharraykey (\%confighash);
4067 foreach my $i (0 .. 31) { $confighash{$key}[$i] = "";}
4068 }
4069 $confighash{$key}[0] = 'on';
4070 &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
4071
4072 system('/usr/local/bin/openvpnctrl', '-sn2n', $confighash{$cgiparams{'KEY'}}[1]);
4073 }
4074 }
4075
4076 ###
4077 # m.a.d n2n end
4078 ###
4079
4080 if ($cgiparams{'EDIT_ADVANCED'} eq 'on') {
4081 $cgiparams{'KEY'} = $key;
4082 $cgiparams{'ACTION'} = $Lang::tr{'advanced'};
4083 }
4084 goto VPNCONF_END;
4085 } else {
4086 $cgiparams{'ENABLED'} = 'on';
4087 ###
4088 # m.a.d n2n begin
4089 ###
4090 $cgiparams{'MSSFIX'} = 'on';
4091 $cgiparams{'FRAGMENT'} = '1300';
4092 $cgiparams{'PMTU_DISCOVERY'} = 'off';
4093 ###
4094 # m.a.d n2n end
4095 ###
4096 $cgiparams{'SIDE'} = 'left';
4097 if ( ! -f "${General::swroot}/ovpn/ca/cakey.pem" ) {
4098 $cgiparams{'AUTH'} = 'psk';
4099 } elsif ( ! -f "${General::swroot}/ovpn/ca/cacert.pem") {
4100 $cgiparams{'AUTH'} = 'certfile';
4101 } else {
4102 $cgiparams{'AUTH'} = 'certgen';
4103 }
4104 $cgiparams{'LOCAL_SUBNET'} ="$netsettings{'GREEN_NETADDRESS'}/$netsettings{'GREEN_NETMASK'}";
4105 $cgiparams{'CERT_ORGANIZATION'} = $vpnsettings{'ROOTCERT_ORGANIZATION'};
4106 $cgiparams{'CERT_CITY'} = $vpnsettings{'ROOTCERT_CITY'};
4107 $cgiparams{'CERT_STATE'} = $vpnsettings{'ROOTCERT_STATE'};
4108 $cgiparams{'CERT_COUNTRY'} = $vpnsettings{'ROOTCERT_COUNTRY'};
4109 }
4110
4111 VPNCONF_ERROR:
4112 $checked{'ENABLED'}{'off'} = '';
4113 $checked{'ENABLED'}{'on'} = '';
4114 $checked{'ENABLED'}{$cgiparams{'ENABLED'}} = 'CHECKED';
4115 $checked{'ENABLED_BLUE'}{'off'} = '';
4116 $checked{'ENABLED_BLUE'}{'on'} = '';
4117 $checked{'ENABLED_BLUE'}{$cgiparams{'ENABLED_BLUE'}} = 'CHECKED';
4118 $checked{'ENABLED_ORANGE'}{'off'} = '';
4119 $checked{'ENABLED_ORANGE'}{'on'} = '';
4120 $checked{'ENABLED_ORANGE'}{$cgiparams{'ENABLED_ORANGE'}} = 'CHECKED';
4121
4122
4123 $checked{'EDIT_ADVANCED'}{'off'} = '';
4124 $checked{'EDIT_ADVANCED'}{'on'} = '';
4125 $checked{'EDIT_ADVANCED'}{$cgiparams{'EDIT_ADVANCED'}} = 'CHECKED';
4126
4127 $selected{'SIDE'}{'server'} = '';
4128 $selected{'SIDE'}{'client'} = '';
4129 $selected{'SIDE'}{$cgiparams{'SIDE'}} = 'SELECTED';
4130
4131 $selected{'PROTOCOL'}{'udp'} = '';
4132 $selected{'PROTOCOL'}{'tcp'} = '';
4133 $selected{'PROTOCOL'}{$cgiparams{'PROTOCOL'}} = 'SELECTED';
4134
4135
4136 $checked{'AUTH'}{'psk'} = '';
4137 $checked{'AUTH'}{'certreq'} = '';
4138 $checked{'AUTH'}{'certgen'} = '';
4139 $checked{'AUTH'}{'certfile'} = '';
4140 $checked{'AUTH'}{$cgiparams{'AUTH'}} = 'CHECKED';
4141
4142 $selected{'INTERFACE'}{$cgiparams{'INTERFACE'}} = 'SELECTED';
4143
4144 $checked{'COMPLZO'}{'off'} = '';
4145 $checked{'COMPLZO'}{'on'} = '';
4146 $checked{'COMPLZO'}{$cgiparams{'COMPLZO'}} = 'CHECKED';
4147
4148 $checked{'MSSFIX'}{'off'} = '';
4149 $checked{'MSSFIX'}{'on'} = '';
4150 $checked{'MSSFIX'}{$cgiparams{'MSSFIX'}} = 'CHECKED';
4151
4152 if ($cgiparams{'PMTU_DISCOVERY'} eq '') {
4153 $cgiparams{'PMTU_DISCOVERY'} = 'off';
4154 }
4155 $checked{'PMTU_DISCOVERY'}{$cgiparams{'PMTU_DISCOVERY'}} = 'checked=\'checked\'';
4156
4157
4158 if (1) {
4159 &Header::showhttpheaders();
4160 &Header::openpage($Lang::tr{'vpn configuration main'}, 1, '');
4161 &Header::openbigbox('100%', 'LEFT', '', $errormessage);
4162 if ($errormessage) {
4163 &Header::openbox('100%', 'LEFT', $Lang::tr{'error messages'});
4164 print "<class name='base'>$errormessage";
4165 print "&nbsp;</class>";
4166 &Header::closebox();
4167 }
4168
4169 if ($warnmessage) {
4170 &Header::openbox('100%', 'LEFT', "$Lang::tr{'warning messages'}:");
4171 print "<class name='base'>$warnmessage";
4172 print "&nbsp;</class>";
4173 &Header::closebox();
4174 }
4175
4176 print "<form method='post' enctype='multipart/form-data'>";
4177 print "<input type='hidden' name='TYPE' value='$cgiparams{'TYPE'}' />";
4178
4179 if ($cgiparams{'KEY'}) {
4180 print "<input type='hidden' name='KEY' value='$cgiparams{'KEY'}' />";
4181 print "<input type='hidden' name='AUTH' value='$cgiparams{'AUTH'}' />";
4182 }
4183
4184 &Header::openbox('100%', 'LEFT', "$Lang::tr{'connection'}:");
4185 print "<table width='100%' border='0'>\n";
4186
4187
4188
4189 print "<tr><td width='14%' class='boldbase'>$Lang::tr{'name'}: </td>";
4190
4191 if ($cgiparams{'TYPE'} eq 'host') {
4192 if ($cgiparams{'KEY'}) {
4193 print "<td width='35%' class='base'><input type='hidden' name='NAME' value='$cgiparams{'NAME'}' />$cgiparams{'NAME'}</td>";
4194 } else {
4195
4196 print "<td width='35%'><input type='text' name='NAME' value='$cgiparams{'NAME'}' maxlength='20' size='30' /></td>";
4197 }
4198 # print "<tr><td>$Lang::tr{'interface'}</td>";
4199 # print "<td><select name='INTERFACE'>";
4200 # print "<option value='RED' $selected{'INTERFACE'}{'RED'}>RED</option>";
4201 # if ($netsettings{'BLUE_DEV'} ne '') {
4202 # print "<option value='BLUE' $selected{'INTERFACE'}{'BLUE'}>BLUE</option>";
4203 # }
4204 # print "<option value='GREEN' $selected{'INTERFACE'}{'GREEN'}>GREEN</option>";
4205 # print "<option value='ORANGE' $selected{'INTERFACE'}{'ORANGE'}>ORANGE</option>";
4206 # print "</select></td></tr>";
4207 # print <<END
4208 } else {
4209 print "<input type='hidden' name='INTERFACE' value='red' />";
4210 if ($cgiparams{'KEY'}) {
4211 print "<td width='25%' class='base' nowrap='nowrap'><input type='hidden' name='NAME' value='$cgiparams{'NAME'}' />$cgiparams{'NAME'}</td>";
4212 } else {
4213 print "<td width='25%'><input type='text' name='NAME' value='$cgiparams{'NAME'}' maxlength='20' /></td>";
4214 }
4215
4216
4217
4218 print <<END
4219 <td width='25%'>&nbsp;</td>
4220 <td width='25%'>&nbsp;</td></tr>
4221 <tr><td class='boldbase' nowrap='nowrap'>$Lang::tr{'Act as'}</td>
4222 <td><select name='SIDE'><option value='server' $selected{'SIDE'}{'server'}>$Lang::tr{'openvpn server'}</option>
4223 <option value='client' $selected{'SIDE'}{'client'}>$Lang::tr{'openvpn client'}</option></select></td>
4224 <td class='boldbase'>$Lang::tr{'remote host/ip'}:</td>
4225 <td><input type='TEXT' name='REMOTE' value='$cgiparams{'REMOTE'}' /></td></tr>
4226 <tr><td class='boldbase' nowrap='nowrap'>$Lang::tr{'local subnet'}</td>
4227 <td><input type='TEXT' name='LOCAL_SUBNET' value='$cgiparams{'LOCAL_SUBNET'}' /></td>
4228 <td class='boldbase' nowrap='nowrap'>$Lang::tr{'remote subnet'}</td>
4229 <td><input type='text' name='REMOTE_SUBNET' value='$cgiparams{'REMOTE_SUBNET'}' /></td></tr>
4230 <tr><td class='boldbase' nowrap='nowrap'>$Lang::tr{'ovpn subnet'}</td>
4231 <td><input type='TEXT' name='OVPN_SUBNET' value='$cgiparams{'OVPN_SUBNET'}' /></td></tr>
4232 <tr><td class='boldbase' nowrap='nowrap'>$Lang::tr{'protocol'}</td>
4233
4234 <td><select name='PROTOCOL'><option value='udp' $selected{'PROTOCOL'}{'udp'}>UDP</option>
4235 <option value='tcp' $selected{'PROTOCOL'}{'tcp'}>TCP</option></select></td>
4236
4237 <td class='boldbase'>$Lang::tr{'destination port'}:</td>
4238 <td><input type='TEXT' name='DEST_PORT' value='$cgiparams{'DEST_PORT'}' size='5' /></td></tr>
4239 <tr><td class='boldbase' nowrap='nowrap'>$Lang::tr{'comp-lzo'} &nbsp;<img src='/blob.gif'</td>
4240 <td><input type='checkbox' name='COMPLZO' $checked{'COMPLZO'}{'on'} /></td>
4241
4242 <tr><td class='boldbase' nowrap='nowrap'>mssfix &nbsp;<img src='/blob.gif' /></td>
4243 <td><input type='checkbox' name='MSSFIX' $checked{'MSSFIX'}{'on'} /></td>
4244 <td>$Lang::tr{'openvpn default'}: <span class="base">on</span></td>
4245
4246 <tr><td class='boldbase' nowrap='nowrap'>fragment &nbsp;<img src='/blob.gif' /></td>
4247 <td><input type='TEXT' name='FRAGMENT' VALUE='$cgiparams{'FRAGMENT'}'size='5' /></td>
4248 <td>$Lang::tr{'openvpn default'}: <span class="base">1300</span></td>
4249
4250 <tr><td class='boldbase' nowrap='nowrap'>$Lang::tr{'MTU'}&nbsp;<img src='/blob.gif' /></td>
4251 <td> <input type='TEXT' name='MTU' VALUE='$cgiparams{'MTU'}'size='5' /></td>
4252 <td colspan='2'>$Lang::tr{'openvpn default'}: udp/tcp <span class="base">1500/1400</span></td>
4253
4254 <tr><td class='boldbase' nowrap='nowrap'>Management Port&nbsp;<img src='/blob.gif' /></td>
4255 <td> <input type='TEXT' name='OVPN_MGMT' VALUE='$cgiparams{'OVPN_MGMT'}'size='5' /></td>
4256 <td colspan='2'>$Lang::tr{'openvpn default'}: <span class="base">$Lang::tr{'destination port'}</span></td>
4257
4258 <tr>
4259 <td class='boldbase' nowrap='nowrap'>$Lang::tr{'ovpn mtu-disc'}</td>
4260 <td colspan='3'>
4261 <input type='radio' name='PMTU_DISCOVERY' value='yes' $checked{'PMTU_DISCOVERY'}{'yes'} /> $Lang::tr{'ovpn mtu-disc yes'}
4262 <input type='radio' name='PMTU_DISCOVERY' value='maybe' $checked{'PMTU_DISCOVERY'}{'maybe'} /> $Lang::tr{'ovpn mtu-disc maybe'}
4263 <input type='radio' name='PMTU_DISCOVERY' value='no' $checked{'PMTU_DISCOVERY'}{'no'} /> $Lang::tr{'ovpn mtu-disc no'}
4264 <input type='radio' name='PMTU_DISCOVERY' value='off' $checked{'PMTU_DISCOVERY'}{'off'} /> $Lang::tr{'ovpn mtu-disc off'}
4265 </td>
4266 </tr>
4267
4268 END
4269 ;
4270 }
4271 #jumper
4272 print "<tr><td class='boldbase'>$Lang::tr{'remark title'}&nbsp;<img src='/blob.gif' /></td>";
4273 print "<td colspan='3'><input type='text' name='REMARK' value='$cgiparams{'REMARK'}' size='55' maxlength='50' /></td></tr></table>";
4274
4275 if ($cgiparams{'TYPE'} eq 'host') {
4276 print "<tr><td>$Lang::tr{'enabled'} <input type='checkbox' name='ENABLED' $checked{'ENABLED'}{'on'} /></td>";
4277 }
4278
4279 print"</tr></table><br><br>";
4280 #A.Marx CCD new client
4281 if ($cgiparams{'TYPE'} eq 'host') {
4282 print "<table border='0' width='100%' cellspacing='1' cellpadding='0'><tr><td colspan='3'><hr><br><b>$Lang::tr{'ccd choose net'}</td></tr><tr><td height='20' colspan='3'></td></tr>";
4283 my %vpnnet=();
4284 my $vpnip;
4285 &General::readhash("${General::swroot}/ovpn/settings", \%vpnnet);
4286 $vpnip=$vpnnet{'DOVPN_SUBNET'};
4287 &General::readhasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash);
4288 my @ccdconf=();
4289 my $count=0;
4290 my $checked;
4291 $checked{'check1'}{'off'} = '';
4292 $checked{'check1'}{'on'} = '';
4293 $checked{'check1'}{$cgiparams{'CHECK1'}} = 'CHECKED';
4294 print"<tr><td align='center' width='1%' valign='top'><input type='radio' name='CHECK1' value='dynamic' checked /></td><td align='left' valign='top' width='35%'>$Lang::tr{'ccd dynrange'} ($vpnip)</td><td width='30%'>";
4295 print"</td></tr></table><br><br>";
4296 my $name=$cgiparams{'CHECK1'};
4297 $checked{'RG'}{$cgiparams{'RG'}} = 'CHECKED';
4298
4299 if (! -z "${General::swroot}/ovpn/ccd.conf"){
4300 print"<table border='0' width='100%' cellspacing='1' cellpadding='0'><tr><td width='1%'></td><td width='30%' class='boldbase' align='center'><b>$Lang::tr{'ccd name'}</td><td width='15%' class='boldbase' align='center'><b>$Lang::tr{'network'}</td><td class='boldbase' align='center' width='18%'><b>$Lang::tr{'ccd clientip'}</td></tr>";
4301 foreach my $key (sort { uc($ccdconfhash{$a}[0]) cmp uc($ccdconfhash{$b}[0]) } keys %ccdconfhash) {
4302 $count++;
4303 @ccdconf=($ccdconfhash{$key}[0],$ccdconfhash{$key}[1]);
4304 if ($count % 2){print"<tr bgcolor='$color{'color22'}'>";}else{print"<tr bgcolor='$color{'color20'}'>";}
4305 print"<td align='center' width='1%'><input type='radio' name='CHECK1' value='$ccdconf[0]' $checked{'check1'}{$ccdconf[0]}/></td><td>$ccdconf[0]</td><td width='40%' align='center'>$ccdconf[1]</td><td align='left' width='10%'>";
4306 &fillselectbox($ccdconf[1],$ccdconf[0],$cgiparams{$name});
4307 print"</td></tr>";
4308 }
4309 print "</table><br><br><hr><br><br>";
4310 }
4311 }
4312 # ccd end
4313 &Header::closebox();
4314 if ($cgiparams{'KEY'} && $cgiparams{'AUTH'} eq 'psk') {
4315
4316 } elsif (! $cgiparams{'KEY'}) {
4317
4318
4319 my $disabled='';
4320 my $cakeydisabled='';
4321 my $cacrtdisabled='';
4322 if ( ! -f "${General::swroot}/ovpn/ca/cakey.pem" ) { $cakeydisabled = "disabled='disabled'" } else { $cakeydisabled = "" };
4323 if ( ! -f "${General::swroot}/ovpn/ca/cacert.pem" ) { $cacrtdisabled = "disabled='disabled'" } else { $cacrtdisabled = "" };
4324
4325 &Header::openbox('100%', 'LEFT', $Lang::tr{'authentication'});
4326
4327
4328 if ($cgiparams{'TYPE'} eq 'host') {
4329
4330 print <<END
4331 <table width='100%' cellpadding='0' cellspacing='5' border='0'>
4332
4333 <tr><td><input type='radio' name='AUTH' value='certreq' $checked{'AUTH'}{'certreq'} $cakeydisabled /></td><td class='base'>$Lang::tr{'upload a certificate request'}</td><td class='base' rowspan='2'><input type='file' name='FH' size='30' $cacrtdisabled></td></tr>
4334 <tr><td><input type='radio' name='AUTH' value='certfile' $checked{'AUTH'}{'certfile'} $cacrtdisabled /></td><td class='base'>$Lang::tr{'upload a certificate'}</td></tr>
4335 <tr><td colspan='3'>&nbsp;</td></tr>
4336 <tr><td colspan='3'><hr /></td></tr>
4337 <tr><td colspan='3'>&nbsp;</td></tr>
4338 <tr><td><input type='radio' name='AUTH' value='certgen' $checked{'AUTH'}{'certgen'} $cakeydisabled /></td><td class='base'>$Lang::tr{'generate a certificate'}</td><td>&nbsp;</td></tr>
4339 <tr><td>&nbsp;</td><td class='base'>$Lang::tr{'users fullname or system hostname'}:</td><td class='base' nowrap='nowrap'><input type='text' name='CERT_NAME' value='$cgiparams{'CERT_NAME'}' SIZE='32' $cakeydisabled /></td></tr>
4340 <tr><td>&nbsp;</td><td class='base'>$Lang::tr{'users email'}:&nbsp;<img src='/blob.gif' /></td><td class='base' nowrap='nowrap'><input type='text' name='CERT_EMAIL' value='$cgiparams{'CERT_EMAIL'}' SIZE='32' $cakeydisabled /></td></tr>
4341 <tr><td>&nbsp;</td><td class='base'>$Lang::tr{'users department'}:&nbsp;<img src='/blob.gif' /></td><td class='base' nowrap='nowrap'><input type='text' name='CERT_OU' value='$cgiparams{'CERT_OU'}' SIZE='32' $cakeydisabled /></td></tr>
4342 <tr><td>&nbsp;</td><td class='base'>$Lang::tr{'organization name'}:&nbsp;<img src='/blob.gif' /></td><td class='base' nowrap='nowrap'><input type='text' name='CERT_ORGANIZATION' value='$cgiparams{'CERT_ORGANIZATION'}' SIZE='32' $cakeydisabled /></td></tr>
4343 <tr><td>&nbsp;</td><td class='base'>$Lang::tr{'city'}:&nbsp;<img src='/blob.gif'></td><td class='base' nowrap='nowrap'><input type='text' name='CERT_CITY' value='$cgiparams{'CERT_CITY'}' SIZE='32' $cakeydisabled /></td></tr>
4344 <tr><td>&nbsp;</td><td class='base'>$Lang::tr{'state or province'}:&nbsp;<img src='/blob.gif' /></td><td class='base' nowrap='nowrap'><input type='text' name='CERT_STATE' value='$cgiparams{'CERT_STATE'}' SIZE='32' $cakeydisabled /></td></tr>
4345 <tr><td>&nbsp;</td><td class='base'>$Lang::tr{'country'}:</td><td class='base'><select name='CERT_COUNTRY' $cakeydisabled>
4346 END
4347 ;
4348
4349 ###
4350 # m.a.d net2net
4351 ###
4352
4353 } else {
4354
4355 print <<END
4356 <table width='100%' cellpadding='0' cellspacing='5' border='0'>
4357
4358 <tr><td><input type='radio' name='AUTH' value='certgen' $checked{'AUTH'}{'certgen'} $cakeydisabled /></td><td class='base'>$Lang::tr{'generate a certificate'}</td><td>&nbsp;</td></tr>
4359 <tr><td>&nbsp;</td><td class='base'>$Lang::tr{'users fullname or system hostname'}:</td><td class='base' nowrap='nowrap'><input type='text' name='CERT_NAME' value='$cgiparams{'CERT_NAME'}' SIZE='32' $cakeydisabled /></td></tr>
4360 <tr><td>&nbsp;</td><td class='base'>$Lang::tr{'users email'}:&nbsp;<img src='/blob.gif' /></td><td class='base' nowrap='nowrap'><input type='text' name='CERT_EMAIL' value='$cgiparams{'CERT_EMAIL'}' SIZE='32' $cakeydisabled /></td></tr>
4361 <tr><td>&nbsp;</td><td class='base'>$Lang::tr{'users department'}:&nbsp;<img src='/blob.gif' /></td><td class='base' nowrap='nowrap'><input type='text' name='CERT_OU' value='$cgiparams{'CERT_OU'}' SIZE='32' $cakeydisabled /></td></tr>
4362 <tr><td>&nbsp;</td><td class='base'>$Lang::tr{'organization name'}:&nbsp;<img src='/blob.gif' /></td><td class='base' nowrap='nowrap'><input type='text' name='CERT_ORGANIZATION' value='$cgiparams{'CERT_ORGANIZATION'}' SIZE='32' $cakeydisabled /></td></tr>
4363 <tr><td>&nbsp;</td><td class='base'>$Lang::tr{'city'}:&nbsp;<img src='/blob.gif'></td><td class='base' nowrap='nowrap'><input type='text' name='CERT_CITY' value='$cgiparams{'CERT_CITY'}' SIZE='32' $cakeydisabled /></td></tr>
4364 <tr><td>&nbsp;</td><td class='base'>$Lang::tr{'state or province'}:&nbsp;<img src='/blob.gif' /></td><td class='base' nowrap='nowrap'><input type='text' name='CERT_STATE' value='$cgiparams{'CERT_STATE'}' SIZE='32' $cakeydisabled /></td></tr>
4365 <tr><td>&nbsp;</td><td class='base'>$Lang::tr{'country'}:</td><td class='base'><select name='CERT_COUNTRY' $cakeydisabled>
4366
4367
4368 END
4369 ;
4370
4371 }
4372
4373 ###
4374 # m.a.d net2net
4375 ###
4376
4377 foreach my $country (sort keys %{Countries::countries}) {
4378 print "<option value='$Countries::countries{$country}'";
4379 if ( $Countries::countries{$country} eq $cgiparams{'CERT_COUNTRY'} ) {
4380 print " selected='selected'";
4381 }
4382 print ">$country</option>";
4383 }
4384 ###
4385 # m.a.d net2net
4386 ###
4387
4388 if ($cgiparams{'TYPE'} eq 'host') {
4389 print <<END
4390 </select></td></tr>
4391
4392 <td>&nbsp;</td><td class='base'>$Lang::tr{'valid till'} (days):</td>
4393 <td class='base' nowrap='nowrap'><input type='text' name='DAYS_VALID' value='$cgiparams{'DAYS_VALID'}' size='32' $cakeydisabled /></td></tr>
4394 <tr><td>&nbsp;</td>
4395 <td class='base'>$Lang::tr{'pkcs12 file password'}:</td>
4396 <td class='base' nowrap='nowrap'><input type='password' name='CERT_PASS1' value='$cgiparams{'CERT_PASS1'}' size='32' $cakeydisabled /></td></tr>
4397 <tr><td>&nbsp;</td><td class='base'>$Lang::tr{'pkcs12 file password'}:<BR>($Lang::tr{'confirmation'})</td>
4398 <td class='base' nowrap='nowrap'><input type='password' name='CERT_PASS2' value='$cgiparams{'CERT_PASS2'}' size='32' $cakeydisabled /></td></tr>
4399 <tr><td colspan='3'>&nbsp;</td></tr>
4400 <tr><td colspan='3'><hr /></td></tr>
4401 <tr><td class='base' colspan='3' align='left'><img src='/blob.gif' alt='*' />&nbsp;$Lang::tr{'this field may be blank'}</td></tr>
4402 </table>
4403 END
4404 }else{
4405 print <<END
4406 </select></td></tr>
4407 <tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr>
4408 <tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr>
4409 <tr><td colspan='3'><hr /></td></tr>
4410 <tr><td class='base' colspan='3' align='left'><img src='/blob.gif' alt='*' />&nbsp;$Lang::tr{'this field may be blank'}</td></tr>
4411 </table>
4412
4413 END
4414 }
4415
4416 ###
4417 # m.a.d net2net
4418 ###
4419 ;
4420 &Header::closebox();
4421
4422 }
4423
4424 #A.Marx CCD new client
4425 if ($cgiparams{'TYPE'} eq 'host') {
4426 print"<br><br>";
4427 &Header::openbox('100%', 'LEFT', "$Lang::tr{'ccd client options'}:");
4428
4429
4430 print <<END;
4431 <table border='0' width='100%'>
4432 <tr><td width='20%'>Redirect Gateway:</td><td colspan='3'><input type='checkbox' name='RG' $checked{'RG'}{'on'} /></td></tr>
4433 <tr><td colspan='4'><b><br>$Lang::tr{'ccd routes'}</b></td></tr>
4434 <tr><td colspan='4'>&nbsp</td></tr>
4435 <tr><td valign='top'>$Lang::tr{'ccd iroute'}</td><td align='left' width='30%'><textarea name='IR' cols='26' rows='6' wrap='off'>
4436 END
4437
4438 if ($cgiparams{'IR'} ne ''){
4439 print $cgiparams{'IR'};
4440 }else{
4441 &General::readhasharray ("${General::swroot}/ovpn/ccdroute", \%ccdroutehash);
4442 foreach my $key (keys %ccdroutehash) {
4443 if( $cgiparams{'NAME'} eq $ccdroutehash{$key}[0]){
4444 foreach my $i (1 .. $#{$ccdroutehash{$key}}) {
4445 if ($ccdroutehash{$key}[$i] ne ''){
4446 print $ccdroutehash{$key}[$i]."\n";
4447 }
4448 $cgiparams{'IR'} .= $ccdroutehash{$key}[$i];
4449 }
4450 }
4451 }
4452 }
4453
4454 print <<END;
4455 </textarea></td><td valign='top' colspan='2'>$Lang::tr{'ccd iroutehint'}</td></tr>
4456 <tr><td colspan='4'><br></td></tr>
4457 <tr><td valign='top' rowspan='3'>$Lang::tr{'ccd iroute2'}</td><td align='left' valign='top' rowspan='3'><select name='IFROUTE' style="width: 205px"; size='6' multiple>
4458 END
4459
4460 my $set=0;
4461 my $selorange=0;
4462 my $selblue=0;
4463 my $selgreen=0;
4464 my $helpblue=0;
4465 my $helporange=0;
4466 my $other=0;
4467 my $none=0;
4468 my @temp=();
4469
4470 our @current = ();
4471 open(FILE, "${General::swroot}/main/routing") ;
4472 @current = <FILE>;
4473 close (FILE);
4474 &General::readhasharray ("${General::swroot}/ovpn/ccdroute2", \%ccdroute2hash);
4475 #check for "none"
4476 foreach my $key (keys %ccdroute2hash) {
4477 if($ccdroute2hash{$key}[0] eq $cgiparams{'NAME'}){
4478 if ($ccdroute2hash{$key}[1] eq ''){
4479 $none=1;
4480 last;
4481 }
4482 }
4483 }
4484 if ($none ne '1'){
4485 print"<option>$Lang::tr{'ccd none'}</option>";
4486 }else{
4487 print"<option selected>$Lang::tr{'ccd none'}</option>";
4488 }
4489 #check if static routes are defined for client
4490 foreach my $line (@current) {
4491 chomp($line);
4492 $line=~s/\s*$//g; # remove newline
4493 @temp=split(/\,/,$line);
4494 $temp[1] = '' unless defined $temp[1]; # not always populated
4495 my ($a,$b) = split(/\//,$temp[1]);
4496 $temp[1] = $a."/".&General::iporsubtocidr($b);
4497 foreach my $key (keys %ccdroute2hash) {
4498 if($ccdroute2hash{$key}[0] eq $cgiparams{'NAME'}){
4499 foreach my $i (1 .. $#{$ccdroute2hash{$key}}) {
4500 if($ccdroute2hash{$key}[$i] eq $a."/".&General::iporsubtodec($b)){
4501 $set=1;
4502 }
4503 }
4504 }
4505 }
4506 if ($set == '1' && $#temp != -1){ print"<option selected>$temp[1]</option>";$set=0;}elsif($set == '0' && $#temp != -1){print"<option>$temp[1]</option>";}
4507 }
4508 #check if green,blue,orange are defined for client
4509 foreach my $key (keys %ccdroute2hash) {
4510 if($ccdroute2hash{$key}[0] eq $cgiparams{'NAME'}){
4511 $other=1;
4512 foreach my $i (1 .. $#{$ccdroute2hash{$key}}) {
4513 if ($ccdroute2hash{$key}[$i] eq $netsettings{'GREEN_NETADDRESS'}."/".&General::iporsubtodec($netsettings{'GREEN_NETMASK'})){
4514 $selgreen=1;
4515 }
4516 if (&haveBlueNet()){
4517 if( $ccdroute2hash{$key}[$i] eq $netsettings{'BLUE_NETADDRESS'}."/".&General::iporsubtodec($netsettings{'BLUE_NETMASK'})) {
4518 $selblue=1;
4519 }
4520 }
4521 if (&haveOrangeNet()){
4522 if( $ccdroute2hash{$key}[$i] eq $netsettings{'ORANGE_NETADDRESS'}."/".&General::iporsubtodec($netsettings{'ORANGE_NETMASK'}) ) {
4523 $selorange=1;
4524 }
4525 }
4526 }
4527 }
4528 }
4529 if (&haveBlueNet() && $selblue == '1'){ print"<option selected>$Lang::tr{'blue'}</option>";$selblue=0;}elsif(&haveBlueNet() && $selblue == '0'){print"<option>$Lang::tr{'blue'}</option>";}
4530 if (&haveOrangeNet() && $selorange == '1'){ print"<option selected>$Lang::tr{'orange'}</option>";$selorange=0;}elsif(&haveOrangeNet() && $selorange == '0'){print"<option>$Lang::tr{'orange'}</option>";}
4531 if ($selgreen == '1' || $other == '0'){ print"<option selected>$Lang::tr{'green'}</option>";$set=0;}else{print"<option>$Lang::tr{'green'}</option>";};
4532
4533 print<<END
4534 </select></td><td valign='top'>DNS1:</td><td valign='top'><input type='TEXT' name='CCD_DNS1' value='$cgiparams{'CCD_DNS1'}' size='30' /></td></tr>
4535 <tr valign='top'><td>DNS2:</td><td><input type='TEXT' name='CCD_DNS2' value='$cgiparams{'CCD_DNS2'}' size='30' /></td></tr>
4536 <tr valign='top'><td valign='top'>WINS:</td><td><input type='TEXT' name='CCD_WINS' value='$cgiparams{'CCD_WINS'}' size='30' /></td></tr></table><br><hr>
4537
4538 END
4539 ;
4540 &Header::closebox();
4541 }
4542 print "<div align='center'><input type='submit' name='ACTION' value='$Lang::tr{'save'}' />";
4543 if ($cgiparams{'KEY'}) {
4544 # print "<input type='submit' name='ACTION' value='$Lang::tr{'advanced'}' />";
4545 }
4546 print "<input type='submit' name='ACTION' value='$Lang::tr{'cancel'}' /></div></form>";
4547 &Header::closebigbox();
4548 &Header::closepage();
4549 exit (0);
4550 }
4551 VPNCONF_END:
4552 }
4553
4554 # SETTINGS_ERROR:
4555 ###
4556 ### Default status page
4557 ###
4558 %cgiparams = ();
4559 %cahash = ();
4560 %confighash = ();
4561 &General::readhash("${General::swroot}/ovpn/settings", \%cgiparams);
4562 &General::readhasharray("${General::swroot}/ovpn/caconfig", \%cahash);
4563 &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
4564
4565 my @status = `/bin/cat /var/log/ovpnserver.log`;
4566
4567 if ($cgiparams{'VPN_IP'} eq '' && -e "${General::swroot}/red/active") {
4568 if (open(IPADDR, "${General::swroot}/red/local-ipaddress")) {
4569 my $ipaddr = <IPADDR>;
4570 close IPADDR;
4571 chomp ($ipaddr);
4572 $cgiparams{'VPN_IP'} = (gethostbyaddr(pack("C4", split(/\./, $ipaddr)), 2))[0];
4573 if ($cgiparams{'VPN_IP'} eq '') {
4574 $cgiparams{'VPN_IP'} = $ipaddr;
4575 }
4576 }
4577 }
4578
4579 #default setzen
4580 if ($cgiparams{'DCIPHER'} eq '') {
4581 $cgiparams{'DCIPHER'} = 'BF-CBC';
4582 }
4583 if ($cgiparams{'DDEST_PORT'} eq '') {
4584 $cgiparams{'DDEST_PORT'} = '1194';
4585 }
4586 if ($cgiparams{'DMTU'} eq '') {
4587 $cgiparams{'DMTU'} = '1400';
4588 }
4589 if ($cgiparams{'DOVPN_SUBNET'} eq '') {
4590 $cgiparams{'DOVPN_SUBNET'} = '10.' . int(rand(256)) . '.' . int(rand(256)) . '.0/255.255.255.0';
4591 }
4592 $checked{'ENABLED'}{'off'} = '';
4593 $checked{'ENABLED'}{'on'} = '';
4594 $checked{'ENABLED'}{$cgiparams{'ENABLED'}} = 'CHECKED';
4595 $checked{'ENABLED_BLUE'}{'off'} = '';
4596 $checked{'ENABLED_BLUE'}{'on'} = '';
4597 $checked{'ENABLED_BLUE'}{$cgiparams{'ENABLED_BLUE'}} = 'CHECKED';
4598 $checked{'ENABLED_ORANGE'}{'off'} = '';
4599 $checked{'ENABLED_ORANGE'}{'on'} = '';
4600 $checked{'ENABLED_ORANGE'}{$cgiparams{'ENABLED_ORANGE'}} = 'CHECKED';
4601 $selected{'DDEVICE'}{'tun'} = '';
4602 $selected{'DDEVICE'}{'tap'} = '';
4603 $selected{'DDEVICE'}{$cgiparams{'DDEVICE'}} = 'SELECTED';
4604
4605 $selected{'DPROTOCOL'}{'udp'} = '';
4606 $selected{'DPROTOCOL'}{'tcp'} = '';
4607 $selected{'DPROTOCOL'}{$cgiparams{'DPROTOCOL'}} = 'SELECTED';
4608
4609 $selected{'DCIPHER'}{'DES-CBC'} = '';
4610 $selected{'DCIPHER'}{'DES-EDE-CBC'} = '';
4611 $selected{'DCIPHER'}{'DES-EDE3-CBC'} = '';
4612 $selected{'DCIPHER'}{'DESX-CBC'} = '';
4613 $selected{'DCIPHER'}{'RC2-CBC'} = '';
4614 $selected{'DCIPHER'}{'RC2-40-CBC'} = '';
4615 $selected{'DCIPHER'}{'RC2-64-CBC'} = '';
4616 $selected{'DCIPHER'}{'BF-CBC'} = '';
4617 $selected{'DCIPHER'}{'CAST5-CBC'} = '';
4618 $selected{'DCIPHER'}{'AES-128-CBC'} = '';
4619 $selected{'DCIPHER'}{'AES-192-CBC'} = '';
4620 $selected{'DCIPHER'}{'AES-256-CBC'} = '';
4621 $selected{'DCIPHER'}{$cgiparams{'DCIPHER'}} = 'SELECTED';
4622 $checked{'DCOMPLZO'}{'off'} = '';
4623 $checked{'DCOMPLZO'}{'on'} = '';
4624 $checked{'DCOMPLZO'}{$cgiparams{'DCOMPLZO'}} = 'CHECKED';
4625 # m.a.d
4626 $checked{'MSSFIX'}{'off'} = '';
4627 $checked{'MSSFIX'}{'on'} = '';
4628 $checked{'MSSFIX'}{$cgiparams{'MSSFIX'}} = 'CHECKED';
4629 #new settings
4630 &Header::showhttpheaders();
4631 &Header::openpage($Lang::tr{'status ovpn'}, 1, '');
4632 &Header::openbigbox('100%', 'LEFT', '', $errormessage);
4633
4634 if ($errormessage) {
4635 &Header::openbox('100%', 'LEFT', $Lang::tr{'error messages'});
4636 print "<class name='base'>$errormessage\n";
4637 print "&nbsp;</class>\n";
4638 &Header::closebox();
4639 }
4640
4641 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>";
4642 my $srunning = "no";
4643 my $activeonrun = "";
4644 if ( -e "/var/run/openvpn.pid"){
4645 $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>";
4646 $srunning ="yes";
4647 $activeonrun = "";
4648 } else {
4649 $activeonrun = "disabled='disabled'";
4650 }
4651 &Header::openbox('100%', 'LEFT', $Lang::tr{'global settings'});
4652 print <<END
4653 <table width='100%' border=0>
4654 <form method='post'>
4655 <td width='25%'>&nbsp;</td>
4656 <td width='25%'>&nbsp;</td>
4657 <td width='25%'>&nbsp;</td></tr>
4658 <tr><td class='boldbase'>$Lang::tr{'ovpn server status'}</td>
4659 <td align='left'>$sactive</td>
4660 <tr><td class='boldbase'>$Lang::tr{'ovpn on red'}</td>
4661 <td><input type='checkbox' name='ENABLED' $checked{'ENABLED'}{'on'} /></td>
4662 END
4663 ;
4664 if (&haveBlueNet()) {
4665 print "<tr><td class='boldbase'>$Lang::tr{'ovpn on blue'}</td>";
4666 print "<td><input type='checkbox' name='ENABLED_BLUE' $checked{'ENABLED_BLUE'}{'on'} /></td>";
4667 }
4668 if (&haveOrangeNet()) {
4669 print "<tr><td class='boldbase'>$Lang::tr{'ovpn on orange'}</td>";
4670 print "<td><input type='checkbox' name='ENABLED_ORANGE' $checked{'ENABLED_ORANGE'}{'on'} /></td>";
4671 }
4672 print <<END
4673 <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>
4674 <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>
4675 <tr><td class='boldbase' nowrap='nowrap'>$Lang::tr{'ovpn device'}</td>
4676 <td><select name='DDEVICE' ><option value='tun' $selected{'DDEVICE'}{'tun'}>TUN</option>
4677 <!-- this is still not working
4678 <option value='tap' $selected{'DDEVICE'}{'tap'}>TAP</option></select>--> </td>
4679 <tr><td class='boldbase' nowrap='nowrap'>$Lang::tr{'protocol'}</td>
4680 <td><select name='DPROTOCOL'><option value='udp' $selected{'DPROTOCOL'}{'udp'}>UDP</option>
4681 <option value='tcp' $selected{'DPROTOCOL'}{'tcp'}>TCP</option></select></td>
4682 <td class='boldbase'>$Lang::tr{'destination port'}:</td>
4683 <td><input type='TEXT' name='DDEST_PORT' value='$cgiparams{'DDEST_PORT'}' size='5' /></td></tr>
4684 <tr><td class='boldbase' nowrap='nowrap'>$Lang::tr{'MTU'}&nbsp;</td>
4685 <td> <input type='TEXT' name='DMTU' VALUE='$cgiparams{'DMTU'}'size='5' /></TD>
4686 <tr><td class='boldbase' nowrap='nowrap'>$Lang::tr{'comp-lzo'}</td>
4687 <td><input type='checkbox' name='DCOMPLZO' $checked{'DCOMPLZO'}{'on'} /></td>
4688 <td class='boldbase' nowrap='nowrap'>$Lang::tr{'cipher'}</td>
4689 <td><select name='DCIPHER'><option value='DES-CBC' $selected{'DCIPHER'}{'DES-CBC'}>DES-CBC</option>
4690 <option value='DES-EDE-CBC' $selected{'DCIPHER'}{'DES-EDE-CBC'}>DES-EDE-CBC</option>
4691 <option value='DES-EDE3-CBC' $selected{'DCIPHER'}{'DES-EDE3-CBC'}>DES-EDE3-CBC</option>
4692 <option value='DESX-CBC' $selected{'DCIPHER'}{'DESX-CBC'}>DESX-CBC</option>
4693 <option value='RC2-CBC' $selected{'DCIPHER'}{'RC2-CBC'}>RC2-CBC</option>
4694 <option value='RC2-40-CBC' $selected{'DCIPHER'}{'RC2-40-CBC'}>RC2-40-CBC</option>
4695 <option value='RC2-64-CBC' $selected{'DCIPHER'}{'RC2-64-CBC'}>RC2-64-CBC</option>
4696 <option value='BF-CBC' $selected{'DCIPHER'}{'BF-CBC'}>BF-CBC</option>
4697 <option value='CAST5-CBC' $selected{'DCIPHER'}{'CAST5-CBC'}>CAST5-CBC</option>
4698 <option value='AES-128-CBC' $selected{'DCIPHER'}{'AES-128-CBC'}>AES-128-CBC</option>
4699 <option value='AES-192-CBC' $selected{'DCIPHER'}{'AES-192-CBC'}>AES-192-CBC</option>
4700 <option value='AES-256-CBC' $selected{'DCIPHER'}{'AES-256-CBC'}>AES-256-CBC</option></select></td></tr>
4701 <tr><td colspan='4'><hr /></td></tr>
4702 END
4703 ;
4704
4705 if ( $srunning eq "yes" ) {
4706 print "<tr><td align='right' colspan='4'><input type='submit' name='ACTION' value='$Lang::tr{'save'}' disabled='disabled' />";
4707 print "<input type='submit' name='ACTION' value='$Lang::tr{'ccd net'}' />";
4708 print "<input type='submit' name='ACTION' value='$Lang::tr{'advanced server'}' />";
4709 print "<input type='submit' name='ACTION' value='$Lang::tr{'stop ovpn server'}' /></td></tr>";
4710 } else{
4711 print "<tr><td align='right' colspan='4'><input type='submit' name='ACTION' value='$Lang::tr{'save'}' />";
4712 print "<input type='submit' name='ACTION' value='$Lang::tr{'ccd net'}' />";
4713 print "<input type='submit' name='ACTION' value='$Lang::tr{'advanced server'}' />";
4714 if (( -e "${General::swroot}/ovpn/ca/cacert.pem" &&
4715 -e "${General::swroot}/ovpn/ca/dh1024.pem" &&
4716 -e "${General::swroot}/ovpn/certs/servercert.pem" &&
4717 -e "${General::swroot}/ovpn/certs/serverkey.pem") &&
4718 (( $cgiparams{'ENABLED'} eq 'on') ||
4719 ( $cgiparams{'ENABLED_BLUE'} eq 'on') ||
4720 ( $cgiparams{'ENABLED_ORANGE'} eq 'on'))){
4721 print "<input type='submit' name='ACTION' value='$Lang::tr{'start ovpn server'}' /></td></tr>";
4722 } else {
4723 print "<input type='submit' name='ACTION' value='$Lang::tr{'start ovpn server'}' disabled='disabled' /></td></tr>";
4724 }
4725 }
4726 print "</form></table>";
4727 &Header::closebox();
4728 &Header::openbox('100%', 'LEFT', "$Lang::tr{'certificate authorities'}:");
4729 print <<EOF#'
4730 <table width='100%' border='0' cellspacing='1' cellpadding='0'>
4731 <tr>
4732 <td width='25%' class='boldbase' align='center'><b>$Lang::tr{'name'}</b></td>
4733 <td width='65%' class='boldbase' align='center'><b>$Lang::tr{'subject'}</b></td>
4734 <td width='10%' class='boldbase' colspan='3' align='center'><b>$Lang::tr{'action'}</b></td>
4735 </tr>
4736 EOF
4737 ;
4738 if (-f "${General::swroot}/ovpn/ca/cacert.pem") {
4739 my $casubject = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/ca/cacert.pem`;
4740 $casubject =~ /Subject: (.*)[\n]/;
4741 $casubject = $1;
4742 $casubject =~ s+/Email+, E+;
4743 $casubject =~ s/ ST=/ S=/;
4744
4745 print <<END
4746 <tr bgcolor='$color{'color22'}'>
4747 <td class='base'>$Lang::tr{'root certificate'}</td>
4748 <td class='base'>$casubject</td>
4749 <form method='post' name='frmrootcrta'><td width='3%' align='center'>
4750 <input type='hidden' name='ACTION' value='$Lang::tr{'show root certificate'}' />
4751 <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' />
4752 </td></form>
4753 <form method='post' name='frmrootcrtb'><td width='3%' align='center'>
4754 <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' />
4755 <input type='hidden' name='ACTION' value='$Lang::tr{'download root certificate'}' />
4756 </td></form>
4757 <td width='4%'>&nbsp;</td></tr>
4758 END
4759 ;
4760 } else {
4761 # display rootcert generation buttons
4762 print <<END
4763 <tr bgcolor='$color{'color22'}'>
4764 <td class='base'>$Lang::tr{'root certificate'}:</td>
4765 <td class='base'>$Lang::tr{'not present'}</td>
4766 <td colspan='3'>&nbsp;</td></tr>
4767 END
4768 ;
4769 }
4770
4771 if (-f "${General::swroot}/ovpn/certs/servercert.pem") {
4772 my $hostsubject = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/certs/servercert.pem`;
4773 $hostsubject =~ /Subject: (.*)[\n]/;
4774 $hostsubject = $1;
4775 $hostsubject =~ s+/Email+, E+;
4776 $hostsubject =~ s/ ST=/ S=/;
4777
4778 print <<END
4779 <tr bgcolor='$color{'color20'}'>
4780 <td class='base'>$Lang::tr{'host certificate'}</td>
4781 <td class='base'>$hostsubject</td>
4782 <form method='post' name='frmhostcrta'><td width='3%' align='center'>
4783 <input type='hidden' name='ACTION' value='$Lang::tr{'show host certificate'}' />
4784 <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' />
4785 </td></form>
4786 <form method='post' name='frmhostcrtb'><td width='3%' align='center'>
4787 <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' />
4788 <input type='hidden' name='ACTION' value='$Lang::tr{'download host certificate'}' />
4789 </td></form>
4790 <td width='4%'>&nbsp;</td></tr>
4791 END
4792 ;
4793 } else {
4794 # Nothing
4795 print <<END
4796 <tr bgcolor='$color{'color20'}'>
4797 <td width='25%' class='base'>$Lang::tr{'host certificate'}:</td>
4798 <td class='base'>$Lang::tr{'not present'}</td>
4799 </td><td colspan='3'>&nbsp;</td></tr>
4800 END
4801 ;
4802 }
4803
4804 if (! -f "${General::swroot}/ovpn/ca/cacert.pem") {
4805 print "<tr><td colspan='5' align='center'><form method='post'>";
4806 print "<input type='submit' name='ACTION' value='$Lang::tr{'generate root/host certificates'}' />";
4807 print "</form></td></tr>\n";
4808 }
4809
4810 if (keys %cahash > 0) {
4811 foreach my $key (keys %cahash) {
4812 if (($key + 1) % 2) {
4813 print "<tr bgcolor='$color{'color20'}'>\n";
4814 } else {
4815 print "<tr bgcolor='$color{'color22'}'>\n";
4816 }
4817 print "<td class='base'>$cahash{$key}[0]</td>\n";
4818 print "<td class='base'>$cahash{$key}[1]</td>\n";
4819 print <<END
4820 <form method='post' name='cafrm${key}a'><td align='center'>
4821 <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' />
4822 <input type='hidden' name='ACTION' value='$Lang::tr{'show ca certificate'}' />
4823 <input type='hidden' name='KEY' value='$key' />
4824 </td></form>
4825 <form method='post' name='cafrm${key}b'><td align='center'>
4826 <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' />
4827 <input type='hidden' name='ACTION' value='$Lang::tr{'download ca certificate'}' />
4828 <input type='hidden' name='KEY' value='$key' />
4829 </td></form>
4830 <form method='post' name='cafrm${key}c'><td align='center'>
4831 <input type='hidden' name='ACTION' value='$Lang::tr{'remove ca certificate'}' />
4832 <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' />
4833 <input type='hidden' name='KEY' value='$key' />
4834 </td></form></tr>
4835 END
4836 ;
4837 }
4838 }
4839
4840 print "</table>";
4841
4842 # If the file contains entries, print Key to action icons
4843 if ( -f "${General::swroot}/ovpn/ca/cacert.pem") {
4844 print <<END
4845 <table>
4846 <tr>
4847 <td class='boldbase'>&nbsp; <b>$Lang::tr{'legend'}:</b></td>
4848 <td>&nbsp; &nbsp; <img src='/images/info.gif' alt='$Lang::tr{'show certificate'}' /></td>
4849 <td class='base'>$Lang::tr{'show certificate'}</td>
4850 <td>&nbsp; &nbsp; <img src='/images/media-floppy.png' alt='$Lang::tr{'download certificate'}' /></td>
4851 <td class='base'>$Lang::tr{'download certificate'}</td>
4852 </tr>
4853 </table>
4854 END
4855 ;
4856 }
4857
4858 print <<END
4859 <form method='post' enctype='multipart/form-data'>
4860 <table width='100%' border='0'>
4861 <tr><td class='base' nowrap='nowrap'>$Lang::tr{'ca name'}:</td><td nowrap='nowrap' width='8%'><input type='text' name='CA_NAME' value='$cgiparams{'CA_NAME'}' size='15' align='left'/></td><td nowrap='nowrap' align='right'><input type='file' name='FH' size='25' /><input type='submit' name='ACTION' value='$Lang::tr{'upload ca certificate'}' /></td></tr>
4862 <tr><td colspan='4'><hr /></td></tr>
4863 <tr align='right'><td colspan='4' align='right' width='80%'><input type='submit' name='ACTION' value='$Lang::tr{'show crl'}' /></td></tr>
4864 </table>
4865 END
4866 ;
4867
4868
4869 &Header::closebox();
4870 if ( $srunning eq "yes" ) {
4871 print "<div align='center'><form method='post'><input type='submit' name='ACTION' value='$Lang::tr{'reset'}' disabled='disabled' /></div></form>\n";
4872 }else{
4873 print "<div align='center'><form method='post'><input type='submit' name='ACTION' value='$Lang::tr{'reset'}' /></div></form>\n";
4874 }
4875 if ( -f "${General::swroot}/ovpn/ca/cacert.pem" ) {
4876
4877 ###
4878 # m.a.d net2net
4879 #<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>
4880 ###
4881
4882 &Header::openbox('100%', 'LEFT', $Lang::tr{'Client status and controlc' });
4883 print <<END
4884
4885
4886 <table width='100%' border='0' cellspacing='1' cellpadding='0'>
4887 <tr>
4888 <td width='10%' class='boldbase' align='center'><b>$Lang::tr{'name'}</b></td>
4889 <td width='15%' class='boldbase' align='center'><b>$Lang::tr{'type'}</b></td>
4890 <td width='22%' class='boldbase' align='center'><b>$Lang::tr{'network'}</b></td>
4891 <td width='20%' class='boldbase' align='center'><b>$Lang::tr{'remark'}</b></td>
4892 <td width='10%' class='boldbase' align='center'><b>$Lang::tr{'status'}</b></td>
4893 <td width='5%' class='boldbase' colspan='6' align='center'><b>$Lang::tr{'action'}</b></td>
4894 </tr>
4895 END
4896 ;
4897 my $id = 0;
4898 my $gif;
4899 foreach my $key (sort { uc($confighash{$a}[1]) cmp uc($confighash{$b}[1]) } keys %confighash) {
4900 if ($confighash{$key}[0] eq 'on') { $gif = 'on.gif'; } else { $gif = 'off.gif'; }
4901
4902 if ($id % 2) {
4903 print "<tr bgcolor='$color{'color20'}'>\n";
4904 } else {
4905 print "<tr bgcolor='$color{'color22'}'>\n";
4906 }
4907 print "<td align='center' nowrap='nowrap'>$confighash{$key}[1]</td>";
4908 print "<td align='center' nowrap='nowrap'>" . $Lang::tr{"$confighash{$key}[3]"} . " (" . $Lang::tr{"$confighash{$key}[4]"} . ")</td>";
4909 #if ($confighash{$key}[4] eq 'cert') {
4910 #print "<td align='left' nowrap='nowrap'>$confighash{$key}[2]</td>";
4911 #} else {
4912 #print "<td align='left'>&nbsp;</td>";
4913 #}
4914 my $cavalid = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/certs/$confighash{$key}[1]cert.pem`;
4915 $cavalid =~ /Not After : (.*)[\n]/;
4916 $cavalid = $1;
4917 if ($confighash{$key}[32] eq "" && $confighash{$key}[3] eq 'net' ){$confighash{$key}[32]="net-2-net";}
4918 if ($confighash{$key}[32] eq "" && $confighash{$key}[3] eq 'host' ){$confighash{$key}[32]="dynamic";}
4919 print "<td align='center'>$confighash{$key}[32]</td>";
4920 print "<td align='center'>$confighash{$key}[25]</td>";
4921
4922 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>";
4923
4924 if ($confighash{$key}[0] eq 'off') {
4925 $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>";
4926 } else {
4927
4928 ###
4929 # m.a.d net2net
4930 ###
4931
4932 if ($confighash{$key}[3] eq 'net') {
4933
4934 if (-e "/var/run/$confighash{$key}[1]n2n.pid") {
4935 my @output = "";
4936 my @tustate = "";
4937 my $tport = $confighash{$key}[22];
4938 my $tnet = new Net::Telnet ( Timeout=>5, Errmode=>'return', Port=>$tport);
4939 if ($tport ne '') {
4940 $tnet->open('127.0.0.1');
4941 @output = $tnet->cmd(String => 'state', Prompt => '/(END.*\n|ERROR:.*\n)/');
4942 @tustate = split(/\,/, $output[1]);
4943 ###
4944 #CONNECTING -- OpenVPN's initial state.
4945 #WAIT -- (Client only) Waiting for initial response from server.
4946 #AUTH -- (Client only) Authenticating with server.
4947 #GET_CONFIG -- (Client only) Downloading configuration options from server.
4948 #ASSIGN_IP -- Assigning IP address to virtual network interface.
4949 #ADD_ROUTES -- Adding routes to system.
4950 #CONNECTED -- Initialization Sequence Completed.
4951 #RECONNECTING -- A restart has occurred.
4952 #EXITING -- A graceful exit is in progress.
4953 ####
4954
4955 if ( $tustate[1] eq 'CONNECTED') {
4956 $active = "<table cellpadding='2' cellspacing='0' bgcolor='${Header::colourgreen}' width='100%'><tr><td align='center'><b><font color='#FFFFFF'>$Lang::tr{'capsopen'}</font></b></tr></td></table>";
4957 } else {
4958 $active = "<table cellpadding='2' cellspacing='0' bgcolor='${Header::colourred}' width='100%'><tr><td align='center'><b><font color='#FFFFFF'>$tustate[1]</font></b></td></tr></table>";
4959 }
4960 }
4961 }
4962 } else {
4963
4964 my $cn;
4965 my @match = ();
4966 foreach my $line (@status) {
4967 chomp($line);
4968 if ( $line =~ /^(.+),(\d+\.\d+\.\d+\.\d+\:\d+),(\d+),(\d+),(.+)/) {
4969 @match = split(m/^(.+),(\d+\.\d+\.\d+\.\d+\:\d+),(\d+),(\d+),(.+)/, $line);
4970 if ($match[1] ne "Common Name") {
4971 $cn = $match[1];
4972 }
4973 $cn =~ s/[_]/ /g;
4974 if ($cn eq "$confighash{$key}[2]") {
4975 $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>";
4976 }
4977 }
4978
4979 }
4980 }
4981 }
4982
4983
4984 print <<END
4985 <td align='center'>$active</td>
4986
4987 <form method='post' name='frm${key}a'><td align='center'>
4988 <input type='image' name='$Lang::tr{'dl client arch'}' src='/images/openvpn.png' alt='$Lang::tr{'dl client arch'}' title='$Lang::tr{'dl client arch'}' border='0' />
4989 <input type='hidden' name='ACTION' value='$Lang::tr{'dl client arch'}' />
4990 <input type='hidden' name='KEY' value='$key' />
4991 </td></form>
4992 END
4993 ;
4994 if ($confighash{$key}[4] eq 'cert') {
4995 print <<END
4996 <form method='post' name='frm${key}b'><td align='center'>
4997 <input type='image' name='$Lang::tr{'show certificate'}' src='/images/info.gif' alt='$Lang::tr{'show certificate'}' title='$Lang::tr{'show certificate'}' border='0' />
4998 <input type='hidden' name='ACTION' value='$Lang::tr{'show certificate'}' />
4999 <input type='hidden' name='KEY' value='$key' />
5000 </td></form>
5001 END
5002 ; } else {
5003 print "<td>&nbsp;</td>";
5004 }
5005 if ($confighash{$key}[4] eq 'cert' && -f "${General::swroot}/ovpn/certs/$confighash{$key}[1].p12") {
5006 print <<END
5007 <form method='post' name='frm${key}c'><td align='center'>
5008 <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' />
5009 <input type='hidden' name='ACTION' value='$Lang::tr{'download pkcs12 file'}' />
5010 <input type='hidden' name='KEY' value='$key' />
5011 </td></form>
5012 END
5013 ; } elsif ($confighash{$key}[4] eq 'cert') {
5014 print <<END
5015 <form method='post' name='frm${key}c'><td align='center'>
5016 <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' />
5017 <input type='hidden' name='ACTION' value='$Lang::tr{'download certificate'}' />
5018 <input type='hidden' name='KEY' value='$key' />
5019 </td></form>
5020 END
5021 ; } else {
5022 print "<td>&nbsp;</td>";
5023 }
5024 print <<END
5025 <form method='post' name='frm${key}d'><td align='center'>
5026 <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' />
5027 <input type='hidden' name='ACTION' value='$Lang::tr{'toggle enable disable'}' />
5028 <input type='hidden' name='KEY' value='$key' />
5029 </td></form>
5030
5031 <form method='post' name='frm${key}e'><td align='center'>
5032 <input type='hidden' name='ACTION' value='$Lang::tr{'edit'}' />
5033 <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'/>
5034 <input type='hidden' name='KEY' value='$key' />
5035 </td></form>
5036 <form method='post' name='frm${key}f'><td align='center'>
5037 <input type='hidden' name='ACTION' value='$Lang::tr{'remove'}' />
5038 <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' />
5039 <input type='hidden' name='KEY' value='$key' />
5040 </td></form>
5041 </tr>
5042 END
5043 ;
5044 $id++;
5045 }
5046 ;
5047
5048 # If the config file contains entries, print Key to action icons
5049 if ( $id ) {
5050 print <<END
5051 <table border='0'>
5052 <tr>
5053 <td class='boldbase'>&nbsp; <b>$Lang::tr{'legend'}:</b></td>
5054 <td>&nbsp; <img src='/images/on.gif' alt='$Lang::tr{'click to disable'}' /></td>
5055 <td class='base'>$Lang::tr{'click to disable'}</td>
5056 <td>&nbsp; &nbsp; <img src='/images/info.gif' alt='$Lang::tr{'show certificate'}' /></td>
5057 <td class='base'>$Lang::tr{'show certificate'}</td>
5058 <td>&nbsp; &nbsp; <img src='/images/edit.gif' alt='$Lang::tr{'edit'}' /></td>
5059 <td class='base'>$Lang::tr{'edit'}</td>
5060 <td>&nbsp; &nbsp; <img src='/images/delete.gif' alt='$Lang::tr{'remove'}' /></td>
5061 <td class='base'>$Lang::tr{'remove'}</td>
5062 </tr>
5063 <tr>
5064 <td>&nbsp; </td>
5065 <td>&nbsp; <img src='/images/off.gif' alt='?OFF' /></td>
5066 <td class='base'>$Lang::tr{'click to enable'}</td>
5067 <td> <img src='/images/media-floppy.png' alt='?FLOPPY' /></td>
5068 <td class='base'>$Lang::tr{'download certificate'}</td>
5069 <td> <img src='/images/openvpn.png' alt='?RELOAD'/></td>
5070 <td class='base'>$Lang::tr{'dl client arch'}</td>
5071 </tr>
5072 </table><hr>
5073 END
5074 ;
5075 }
5076
5077 print <<END
5078 <table width='100%'>
5079 <form method='post'>
5080 <tr><td align='right'><input type='submit' name='ACTION' value='$Lang::tr{'add'}' />
5081 <input type='submit' name='ACTION' value='$Lang::tr{'ovpn con stat'}' $activeonrun /></td></tr>
5082 </form>
5083 </table>
5084 END
5085 ;
5086 &Header::closebox();
5087 }
5088 &Header::closepage();
5089
5090
5091