openvpn: Changed directioning and added additional generation for ta.key.
[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-2014  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 77
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 use Sort::Naturally;
34 require '/var/ipfire/general-functions.pl';
35 require "${General::swroot}/lang.pl";
36 require "${General::swroot}/header.pl";
37 require "${General::swroot}/countries.pl";
38
39 # enable only the following on debugging purpose
40 #use warnings;
41 #use CGI::Carp 'fatalsToBrowser';
42 #workaround to suppress a warning when a variable is used only once
43 my @dummy = ( ${Header::colourgreen}, ${Header::colourblue} );
44 undef (@dummy);
45
46 my %color = ();
47 my %mainsettings = ();
48 &General::readhash("${General::swroot}/main/settings", \%mainsettings);
49 &General::readhash("/srv/web/ipfire/html/themes/".$mainsettings{'THEME'}."/include/colors.txt", \%color);
50
51 ###
52 ### Initialize variables
53 ###
54 my %ccdconfhash=();
55 my %ccdroutehash=();
56 my %ccdroute2hash=();
57 my %netsettings=();
58 my %cgiparams=();
59 my %vpnsettings=();
60 my %checked=();
61 my %confighash=();
62 my %cahash=();
63 my %selected=();
64 my $warnmessage = '';
65 my $errormessage = '';
66 my %settings=();
67 my $routes_push_file = '';
68 my $confighost="${General::swroot}/fwhosts/customhosts";
69 my $configgrp="${General::swroot}/fwhosts/customgroups";
70 my $customnet="${General::swroot}/fwhosts/customnetworks";
71 my $name;
72 my $col="";
73 &General::readhash("${General::swroot}/ethernet/settings", \%netsettings);
74 $cgiparams{'ENABLED'} = 'off';
75 $cgiparams{'ENABLED_BLUE'} = 'off';
76 $cgiparams{'ENABLED_ORANGE'} = 'off';
77 $cgiparams{'EDIT_ADVANCED'} = 'off';
78 $cgiparams{'NAT'} = 'off';
79 $cgiparams{'COMPRESSION'} = 'off';
80 $cgiparams{'ONLY_PROPOSED'} = 'off';
81 $cgiparams{'ACTION'} = '';
82 $cgiparams{'CA_NAME'} = '';
83 $cgiparams{'DH_NAME'} = 'dh1024.pem';
84 $cgiparams{'DHLENGHT'} = '';
85 $cgiparams{'DHCP_DOMAIN'} = '';
86 $cgiparams{'DHCP_DNS'} = '';
87 $cgiparams{'DHCP_WINS'} = '';
88 $cgiparams{'ROUTES_PUSH'} = '';
89 $cgiparams{'DCOMPLZO'} = 'off';
90 $cgiparams{'MSSFIX'} = '';
91 $cgiparams{'number'} = '';
92 $cgiparams{'PMTU_DISCOVERY'} = '';
93 $cgiparams{'DCIPHER'} = '';
94 $cgiparams{'DAUTH'} = '';
95 $cgiparams{'TLSAUTH'} = '';
96 $routes_push_file = "${General::swroot}/ovpn/routes_push";
97 unless (-e $routes_push_file)    { system("touch $routes_push_file"); }
98 unless (-e "${General::swroot}/ovpn/ccd.conf")    { system("touch ${General::swroot}/ovpn/ccd.conf"); }
99 unless (-e "${General::swroot}/ovpn/ccdroute")    { system("touch ${General::swroot}/ovpn/ccdroute"); }
100 unless (-e "${General::swroot}/ovpn/ccdroute2")    { system("touch ${General::swroot}/ovpn/ccdroute2"); }
101
102 &Header::getcgihash(\%cgiparams, {'wantfile' => 1, 'filevar' => 'FH'});
103
104 # prepare openvpn config file
105 ###
106 ### Useful functions
107 ###
108 sub haveOrangeNet
109 {
110         if ($netsettings{'CONFIG_TYPE'} == 2) {return 1;}
111         if ($netsettings{'CONFIG_TYPE'} == 4) {return 1;}
112         return 0;
113 }
114
115 sub haveBlueNet
116 {
117         if ($netsettings{'CONFIG_TYPE'} == 3) {return 1;}
118         if ($netsettings{'CONFIG_TYPE'} == 4) {return 1;}
119         return 0;
120 }
121
122 sub sizeformat{
123     my $bytesize = shift;
124     my $i = 0;
125
126     while(abs($bytesize) >= 1024){
127         $bytesize=$bytesize/1024;
128         $i++;
129         last if($i==6);
130     }
131
132     my @units = ("Bytes","KB","MB","GB","TB","PB","EB");
133     my $newsize=(int($bytesize*100 +0.5))/100;
134     return("$newsize $units[$i]");
135 }
136
137 sub cleanssldatabase
138 {
139     if (open(FILE, ">${General::swroot}/ovpn/certs/serial")) {
140         print FILE "01";
141         close FILE;
142     }
143     if (open(FILE, ">${General::swroot}/ovpn/certs/index.txt")) {
144         print FILE "";
145         close FILE;
146     }
147     unlink ("${General::swroot}/ovpn/certs/index.txt.old");
148     unlink ("${General::swroot}/ovpn/certs/serial.old");
149     unlink ("${General::swroot}/ovpn/certs/01.pem");
150 }
151
152 sub newcleanssldatabase
153 {
154     if (! -s "${General::swroot}/ovpn/certs/serial" )  {
155         open(FILE, ">${General::swroot}(ovpn/certs/serial");
156         print FILE "01";
157         close FILE;
158     }
159     if (! -s ">${General::swroot}/ovpn/certs/index.txt") {
160         system ("touch ${General::swroot}/ovpn/certs/index.txt");
161     }
162     unlink ("${General::swroot}/ovpn/certs/index.txt.old");
163     unlink ("${General::swroot}/ovpn/certs/serial.old");
164 }
165
166 sub deletebackupcert
167 {
168         if (open(FILE, "${General::swroot}/ovpn/certs/serial.old")) {
169                 my $hexvalue = <FILE>;
170                 chomp $hexvalue;
171                 close FILE;
172                 unlink ("${General::swroot}/ovpn/certs/$hexvalue.pem");
173         }
174 }
175
176 sub writeserverconf {
177     my %sovpnsettings = ();  
178     my @temp = ();  
179     &General::readhash("${General::swroot}/ovpn/settings", \%sovpnsettings);
180     &read_routepushfile;
181     
182     open(CONF,    ">${General::swroot}/ovpn/server.conf") or die "Unable to open ${General::swroot}/ovpn/server.conf: $!";
183     flock CONF, 2;
184     print CONF "#OpenVPN Server conf\n";
185     print CONF "\n";
186     print CONF "daemon openvpnserver\n";
187     print CONF "writepid /var/run/openvpn.pid\n";
188     print CONF "#DAN prepare OpenVPN for listening on blue and orange\n";
189     print CONF ";local $sovpnsettings{'VPN_IP'}\n";
190     print CONF "dev $sovpnsettings{'DDEVICE'}\n";
191     print CONF "proto $sovpnsettings{'DPROTOCOL'}\n";
192     print CONF "port $sovpnsettings{'DDEST_PORT'}\n";
193     print CONF "script-security 3 system\n";
194     print CONF "ifconfig-pool-persist /var/ipfire/ovpn/ovpn-leases.db 3600\n";
195     print CONF "client-config-dir /var/ipfire/ovpn/ccd\n";
196     print CONF "tls-server\n";
197     print CONF "ca ${General::swroot}/ovpn/ca/cacert.pem\n";
198     print CONF "cert ${General::swroot}/ovpn/certs/servercert.pem\n";
199     print CONF "key ${General::swroot}/ovpn/certs/serverkey.pem\n";
200     print CONF "dh ${General::swroot}/ovpn/ca/$cgiparams{'DH_NAME'}\n";
201     my @tempovpnsubnet = split("\/",$sovpnsettings{'DOVPN_SUBNET'});
202     print CONF "server $tempovpnsubnet[0] $tempovpnsubnet[1]\n";
203     #print CONF "push \"route $netsettings{'GREEN_NETADDRESS'} $netsettings{'GREEN_NETMASK'}\"\n";
204
205     # Check if we are using mssfix, fragment or mtu-disc and set the corretct mtu of 1500.
206     # If we doesn't use one of them, we can use the configured mtu value.
207     if ($sovpnsettings{'MSSFIX'} eq 'on') 
208         { print CONF "$sovpnsettings{'DDEVICE'}-mtu 1500\n"; }
209     elsif ($sovpnsettings{'FRAGMENT'} ne '' && $sovpnsettings{'DPROTOCOL'} ne 'tcp') 
210         { print CONF "$sovpnsettings{'DDEVICE'}-mtu 1500\n"; }
211     elsif (($sovpnsettings{'PMTU_DISCOVERY'} eq 'yes') ||
212         ($sovpnsettings{'PMTU_DISCOVERY'} eq 'maybe') ||
213         ($sovpnsettings{'PMTU_DISCOVERY'} eq 'no' ))
214         { print CONF "$sovpnsettings{'DDEVICE'}-mtu 1500\n"; } 
215     else 
216         { print CONF "$sovpnsettings{'DDEVICE'}-mtu $sovpnsettings{'DMTU'}\n"; }
217
218     if ($vpnsettings{'ROUTES_PUSH'} ne '') {
219                 @temp = split(/\n/,$vpnsettings{'ROUTES_PUSH'});
220                 foreach (@temp)
221                 {
222                         @tempovpnsubnet = split("\/",&General::ipcidr2msk($_));
223                         print CONF "push \"route " . $tempovpnsubnet[0]. " " .  $tempovpnsubnet[1] . "\"\n";
224                 }
225         }
226 # a.marx ccd
227         my %ccdconfhash=();
228         &General::readhasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash);
229         foreach my $key (keys %ccdconfhash) {
230                 my $a=$ccdconfhash{$key}[1];
231                 my ($b,$c) = split (/\//, $a);
232                 print CONF "route $b ".&General::cidrtosub($c)."\n";
233         }
234         my %ccdroutehash=();
235         &General::readhasharray("${General::swroot}/ovpn/ccdroute", \%ccdroutehash);
236         foreach my $key (keys %ccdroutehash) {
237                 foreach my $i ( 1 .. $#{$ccdroutehash{$key}}){
238                         my ($a,$b)=split (/\//,$ccdroutehash{$key}[$i]);
239                         print CONF "route $a $b\n";
240                 }
241         }
242 # ccd end
243
244         if ($sovpnsettings{CLIENT2CLIENT} eq 'on') {
245         print CONF "client-to-client\n";
246     }
247     if ($sovpnsettings{MSSFIX} eq 'on') {
248                 print CONF "mssfix\n";
249     }
250     if ($sovpnsettings{FRAGMENT} ne '' && $sovpnsettings{'DPROTOCOL'} ne 'tcp') {
251                 print CONF "fragment $sovpnsettings{'FRAGMENT'}\n";
252     }
253
254     # Check if a valid operating mode has been choosen and use it.
255     if (($sovpnsettings{'PMTU_DISCOVERY'} eq 'yes') ||
256         ($sovpnsettings{'PMTU_DISCOVERY'} eq 'maybe') ||
257         ($sovpnsettings{'PMTU_DISCOVERY'} eq 'no' )) {
258                 print CONF "mtu-disc $sovpnsettings{'PMTU_DISCOVERY'}\n";
259     }
260
261     if ($sovpnsettings{KEEPALIVE_1} > 0 && $sovpnsettings{KEEPALIVE_2} > 0) {   
262         print CONF "keepalive $sovpnsettings{'KEEPALIVE_1'} $sovpnsettings{'KEEPALIVE_2'}\n";
263     }   
264     print CONF "status-version 1\n";
265     print CONF "status /var/log/ovpnserver.log 30\n";
266     print CONF "cipher $sovpnsettings{DCIPHER}\n";
267     if ($sovpnsettings{'DAUTH'} eq '') {
268         print CONF "";
269     } else {
270         print CONF "auth $sovpnsettings{'DAUTH'}\n";
271     }
272     if ($sovpnsettings{'TLSAUTH'} eq 'on') {
273         print CONF "tls-auth ${General::swroot}/ovpn/certs/ta.key\n";
274     }
275     if ($sovpnsettings{DCOMPLZO} eq 'on') {
276         print CONF "comp-lzo\n";
277     }
278     if ($sovpnsettings{REDIRECT_GW_DEF1} eq 'on') {
279         print CONF "push \"redirect-gateway def1\"\n";
280     }
281     if ($sovpnsettings{DHCP_DOMAIN} ne '') {
282         print CONF "push \"dhcp-option DOMAIN $sovpnsettings{DHCP_DOMAIN}\"\n";
283     }
284
285     if ($sovpnsettings{DHCP_DNS} ne '') {
286         print CONF "push \"dhcp-option DNS $sovpnsettings{DHCP_DNS}\"\n";
287     }
288
289     if ($sovpnsettings{DHCP_WINS} ne '') {
290         print CONF "push \"dhcp-option WINS $sovpnsettings{DHCP_WINS}\"\n";
291     }
292     
293     if ($sovpnsettings{DHCP_WINS} eq '') {
294         print CONF "max-clients 100\n";
295     }
296     if ($sovpnsettings{DHCP_WINS} ne '') {
297         print CONF "max-clients $sovpnsettings{MAX_CLIENTS}\n";
298     }   
299     print CONF "tls-verify /usr/lib/openvpn/verify\n";
300     print CONF "crl-verify /var/ipfire/ovpn/crls/cacrl.pem\n";
301     print CONF "user nobody\n";
302     print CONF "group nobody\n";
303     print CONF "persist-key\n";
304     print CONF "persist-tun\n";
305         if ($sovpnsettings{LOG_VERB} ne '') {
306                 print CONF "verb $sovpnsettings{LOG_VERB}\n";
307         } else {
308                 print CONF "verb 3\n";
309         }       
310     print CONF "\n";
311     
312     close(CONF);
313 }    
314
315 sub emptyserverlog{
316     if (open(FILE, ">/var/log/ovpnserver.log")) {
317         flock FILE, 2;
318         print FILE "";
319         close FILE;
320     }
321
322 }
323
324 sub delccdnet 
325 {
326         my %ccdconfhash = ();
327         my %ccdhash = ();
328         my $ccdnetname=$_[0];
329         if (-f "${General::swroot}/ovpn/ovpnconfig"){
330                 &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%ccdhash);
331                 foreach my $key (keys %ccdhash) {
332                         if ($ccdhash{$key}[32] eq $ccdnetname) {
333                                 $errormessage=$Lang::tr{'ccd err hostinnet'};
334                                 return;
335                         }
336                 }
337         }
338         &General::readhasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash);
339         foreach my $key (keys %ccdconfhash) {
340                         if ($ccdconfhash{$key}[0] eq $ccdnetname){
341                                 delete $ccdconfhash{$key};
342                         }
343         }
344         &General::writehasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash);
345         
346         &writeserverconf;
347         return 0;
348 }
349
350 sub addccdnet
351 {
352         my %ccdconfhash=();
353         my @ccdconf=();
354         my $ccdname=$_[0];
355         my $ccdnet=$_[1];
356         my $subcidr;
357         my @ip2=();
358         my $checkup;
359         my $ccdip;
360         my $baseaddress;
361         
362         
363         #check name     
364         if ($ccdname eq '') 
365         {
366                 $errormessage=$errormessage.$Lang::tr{'ccd err name'}."<br>";
367                 return
368         }
369         
370         if(!&General::validhostname($ccdname))
371         {
372                 $errormessage=$Lang::tr{'ccd err invalidname'};
373                 return;
374         }
375                 
376         ($ccdip,$subcidr) = split (/\//,$ccdnet);
377         $subcidr=&General::iporsubtocidr($subcidr);
378         #check subnet
379         if ($subcidr > 30)
380         {
381                 $errormessage=$Lang::tr{'ccd err invalidnet'};
382                 return;
383         }
384         #check ip
385         if (!&General::validipandmask($ccdnet)){
386                 $errormessage=$Lang::tr{'ccd err invalidnet'};
387                 return;
388         }
389         
390         $errormessage=&General::checksubnets($ccdname,$ccdnet);
391         
392                 
393         if (!$errormessage) {
394                 my %ccdconfhash=();
395                 $baseaddress=&General::getnetworkip($ccdip,$subcidr);
396                 &General::readhasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash);
397                 my $key = &General::findhasharraykey (\%ccdconfhash);
398                 foreach my $i (0 .. 1) { $ccdconfhash{$key}[$i] = "";}
399                 $ccdconfhash{$key}[0] = $ccdname;
400                 $ccdconfhash{$key}[1] = $baseaddress."/".$subcidr;
401                 &General::writehasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash);
402                 &writeserverconf;
403                 $cgiparams{'ccdname'}='';
404                 $cgiparams{'ccdsubnet'}='';
405                 return 1;
406         }
407 }
408
409 sub modccdnet
410 {
411         
412         my $newname=$_[0];
413         my $oldname=$_[1];
414         my %ccdconfhash=();
415         my %ccdhash=();
416         &General::readhasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash);
417         foreach my $key (keys %ccdconfhash) {
418                 if ($ccdconfhash{$key}[0] eq $oldname) {
419                         foreach my $key1 (keys %ccdconfhash) {
420                                 if ($ccdconfhash{$key1}[0] eq $newname){
421                                         $errormessage=$errormessage.$Lang::tr{'ccd err netadrexist'};
422                                         return;
423                                 }else{
424                                         $ccdconfhash{$key}[0]= $newname;
425                                         &General::writehasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash);
426                                         last;
427                                 }
428                         }
429                 }
430         }
431         
432         &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%ccdhash);
433                 foreach my $key (keys %ccdhash) {
434                         if ($ccdhash{$key}[32] eq $oldname) {
435                                 $ccdhash{$key}[32]=$newname;
436                                 &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%ccdhash);
437                                 last;
438                         }
439                 }
440         
441         return 0;
442 }
443 sub ccdmaxclients
444 {
445         my $ccdnetwork=$_[0];
446         my @octets=();
447         my @subnet=();
448         @octets=split("\/",$ccdnetwork);
449         @subnet= split /\./, &General::cidrtosub($octets[1]);
450         my ($a,$b,$c,$d,$e);
451         $a=256-$subnet[0];
452         $b=256-$subnet[1];
453         $c=256-$subnet[2];
454         $d=256-$subnet[3];
455         $e=($a*$b*$c*$d)/4;
456         return $e-1;
457 }
458
459 sub getccdadresses 
460 {
461         my $ipin=$_[0];
462         my ($ip1,$ip2,$ip3,$ip4)=split  /\./, $ipin;
463         my $cidr=$_[1];
464         chomp($cidr);
465         my $count=$_[2];
466         my $hasip=$_[3];
467         chomp($hasip);
468         my @iprange=();
469         my %ccdhash=();
470         &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%ccdhash);
471         $iprange[0]=$ip1.".".$ip2.".".$ip3.".".($ip4+2);
472         for (my $i=1;$i<=$count;$i++) {
473                 my $tmpip=$iprange[$i-1];
474                 my $stepper=$i*4;
475                 $iprange[$i]= &General::getnextip($tmpip,4);
476         }
477         my $r=0;
478         foreach my $key (keys %ccdhash) {
479                 $r=0;
480                 foreach  my $tmp (@iprange){
481                         my ($net,$sub) = split (/\//,$ccdhash{$key}[33]);
482                         if ($net eq $tmp) {
483                                 if ( $hasip ne  $ccdhash{$key}[33] ){
484                                         splice (@iprange,$r,1);
485                                 }
486                         }
487                         $r++;
488                 }
489         }
490         return @iprange;
491 }
492
493 sub fillselectbox
494 {
495         my $boxname=$_[1];
496         my ($ccdip,$subcidr) = split("/",$_[0]); 
497         my $tz=$_[2];
498         my @allccdips=&getccdadresses($ccdip,$subcidr,&ccdmaxclients($ccdip."/".$subcidr),$tz);
499         print"<select name='$boxname' STYLE='font-family : arial; font-size : 9pt; width:130px;' >";
500         foreach (@allccdips) {
501                 my $ip=$_."/30";
502                 chomp($ip);
503                 print "<option value='$ip' ";
504                 if ( $ip eq $cgiparams{$boxname} ){
505                         print"selected";
506                 }
507                 print ">$ip</option>";
508         }
509         print "</select>";
510 }
511
512 sub hostsinnet
513 {
514         my $name=$_[0];
515         my %ccdhash=();
516         my $i=0;
517         &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%ccdhash);
518         foreach my $key (keys %ccdhash) {
519                 if ($ccdhash{$key}[32] eq $name){ $i++;}
520         }
521         return $i;
522 }
523
524 sub check_routes_push
525 {
526                         my $val=$_[0];
527                         my ($ip,$cidr) = split (/\//, $val);
528                         ##check for existing routes in routes_push
529                         if (-e "${General::swroot}/ovpn/routes_push") {
530                                 open(FILE,"${General::swroot}/ovpn/routes_push");
531                                 while (<FILE>) {
532                                         $_=~s/\s*$//g;
533                                         
534                                         my ($ip2,$cidr2) = split (/\//,"$_");
535                                         my $val2=$ip2."/".&General::iporsubtodec($cidr2);
536                                         
537                                         if($val eq $val2){
538                                                 return 0;
539                                         }
540                                         #subnetcheck
541                                         if (&General::IpInSubnet ($ip,$ip2,&General::iporsubtodec($cidr2))){
542                                                 return 0;
543                                         }
544                                 };
545                                 close(FILE);
546                         }
547         return 1;
548 }
549
550 sub check_ccdroute
551 {
552         my %ccdroutehash=();
553         my $val=$_[0];
554         my ($ip,$cidr) = split (/\//, $val);
555         #check for existing routes in ccdroute
556         &General::readhasharray("${General::swroot}/ovpn/ccdroute", \%ccdroutehash);
557         foreach my $key (keys %ccdroutehash) {
558                 foreach my $i (1 .. $#{$ccdroutehash{$key}}) {
559                         if (&General::iporsubtodec($val) eq $ccdroutehash{$key}[$i] && $ccdroutehash{$key}[0] ne $cgiparams{'NAME'}){
560                                 return 0;
561                         }
562                         my ($ip2,$cidr2) = split (/\//,$ccdroutehash{$key}[$i]);
563                         #subnetcheck
564                         if (&General::IpInSubnet ($ip,$ip2,$cidr2)&& $ccdroutehash{$key}[0] ne $cgiparams{'NAME'} ){
565                                 return 0;
566                         }
567                 }
568         }
569         return 1;
570 }
571 sub check_ccdconf
572 {
573         my %ccdconfhash=();
574         my $val=$_[0];
575         my ($ip,$cidr) = split (/\//, $val);
576         #check for existing routes in ccdroute
577         &General::readhasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash);
578         foreach my $key (keys %ccdconfhash) {
579                 if (&General::iporsubtocidr($val) eq $ccdconfhash{$key}[1]){
580                                 return 0;
581                         }
582                         my ($ip2,$cidr2) = split (/\//,$ccdconfhash{$key}[1]);
583                         #subnetcheck
584                         if (&General::IpInSubnet ($ip,$ip2,&General::cidrtosub($cidr2))){
585                                 return 0;
586                         }
587                 
588         }
589         return 1;
590 }
591
592 ###
593 # m.a.d net2net
594 ###
595
596 sub validdotmask
597 {
598         my $ipdotmask = $_[0];
599         if (&General::validip($ipdotmask)) { return 0; }
600         if (!($ipdotmask =~ /^(.*?)\/(.*?)$/)) {  }
601         my $mask = $2;
602         if (($mask =~ /\./ )) { return 0; }     
603   return 1;
604 }
605
606 # -------------------------------------------------------------------
607
608 sub write_routepushfile
609 {
610         open(FILE, ">$routes_push_file");
611         flock(FILE, 2);
612         if ($vpnsettings{'ROUTES_PUSH'} ne '') {
613                 print FILE $vpnsettings{'ROUTES_PUSH'};
614         }
615         close(FILE); 
616 }
617
618 sub read_routepushfile
619 {
620         if (-e "$routes_push_file") {
621                 open(FILE,"$routes_push_file");
622                 delete $vpnsettings{'ROUTES_PUSH'};
623                 while (<FILE>) { $vpnsettings{'ROUTES_PUSH'} .= $_ };
624                 close(FILE);
625                 $cgiparams{'ROUTES_PUSH'} = $vpnsettings{'ROUTES_PUSH'};
626                 
627         }
628 }
629
630
631 #hier die refresh page
632 if ( -e "${General::swroot}/ovpn/gencanow") {
633     my $refresh = '';
634     $refresh = "<meta http-equiv='refresh' content='15;' />";
635     &Header::showhttpheaders();
636     &Header::openpage($Lang::tr{'OVPN'}, 1, $refresh);
637     &Header::openbigbox('100%', 'center');
638     &Header::openbox('100%', 'left', "$Lang::tr{'generate root/host certificates'}:");
639     print "<tr>\n<td align='center'><img src='/images/clock.gif' alt='' /></td>\n";
640     print "<td colspan='2'><font color='red'>Please be patient this realy can take some time on older hardware...</font></td></tr>\n";
641     &Header::closebox();
642     &Header::closebigbox();
643     &Header::closepage();
644     exit (0);
645 }
646 ##hier die refresh page
647
648
649 ###
650 ### OpenVPN Server Control
651 ###
652 if ($cgiparams{'ACTION'} eq $Lang::tr{'start ovpn server'} ||
653     $cgiparams{'ACTION'} eq $Lang::tr{'stop ovpn server'} ||
654     $cgiparams{'ACTION'} eq $Lang::tr{'restart ovpn server'}) {
655     #start openvpn server
656     if ($cgiparams{'ACTION'} eq $Lang::tr{'start ovpn server'}){
657         &emptyserverlog();
658         system('/usr/local/bin/openvpnctrl', '-s');
659     }   
660     #stop openvpn server
661     if ($cgiparams{'ACTION'} eq $Lang::tr{'stop ovpn server'}){
662         system('/usr/local/bin/openvpnctrl', '-k');
663         &emptyserverlog();      
664     }   
665 #    #restart openvpn server
666 #    if ($cgiparams{'ACTION'} eq $Lang::tr{'restart ovpn server'}){
667 #workarund, till SIGHUP also works when running as nobody    
668 #       system('/usr/local/bin/openvpnctrl', '-r');     
669 #       &emptyserverlog();      
670 #    }       
671 }
672
673 ###
674 ### Save Advanced options
675 ###
676
677 if ($cgiparams{'ACTION'} eq $Lang::tr{'save-adv-options'}) {
678     &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings);
679     #DAN do we really need (to to check) this value? Besides if we listen on blue and orange too,
680     #DAN this value has to leave.
681 #new settings for daemon
682     $vpnsettings{'LOG_VERB'} = $cgiparams{'LOG_VERB'};
683     $vpnsettings{'KEEPALIVE_1'} = $cgiparams{'KEEPALIVE_1'};
684     $vpnsettings{'KEEPALIVE_2'} = $cgiparams{'KEEPALIVE_2'};
685     $vpnsettings{'MAX_CLIENTS'} = $cgiparams{'MAX_CLIENTS'};
686     $vpnsettings{'REDIRECT_GW_DEF1'} = $cgiparams{'REDIRECT_GW_DEF1'};
687     $vpnsettings{'CLIENT2CLIENT'} = $cgiparams{'CLIENT2CLIENT'};
688     $vpnsettings{'DHCP_DOMAIN'} = $cgiparams{'DHCP_DOMAIN'};
689     $vpnsettings{'DHCP_DNS'} = $cgiparams{'DHCP_DNS'};
690     $vpnsettings{'DHCP_WINS'} = $cgiparams{'DHCP_WINS'};
691     $vpnsettings{'ROUTES_PUSH'} = $cgiparams{'ROUTES_PUSH'};
692     $vpnsettings{'PMTU_DISCOVERY'} = $cgiparams{'PMTU_DISCOVERY'};
693     $vpnsettings{'DAUTH'} = $cgiparams{'DAUTH'};
694     $vpnsettings{'TLSAUTH'} = $cgiparams{'TLSAUTH'};
695     my @temp=();
696     
697     if ($cgiparams{'FRAGMENT'} eq '') {
698         delete $vpnsettings{'FRAGMENT'};
699     } else {
700         if ($cgiparams{'FRAGMENT'} !~ /^[0-9]+$/) { 
701             $errormessage = "Incorrect value, please insert only numbers.";
702         goto ADV_ERROR;
703                 } else {
704                         $vpnsettings{'FRAGMENT'} = $cgiparams{'FRAGMENT'};
705         }
706     }
707
708     if ($cgiparams{'MSSFIX'} ne 'on') {
709         delete $vpnsettings{'MSSFIX'};
710     } else {
711         $vpnsettings{'MSSFIX'} = $cgiparams{'MSSFIX'};
712     }
713
714     if (($cgiparams{'PMTU_DISCOVERY'} eq 'yes') ||
715         ($cgiparams{'PMTU_DISCOVERY'} eq 'maybe') ||
716         ($cgiparams{'PMTU_DISCOVERY'} eq 'no' )) {
717
718         if (($cgiparams{'MSSFIX'} eq 'on') || ($cgiparams{'FRAGMENT'} ne '')) {
719                 $errormessage = $Lang::tr{'ovpn mtu-disc with mssfix or fragment'};
720                 goto ADV_ERROR;
721         }
722     }
723                 
724     if ($cgiparams{'DHCP_DOMAIN'} ne ''){
725         unless (&General::validdomainname($cgiparams{'DHCP_DOMAIN'}) || &General::validip($cgiparams{'DHCP_DOMAIN'})) {
726                 $errormessage = $Lang::tr{'invalid input for dhcp domain'};
727         goto ADV_ERROR;
728         }
729     }
730     if ($cgiparams{'DHCP_DNS'} ne ''){
731         unless (&General::validfqdn($cgiparams{'DHCP_DNS'}) || &General::validip($cgiparams{'DHCP_DNS'})) {
732                 $errormessage = $Lang::tr{'invalid input for dhcp dns'};
733         goto ADV_ERROR;
734         }
735     }
736     if ($cgiparams{'DHCP_WINS'} ne ''){
737         unless (&General::validfqdn($cgiparams{'DHCP_WINS'}) || &General::validip($cgiparams{'DHCP_WINS'})) {
738                 $errormessage = $Lang::tr{'invalid input for dhcp wins'};
739                 goto ADV_ERROR;
740         }
741     }
742     if ($cgiparams{'ROUTES_PUSH'} ne ''){
743         @temp = split(/\n/,$cgiparams{'ROUTES_PUSH'});
744         undef $vpnsettings{'ROUTES_PUSH'};
745         
746         foreach my $tmpip (@temp)
747         {
748                 s/^\s+//g; s/\s+$//g;
749                 
750                 if ($tmpip)
751                 {
752                         $tmpip=~s/\s*$//g; 
753                         unless (&General::validipandmask($tmpip)) {
754                                 $errormessage = "$tmpip ".$Lang::tr{'ovpn errmsg invalid ip or mask'};
755                                 goto ADV_ERROR;
756                         }
757                         my ($ip, $cidr) = split("\/",&General::ipcidr2msk($tmpip));
758                         
759                         if ($ip eq $netsettings{'GREEN_NETADDRESS'} && $cidr eq $netsettings{'GREEN_NETMASK'}) {
760                                 $errormessage = $Lang::tr{'ovpn errmsg green already pushed'};
761                                 goto ADV_ERROR;
762                         }
763 # a.marx ccd                    
764                         my %ccdroutehash=();
765                         &General::readhasharray("${General::swroot}/ovpn/ccdroute", \%ccdroutehash);
766                         foreach my $key (keys %ccdroutehash) {
767                                 foreach my $i (1 .. $#{$ccdroutehash{$key}}) { 
768                                         if ( $ip."/".$cidr eq $ccdroutehash{$key}[$i] ){
769                                                 $errormessage="Route $ip\/$cidr ".$Lang::tr{'ccd err inuse'}." $ccdroutehash{$key}[0]" ;
770                                                 goto ADV_ERROR;
771                                         }
772                                         my ($ip2,$cidr2) = split(/\//,$ccdroutehash{$key}[$i]);
773                                         if (&General::IpInSubnet ($ip,$ip2,$cidr2)){
774                                                 $errormessage="Route $ip\/$cidr ".$Lang::tr{'ccd err inuse'}." $ccdroutehash{$key}[0]" ;
775                                                 goto ADV_ERROR;
776                                         }
777                                 }
778                         }
779                         
780 # ccd end
781                         
782                         $vpnsettings{'ROUTES_PUSH'} .= $tmpip."\n";
783                 }
784         }
785     &write_routepushfile;
786         undef $vpnsettings{'ROUTES_PUSH'};
787     }
788         else {
789         undef $vpnsettings{'ROUTES_PUSH'};
790         &write_routepushfile;
791     }
792     if ((length($cgiparams{'MAX_CLIENTS'}) == 0) || (($cgiparams{'MAX_CLIENTS'}) < 1 ) || (($cgiparams{'MAX_CLIENTS'}) > 255 )) {
793         $errormessage = $Lang::tr{'invalid input for max clients'};
794         goto ADV_ERROR;
795     }
796     if ($cgiparams{'KEEPALIVE_1'} ne '') {
797         if ($cgiparams{'KEEPALIVE_1'} !~ /^[0-9]+$/) { 
798             $errormessage = $Lang::tr{'invalid input for keepalive 1'};
799         goto ADV_ERROR;
800         }
801     }
802     if ($cgiparams{'KEEPALIVE_2'} ne ''){
803         if ($cgiparams{'KEEPALIVE_2'} !~ /^[0-9]+$/) { 
804             $errormessage = $Lang::tr{'invalid input for keepalive 2'};
805         goto ADV_ERROR;
806         }
807     }
808     if ($cgiparams{'KEEPALIVE_2'} < ($cgiparams{'KEEPALIVE_1'} * 2)){
809         $errormessage = $Lang::tr{'invalid input for keepalive 1:2'};
810         goto ADV_ERROR; 
811     }
812     # Create ta.key for tls-auth if not presant
813     if ($cgiparams{'TLSAUTH'} eq 'on') {
814         if ( ! -e "${General::swroot}/ovpn/certs/ta.key") {
815                 system('/usr/sbin/openvpn', '--genkey', '--secret', "${General::swroot}/ovpn/certs/ta.key");
816                 if ($?) {
817                 $errormessage = "$Lang::tr{'openssl produced an error'}: $?";
818         goto ADV_ERROR;
819                 }
820         }
821     }
822     
823     &General::writehash("${General::swroot}/ovpn/settings", \%vpnsettings);
824     &writeserverconf();#hier ok
825 }
826
827 ###
828 # m.a.d net2net
829 ###
830
831 if ($cgiparams{'ACTION'} eq $Lang::tr{'save'} && $cgiparams{'TYPE'} eq 'net' && $cgiparams{'SIDE'} eq 'server')
832 {
833
834 my @remsubnet = split(/\//,$cgiparams{'REMOTE_SUBNET'});
835 my @ovsubnettemp =  split(/\./,$cgiparams{'OVPN_SUBNET'});
836 my $ovsubnet =  "$ovsubnettemp[0].$ovsubnettemp[1].$ovsubnettemp[2]";
837 my $tunmtu =  '';
838
839 unless(-d "${General::swroot}/ovpn/n2nconf/"){mkdir "${General::swroot}/ovpn/n2nconf", 0755 or die "Unable to create dir $!";}
840 unless(-d "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}", 0770 or die "Unable to create dir $!";}   
841
842   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: $!";
843   
844   flock SERVERCONF, 2;
845   print SERVERCONF "# IPFire n2n Open VPN Server Config by ummeegge und m.a.d\n"; 
846   print SERVERCONF "\n"; 
847   print SERVERCONF "# User Security\n";
848   print SERVERCONF "user nobody\n";
849   print SERVERCONF "group nobody\n";
850   print SERVERCONF "persist-tun\n";
851   print SERVERCONF "persist-key\n";
852   print SERVERCONF "script-security 2\n";
853   print SERVERCONF "# IP/DNS for remote Server Gateway\n"; 
854
855   if ($cgiparams{'REMOTE'} ne '') {
856   print SERVERCONF "remote $cgiparams{'REMOTE'}\n";
857   }
858
859   print SERVERCONF "float\n";
860   print SERVERCONF "# IP adresses of the VPN Subnet\n"; 
861   print SERVERCONF "ifconfig $ovsubnet.1 $ovsubnet.2\n"; 
862   print SERVERCONF "# Client Gateway Network\n"; 
863   print SERVERCONF "route $remsubnet[0] $remsubnet[1]\n";
864   print SERVERCONF "# tun Device\n"; 
865   print SERVERCONF "dev tun\n"; 
866   print SERVERCONF "# Port and Protokol\n"; 
867   print SERVERCONF "port $cgiparams{'DEST_PORT'}\n"; 
868   
869   if ($cgiparams{'PROTOCOL'} eq 'tcp') {
870   print SERVERCONF "proto tcp-server\n";
871   print SERVERCONF "# Packet size\n";
872   if ($cgiparams{'MTU'} eq '') {$tunmtu = '1400'} else {$tunmtu = $cgiparams{'MTU'}};
873   print SERVERCONF "tun-mtu $tunmtu\n";
874   }
875   
876   if ($cgiparams{'PROTOCOL'} eq 'udp') {
877   print SERVERCONF "proto udp\n"; 
878   print SERVERCONF "# Paketsize\n";
879   if ($cgiparams{'MTU'} eq '') {$tunmtu = '1500'} else {$tunmtu = $cgiparams{'MTU'}};
880   print SERVERCONF "tun-mtu $tunmtu\n";
881   if ($cgiparams{'FRAGMENT'} ne '') {print SERVERCONF "fragment $cgiparams{'FRAGMENT'}\n";} 
882   if ($cgiparams{'MSSFIX'} eq 'on') {print SERVERCONF "mssfix\n"; }; 
883   }
884
885   # Check if a valid operating mode has been choosen and use it.
886   if (($cgiparams{'PMTU_DISCOVERY'} eq 'yes') ||
887       ($cgiparams{'PMTU_DISCOVERY'} eq 'maybe') ||
888       ($cgiparams{'PMTU_DISCOVERY'} eq 'no' )) {
889         if(($cgiparams{'MSSFIX'} ne 'on') || ($cgiparams{'FRAGMENT'} eq '')) {
890                 if($cgiparams{'MTU'} eq '1500') {
891                         print SERVERCONF "mtu-disc $cgiparams{'PMTU_DISCOVERY'}\n";
892                 }
893         }
894   }
895   print SERVERCONF "# Auth. Server\n"; 
896   print SERVERCONF "tls-server\n"; 
897   print SERVERCONF "ca ${General::swroot}/ovpn/ca/cacert.pem\n"; 
898   print SERVERCONF "cert ${General::swroot}/ovpn/certs/servercert.pem\n"; 
899   print SERVERCONF "key ${General::swroot}/ovpn/certs/serverkey.pem\n"; 
900   print SERVERCONF "dh ${General::swroot}/ovpn/ca/$cgiparams{'DH_NAME'}\n";
901   print SERVERCONF "# Cipher\n"; 
902   print SERVERCONF "cipher $cgiparams{'DCIPHER'}\n";
903   if ($cgiparams{'DAUTH'} eq '') {
904         print SERVERCONF "auth SHA1\n";
905   } else {
906         print SERVERCONF "# HMAC algorithm\n";
907         print SERVERCONF "auth $cgiparams{'DAUTH'}\n";
908   }
909   if ($cgiparams{'COMPLZO'} eq 'on') {
910    print SERVERCONF "# Enable Compression\n";
911    print SERVERCONF "comp-lzo\r\n";
912      }
913   print SERVERCONF "# Debug Level\n"; 
914   print SERVERCONF "verb 3\n"; 
915   print SERVERCONF "# Tunnel check\n"; 
916   print SERVERCONF "keepalive 10 60\n"; 
917   print SERVERCONF "# Start as daemon\n"; 
918   print SERVERCONF "daemon $cgiparams{'NAME'}n2n\n"; 
919   print SERVERCONF "writepid /var/run/$cgiparams{'NAME'}n2n.pid\n"; 
920   print SERVERCONF "# Activate Management Interface and Port\n"; 
921   if ($cgiparams{'OVPN_MGMT'} eq '') {print SERVERCONF "management localhost $cgiparams{'DEST_PORT'}\n"}
922   else {print SERVERCONF "management localhost $cgiparams{'OVPN_MGMT'}\n"};
923   close(SERVERCONF);
924
925 }
926
927 ###
928 # m.a.d net2net
929 ###
930
931 if ($cgiparams{'ACTION'} eq $Lang::tr{'save'} && $cgiparams{'TYPE'} eq 'net' && $cgiparams{'SIDE'} eq 'client')
932 {
933
934         my @ovsubnettemp =  split(/\./,$cgiparams{'OVPN_SUBNET'});
935         my $ovsubnet =  "$ovsubnettemp[0].$ovsubnettemp[1].$ovsubnettemp[2]";
936         my @remsubnet =  split(/\//,$cgiparams{'REMOTE_SUBNET'});
937         my $tunmtu =  '';
938                    
939 unless(-d "${General::swroot}/ovpn/n2nconf/"){mkdir "${General::swroot}/ovpn/n2nconf", 0755 or die "Unable to create dir $!";}
940 unless(-d "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}", 0770 or die "Unable to create dir $!";}
941   
942   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: $!";
943   
944   flock CLIENTCONF, 2;
945   print CLIENTCONF "# IPFire rewritten n2n Open VPN Client Config by ummeegge und m.a.d\n";
946   print CLIENTCONF "#\n"; 
947   print CLIENTCONF "# User Security\n";
948   print CLIENTCONF "user nobody\n";
949   print CLIENTCONF "group nobody\n";
950   print CLIENTCONF "persist-tun\n";
951   print CLIENTCONF "persist-key\n";
952   print CLIENTCONF "script-security 2\n";
953   print CLIENTCONF "# IP/DNS for remote Server Gateway\n"; 
954   print CLIENTCONF "remote $cgiparams{'REMOTE'}\n";
955   print CLIENTCONF "float\n";
956   print CLIENTCONF "# IP adresses of the VPN Subnet\n"; 
957   print CLIENTCONF "ifconfig $ovsubnet.2 $ovsubnet.1\n"; 
958   print CLIENTCONF "# Server Gateway Network\n"; 
959   print CLIENTCONF "route $remsubnet[0] $remsubnet[1]\n"; 
960   print CLIENTCONF "# tun Device\n"; 
961   print CLIENTCONF "dev tun\n"; 
962   print CLIENTCONF "# Port and Protokol\n"; 
963   print CLIENTCONF "port $cgiparams{'DEST_PORT'}\n"; 
964
965   if ($cgiparams{'PROTOCOL'} eq 'tcp') {
966   print CLIENTCONF "proto tcp-client\n";
967   print CLIENTCONF "# Packet size\n";
968   if ($cgiparams{'MTU'} eq '') {$tunmtu = '1400'} else {$tunmtu = $cgiparams{'MTU'}};
969   print CLIENTCONF "tun-mtu $tunmtu\n";
970   }
971   
972   if ($cgiparams{'PROTOCOL'} eq 'udp') {
973   print CLIENTCONF "proto udp\n"; 
974   print CLIENTCONF "# Paketsize\n";
975   if ($cgiparams{'MTU'} eq '') {$tunmtu = '1500'} else {$tunmtu = $cgiparams{'MTU'}};
976   print CLIENTCONF "tun-mtu $tunmtu\n";
977   if ($cgiparams{'FRAGMENT'} ne '') {print CLIENTCONF "fragment $cgiparams{'FRAGMENT'}\n";}
978   if ($cgiparams{'MSSFIX'} eq 'on') {print CLIENTCONF "mssfix\n"; }; 
979   }
980
981   # Check if a valid operating mode has been choosen and use it.
982   if (($cgiparams{'PMTU_DISCOVERY'} eq 'yes') ||
983       ($cgiparams{'PMTU_DISCOVERY'} eq 'maybe') ||
984       ($cgiparams{'PMTU_DISCOVERY'} eq 'no' )) {
985         if(($cgiparams{'MSSFIX'} ne 'on') || ($cgiparams{'FRAGMENT'} eq '')) {
986                 if ($cgiparams{'MTU'} eq '1500') {
987                         print CLIENTCONF "mtu-disc $cgiparams{'PMTU_DISCOVERY'}\n";
988                 }
989         }
990   }
991  
992   print CLIENTCONF "ns-cert-type server\n";   
993   print CLIENTCONF "# Auth. Client\n"; 
994   print CLIENTCONF "tls-client\n"; 
995   print CLIENTCONF "# Cipher\n"; 
996   print CLIENTCONF "cipher $cgiparams{'DCIPHER'}\n";
997   print CLIENTCONF "pkcs12 ${General::swroot}/ovpn/certs/$cgiparams{'NAME'}.p12\r\n";
998   if ($cgiparams{'DAUTH'} eq '') {
999         print CLIENTCONF "auth SHA1\n";
1000   } else {
1001         print CLIENTCONF "# HMAC algorithm\n";
1002         print CLIENTCONF "auth $cgiparams{'DAUTH'}\n";
1003   }
1004   if ($cgiparams{'COMPLZO'} eq 'on') {
1005    print CLIENTCONF "# Enable Compression\n";
1006    print CLIENTCONF "comp-lzo\r\n";
1007   }
1008   print CLIENTCONF "# Debug Level\n"; 
1009   print CLIENTCONF "verb 3\n"; 
1010   print CLIENTCONF "# Tunnel check\n"; 
1011   print CLIENTCONF "keepalive 10 60\n"; 
1012   print CLIENTCONF "# Start as daemon\n"; 
1013   print CLIENTCONF "daemon $cgiparams{'NAME'}n2n\n";
1014   print CLIENTCONF "writepid /var/run/$cgiparams{'NAME'}n2n.pid\n"; 
1015   print CLIENTCONF "# Activate Management Interface and Port\n"; 
1016   if ($cgiparams{'OVPN_MGMT'} eq '') {print CLIENTCONF "management localhost $cgiparams{'DEST_PORT'}\n"}
1017   else {print CLIENTCONF "management localhost $cgiparams{'OVPN_MGMT'}\n"};
1018   close(CLIENTCONF);
1019
1020 }
1021   
1022 ###
1023 ### Save main settings
1024 ###
1025
1026
1027 if ($cgiparams{'ACTION'} eq $Lang::tr{'save'} && $cgiparams{'TYPE'} eq '' && $cgiparams{'KEY'} eq '') {
1028     &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings);
1029     #DAN do we really need (to to check) this value? Besides if we listen on blue and orange too,
1030     #DAN this value has to leave.
1031     if ($cgiparams{'ENABLED'} eq 'on'){
1032         unless (&General::validfqdn($cgiparams{'VPN_IP'}) || &General::validip($cgiparams{'VPN_IP'})) {
1033                 $errormessage = $Lang::tr{'invalid input for hostname'};
1034         goto SETTINGS_ERROR;
1035         }
1036     }
1037     if ($errormessage) { goto SETTINGS_ERROR; }
1038     
1039     if (! &General::validipandmask($cgiparams{'DOVPN_SUBNET'})) {
1040             $errormessage = $Lang::tr{'ovpn subnet is invalid'};
1041                         goto SETTINGS_ERROR;
1042     }
1043     my @tmpovpnsubnet = split("\/",$cgiparams{'DOVPN_SUBNET'});
1044     
1045     if (&General::IpInSubnet ( $netsettings{'RED_ADDRESS'}, 
1046         $tmpovpnsubnet[0], $tmpovpnsubnet[1])) {
1047         $errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire RED Network $netsettings{'RED_ADDRESS'}";
1048         goto SETTINGS_ERROR;
1049     }
1050     
1051     if (&General::IpInSubnet ( $netsettings{'GREEN_ADDRESS'}, 
1052         $tmpovpnsubnet[0], $tmpovpnsubnet[1])) {
1053         $errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire Green Network $netsettings{'GREEN_ADDRESS'}";
1054         goto SETTINGS_ERROR;
1055     }
1056
1057     if (&General::IpInSubnet ( $netsettings{'BLUE_ADDRESS'}, 
1058         $tmpovpnsubnet[0], $tmpovpnsubnet[1])) {
1059         $errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire Blue Network $netsettings{'BLUE_ADDRESS'}";
1060         goto SETTINGS_ERROR;
1061     }
1062     
1063     if (&General::IpInSubnet ( $netsettings{'ORANGE_ADDRESS'}, 
1064         $tmpovpnsubnet[0], $tmpovpnsubnet[1])) {
1065         $errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire Orange Network $netsettings{'ORANGE_ADDRESS'}";
1066         goto SETTINGS_ERROR;
1067     }
1068     open(ALIASES, "${General::swroot}/ethernet/aliases") or die 'Unable to open aliases file.';
1069     while (<ALIASES>)
1070     {
1071         chomp($_);
1072         my @tempalias = split(/\,/,$_);
1073         if ($tempalias[1] eq 'on') {
1074             if (&General::IpInSubnet ($tempalias[0] , 
1075                 $tmpovpnsubnet[0], $tmpovpnsubnet[1])) {
1076                 $errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire alias entry $tempalias[0]";
1077             }           
1078         }
1079     }
1080     close(ALIASES);
1081     if ($errormessage ne ''){
1082         goto SETTINGS_ERROR;
1083     }
1084     if ($cgiparams{'ENABLED'} !~ /^(on|off)$/) {
1085         $errormessage = $Lang::tr{'invalid input'};
1086         goto SETTINGS_ERROR;
1087     }
1088     if ((length($cgiparams{'DMTU'})==0) || (($cgiparams{'DMTU'}) < 1000 )) {
1089         $errormessage = $Lang::tr{'invalid mtu input'};
1090         goto SETTINGS_ERROR;
1091     }
1092     
1093     unless (&General::validport($cgiparams{'DDEST_PORT'})) {
1094         $errormessage = $Lang::tr{'invalid port'};
1095         goto SETTINGS_ERROR;
1096     }
1097
1098     $vpnsettings{'ENABLED_BLUE'} = $cgiparams{'ENABLED_BLUE'};
1099     $vpnsettings{'ENABLED_ORANGE'} =$cgiparams{'ENABLED_ORANGE'};
1100     $vpnsettings{'ENABLED'} = $cgiparams{'ENABLED'};
1101     $vpnsettings{'VPN_IP'} = $cgiparams{'VPN_IP'};
1102 #new settings for daemon
1103     $vpnsettings{'DOVPN_SUBNET'} = $cgiparams{'DOVPN_SUBNET'};
1104     $vpnsettings{'DDEVICE'} = $cgiparams{'DDEVICE'};
1105     $vpnsettings{'DPROTOCOL'} = $cgiparams{'DPROTOCOL'};
1106     $vpnsettings{'DDEST_PORT'} = $cgiparams{'DDEST_PORT'};
1107     $vpnsettings{'DMTU'} = $cgiparams{'DMTU'};
1108     $vpnsettings{'DCOMPLZO'} = $cgiparams{'DCOMPLZO'};
1109     $vpnsettings{'DCIPHER'} = $cgiparams{'DCIPHER'};
1110 #wrtie enable
1111
1112   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");}
1113   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");}
1114   if ( $vpnsettings{'ENABLED'} eq 'on' ) {system("touch ${General::swroot}/ovpn/enable 2>/dev/null");}else{system("unlink ${General::swroot}/ovpn/enable 2>/dev/null");}
1115 #new settings for daemon    
1116     &General::writehash("${General::swroot}/ovpn/settings", \%vpnsettings);
1117     &writeserverconf();#hier ok
1118 SETTINGS_ERROR:
1119 ###
1120 ### Reset all step 2
1121 ###
1122 }elsif ($cgiparams{'ACTION'} eq $Lang::tr{'remove x509'} && $cgiparams{'AREUSURE'} eq 'yes') {
1123     my $file = '';
1124     &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
1125
1126     foreach my $key (keys %confighash) {
1127         if ($confighash{$key}[4] eq 'cert') {
1128             delete $confighash{$cgiparams{'$key'}};
1129         }
1130     }
1131     while ($file = glob("${General::swroot}/ovpn/ca/*")) {
1132         unlink $file;
1133     }
1134     while ($file = glob("${General::swroot}/ovpn/certs/*")) {
1135         unlink $file;
1136     }
1137     while ($file = glob("${General::swroot}/ovpn/crls/*")) {
1138         unlink $file;
1139     }
1140         &cleanssldatabase();
1141     if (open(FILE, ">${General::swroot}/ovpn/caconfig")) {
1142         print FILE "";
1143         close FILE;
1144     }
1145     if (open(FILE, ">${General::swroot}/ovpn/ccdroute")) {
1146         print FILE "";
1147         close FILE;
1148     }
1149     if (open(FILE, ">${General::swroot}/ovpn/ccdroute2")) {
1150         print FILE "";
1151         close FILE;
1152     }
1153     while ($file = glob("${General::swroot}/ovpn/ccd/*")) {
1154         unlink $file
1155     }
1156     if (open(FILE, ">${General::swroot}/ovpn/ovpn-leases.db")) {
1157         print FILE "";
1158         close FILE;
1159     }
1160     if (open(FILE, ">${General::swroot}/ovpn/ovpnconfig")) {
1161         print FILE "";
1162         close FILE;
1163     }
1164     while ($file = glob("${General::swroot}/ovpn/n2nconf/*")) {
1165         system ("rm -rf $file");
1166     }
1167
1168     #&writeserverconf();
1169 ###
1170 ### Reset all step 1
1171 ###
1172 }elsif ($cgiparams{'ACTION'} eq $Lang::tr{'remove x509'}) {
1173     &Header::showhttpheaders();
1174     &Header::openpage($Lang::tr{'ovpn'}, 1, '');
1175     &Header::openbigbox('100%', 'left', '', '');
1176     &Header::openbox('100%', 'left', $Lang::tr{'are you sure'});
1177     print <<END;
1178         <form method='post'>
1179                 <table width='100%'>
1180                         <tr>
1181                                 <td align='center'>
1182                                 <input type='hidden' name='AREUSURE' value='yes' />
1183                                 <b><font color='${Header::colourred}'>$Lang::tr{'capswarning'}</font></b>:
1184                                 $Lang::tr{'resetting the vpn configuration will remove the root ca, the host certificate and all certificate based connections'}</td>
1185                         </tr>
1186                         <tr>
1187                                 <td align='center'><input type='submit' name='ACTION' value='$Lang::tr{'remove x509'}' />
1188                                 <input type='submit' name='ACTION' value='$Lang::tr{'cancel'}' /></td>
1189                         </tr>
1190                 </table>
1191         </form>
1192 END
1193     ;
1194     &Header::closebox();
1195     &Header::closebigbox();
1196     &Header::closepage();
1197     exit (0);
1198
1199 ###
1200 ### Generate DH key step 2
1201 ###
1202 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'generate dh key'} && $cgiparams{'AREUSURE'} eq 'yes') {
1203     # Delete if old key exists
1204     if (-f "${General::swroot}/ovpn/ca/$cgiparams{'DH_NAME'}") {
1205         unlink "${General::swroot}/ovpn/ca/$cgiparams{'DH_NAME'}";
1206         }
1207         # Create Diffie Hellmann Parameter
1208         system('/usr/bin/openssl', 'dhparam', '-rand', '/proc/interrupts:/proc/net/rt_cache',
1209         '-out', "${General::swroot}/ovpn/ca/dh1024.pem", "$cgiparams{'DHLENGHT'}");
1210         if ($?) {
1211                 $errormessage = "$Lang::tr{'openssl produced an error'}: $?";
1212                 unlink ("${General::swroot}/ovpn/ca/dh1024.pem");
1213         }
1214
1215 ###
1216 ### Generate DH key step 1
1217 ###
1218 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'generate dh key'}) {
1219         &Header::showhttpheaders();
1220         &Header::openpage($Lang::tr{'ovpn'}, 1, '');
1221         &Header::openbigbox('100%', 'LEFT', '', '');
1222         &Header::openbox('100%', 'LEFT', "$Lang::tr{'gen dh'}:");
1223         print <<END;
1224         <table width='100%'>
1225         <tr>
1226                 <td width='20%'> </td> <td width='15%'></td> <td width='65%'></td>
1227         </tr>
1228         <tr>
1229                 <td class='base'>$Lang::tr{'ovpn dh'}:</td>
1230                 <td align='center'>
1231                 <form method='post'><input type='hidden' name='AREUSURE' value='yes' />
1232                 <input type='hidden' name='KEY' value='$cgiparams{'KEY'}' />
1233                         <select name='DHLENGHT'>
1234                                 <option value='1024' $selected{'DHLENGHT'}{'1024'}>1024 $Lang::tr{'bit'}</option>
1235                                 <option value='2048' $selected{'DHLENGHT'}{'2048'}>2048 $Lang::tr{'bit'}</option>
1236                                 <option value='3072' $selected{'DHLENGHT'}{'3072'}>3072 $Lang::tr{'bit'}</option>
1237                                 <option value='4096' $selected{'DHLENGHT'}{'4096'}>4096 $Lang::tr{'bit'}</option>
1238                         </select>
1239                 </td>
1240         </tr>
1241         <tr><td colspan='4'><br></td></tr>
1242         </table>
1243         <table width='100%'>
1244         <tr>
1245                 <b><font color='${Header::colourred}'>$Lang::tr{'capswarning'}: </font></b>$Lang::tr{'dh key warn'}
1246         </tr>
1247         <tr>
1248                 <td class='base'>$Lang::tr{'dh key warn1'}</td>
1249         </tr>
1250         <tr><td colspan='2'><br></td></tr>
1251         <tr>
1252                 <td align='center'><input type='submit' name='ACTION' value='$Lang::tr{'generate dh key'}' /></td>
1253                 </form>
1254         </tr>
1255         </table>
1256
1257 END
1258         ;
1259         &Header::closebox();
1260         print "<div align='center'><a href='/cgi-bin/ovpnmain.cgi'>$Lang::tr{'back'}</a></div>";
1261         &Header::closebigbox();
1262         &Header::closepage();
1263         exit (0);
1264
1265 ###
1266 ### Upload DH key
1267 ###
1268 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'upload dh key'}) {
1269     if (ref ($cgiparams{'FH'}) ne 'Fh') {
1270          $errormessage = $Lang::tr{'there was no file upload'};
1271          goto UPLOADCA_ERROR;
1272     }
1273     # Move uploaded dh key to a temporary file
1274     (my $fh, my $filename) = tempfile( );
1275     if (copy ($cgiparams{'FH'}, $fh) != 1) {
1276         $errormessage = $!;
1277         goto UPLOADCA_ERROR;
1278     }
1279     my $temp = `/usr/bin/openssl dhparam -text -in $filename`;
1280     if ($temp !~ /DH Parameters: \((1024|2048|3072|4096) bit\)/) {
1281         $errormessage = $Lang::tr{'not a valid dh key'};
1282         unlink ($filename);
1283         goto UPLOADCA_ERROR;
1284     } else {
1285     # Delete if old key exists
1286     if (-f "${General::swroot}/ovpn/ca/$cgiparams{'DH_NAME'}") {
1287         unlink "${General::swroot}/ovpn/ca/$cgiparams{'DH_NAME'}";
1288         }
1289     move($filename, "${General::swroot}/ovpn/ca/$cgiparams{'DH_NAME'}");
1290         if ($? ne 0) {
1291                 $errormessage = "$Lang::tr{'dh key move failed'}: $!";
1292                 unlink ($filename);
1293                 goto UPLOADCA_ERROR;
1294         }
1295     }
1296
1297 ###
1298 ### Upload CA Certificate
1299 ###
1300 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'upload ca certificate'}) {
1301     &General::readhasharray("${General::swroot}/ovpn/caconfig", \%cahash);
1302
1303     if ($cgiparams{'CA_NAME'} !~ /^[a-zA-Z0-9]+$/) {
1304         $errormessage = $Lang::tr{'name must only contain characters'};
1305         goto UPLOADCA_ERROR;
1306     }
1307
1308     if (length($cgiparams{'CA_NAME'}) >60) {
1309         $errormessage = $Lang::tr{'name too long'};
1310         goto VPNCONF_ERROR;
1311     }
1312
1313     if ($cgiparams{'CA_NAME'} eq 'ca') {
1314         $errormessage = $Lang::tr{'name is invalid'};
1315         goto UPLOADCA_ERROR;
1316     }
1317
1318     # Check if there is no other entry with this name
1319     foreach my $key (keys %cahash) {
1320         if ($cahash{$key}[0] eq $cgiparams{'CA_NAME'}) {
1321             $errormessage = $Lang::tr{'a ca certificate with this name already exists'};
1322             goto UPLOADCA_ERROR;
1323         }
1324     }
1325
1326     if (ref ($cgiparams{'FH'}) ne 'Fh') {
1327         $errormessage = $Lang::tr{'there was no file upload'};
1328         goto UPLOADCA_ERROR;
1329     }
1330     # Move uploaded ca to a temporary file
1331     (my $fh, my $filename) = tempfile( );
1332     if (copy ($cgiparams{'FH'}, $fh) != 1) {
1333         $errormessage = $!;
1334         goto UPLOADCA_ERROR;
1335     }
1336     my $temp = `/usr/bin/openssl x509 -text -in $filename`;
1337     if ($temp !~ /CA:TRUE/i) {
1338         $errormessage = $Lang::tr{'not a valid ca certificate'};
1339         unlink ($filename);
1340         goto UPLOADCA_ERROR;
1341     } else {
1342         move($filename, "${General::swroot}/ovpn/ca/$cgiparams{'CA_NAME'}cert.pem");
1343         if ($? ne 0) {
1344             $errormessage = "$Lang::tr{'certificate file move failed'}: $!";
1345             unlink ($filename);
1346             goto UPLOADCA_ERROR;
1347         }
1348     }
1349
1350     my $casubject = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/ca/$cgiparams{'CA_NAME'}cert.pem`;
1351     $casubject    =~ /Subject: (.*)[\n]/;
1352     $casubject    = $1;
1353     $casubject    =~ s+/Email+, E+;
1354     $casubject    =~ s/ ST=/ S=/;
1355     $casubject    = &Header::cleanhtml($casubject);
1356
1357     my $key = &General::findhasharraykey (\%cahash);
1358     $cahash{$key}[0] = $cgiparams{'CA_NAME'};
1359     $cahash{$key}[1] = $casubject;
1360     &General::writehasharray("${General::swroot}/ovpn/caconfig", \%cahash);
1361 #    system('/usr/local/bin/ipsecctrl', 'R');
1362
1363     UPLOADCA_ERROR:
1364
1365 ###
1366 ### Display ca certificate
1367 ###
1368 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'show ca certificate'}) {
1369     &General::readhasharray("${General::swroot}/ovpn/caconfig", \%cahash);
1370
1371     if ( -f "${General::swroot}/ovpn/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem") {
1372         &Header::showhttpheaders();
1373         &Header::openpage($Lang::tr{'ovpn'}, 1, '');
1374         &Header::openbigbox('100%', 'LEFT', '', $errormessage);
1375         &Header::openbox('100%', 'LEFT', "$Lang::tr{'ca certificate'}:");
1376         my $output = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem`;
1377         $output = &Header::cleanhtml($output,"y");
1378         print "<pre>$output</pre>\n";
1379         &Header::closebox();
1380         print "<div align='center'><a href='/cgi-bin/ovpnmain.cgi'>$Lang::tr{'back'}</a></div>";
1381         &Header::closebigbox();
1382         &Header::closepage();
1383         exit(0);
1384     } else {
1385         $errormessage = $Lang::tr{'invalid key'};
1386     }
1387
1388 ###
1389 ### Download ca certificate
1390 ###
1391 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'download ca certificate'}) {
1392     &General::readhasharray("${General::swroot}/ovpn/caconfig", \%cahash);
1393
1394     if ( -f "${General::swroot}/ovpn/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem" ) {
1395         print "Content-Type: application/octet-stream\r\n";
1396         print "Content-Disposition: filename=$cahash{$cgiparams{'KEY'}}[0]cert.pem\r\n\r\n";
1397         print `/usr/bin/openssl x509 -in ${General::swroot}/ovpn/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem`;
1398         exit(0);
1399     } else {
1400         $errormessage = $Lang::tr{'invalid key'};
1401     }
1402
1403 ###
1404 ### Remove ca certificate (step 2)
1405 ###
1406 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'remove ca certificate'} && $cgiparams{'AREUSURE'} eq 'yes') {
1407     &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
1408     &General::readhasharray("${General::swroot}/ovpn/caconfig", \%cahash);
1409
1410     if ( -f "${General::swroot}/ovpn/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem" ) {
1411         foreach my $key (keys %confighash) {
1412             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`;
1413             if ($test =~ /: OK/) {
1414                 # Delete connection
1415 #               if ($vpnsettings{'ENABLED'} eq 'on' ||
1416 #                   $vpnsettings{'ENABLED_BLUE'} eq 'on') {
1417 #                   system('/usr/local/bin/ipsecctrl', 'D', $key);
1418 #               }
1419                 unlink ("${General::swroot}/ovpn//certs/$confighash{$key}[1]cert.pem");
1420                 unlink ("${General::swroot}/ovpn/certs/$confighash{$key}[1].p12");
1421                 delete $confighash{$key};
1422                 &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
1423 #               &writeipsecfiles();
1424             }
1425         }
1426         unlink ("${General::swroot}/ovpn/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem");
1427         delete $cahash{$cgiparams{'KEY'}};
1428         &General::writehasharray("${General::swroot}/ovpn/caconfig", \%cahash);
1429 #       system('/usr/local/bin/ipsecctrl', 'R');
1430     } else {
1431         $errormessage = $Lang::tr{'invalid key'};
1432     }
1433 ###
1434 ### Remove ca certificate (step 1)
1435 ###
1436 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'remove ca certificate'}) {
1437     &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
1438     &General::readhasharray("${General::swroot}/ovpn/caconfig", \%cahash);
1439
1440     my $assignedcerts = 0;
1441     if ( -f "${General::swroot}/ovpn/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem" ) {
1442         foreach my $key (keys %confighash) {
1443             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`;
1444             if ($test =~ /: OK/) {
1445                 $assignedcerts++;
1446             }
1447         }
1448         if ($assignedcerts) {
1449             &Header::showhttpheaders();
1450             &Header::openpage($Lang::tr{'ovpn'}, 1, '');
1451             &Header::openbigbox('100%', 'LEFT', '', $errormessage);
1452             &Header::openbox('100%', 'LEFT', $Lang::tr{'are you sure'});
1453             print <<END;
1454                 <table><form method='post'><input type='hidden' name='AREUSURE' value='yes' />
1455                        <input type='hidden' name='KEY' value='$cgiparams{'KEY'}' />
1456                     <tr><td align='center'>
1457                         <b><font color='${Header::colourred}'>$Lang::tr{'capswarning'}</font></b>: $assignedcerts
1458                         $Lang::tr{'connections are associated with this ca.  deleting the ca will delete these connections as well.'}
1459                     <tr><td align='center'><input type='submit' name='ACTION' value='$Lang::tr{'remove ca certificate'}' />
1460                         <input type='submit' name='ACTION' value='$Lang::tr{'cancel'}' /></td></tr>
1461                 </form></table>
1462 END
1463             ;
1464             &Header::closebox();
1465             &Header::closebigbox();
1466             &Header::closepage();
1467             exit (0);
1468         } else {
1469             unlink ("${General::swroot}/ovpn/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem");
1470             delete $cahash{$cgiparams{'KEY'}};
1471             &General::writehasharray("${General::swroot}/ovpn/caconfig", \%cahash);
1472 #           system('/usr/local/bin/ipsecctrl', 'R');
1473         }
1474     } else {
1475         $errormessage = $Lang::tr{'invalid key'};
1476     }
1477
1478 ###
1479 ### Display root certificate
1480 ###
1481 }elsif ($cgiparams{'ACTION'} eq $Lang::tr{'show root certificate'} ||
1482     $cgiparams{'ACTION'} eq $Lang::tr{'show host certificate'}) {
1483     my $output;
1484     &Header::showhttpheaders();
1485     &Header::openpage($Lang::tr{'ovpn'}, 1, '');
1486     &Header::openbigbox('100%', 'LEFT', '', '');
1487     if ($cgiparams{'ACTION'} eq $Lang::tr{'show root certificate'}) {
1488         &Header::openbox('100%', 'LEFT', "$Lang::tr{'root certificate'}:");
1489         $output = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/ca/cacert.pem`;
1490     } else {
1491         &Header::openbox('100%', 'LEFT', "$Lang::tr{'host certificate'}:");
1492         $output = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/certs/servercert.pem`;
1493     }
1494     $output = &Header::cleanhtml($output,"y");
1495     print "<pre>$output</pre>\n";
1496     &Header::closebox();
1497     print "<div align='center'><a href='/cgi-bin/ovpnmain.cgi'>$Lang::tr{'back'}</a></div>";
1498     &Header::closebigbox();
1499     &Header::closepage();
1500     exit(0);
1501
1502 ###
1503 ### Download root certificate
1504 ###
1505 }elsif ($cgiparams{'ACTION'} eq $Lang::tr{'download root certificate'}) {
1506     if ( -f "${General::swroot}/ovpn/ca/cacert.pem" ) {
1507         print "Content-Type: application/octet-stream\r\n";
1508         print "Content-Disposition: filename=cacert.pem\r\n\r\n";
1509         print `/usr/bin/openssl x509 -in ${General::swroot}/ovpn/ca/cacert.pem`;
1510         exit(0);
1511     }
1512     
1513 ###
1514 ### Download host certificate
1515 ###
1516 }elsif ($cgiparams{'ACTION'} eq $Lang::tr{'download host certificate'}) {
1517     if ( -f "${General::swroot}/ovpn/certs/servercert.pem" ) {
1518         print "Content-Type: application/octet-stream\r\n";
1519         print "Content-Disposition: filename=servercert.pem\r\n\r\n";
1520         print `/usr/bin/openssl x509 -in ${General::swroot}/ovpn/certs/servercert.pem`;
1521         exit(0);
1522     }
1523 ###
1524 ### Form for generating a root certificate
1525 ###
1526 }elsif ($cgiparams{'ACTION'} eq $Lang::tr{'generate root/host certificates'} ||
1527          $cgiparams{'ACTION'} eq $Lang::tr{'upload p12 file'}) {
1528
1529     &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings);
1530     if (-f "${General::swroot}/ovpn/ca/cacert.pem") {
1531         $errormessage = $Lang::tr{'valid root certificate already exists'};
1532         $cgiparams{'ACTION'} = '';
1533         goto ROOTCERT_ERROR;
1534     }
1535
1536     if (($cgiparams{'ROOTCERT_HOSTNAME'} eq '') && -e "${General::swroot}/red/active") {
1537         if (open(IPADDR, "${General::swroot}/red/local-ipaddress")) {
1538             my $ipaddr = <IPADDR>;
1539             close IPADDR;
1540             chomp ($ipaddr);
1541             $cgiparams{'ROOTCERT_HOSTNAME'} = (gethostbyaddr(pack("C4", split(/\./, $ipaddr)), 2))[0];
1542             if ($cgiparams{'ROOTCERT_HOSTNAME'} eq '') {
1543                 $cgiparams{'ROOTCERT_HOSTNAME'} = $ipaddr;
1544             }
1545         }
1546     } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'upload p12 file'}) {
1547
1548         if (ref ($cgiparams{'FH'}) ne 'Fh') {
1549             $errormessage = $Lang::tr{'there was no file upload'};
1550             goto ROOTCERT_ERROR;
1551         }
1552
1553         # Move uploaded certificate request to a temporary file
1554         (my $fh, my $filename) = tempfile( );
1555         if (copy ($cgiparams{'FH'}, $fh) != 1) {
1556             $errormessage = $!;
1557             goto ROOTCERT_ERROR;
1558         }
1559
1560         # Create a temporary dirctory
1561         my $tempdir = tempdir( CLEANUP => 1 );
1562
1563         # Extract the CA certificate from the file
1564         my $pid = open(OPENSSL, "|-");
1565         $SIG{ALRM} = sub { $errormessage = $Lang::tr{'broken pipe'}; goto ROOTCERT_ERROR;};
1566         if ($pid) {     # parent
1567             if ($cgiparams{'P12_PASS'} ne '') {
1568                 print OPENSSL "$cgiparams{'P12_PASS'}\n";
1569             }
1570             close (OPENSSL);
1571             if ($?) {
1572                 $errormessage = "$Lang::tr{'openssl produced an error'}: $?";
1573                 unlink ($filename);
1574                 goto ROOTCERT_ERROR;
1575             }
1576         } else {        # child
1577             unless (exec ('/usr/bin/openssl', 'pkcs12', '-cacerts', '-nokeys',
1578                     '-in', $filename,
1579                     '-out', "$tempdir/cacert.pem")) {
1580                 $errormessage = "$Lang::tr{'cant start openssl'}: $!";
1581                 unlink ($filename);
1582                 goto ROOTCERT_ERROR;
1583             }
1584         }
1585
1586         # Extract the Host certificate from the file
1587         $pid = open(OPENSSL, "|-");
1588         $SIG{ALRM} = sub { $errormessage = $Lang::tr{'broken pipe'}; goto ROOTCERT_ERROR;};
1589         if ($pid) {     # parent
1590             if ($cgiparams{'P12_PASS'} ne '') {
1591                 print OPENSSL "$cgiparams{'P12_PASS'}\n";
1592             }
1593             close (OPENSSL);
1594             if ($?) {
1595                 $errormessage = "$Lang::tr{'openssl produced an error'}: $?";
1596                 unlink ($filename);
1597                 goto ROOTCERT_ERROR;
1598             }
1599         } else {        # child
1600             unless (exec ('/usr/bin/openssl', 'pkcs12', '-clcerts', '-nokeys',
1601                     '-in', $filename,
1602                     '-out', "$tempdir/hostcert.pem")) {
1603                 $errormessage = "$Lang::tr{'cant start openssl'}: $!";
1604                 unlink ($filename);
1605                 goto ROOTCERT_ERROR;
1606             }
1607         }
1608
1609         # Extract the Host key from the file
1610         $pid = open(OPENSSL, "|-");
1611         $SIG{ALRM} = sub { $errormessage = $Lang::tr{'broken pipe'}; goto ROOTCERT_ERROR;};
1612         if ($pid) {     # parent
1613             if ($cgiparams{'P12_PASS'} ne '') {
1614                 print OPENSSL "$cgiparams{'P12_PASS'}\n";
1615             }
1616             close (OPENSSL);
1617             if ($?) {
1618                 $errormessage = "$Lang::tr{'openssl produced an error'}: $?";
1619                 unlink ($filename);
1620                 goto ROOTCERT_ERROR;
1621             }
1622         } else {        # child
1623             unless (exec ('/usr/bin/openssl', 'pkcs12', '-nocerts',
1624                     '-nodes',
1625                     '-in', $filename,
1626                     '-out', "$tempdir/serverkey.pem")) {
1627                 $errormessage = "$Lang::tr{'cant start openssl'}: $!";
1628                 unlink ($filename);
1629                 goto ROOTCERT_ERROR;
1630             }
1631         }
1632
1633         move("$tempdir/cacert.pem", "${General::swroot}/ovpn/ca/cacert.pem");
1634         if ($? ne 0) {
1635             $errormessage = "$Lang::tr{'certificate file move failed'}: $!";
1636             unlink ($filename);
1637             unlink ("${General::swroot}/ovpn/ca/cacert.pem");
1638             unlink ("${General::swroot}/ovpn/certs/servercert.pem");
1639             unlink ("${General::swroot}/ovpn/certs/serverkey.pem");
1640             goto ROOTCERT_ERROR;
1641         }
1642
1643         move("$tempdir/hostcert.pem", "${General::swroot}/ovpn/certs/servercert.pem");
1644         if ($? ne 0) {
1645             $errormessage = "$Lang::tr{'certificate file move failed'}: $!";
1646             unlink ($filename);
1647             unlink ("${General::swroot}/ovpn/ca/cacert.pem");
1648             unlink ("${General::swroot}/ovpn/certs/servercert.pem");
1649             unlink ("${General::swroot}/ovpn/certs/serverkey.pem");
1650             goto ROOTCERT_ERROR;
1651         }
1652
1653         move("$tempdir/serverkey.pem", "${General::swroot}/ovpn/certs/serverkey.pem");
1654         if ($? ne 0) {
1655             $errormessage = "$Lang::tr{'certificate file move failed'}: $!";
1656             unlink ($filename);
1657             unlink ("${General::swroot}/ovpn/ca/cacert.pem");
1658             unlink ("${General::swroot}/ovpn/certs/servercert.pem");
1659             unlink ("${General::swroot}/ovpn/certs/serverkey.pem");
1660             goto ROOTCERT_ERROR;
1661         }
1662
1663         goto ROOTCERT_SUCCESS;
1664
1665     } elsif ($cgiparams{'ROOTCERT_COUNTRY'} ne '') {
1666
1667         # Validate input since the form was submitted
1668         if ($cgiparams{'ROOTCERT_ORGANIZATION'} eq ''){
1669             $errormessage = $Lang::tr{'organization cant be empty'};
1670             goto ROOTCERT_ERROR;
1671         }
1672         if (length($cgiparams{'ROOTCERT_ORGANIZATION'}) >60) {
1673             $errormessage = $Lang::tr{'organization too long'};
1674             goto ROOTCERT_ERROR;
1675         }
1676         if ($cgiparams{'ROOTCERT_ORGANIZATION'} !~ /^[a-zA-Z0-9 ,\.\-_]*$/) {
1677             $errormessage = $Lang::tr{'invalid input for organization'};
1678             goto ROOTCERT_ERROR;
1679         }
1680         if ($cgiparams{'ROOTCERT_HOSTNAME'} eq ''){
1681             $errormessage = $Lang::tr{'hostname cant be empty'};
1682             goto ROOTCERT_ERROR;
1683         }
1684         unless (&General::validfqdn($cgiparams{'ROOTCERT_HOSTNAME'}) || &General::validip($cgiparams{'ROOTCERT_HOSTNAME'})) {
1685             $errormessage = $Lang::tr{'invalid input for hostname'};
1686             goto ROOTCERT_ERROR;
1687         }
1688         if ($cgiparams{'ROOTCERT_EMAIL'} ne '' && (! &General::validemail($cgiparams{'ROOTCERT_EMAIL'}))) {
1689             $errormessage = $Lang::tr{'invalid input for e-mail address'};
1690             goto ROOTCERT_ERROR;
1691         }
1692         if (length($cgiparams{'ROOTCERT_EMAIL'}) > 40) {
1693             $errormessage = $Lang::tr{'e-mail address too long'};
1694             goto ROOTCERT_ERROR;
1695         }
1696         if ($cgiparams{'ROOTCERT_OU'} ne '' && $cgiparams{'ROOTCERT_OU'} !~ /^[a-zA-Z0-9 ,\.\-_]*$/) {
1697             $errormessage = $Lang::tr{'invalid input for department'};
1698             goto ROOTCERT_ERROR;
1699         }
1700         if ($cgiparams{'ROOTCERT_CITY'} ne '' && $cgiparams{'ROOTCERT_CITY'} !~ /^[a-zA-Z0-9 ,\.\-_]*$/) {
1701             $errormessage = $Lang::tr{'invalid input for city'};
1702             goto ROOTCERT_ERROR;
1703         }
1704         if ($cgiparams{'ROOTCERT_STATE'} ne '' && $cgiparams{'ROOTCERT_STATE'} !~ /^[a-zA-Z0-9 ,\.\-_]*$/) {
1705             $errormessage = $Lang::tr{'invalid input for state or province'};
1706             goto ROOTCERT_ERROR;
1707         }
1708         if ($cgiparams{'ROOTCERT_COUNTRY'} !~ /^[A-Z]*$/) {
1709             $errormessage = $Lang::tr{'invalid input for country'};
1710             goto ROOTCERT_ERROR;
1711         }
1712
1713         # Copy the cgisettings to vpnsettings and save the configfile
1714         $vpnsettings{'ROOTCERT_ORGANIZATION'}   = $cgiparams{'ROOTCERT_ORGANIZATION'};
1715         $vpnsettings{'ROOTCERT_HOSTNAME'}       = $cgiparams{'ROOTCERT_HOSTNAME'};
1716         $vpnsettings{'ROOTCERT_EMAIL'}          = $cgiparams{'ROOTCERT_EMAIL'};
1717         $vpnsettings{'ROOTCERT_OU'}             = $cgiparams{'ROOTCERT_OU'};
1718         $vpnsettings{'ROOTCERT_CITY'}           = $cgiparams{'ROOTCERT_CITY'};
1719         $vpnsettings{'ROOTCERT_STATE'}          = $cgiparams{'ROOTCERT_STATE'};
1720         $vpnsettings{'ROOTCERT_COUNTRY'}        = $cgiparams{'ROOTCERT_COUNTRY'};
1721         &General::writehash("${General::swroot}/ovpn/settings", \%vpnsettings);
1722
1723         # Replace empty strings with a .
1724         (my $ou = $cgiparams{'ROOTCERT_OU'}) =~ s/^\s*$/\./;
1725         (my $city = $cgiparams{'ROOTCERT_CITY'}) =~ s/^\s*$/\./;
1726         (my $state = $cgiparams{'ROOTCERT_STATE'}) =~ s/^\s*$/\./;
1727
1728         # refresh
1729         #system ('/bin/touch', "${General::swroot}/ovpn/gencanow");
1730         
1731         # Create the CA certificate
1732         my $pid = open(OPENSSL, "|-");
1733         $SIG{ALRM} = sub { $errormessage = $Lang::tr{'broken pipe'}; goto ROOTCERT_ERROR;};
1734         if ($pid) {     # parent
1735             print OPENSSL "$cgiparams{'ROOTCERT_COUNTRY'}\n";
1736             print OPENSSL "$state\n";
1737             print OPENSSL "$city\n";
1738             print OPENSSL "$cgiparams{'ROOTCERT_ORGANIZATION'}\n";
1739             print OPENSSL "$ou\n";
1740             print OPENSSL "$cgiparams{'ROOTCERT_ORGANIZATION'} CA\n";
1741             print OPENSSL "$cgiparams{'ROOTCERT_EMAIL'}\n";
1742             close (OPENSSL);
1743             if ($?) {
1744                 $errormessage = "$Lang::tr{'openssl produced an error'}: $?";
1745                 unlink ("${General::swroot}/ovpn/ca/cakey.pem");
1746                 unlink ("${General::swroot}/ovpn/ca/cacert.pem");
1747                 goto ROOTCERT_ERROR;
1748             }
1749         } else {        # child
1750             unless (exec ('/usr/bin/openssl', 'req', '-x509', '-nodes', '-rand', '/proc/interrupts:/proc/net/rt_cache',
1751                         '-days', '999999', '-newkey', 'rsa:4096', '-sha512',
1752                         '-keyout', "${General::swroot}/ovpn/ca/cakey.pem",
1753                         '-out', "${General::swroot}/ovpn/ca/cacert.pem",
1754                         '-config',"${General::swroot}/ovpn/openssl/ovpn.cnf")) {
1755                 $errormessage = "$Lang::tr{'cant start openssl'}: $!";
1756                 goto ROOTCERT_ERROR;
1757             }
1758         }
1759
1760         # Create the Host certificate request
1761         $pid = open(OPENSSL, "|-");
1762         $SIG{ALRM} = sub { $errormessage = $Lang::tr{'broken pipe'}; goto ROOTCERT_ERROR;};
1763         if ($pid) {     # parent
1764             print OPENSSL "$cgiparams{'ROOTCERT_COUNTRY'}\n";
1765             print OPENSSL "$state\n";
1766             print OPENSSL "$city\n";
1767             print OPENSSL "$cgiparams{'ROOTCERT_ORGANIZATION'}\n";
1768             print OPENSSL "$ou\n";
1769             print OPENSSL "$cgiparams{'ROOTCERT_HOSTNAME'}\n";
1770             print OPENSSL "$cgiparams{'ROOTCERT_EMAIL'}\n";
1771             print OPENSSL ".\n";
1772             print OPENSSL ".\n";
1773             close (OPENSSL);
1774             if ($?) {
1775                 $errormessage = "$Lang::tr{'openssl produced an error'}: $?";
1776                 unlink ("${General::swroot}/ovpn/certs/serverkey.pem");
1777                 unlink ("${General::swroot}/ovpn/certs/serverreq.pem");
1778                 goto ROOTCERT_ERROR;
1779             }
1780         } else {        # child
1781             unless (exec ('/usr/bin/openssl', 'req', '-nodes', '-rand', '/proc/interrupts:/proc/net/rt_cache',
1782                         '-newkey', 'rsa:2048',
1783                         '-keyout', "${General::swroot}/ovpn/certs/serverkey.pem",
1784                         '-out', "${General::swroot}/ovpn/certs/serverreq.pem",
1785                         '-extensions', 'server',
1786                         '-config', "${General::swroot}/ovpn/openssl/ovpn.cnf" )) {
1787                 $errormessage = "$Lang::tr{'cant start openssl'}: $!";
1788                 unlink ("${General::swroot}/ovpn/certs/serverkey.pem");
1789                 unlink ("${General::swroot}/ovpn/certs/serverreq.pem");
1790                 unlink ("${General::swroot}/ovpn/ca/cakey.pem");
1791                 unlink ("${General::swroot}/ovpn/ca/cacert.pem");
1792                 goto ROOTCERT_ERROR;
1793             }
1794         }
1795         
1796         # Sign the host certificate request
1797         system('/usr/bin/openssl', 'ca', '-days', '999999',
1798                 '-batch', '-notext',
1799                 '-in',  "${General::swroot}/ovpn/certs/serverreq.pem",
1800                 '-out', "${General::swroot}/ovpn/certs/servercert.pem",
1801                 '-extensions', 'server',
1802                 '-config', "${General::swroot}/ovpn/openssl/ovpn.cnf");
1803         if ($?) {
1804             $errormessage = "$Lang::tr{'openssl produced an error'}: $?";
1805             unlink ("${General::swroot}/ovpn/ca/cakey.pem");
1806             unlink ("${General::swroot}/ovpn/ca/cacert.pem");
1807             unlink ("${General::swroot}/ovpn/serverkey.pem");
1808             unlink ("${General::swroot}/ovpn/certs/serverreq.pem");
1809             unlink ("${General::swroot}/ovpn/certs/servercert.pem");
1810             &newcleanssldatabase();
1811             goto ROOTCERT_ERROR;
1812         } else {
1813             unlink ("${General::swroot}/ovpn/certs/serverreq.pem");
1814             &deletebackupcert();
1815         }
1816
1817         # Create an empty CRL
1818         system('/usr/bin/openssl', 'ca', '-gencrl',
1819                 '-out', "${General::swroot}/ovpn/crls/cacrl.pem",
1820                 '-config', "${General::swroot}/ovpn/openssl/ovpn.cnf" );
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             &cleanssldatabase();
1828             goto ROOTCERT_ERROR;
1829 #       } else {
1830 #           &cleanssldatabase();
1831         }
1832         # Create Diffie Hellmann Parameter
1833         system('/usr/bin/openssl', 'dhparam', '-rand', '/proc/interrupts:/proc/net/rt_cache',
1834                '-out', "${General::swroot}/ovpn/ca/dh1024.pem", "$cgiparams{'DHLENGHT'}");
1835         if ($?) {
1836             $errormessage = "$Lang::tr{'openssl produced an error'}: $?";
1837             unlink ("${General::swroot}/ovpn/certs/serverkey.pem");
1838             unlink ("${General::swroot}/ovpn/certs/servercert.pem");
1839             unlink ("${General::swroot}/ovpn/ca/cacert.pem");
1840             unlink ("${General::swroot}/ovpn/crls/cacrl.pem");
1841             unlink ("${General::swroot}/ovpn/ca/dh1024.pem");
1842             &cleanssldatabase();
1843             goto ROOTCERT_ERROR;
1844 #       } else {
1845 #           &cleanssldatabase();
1846         }
1847         # Create ta.key for tls-auth
1848         system('/usr/sbin/openvpn', '--genkey', '--secret', "${General::swroot}/ovpn/certs/ta.key");
1849         if ($?) {
1850             $errormessage = "$Lang::tr{'openssl produced an error'}: $?";
1851             &cleanssldatabase();
1852             goto ROOTCERT_ERROR;
1853         }
1854         goto ROOTCERT_SUCCESS;
1855     }
1856     ROOTCERT_ERROR:
1857     if ($cgiparams{'ACTION'} ne '') {
1858         &Header::showhttpheaders();
1859         &Header::openpage($Lang::tr{'ovpn'}, 1, '');
1860         &Header::openbigbox('100%', 'LEFT', '', '');
1861         if ($errormessage) {
1862             &Header::openbox('100%', 'LEFT', $Lang::tr{'error messages'});
1863             print "<class name='base'>$errormessage";
1864             print "&nbsp;</class>";
1865             &Header::closebox();
1866         }
1867         &Header::openbox('100%', 'LEFT', "$Lang::tr{'generate root/host certificates'}:");
1868         print <<END;
1869         <form method='post' enctype='multipart/form-data'>
1870         <table width='100%' border='0' cellspacing='1' cellpadding='0'>
1871         <tr><td width='30%' class='base'>$Lang::tr{'organization name'}:</td>
1872             <td width='35%' class='base' nowrap='nowrap'><input type='text' name='ROOTCERT_ORGANIZATION' value='$cgiparams{'ROOTCERT_ORGANIZATION'}' size='32' /></td>
1873             <td width='35%' colspan='2'>&nbsp;</td></tr>
1874         <tr><td class='base'>$Lang::tr{'ipfires hostname'}:</td>
1875             <td class='base' nowrap='nowrap'><input type='text' name='ROOTCERT_HOSTNAME' value='$cgiparams{'ROOTCERT_HOSTNAME'}' size='32' /></td>
1876             <td colspan='2'>&nbsp;</td></tr>
1877         <tr><td class='base'>$Lang::tr{'your e-mail'}:&nbsp;<img src='/blob.gif' alt'*' /></td>
1878             <td class='base' nowrap='nowrap'><input type='text' name='ROOTCERT_EMAIL' value='$cgiparams{'ROOTCERT_EMAIL'}' size='32' /></td>
1879             <td colspan='2'>&nbsp;</td></tr>
1880         <tr><td class='base'>$Lang::tr{'your department'}:&nbsp;<img src='/blob.gif' alt'*' /></td>
1881             <td class='base' nowrap='nowrap'><input type='text' name='ROOTCERT_OU' value='$cgiparams{'ROOTCERT_OU'}' size='32' /></td>
1882             <td colspan='2'>&nbsp;</td></tr>
1883         <tr><td class='base'>$Lang::tr{'city'}:&nbsp;<img src='/blob.gif' alt'*' /></td>
1884             <td class='base' nowrap='nowrap'><input type='text' name='ROOTCERT_CITY' value='$cgiparams{'ROOTCERT_CITY'}' size='32' /></td>
1885             <td colspan='2'>&nbsp;</td></tr>
1886         <tr><td class='base'>$Lang::tr{'state or province'}:&nbsp;<img src='/blob.gif' alt'*' /></td>
1887             <td class='base' nowrap='nowrap'><input type='text' name='ROOTCERT_STATE' value='$cgiparams{'ROOTCERT_STATE'}' size='32' /></td>
1888             <td colspan='2'>&nbsp;</td></tr>
1889         <tr><td class='base'>$Lang::tr{'country'}:</td>
1890             <td class='base'><select name='ROOTCERT_COUNTRY'> 
1891
1892 END
1893         ;
1894         foreach my $country (sort keys %{Countries::countries}) {
1895             print "<option value='$Countries::countries{$country}'";
1896             if ( $Countries::countries{$country} eq $cgiparams{'ROOTCERT_COUNTRY'} ) {
1897                 print " selected='selected'";
1898             }
1899             print ">$country</option>";
1900         }
1901         print <<END;
1902             </select></td>
1903         <tr><td class='base'>$Lang::tr{'ovpn dh'}:</td>
1904                 <td class='base'><select name='DHLENGHT'>
1905                                 <option value='1024' $selected{'DHLENGHT'}{'1024'}>1024 $Lang::tr{'bit'}</option>
1906                                 <option value='2048' $selected{'DHLENGHT'}{'2048'}>2048 $Lang::tr{'bit'}</option>
1907                                 <option value='3072' $selected{'DHLENGHT'}{'3072'}>3072 $Lang::tr{'bit'}</option>
1908                                 <option value='4096' $selected{'DHLENGHT'}{'4096'}>4096 $Lang::tr{'bit'}</option>
1909                         </select>
1910                 </td>
1911         </tr>
1912
1913         <tr><td>&nbsp;</td>
1914             <td><input type='submit' name='ACTION' value='$Lang::tr{'generate root/host certificates'}' /></td>
1915             <td>&nbsp;</td><td>&nbsp;</td></tr> 
1916         <tr><td class='base' colspan='4' align='left'>
1917             <img src='/blob.gif' valign='top' alt='*' />&nbsp;$Lang::tr{'this field may be blank'}</td></tr>
1918         <tr><td colspan='2'><br></td></tr>
1919         <table width='100%'>
1920         <tr>
1921                 <b><font color='${Header::colourred}'>$Lang::tr{'capswarning'}: </font></b>$Lang::tr{'ovpn generating the root and host certificates'}
1922                 <td class='base'>$Lang::tr{'dh key warn'}</td>
1923         </tr>
1924         <tr>
1925                 <td class='base'>$Lang::tr{'dh key warn1'}</td>
1926         </tr>
1927         <tr><td colspan='2'><br></td></tr>
1928         <tr>
1929         </table>
1930
1931         <table width='100%'>
1932         <tr><td colspan='4'><hr></td></tr>
1933         <tr><td class='base' nowrap='nowrap'>$Lang::tr{'upload p12 file'}:</td>
1934             <td nowrap='nowrap'><input type='file' name='FH' size='32'></td>
1935             <td colspan='2'>&nbsp;</td></tr>
1936         <tr><td class='base'>$Lang::tr{'pkcs12 file password'}:&nbsp;<img src='/blob.gif' alt='*' ></td>
1937             <td class='base' nowrap='nowrap'><input type='password' name='P12_PASS' value='$cgiparams{'P12_PASS'}' size='32' /></td>
1938             <td colspan='2'>&nbsp;</td></tr>
1939         <tr><td>&nbsp;</td>
1940             <td><input type='submit' name='ACTION' value='$Lang::tr{'upload p12 file'}' /></td>
1941             <td colspan='2'>&nbsp;</td></tr>
1942         <tr><td class='base' colspan='4' align='left'>
1943             <img src='/blob.gif' valign='top' al='*' >&nbsp;$Lang::tr{'this field may be blank'}</td>
1944         </tr>
1945         </form></table>
1946 END
1947         ;
1948         &Header::closebox();
1949         print "<div align='center'><a href='/cgi-bin/ovpnmain.cgi'>$Lang::tr{'back'}</a></div>";
1950         &Header::closebigbox();
1951         &Header::closepage();
1952         exit(0)
1953     }
1954
1955     ROOTCERT_SUCCESS:
1956     system ("chmod 600 ${General::swroot}/ovpn/certs/serverkey.pem");
1957 #    if ($vpnsettings{'ENABLED'} eq 'on' ||
1958 #       $vpnsettings{'ENABLE_BLUE'} eq 'on') {
1959 #       system('/usr/local/bin/ipsecctrl', 'S');
1960 #    }
1961
1962 ###
1963 ### Enable/Disable connection
1964 ###
1965
1966 ###
1967 # m.a.d net2net
1968 ###
1969
1970 }elsif ($cgiparams{'ACTION'} eq $Lang::tr{'toggle enable disable'}) {
1971     
1972     &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings);
1973     &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
1974 #    my $n2nactive = '';
1975     my $n2nactive = `/bin/ps ax|grep $confighash{$cgiparams{'KEY'}}[1]|grep -v grep|awk \'{print \$1}\'`;
1976     
1977     if ($confighash{$cgiparams{'KEY'}}) {
1978                 if ($confighash{$cgiparams{'KEY'}}[0] eq 'off') {
1979                         $confighash{$cgiparams{'KEY'}}[0] = 'on';
1980                         &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
1981
1982                         if ($confighash{$cgiparams{'KEY'}}[3] eq 'net'){
1983                  system('/usr/local/bin/openvpnctrl', '-sn2n', $confighash{$cgiparams{'KEY'}}[1]);
1984                         }
1985                 } else {
1986
1987                         $confighash{$cgiparams{'KEY'}}[0] = 'off';
1988                         &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
1989
1990                         if ($confighash{$cgiparams{'KEY'}}[3] eq 'net'){
1991                     if ($n2nactive ne ''){                              
1992                                                 system('/usr/local/bin/openvpnctrl', '-kn2n', $confighash{$cgiparams{'KEY'}}[1]);
1993                                         }
1994  
1995                         } else {
1996                   $errormessage = $Lang::tr{'invalid key'};
1997                         }
1998       }
1999   }
2000
2001 ###
2002 ### Download OpenVPN client package
2003 ###
2004
2005
2006 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'dl client arch'}) {
2007     &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings);
2008     &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
2009     my $file = '';
2010     my $clientovpn = '';
2011     my @fileholder;
2012     my $tempdir = tempdir( CLEANUP => 1 );
2013     my $zippath = "$tempdir/";
2014
2015 ###
2016 # m.a.d net2net
2017 ###
2018
2019 if ($confighash{$cgiparams{'KEY'}}[3] eq 'net'){
2020         
2021         my $zipname = "$confighash{$cgiparams{'KEY'}}[1]-Client.zip";
2022         my $zippathname = "$zippath$zipname";
2023         $clientovpn = "$confighash{$cgiparams{'KEY'}}[1].conf";  
2024         my @ovsubnettemp =  split(/\./,$confighash{$cgiparams{'KEY'}}[27]);
2025         my $ovsubnet =  "$ovsubnettemp[0].$ovsubnettemp[1].$ovsubnettemp[2]";
2026         my $tunmtu = ''; 
2027         my @remsubnet = split(/\//,$confighash{$cgiparams{'KEY'}}[8]);
2028         my $n2nfragment = '';
2029         
2030     open(CLIENTCONF, ">$tempdir/$clientovpn") or die "Unable to open tempfile: $!";
2031     flock CLIENTCONF, 2;
2032     
2033     my $zip = Archive::Zip->new();
2034    print CLIENTCONF "# IPFire n2n Open VPN Client Config by ummeegge und m.a.d\n";
2035    print CLIENTCONF "# \n";
2036    print CLIENTCONF "# User Security\n";
2037    print CLIENTCONF "user nobody\n";
2038    print CLIENTCONF "group nobody\n";
2039    print CLIENTCONF "persist-tun\n";
2040    print CLIENTCONF "persist-key\n";
2041    print CLIENTCONF "script-security 2\n";
2042    print CLIENTCONF "# IP/DNS for remote Server Gateway\n"; 
2043    print CLIENTCONF "remote $vpnsettings{'VPN_IP'}\n";
2044    print CLIENTCONF "float\n";
2045    print CLIENTCONF "# IP adresses of the VPN Subnet\n"; 
2046    print CLIENTCONF "ifconfig $ovsubnet.2 $ovsubnet.1\n"; 
2047    print CLIENTCONF "# Server Gateway Network\n"; 
2048    print CLIENTCONF "route $remsubnet[0] $remsubnet[1]\n";
2049    print CLIENTCONF "# tun Device\n"; 
2050    print CLIENTCONF "dev $vpnsettings{'DDEVICE'}\n"; 
2051    print CLIENTCONF "# Port and Protokoll\n"; 
2052    print CLIENTCONF "port $confighash{$cgiparams{'KEY'}}[29]\n"; 
2053    
2054    if ($confighash{$cgiparams{'KEY'}}[28] eq 'tcp') {
2055    print CLIENTCONF "proto tcp-client\n";
2056    print CLIENTCONF "# Packet size\n";
2057    if ($confighash{$cgiparams{'KEY'}}[31] eq '') {$tunmtu = '1400'} else {$tunmtu = $confighash{$cgiparams{'KEY'}}[31]};
2058    print CLIENTCONF "tun-mtu $tunmtu\n";
2059    }
2060   
2061    if ($confighash{$cgiparams{'KEY'}}[28] eq 'udp') {
2062    print CLIENTCONF "proto udp\n"; 
2063    print CLIENTCONF "# Paketsize\n";
2064    if ($confighash{$cgiparams{'KEY'}}[31] eq '') {$tunmtu = '1500'} else {$tunmtu = $confighash{$cgiparams{'KEY'}}[31]};
2065    print CLIENTCONF "tun-mtu $tunmtu\n";
2066    if ($confighash{$cgiparams{'KEY'}}[24] ne '') {print CLIENTCONF "fragment $confighash{$cgiparams{'KEY'}}[24]\n";}
2067    if ($confighash{$cgiparams{'KEY'}}[23] eq 'on') {print CLIENTCONF "mssfix\n";}
2068    }
2069    if (($confighash{$cgiparams{'KEY'}}[38] eq 'yes') ||
2070        ($confighash{$cgiparams{'KEY'}}[38] eq 'maybe') ||
2071        ($confighash{$cgiparams{'KEY'}}[38] eq 'no' )) {
2072         if (($confighash{$cgiparams{'KEY'}}[23] ne 'on') || ($confighash{$cgiparams{'KEY'}}[24] eq '')) {
2073                 if ($tunmtu eq '1500' ) {
2074                         print CLIENTCONF "mtu-disc $confighash{$cgiparams{'KEY'}}[38]\n";
2075                 }
2076         }
2077    }
2078    print CLIENTCONF "ns-cert-type server\n";   
2079    print CLIENTCONF "# Auth. Client\n"; 
2080    print CLIENTCONF "tls-client\n"; 
2081    print CLIENTCONF "# Cipher\n";
2082    print CLIENTCONF "cipher $confighash{$cgiparams{'KEY'}}[40]\n";
2083     if ($confighash{$cgiparams{'KEY'}}[4] eq 'cert' && -f "${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12") { 
2084          print CLIENTCONF "pkcs12 ${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12\r\n";
2085      $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";
2086    }
2087    if ($confighash{$cgiparams{'KEY'}}[39] eq '') {
2088         print CLIENTCONF "# HMAC algorithm\n";
2089         print CLIENTCONF "auth SHA1\n";
2090    } else {
2091    print CLIENTCONF "# HMAC algorithm\n";
2092    print CLIENTCONF "auth $confighash{$cgiparams{'KEY'}}[39]\n";
2093    }
2094    if ($confighash{$cgiparams{'KEY'}}[30] eq 'on') {
2095    print CLIENTCONF "# Enable Compression\n";
2096    print CLIENTCONF "comp-lzo\r\n";
2097      }
2098    print CLIENTCONF "# Debug Level\n"; 
2099    print CLIENTCONF "verb 3\n"; 
2100    print CLIENTCONF "# Tunnel check\n"; 
2101    print CLIENTCONF "keepalive 10 60\n"; 
2102    print CLIENTCONF "# Start as daemon\n"; 
2103    print CLIENTCONF "daemon $confighash{$cgiparams{'KEY'}}[1]n2n\n"; 
2104    print CLIENTCONF "writepid /var/run/$confighash{$cgiparams{'KEY'}}[1]n2n.pid\n"; 
2105    print CLIENTCONF "# Activate Management Interface and Port\n"; 
2106    if ($confighash{$cgiparams{'KEY'}}[22] eq '') {print CLIENTCONF "management localhost $confighash{$cgiparams{'KEY'}}[29]\n"}
2107     else {print CLIENTCONF "management localhost $confighash{$cgiparams{'KEY'}}[22]\n"};
2108    print CLIENTCONF "# remsub $confighash{$cgiparams{'KEY'}}[11]\n";
2109   
2110
2111     close(CLIENTCONF);
2112         
2113     $zip->addFile( "$tempdir/$clientovpn", $clientovpn) or die "Can't add file $clientovpn\n";
2114     my $status = $zip->writeToFileNamed($zippathname);
2115
2116     open(DLFILE, "<$zippathname") or die "Unable to open $zippathname: $!";
2117     @fileholder = <DLFILE>;
2118     print "Content-Type:application/x-download\n";
2119     print "Content-Disposition:attachment;filename=$zipname\n\n";
2120     print @fileholder;
2121     exit (0);
2122 }
2123 else
2124 {
2125         my $zipname = "$confighash{$cgiparams{'KEY'}}[1]-TO-IPFire.zip";
2126         my $zippathname = "$zippath$zipname";
2127         $clientovpn = "$confighash{$cgiparams{'KEY'}}[1]-TO-IPFire.ovpn";
2128
2129 ###
2130 # m.a.d net2net
2131 ###
2132   
2133     open(CLIENTCONF, ">$tempdir/$clientovpn") or die "Unable to open tempfile: $!";
2134     flock CLIENTCONF, 2;
2135     
2136     my $zip = Archive::Zip->new();
2137     
2138     print CLIENTCONF "#OpenVPN Client conf\r\n";
2139     print CLIENTCONF "tls-client\r\n";
2140     print CLIENTCONF "client\r\n";
2141     print CLIENTCONF "nobind\r\n";
2142     print CLIENTCONF "dev $vpnsettings{'DDEVICE'}\r\n";
2143     print CLIENTCONF "proto $vpnsettings{'DPROTOCOL'}\r\n";
2144
2145     # Check if we are using fragment, mssfix or mtu-disc and set MTU to 1500
2146     # or use configured value.
2147     if ($vpnsettings{FRAGMENT} ne '' && $vpnsettings{DPROTOCOL} ne 'tcp' )
2148         { print CLIENTCONF "$vpnsettings{'DDEVICE'}-mtu 1500\r\n"; }
2149     elsif ($vpnsettings{MSSFIX} eq 'on')
2150         { print CLIENTCONF "$vpnsettings{'DDEVICE'}-mtu 1500\r\n"; }
2151     elsif (($vpnsettings{'PMTU_DISCOVERY'} eq 'yes') ||
2152            ($vpnsettings{'PMTU_DISCOVERY'} eq 'maybe') ||
2153            ($vpnsettings{'PMTU_DISCOVERY'} eq 'no' )) 
2154         { print CLIENTCONF "$vpnsettings{'DDEVICE'}-mtu 1500\r\n"; }
2155     else
2156         { print CLIENTCONF "$vpnsettings{'DDEVICE'}-mtu $vpnsettings{'DMTU'}\r\n"; }
2157
2158     if ( $vpnsettings{'ENABLED'} eq 'on'){
2159         print CLIENTCONF "remote $vpnsettings{'VPN_IP'} $vpnsettings{'DDEST_PORT'}\r\n";
2160         if ( $vpnsettings{'ENABLED_BLUE'} eq 'on' && (&haveBlueNet())){ 
2161             print CLIENTCONF "#Coment the above line and uncoment the next line, if you want to connect on the Blue interface\r\n";     
2162             print CLIENTCONF ";remote $netsettings{'BLUE_ADDRESS'} $vpnsettings{'DDEST_PORT'}\r\n";
2163         }
2164         if ( $vpnsettings{'ENABLED_ORANGE'} eq 'on' && (&haveOrangeNet())){
2165             print CLIENTCONF "#Coment the above line and uncoment the next line, if you want to connect on the Orange interface\r\n";           
2166             print CLIENTCONF ";remote $netsettings{'ORANGE_ADDRESS'} $vpnsettings{'DDEST_PORT'}\r\n";
2167         }
2168     } elsif ( $vpnsettings{'ENABLED_BLUE'} eq 'on' && (&haveBlueNet())){
2169         print CLIENTCONF "remote $netsettings{'BLUE_ADDRESS'} $vpnsettings{'DDEST_PORT'}\r\n";
2170         if ( $vpnsettings{'ENABLED_ORANGE'} eq 'on' && (&haveOrangeNet())){
2171             print CLIENTCONF "#Coment the above line and uncoment the next line, if you want to connect on the Orange interface\r\n";           
2172             print CLIENTCONF ";remote $netsettings{'ORANGE_ADDRESS'} $vpnsettings{'DDEST_PORT'}\r\n";
2173         }
2174     } elsif ( $vpnsettings{'ENABLED_ORANGE'} eq 'on' && (&haveOrangeNet())){
2175         print CLIENTCONF "remote $netsettings{'ORANGE_ADDRESS'} $vpnsettings{'DDEST_PORT'}\r\n";
2176     }
2177                         
2178     if ($confighash{$cgiparams{'KEY'}}[4] eq 'cert' && -f "${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12") { 
2179         print CLIENTCONF "pkcs12 $confighash{$cgiparams{'KEY'}}[1].p12\r\n";
2180         $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";
2181     } else {
2182         print CLIENTCONF "ca cacert.pem\r\n";
2183         print CLIENTCONF "cert $confighash{$cgiparams{'KEY'}}[1]cert.pem\r\n";
2184         print CLIENTCONF "key $confighash{$cgiparams{'KEY'}}[1].key\r\n";
2185         $zip->addFile( "${General::swroot}/ovpn/ca/cacert.pem", "cacert.pem")  or die "Can't add file cacert.pem\n";
2186         $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";    
2187     }
2188     print CLIENTCONF "cipher $vpnsettings{DCIPHER}\r\n";
2189     if ($vpnsettings{'DAUTH'} eq '') {
2190         print CLIENTCONF "";
2191     } else {
2192         print CLIENTCONF "auth $vpnsettings{'DAUTH'}\r\n";
2193     }
2194     if ($vpnsettings{'TLSAUTH'} eq 'on') {
2195         print CLIENTCONF "tls-auth ta.key\r\n";
2196         $zip->addFile( "${General::swroot}/ovpn/certs/ta.key", "ta.key")  or die "Can't add file ta.key\n";
2197     }
2198     if ($vpnsettings{DCOMPLZO} eq 'on') {
2199         print CLIENTCONF "comp-lzo\r\n";
2200     }
2201     print CLIENTCONF "verb 3\r\n";
2202     print CLIENTCONF "ns-cert-type server\r\n";
2203     print CLIENTCONF "tls-remote $vpnsettings{ROOTCERT_HOSTNAME}\r\n"; 
2204     if ($vpnsettings{MSSFIX} eq 'on') {
2205         print CLIENTCONF "mssfix\r\n";
2206     }
2207     if ($vpnsettings{FRAGMENT} ne '' && $vpnsettings{DPROTOCOL} ne 'tcp' ) {
2208         print CLIENTCONF "fragment $vpnsettings{'FRAGMENT'}\r\n";
2209     }
2210
2211     # Check if a valid operating mode has been choosen and use it.
2212     if (($vpnsettings{'PMTU_DISCOVERY'} eq 'yes') ||
2213         ($vpnsettings{'PMTU_DISCOVERY'} eq 'maybe') ||
2214         ($vpnsettings{'PMTU_DISCOVERY'} eq 'no' )) {
2215         if(($vpnsettings{MSSFIX} ne 'on') || ($vpnsettings{FRAGMENT} eq '')) {
2216                 print CLIENTCONF "mtu-disc $vpnsettings{'PMTU_DISCOVERY'}\r\n";
2217         }
2218     }
2219     close(CLIENTCONF);
2220         
2221     $zip->addFile( "$tempdir/$clientovpn", $clientovpn) or die "Can't add file $clientovpn\n";
2222     my $status = $zip->writeToFileNamed($zippathname);
2223
2224     open(DLFILE, "<$zippathname") or die "Unable to open $zippathname: $!";
2225     @fileholder = <DLFILE>;
2226     print "Content-Type:application/x-download\n";
2227     print "Content-Disposition:attachment;filename=$zipname\n\n";
2228     print @fileholder;
2229     exit (0);
2230    }
2231    
2232    
2233    
2234 ###
2235 ### Remove connection
2236 ###
2237
2238
2239 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'remove'}) {
2240     &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings);
2241     &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
2242
2243     if ($confighash{$cgiparams{'KEY'}}) {
2244 #       if ($vpnsettings{'ENABLED'} eq 'on' ||
2245 #           $vpnsettings{'ENABLED_BLUE'} eq 'on') {
2246 #           system('/usr/local/bin/ipsecctrl', 'D', $cgiparams{'KEY'});
2247 #       }
2248 #
2249         my $temp = `/usr/bin/openssl ca -revoke ${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem -config ${General::swroot}/ovpn/openssl/ovpn.cnf`;
2250
2251 ###
2252 # m.a.d net2net
2253 ###
2254
2255 if ($confighash{$cgiparams{'KEY'}}[3] eq 'net') {
2256         my $conffile = glob("${General::swroot}/ovpn/n2nconf/$confighash{$cgiparams{'KEY'}}[1]/$confighash{$cgiparams{'KEY'}}[1].conf");
2257         my $certfile = glob("${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12");
2258         unlink ($certfile);
2259         unlink ($conffile);
2260
2261         if (-e "${General::swroot}/ovpn/n2nconf/$confighash{$cgiparams{'KEY'}}[1]") {
2262                 rmdir ("${General::swroot}/ovpn/n2nconf/$confighash{$cgiparams{'KEY'}}[1]") || die "Kann Verzeichnis nicht loeschen: $!";
2263         }
2264 }
2265
2266   unlink ("${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem");
2267   unlink ("${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12");
2268
2269 # A.Marx CCD delete ccd files and routes
2270
2271         
2272         if (-f "${General::swroot}/ovpn/ccd/$confighash{$cgiparams{'KEY'}}[2]")
2273         {
2274                 unlink "${General::swroot}/ovpn/ccd/$confighash{$cgiparams{'KEY'}}[2]";
2275         }
2276         
2277         &General::readhasharray("${General::swroot}/ovpn/ccdroute", \%ccdroutehash);
2278         foreach my $key (keys %ccdroutehash) {
2279                 if ($ccdroutehash{$key}[0] eq $confighash{$cgiparams{'KEY'}}[1]){
2280                         delete $ccdroutehash{$key};
2281                 }
2282         }
2283         &General::writehasharray("${General::swroot}/ovpn/ccdroute", \%ccdroutehash);
2284         
2285         &General::readhasharray("${General::swroot}/ovpn/ccdroute2", \%ccdroute2hash);
2286         foreach my $key (keys %ccdroute2hash) {
2287                 if ($ccdroute2hash{$key}[0] eq $confighash{$cgiparams{'KEY'}}[1]){
2288                         delete $ccdroute2hash{$key};
2289                 }
2290         }
2291         &General::writehasharray("${General::swroot}/ovpn/ccdroute2", \%ccdroute2hash);
2292         &writeserverconf;
2293         
2294         
2295 # CCD end 
2296
2297         
2298         delete $confighash{$cgiparams{'KEY'}};
2299         my $temp2 = `/usr/bin/openssl ca -gencrl -out ${General::swroot}/ovpn/crls/cacrl.pem -config ${General::swroot}/ovpn/openssl/ovpn.cnf`;
2300         &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
2301
2302         #&writeserverconf();
2303     } else {
2304         $errormessage = $Lang::tr{'invalid key'};
2305     }
2306         &General::firewall_reload();
2307
2308 ###
2309 ### Download PKCS12 file
2310 ###
2311 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'download pkcs12 file'}) {
2312     &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
2313
2314     print "Content-Disposition: filename=" . $confighash{$cgiparams{'KEY'}}[1] . ".p12\r\n";
2315     print "Content-Type: application/octet-stream\r\n\r\n";
2316     print `/bin/cat ${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12`;
2317     exit (0);
2318
2319 ###
2320 ### Display certificate
2321 ###
2322 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'show certificate'}) {
2323     &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
2324
2325     if ( -f "${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem") {
2326         &Header::showhttpheaders();
2327         &Header::openpage($Lang::tr{'ovpn'}, 1, '');
2328         &Header::openbigbox('100%', 'LEFT', '', '');
2329         &Header::openbox('100%', 'LEFT', "$Lang::tr{'certificate'}:");
2330         my $output = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem`;
2331         $output = &Header::cleanhtml($output,"y");
2332         print "<pre>$output</pre>\n";
2333         &Header::closebox();
2334         print "<div align='center'><a href='/cgi-bin/ovpnmain.cgi'>$Lang::tr{'back'}</a></div>";
2335         &Header::closebigbox();
2336         &Header::closepage();
2337         exit(0);
2338     }
2339
2340 ###
2341 ### Display Diffie-Hellman key
2342 ###
2343 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'show dh'}) {
2344
2345     if (! -e "${General::swroot}/ovpn/ca/dh1024.pem") {
2346         $errormessage = $Lang::tr{'not present'};
2347         } else {
2348                 &Header::showhttpheaders();
2349                 &Header::openpage($Lang::tr{'ovpn'}, 1, '');
2350                 &Header::openbigbox('100%', 'LEFT', '', '');
2351                 &Header::openbox('100%', 'LEFT', "$Lang::tr{'dh'}:");
2352                 my $output = `/usr/bin/openssl dhparam -text -in ${General::swroot}/ovpn/ca/dh1024.pem`;
2353                 $output = &Header::cleanhtml($output,"y");
2354                 print "<pre>$output</pre>\n";
2355                 &Header::closebox();
2356                 print "<div align='center'><a href='/cgi-bin/ovpnmain.cgi'>$Lang::tr{'back'}</a></div>";
2357                 &Header::closebigbox();
2358                 &Header::closepage();
2359                 exit(0);
2360     }
2361
2362 ###
2363 ### Display Certificate Revoke List
2364 ###
2365 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'show crl'}) {
2366 #    &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
2367
2368     if (! -e "${General::swroot}/ovpn/crls/cacrl.pem") {
2369         $errormessage = $Lang::tr{'not present'};
2370         } else {
2371         &Header::showhttpheaders();
2372         &Header::openpage($Lang::tr{'ovpn'}, 1, '');
2373         &Header::openbigbox('100%', 'LEFT', '', '');
2374         &Header::openbox('100%', 'LEFT', "$Lang::tr{'crl'}:");
2375         my $output = `/usr/bin/openssl crl -text -noout -in ${General::swroot}/ovpn/crls/cacrl.pem`;
2376         $output = &Header::cleanhtml($output,"y");
2377         print "<pre>$output</pre>\n";
2378         &Header::closebox();
2379         print "<div align='center'><a href='/cgi-bin/ovpnmain.cgi'>$Lang::tr{'back'}</a></div>";
2380         &Header::closebigbox();
2381         &Header::closepage();
2382         exit(0);
2383     }
2384
2385 ###
2386 ### Advanced Server Settings
2387 ###
2388
2389 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'advanced server'}) {
2390     %cgiparams = ();
2391     %cahash = ();
2392     %confighash = ();
2393     my $disabled;
2394     &General::readhash("${General::swroot}/ovpn/settings", \%cgiparams);
2395     read_routepushfile;
2396         
2397         
2398 #    if ($cgiparams{'CLIENT2CLIENT'} eq '') {
2399 #       $cgiparams{'CLIENT2CLIENT'} =  'on';     
2400 #    }
2401 ADV_ERROR:
2402     if ($cgiparams{'MAX_CLIENTS'} eq '') {
2403                 $cgiparams{'MAX_CLIENTS'} =  '100';
2404     }
2405     if ($cgiparams{'KEEPALIVE_1'} eq '') {
2406                 $cgiparams{'KEEPALIVE_1'} =  '10';
2407     }
2408     if ($cgiparams{'KEEPALIVE_2'} eq '') {
2409                 $cgiparams{'KEEPALIVE_2'} =  '60';
2410     }
2411     if ($cgiparams{'LOG_VERB'} eq '') {
2412                 $cgiparams{'LOG_VERB'} =  '3';
2413     }
2414     if ($cgiparams{'PMTU_DISCOVERY'} eq '') {
2415                 $cgiparams{'PMTU_DISCOVERY'} = 'off';
2416     }
2417     if ($cgiparams{'DAUTH'} eq '') {
2418                 $cgiparams{'DAUTH'} = 'SHA1';
2419     }
2420     if ($cgiparams{'TLSAUTH'} eq '') {
2421                 $cgiparams{'TLSAUTH'} = 'off';
2422     }
2423     $checked{'CLIENT2CLIENT'}{'off'} = '';
2424     $checked{'CLIENT2CLIENT'}{'on'} = '';
2425     $checked{'CLIENT2CLIENT'}{$cgiparams{'CLIENT2CLIENT'}} = 'CHECKED';
2426     $checked{'REDIRECT_GW_DEF1'}{'off'} = '';
2427     $checked{'REDIRECT_GW_DEF1'}{'on'} = '';
2428     $checked{'REDIRECT_GW_DEF1'}{$cgiparams{'REDIRECT_GW_DEF1'}} = 'CHECKED';
2429     $checked{'MSSFIX'}{'off'} = '';
2430     $checked{'MSSFIX'}{'on'} = '';
2431     $checked{'MSSFIX'}{$cgiparams{'MSSFIX'}} = 'CHECKED';
2432     $checked{'PMTU_DISCOVERY'}{$cgiparams{'PMTU_DISCOVERY'}} = 'checked=\'checked\'';
2433     $selected{'LOG_VERB'}{'0'} = '';
2434     $selected{'LOG_VERB'}{'1'} = '';
2435     $selected{'LOG_VERB'}{'2'} = '';
2436     $selected{'LOG_VERB'}{'3'} = '';
2437     $selected{'LOG_VERB'}{'4'} = '';
2438     $selected{'LOG_VERB'}{'5'} = '';
2439     $selected{'LOG_VERB'}{'6'} = '';
2440     $selected{'LOG_VERB'}{'7'} = '';
2441     $selected{'LOG_VERB'}{'8'} = '';
2442     $selected{'LOG_VERB'}{'9'} = '';
2443     $selected{'LOG_VERB'}{'10'} = '';
2444     $selected{'LOG_VERB'}{'11'} = '';
2445     $selected{'LOG_VERB'}{$cgiparams{'LOG_VERB'}} = 'SELECTED';
2446     $selected{'DAUTH'}{'whirlpool'} = '';
2447     $selected{'DAUTH'}{'SHA512'} = '';
2448     $selected{'DAUTH'}{'SHA384'} = '';
2449     $selected{'DAUTH'}{'SHA256'} = '';
2450     $selected{'DAUTH'}{'SHA1'} = '';
2451     $selected{'DAUTH'}{$cgiparams{'DAUTH'}} = 'SELECTED';
2452     $checked{'TLSAUTH'}{'off'} = '';
2453     $checked{'TLSAUTH'}{'on'} = '';
2454     $checked{'TLSAUTH'}{$cgiparams{'TLSAUTH'}} = 'CHECKED';
2455    
2456     &Header::showhttpheaders();
2457     &Header::openpage($Lang::tr{'status ovpn'}, 1, '');
2458     &Header::openbigbox('100%', 'LEFT', '', $errormessage);    
2459     if ($errormessage) {
2460         &Header::openbox('100%', 'LEFT', $Lang::tr{'error messages'});
2461         print "<class name='base'>$errormessage\n";
2462         print "&nbsp;</class>\n";
2463         &Header::closebox();
2464     }
2465     &Header::openbox('100%', 'LEFT', $Lang::tr{'advanced server'});
2466     print <<END;
2467     <form method='post' enctype='multipart/form-data'>
2468 <table width='100%' border=0>
2469         <tr>
2470                 <td colspan='4'><b>$Lang::tr{'dhcp-options'}</b></td>
2471     </tr>
2472     <tr>
2473                 <td width='25%'></td> <td width='20%'> </td><td width='25%'> </td><td width='30%'></td>
2474     </tr>       
2475     <tr>                
2476                 <td class='base'>Domain</td>
2477         <td><input type='TEXT' name='DHCP_DOMAIN' value='$cgiparams{'DHCP_DOMAIN'}' size='30'  /></td>
2478     </tr>
2479     <tr>        
2480                 <td class='base'>DNS</td>
2481                 <td><input type='TEXT' name='DHCP_DNS' value='$cgiparams{'DHCP_DNS'}' size='30' /></td>
2482     </tr>       
2483     <tr>        
2484                 <td class='base'>WINS</td>
2485                 <td><input type='TEXT' name='DHCP_WINS' value='$cgiparams{'DHCP_WINS'}' size='30' /></td>
2486         </tr>
2487     <tr>
2488                 <td colspan='4'><b>$Lang::tr{'ovpn routes push options'}</b></td>
2489     </tr>
2490     <tr>        
2491                 <td class='base'>$Lang::tr{'ovpn routes push'}</td>
2492                 <td colspan='2'>
2493                 <textarea name='ROUTES_PUSH' cols='26' rows='6' wrap='off'>
2494 END
2495 ;
2496
2497 if ($cgiparams{'ROUTES_PUSH'} ne '')
2498 {
2499         print $cgiparams{'ROUTES_PUSH'};
2500 }
2501
2502 print <<END;
2503 </textarea></td>
2504 </tr>
2505     </tr>
2506 </table>
2507 <hr size='1'>
2508 <table width='100%'>
2509     <tr>
2510                 <td class'base'><b>$Lang::tr{'misc-options'}</b></td>
2511     </tr>
2512     <tr>
2513                 <td width='20%'></td> <td width='15%'> </td><td width='15%'> </td><td width='15%'></td><td width='35%'></td>
2514     </tr>
2515     <tr>
2516                 <td class='base'>Client-To-Client</td>
2517                 <td><input type='checkbox' name='CLIENT2CLIENT' $checked{'CLIENT2CLIENT'}{'on'} /></td>
2518     </tr>
2519     <tr>        
2520                 <td class='base'>Redirect-Gateway def1</td>
2521                 <td><input type='checkbox' name='REDIRECT_GW_DEF1' $checked{'REDIRECT_GW_DEF1'}{'on'} /></td>
2522     </tr>
2523     <tr>        
2524         <td class='base'>Max-Clients</td>
2525         <td><input type='text' name='MAX_CLIENTS' value='$cgiparams{'MAX_CLIENTS'}' size='10' /></td>
2526     </tr>       
2527         <tr>
2528           <td class='base'>Keepalive <br />
2529             (ping/ping-restart)</td>
2530           <td><input type='TEXT' name='KEEPALIVE_1' value='$cgiparams{'KEEPALIVE_1'}' size='10' /></td>
2531           <td><input type='TEXT' name='KEEPALIVE_2' value='$cgiparams{'KEEPALIVE_2'}' size='10' /></td>
2532     </tr>
2533         <tr>
2534           <td class='base'>fragment <br></td>
2535           <td><input type='TEXT' name='FRAGMENT' value='$cgiparams{'FRAGMENT'}' size='10' /></td>
2536       </tr>
2537         <tr>
2538           <td class='base'>mssfix</td>
2539           <td><input type='checkbox' name='MSSFIX' $checked{'MSSFIX'}{'on'} /></td>
2540           <td>$Lang::tr{'openvpn default'}: off</td>
2541           </tr>
2542
2543         <tr>
2544                 <td class='base'>$Lang::tr{'ovpn mtu-disc'}</td>
2545                 <td><input type='radio' name='PMTU_DISCOVERY' value='yes' $checked{'PMTU_DISCOVERY'}{'yes'} /> $Lang::tr{'ovpn mtu-disc yes'}</td>
2546                 <td><input type='radio' name='PMTU_DISCOVERY' value='maybe' $checked{'PMTU_DISCOVERY'}{'maybe'} /> $Lang::tr{'ovpn mtu-disc maybe'}</td>
2547                 <td><input type='radio' name='PMTU_DISCOVERY' value='no' $checked{'PMTU_DISCOVERY'}{'no'} /> $Lang::tr{'ovpn mtu-disc no'}</td>
2548                 <td><input type='radio' name='PMTU_DISCOVERY' value='off' $checked{'PMTU_DISCOVERY'}{'off'} /> $Lang::tr{'ovpn mtu-disc off'}</td>
2549         </tr>
2550 </table>
2551
2552 <hr size='1'>
2553 <table width='100%'>
2554     <tr>
2555         <td class'base'><b>$Lang::tr{'log-options'}</b></td>
2556     </tr>
2557     <tr>
2558         <td width='20%'></td> <td width='30%'> </td><td width='25%'> </td><td width='25%'></td>
2559     </tr>
2560
2561     <tr><td class='base'>VERB</td>
2562         <td><select name='LOG_VERB'>
2563                         <option value='0'  $selected{'LOG_VERB'}{'0'}>0</option>
2564                         <option value='1'  $selected{'LOG_VERB'}{'1'}>1</option>
2565                         <option value='2'  $selected{'LOG_VERB'}{'2'}>2</option>
2566                         <option value='3'  $selected{'LOG_VERB'}{'3'}>3</option>
2567                         <option value='4'  $selected{'LOG_VERB'}{'4'}>4</option>
2568                         <option value='5'  $selected{'LOG_VERB'}{'5'}>5</option>
2569                         <option value='6'  $selected{'LOG_VERB'}{'6'}>6</option>
2570                         <option value='7'  $selected{'LOG_VERB'}{'7'}>7</option>
2571                         <option value='8'  $selected{'LOG_VERB'}{'8'}>8</option>
2572                         <option value='9'  $selected{'LOG_VERB'}{'9'}>9</option>
2573                         <option value='10' $selected{'LOG_VERB'}{'10'}>10</option>
2574                         <option value='11' $selected{'LOG_VERB'}{'11'}>11</option>
2575         </td></select>
2576     </table>
2577
2578 <hr size='1'>
2579 <table width='100%'>
2580     <tr>
2581                 <td class'base'><b>$Lang::tr{'ovpn crypt options'}</b></td>
2582         </tr>
2583         <tr>
2584                 <td width='20%'></td> <td width='30%'> </td><td width='25%'> </td><td width='25%'></td>
2585     </tr>       
2586     <tr><td class='base'>$Lang::tr{'ovpn ha'}</td>
2587                 <td><select name='DAUTH'>
2588                                 <option value='whirlpool'               $selected{'DAUTH'}{'whirlpool'}>Whirlpool (512 $Lang::tr{'bit'})</option>
2589                                 <option value='SHA512'                  $selected{'DAUTH'}{'SHA512'}>SHA2 (512 $Lang::tr{'bit'})</option>
2590                                 <option value='SHA384'                  $selected{'DAUTH'}{'SHA384'}>SHA2 (384 $Lang::tr{'bit'})</option>
2591                                 <option value='SHA256'                  $selected{'DAUTH'}{'SHA256'}>SHA2 (256 $Lang::tr{'bit'})</option>
2592                                 <option value='SHA1'                    $selected{'DAUTH'}{'SHA1'}>SHA1 (160 $Lang::tr{'bit'})</option>
2593                         </select>
2594                 </td>
2595                 <td>$Lang::tr{'openvpn default'}: <span class="base">SHA1 (160 $Lang::tr{'bit'})</span></td>
2596     </tr>
2597 </table>
2598
2599 <table width='100%'>
2600     <tr>
2601         <td width='20%'></td> <td width='15%'> </td><td width='15%'> </td><td width='15%'></td><td width='35%'></td>
2602     </tr>
2603
2604     <tr>
2605         <td class='base'>HMAC tls-auth</td>
2606         <td><input type='checkbox' name='TLSAUTH' $checked{'TLSAUTH'}{'on'} /></td>
2607     </tr>
2608     </table><hr>
2609 END
2610
2611 if ( -e "/var/run/openvpn.pid"){
2612 print"  <br><b><font color='#990000'>$Lang::tr{'attention'}:</b></font><br>
2613                 $Lang::tr{'server restart'}<br><br>
2614                 <hr>";
2615         print<<END;
2616 <table width='100%'>
2617 <tr>
2618     <td>&nbsp;</td>
2619     <td allign='center'><input type='submit' name='ACTION' value='$Lang::tr{'save-adv-options'}' disabled='disabled' /></td>
2620     <td allign='center'><input type='submit' name='ACTION' value='$Lang::tr{'cancel-adv-options'}' /></td>
2621     <td>&nbsp;</td>    
2622 </tr>
2623 </table>    
2624 </form>
2625 END
2626 ;               
2627                 
2628                 
2629 }else{
2630
2631         print<<END;
2632 <table width='100%'>
2633 <tr>
2634     <td>&nbsp;</td>
2635     <td allign='center'><input type='submit' name='ACTION' value='$Lang::tr{'save-adv-options'}' /></td>
2636     <td allign='center'><input type='submit' name='ACTION' value='$Lang::tr{'cancel-adv-options'}' /></td>
2637     <td>&nbsp;</td>    
2638 </tr>
2639 </table>    
2640 </form>
2641 END
2642 ;                                  
2643 }
2644     &Header::closebox();
2645 #    print "<div align='center'><a href='/cgi-bin/ovpnmain.cgi'>$Lang::tr{'back'}</a></div>";
2646     &Header::closebigbox();
2647     &Header::closepage();
2648     exit(0);
2649         
2650
2651 # A.Marx CCD   Add,delete or edit CCD net
2652
2653 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'ccd net'} || 
2654                 $cgiparams{'ACTION'} eq $Lang::tr{'ccd add'} ||  
2655                 $cgiparams{'ACTION'} eq "kill" || 
2656                 $cgiparams{'ACTION'} eq "edit" ||
2657                 $cgiparams{'ACTION'} eq 'editsave'){
2658         &Header::showhttpheaders();
2659         &Header::openpage($Lang::tr{'ccd net'}, 1, '');
2660         &Header::openbigbox('100%', 'LEFT', '', '');
2661
2662         if ($cgiparams{'ACTION'} eq "kill"){
2663                 &delccdnet($cgiparams{'net'});
2664         }
2665         
2666         if ($cgiparams{'ACTION'} eq 'editsave'){
2667                 my ($a,$b) =split (/\|/,$cgiparams{'ccdname'});
2668                 if ( $a ne $b){ &modccdnet($a,$b);}
2669                 $cgiparams{'ccdname'}='';
2670                 $cgiparams{'ccdsubnet'}='';
2671         }
2672         
2673         if ($cgiparams{'ACTION'} eq $Lang::tr{'ccd add'}) {
2674                 &addccdnet($cgiparams{'ccdname'},$cgiparams{'ccdsubnet'});
2675         }
2676         if ($errormessage) {
2677             &Header::openbox('100%', 'LEFT', $Lang::tr{'error messages'});
2678             print "<class name='base'>$errormessage";
2679             print "&nbsp;</class>";
2680             &Header::closebox();                
2681         }
2682 if ($cgiparams{'ACTION'} eq "edit"){
2683         
2684         &Header::openbox('100%', 'LEFT', $Lang::tr{'ccd modify'});
2685
2686         print <<END;
2687     <table width='100%' border='0'>
2688     <tr><form method='post'>
2689         <td width='10%' nowrap='nowrap'>$Lang::tr{'ccd name'}:</td><td><input type='TEXT' name='ccdname' value='$cgiparams{'ccdname'}' /></td>
2690         <td width='8%'>$Lang::tr{'ccd subnet'}:</td><td><input type='TEXT' name='ccdsubnet' value='$cgiparams{'ccdsubnet'}' readonly='readonly' /></td></tr>
2691         <tr><td colspan='4' align='right'><hr><input type='submit' value='$Lang::tr{'save'}' /><input type='hidden' name='ACTION' value='editsave'/>
2692         <input type='hidden' name='ccdname' value='$cgiparams{'ccdname'}'/><input type='submit' value='$Lang::tr{'cancel'}' />
2693         </td></tr>
2694         </table></form>
2695 END
2696 ;
2697         &Header::closebox();
2698
2699         &Header::openbox('100%', 'LEFT',$Lang::tr{'ccd net'} );
2700         print <<END;
2701     <table width='100%' border='0'  cellpadding='0' cellspacing='1'>
2702     <tr>
2703         <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>
2704 END
2705 ;
2706 }
2707 else{
2708         if (! -e "/var/run/openvpn.pid"){
2709         &Header::openbox('100%', 'LEFT', $Lang::tr{'ccd add'});
2710         print <<END;
2711             <table width='100%' border='0'>
2712             <tr><form method='post'>
2713                 <td colspan='4'>$Lang::tr{'ccd hint'}<br><br></td></tr>
2714                 <tr>
2715                 <td width='10%' nowrap='nwrap'>$Lang::tr{'ccd name'}:</td><td><input type='TEXT' name='ccdname' value='$cgiparams{'ccdname'}' /></td>
2716                 <td width='8%'>$Lang::tr{'ccd subnet'}:</td><td><input type='TEXT' name='ccdsubnet' value='$cgiparams{'ccdsubnet'}' /></td></tr>
2717                 <tr><td colspan=4><hr /></td></tr><tr>
2718                 <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>
2719                 </table></form>
2720 END
2721         
2722         &Header::closebox();
2723 }
2724         &Header::openbox('100%', 'LEFT',$Lang::tr{'ccd net'} );
2725         if ( -e "/var/run/openvpn.pid"){
2726                 print "<b>$Lang::tr{'attention'}:</b><br>";
2727                 print "$Lang::tr{'ccd noaddnet'}<br><hr>";
2728         }
2729         
2730     print <<END;
2731     <table width='100%' cellpadding='0' cellspacing='1'>
2732     <tr>
2733         <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>
2734 END
2735 ;
2736 }
2737         my %ccdconfhash=();     
2738         &General::readhasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash);     
2739         my @ccdconf=();
2740         my $count=0;
2741         foreach my $key (sort { uc($ccdconfhash{$a}[0]) cmp uc($ccdconfhash{$b}[0]) } keys %ccdconfhash) {
2742                 @ccdconf=($ccdconfhash{$key}[0],$ccdconfhash{$key}[1]);
2743                 $count++;
2744                 my $ccdhosts = &hostsinnet($ccdconf[0]);
2745                 if ($count % 2){ print" <tr bgcolor='$color{'color22'}'>";}
2746                 else{            print" <tr bgcolor='$color{'color20'}'>";}
2747                 print"<td>$ccdconf[0]</td><td align='center'>$ccdconf[1]</td><td align='center'>$ccdhosts/".(&ccdmaxclients($ccdconf[1])+1)."</td><td>";
2748         print <<END;
2749                 <form method='post' />
2750                 <input type='image' src='/images/edit.gif' align='middle' alt='$Lang::tr{'edit'}' title='$Lang::tr{'edit'}' />
2751                 <input type='hidden' name='ACTION' value='edit'/>
2752                 <input type='hidden' name='ccdname' value='$ccdconf[0]' />
2753                 <input type='hidden' name='ccdsubnet' value='$ccdconf[1]' />
2754                 </form></td>
2755                 <form method='post' />
2756                 <td><input type='hidden' name='ACTION' value='kill'/>
2757                 <input type='hidden' name='number' value='$count' />
2758                 <input type='hidden' name='net' value='$ccdconf[0]' />
2759                 <input type='image' src='/images/delete.gif' align='middle' alt='$Lang::tr{'remove'}' title='$Lang::tr{'remove'}' /></form></td></tr>
2760 END
2761 ;
2762         }       
2763         print "</table></form>";
2764         &Header::closebox();
2765         print "<div align='center'><a href='/cgi-bin/ovpnmain.cgi'>$Lang::tr{'back'}</a></div>";
2766         &Header::closebigbox();
2767         &Header::closepage();
2768         exit(0);
2769         
2770 #END CCD
2771
2772 ###
2773 ### Openvpn Connections Statistics
2774 ###
2775 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'ovpn con stat'}) {
2776         &Header::showhttpheaders();
2777         &Header::openpage($Lang::tr{'ovpn con stat'}, 1, '');
2778         &Header::openbigbox('100%', 'LEFT', '', '');
2779     &Header::openbox('100%', 'LEFT', $Lang::tr{'ovpn con stat'});
2780
2781 #
2782 #       <td><b>$Lang::tr{'protocol'}</b></td>
2783 # protocol temp removed 
2784     print <<END;
2785     <table width='100%' cellpadding='2' cellspacing='0' class='tbl'>
2786     <tr>
2787         <th><b>$Lang::tr{'common name'}</b></th>
2788         <th><b>$Lang::tr{'real address'}</b></th>
2789         <th><b>$Lang::tr{'virtual address'}</b></th>
2790         <th><b>$Lang::tr{'loged in at'}</b></th>
2791         <th><b>$Lang::tr{'bytes sent'}</b></th>
2792         <th><b>$Lang::tr{'bytes received'}</b></th>
2793         <th><b>$Lang::tr{'last activity'}</b></th>
2794     </tr>
2795 END
2796 ;
2797         my $filename = "/var/log/ovpnserver.log";
2798         open(FILE, $filename) or die 'Unable to open config file.';
2799         my @current = <FILE>;
2800         close(FILE);
2801         my @users =();
2802         my $status;
2803         my $uid = 0;
2804         my $cn;
2805         my @match = ();
2806         my $proto = "udp";
2807         my $address;
2808         my %userlookup = ();
2809         foreach my $line (@current)
2810         {
2811             chomp($line);
2812             if ( $line =~ /^Updated,(.+)/){
2813                 @match = split( /^Updated,(.+)/, $line); 
2814                 $status = $match[1];
2815             }
2816 #gian       
2817             if ( $line =~ /^(.+),(\d+\.\d+\.\d+\.\d+\:\d+),(\d+),(\d+),(.+)/) {
2818                 @match = split(m/^(.+),(\d+\.\d+\.\d+\.\d+\:\d+),(\d+),(\d+),(.+)/, $line);
2819                 if ($match[1] ne "Common Name") {
2820                     $cn = $match[1];
2821                     $userlookup{$match[2]} = $uid;
2822                     $users[$uid]{'CommonName'} = $match[1];
2823                     $users[$uid]{'RealAddress'} = $match[2];
2824                     $users[$uid]{'BytesReceived'} = &sizeformat($match[3]);
2825                     $users[$uid]{'BytesSent'} = &sizeformat($match[4]);
2826                     $users[$uid]{'Since'} = $match[5];
2827                     $users[$uid]{'Proto'} = $proto;
2828                     $uid++;
2829                 }    
2830             }
2831             if ( $line =~ /^(\d+\.\d+\.\d+\.\d+),(.+),(\d+\.\d+\.\d+\.\d+\:\d+),(.+)/) {
2832                 @match = split(m/^(\d+\.\d+\.\d+\.\d+),(.+),(\d+\.\d+\.\d+\.\d+\:\d+),(.+)/, $line);
2833                 if ($match[1] ne "Virtual Address") {
2834                     $address = $match[3];
2835                     #find the uid in the lookup table
2836                     $uid = $userlookup{$address};
2837                     $users[$uid]{'VirtualAddress'} = $match[1];
2838                     $users[$uid]{'LastRef'} = $match[4];
2839                 }
2840             }
2841         }
2842         my $user2 = @users;
2843         if ($user2 >= 1){
2844                 for (my $idx = 1; $idx <= $user2; $idx++){
2845                                                 if ($idx % 2) {
2846                                                         print "<tr>";
2847                                                         $col="bgcolor='$color{'color22'}'";
2848                                                 } else {
2849                                                         print "<tr>";
2850                                                         $col="bgcolor='$color{'color20'}'";
2851                                                 }
2852                                                 print "<td align='left' $col>$users[$idx-1]{'CommonName'}</td>";
2853                                                 print "<td align='left' $col>$users[$idx-1]{'RealAddress'}</td>";
2854                                                 print "<td align='left' $col>$users[$idx-1]{'VirtualAddress'}</td>";
2855                                                 print "<td align='left' $col>$users[$idx-1]{'Since'}</td>";
2856                                                 print "<td align='left' $col>$users[$idx-1]{'BytesSent'}</td>";
2857                                                 print "<td align='left' $col>$users[$idx-1]{'BytesReceived'}</td>";
2858                                                 print "<td align='left' $col>$users[$idx-1]{'LastRef'}</td>";
2859                         }
2860         }
2861         
2862         print "</table>";
2863         print <<END;
2864         <table width='100%' border='0' cellpadding='2' cellspacing='0'>
2865         <tr><td></td></tr>
2866         <tr><td></td></tr>
2867         <tr><td></td></tr>
2868         <tr><td></td></tr>
2869         <tr><td align='center' >$Lang::tr{'the statistics were last updated at'} <b>$status</b></td></tr>
2870         </table>
2871 END
2872 ;       
2873         &Header::closebox();
2874         print "<div align='center'><a href='/cgi-bin/ovpnmain.cgi'>$Lang::tr{'back'}</a></div>";
2875         &Header::closebigbox();
2876         &Header::closepage();
2877         exit(0);
2878
2879 ###
2880 ### Download Certificate
2881 ###
2882 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'download certificate'}) {
2883     &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
2884
2885     if ( -f "${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem") {
2886         print "Content-Disposition: filename=" . $confighash{$cgiparams{'KEY'}}[1] . "cert.pem\r\n";
2887         print "Content-Type: application/octet-stream\r\n\r\n";
2888         print `/bin/cat ${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem`;
2889         exit (0);
2890     }
2891
2892 ###
2893 ### Enable/Disable connection
2894 ###
2895
2896 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'toggle enable disable'}) {
2897     
2898     &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings);
2899     &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
2900
2901     if ($confighash{$cgiparams{'KEY'}}) {
2902            if ($confighash{$cgiparams{'KEY'}}[0] eq 'off') {
2903             $confighash{$cgiparams{'KEY'}}[0] = 'on';
2904             &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
2905             #&writeserverconf();
2906 #           if ($vpnsettings{'ENABLED'} eq 'on' ||
2907 #               $vpnsettings{'ENABLED_BLUE'} eq 'on') {
2908 #               system('/usr/local/bin/ipsecctrl', 'S', $cgiparams{'KEY'});
2909 #           }
2910         } else {
2911             $confighash{$cgiparams{'KEY'}}[0] = 'off';
2912 #           if ($vpnsettings{'ENABLED'} eq 'on' ||
2913 #               $vpnsettings{'ENABLED_BLUE'} eq 'on') {
2914 #               system('/usr/local/bin/ipsecctrl', 'D', $cgiparams{'KEY'});
2915 #           }
2916             &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
2917             #&writeserverconf();
2918         }
2919     } else {
2920         $errormessage = $Lang::tr{'invalid key'};
2921     }
2922
2923 ###
2924 ### Restart connection
2925 ###
2926 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'restart'}) {
2927     &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings);
2928     &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
2929
2930     if ($confighash{$cgiparams{'KEY'}}) {
2931 #       if ($vpnsettings{'ENABLED'} eq 'on' ||
2932 #           $vpnsettings{'ENABLED_BLUE'} eq 'on') {
2933 #           system('/usr/local/bin/ipsecctrl', 'S', $cgiparams{'KEY'});
2934 #       }
2935     } else {
2936         $errormessage = $Lang::tr{'invalid key'};
2937     }
2938
2939 ###
2940 ### Remove connection
2941 ###
2942 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'remove'}) {
2943     &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings);
2944     &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
2945
2946     if ($confighash{$cgiparams{'KEY'}}) {
2947 #       if ($vpnsettings{'ENABLED'} eq 'on' ||
2948 #           $vpnsettings{'ENABLED_BLUE'} eq 'on') {
2949 #           system('/usr/local/bin/ipsecctrl', 'D', $cgiparams{'KEY'});
2950 #       }
2951         unlink ("${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem");
2952         unlink ("${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12");
2953         delete $confighash{$cgiparams{'KEY'}};
2954         &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
2955         #&writeserverconf();
2956     } else {
2957         $errormessage = $Lang::tr{'invalid key'};
2958     }
2959 #test33
2960
2961 ###
2962 ### Choose between adding a host-net or net-net connection
2963 ###
2964
2965 ###
2966 # m.a.d net2net
2967 ###
2968
2969 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'add'} && $cgiparams{'TYPE'} eq '') {
2970         &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings);
2971         &Header::showhttpheaders();
2972         &Header::openpage($Lang::tr{'ovpn'}, 1, '');
2973         &Header::openbigbox('100%', 'LEFT', '', '');
2974         &Header::openbox('100%', 'LEFT', $Lang::tr{'connection type'});
2975
2976 if ( -s "${General::swroot}/ovpn/settings") {
2977
2978         print <<END;
2979             <b>$Lang::tr{'connection type'}:</b><br />
2980             <table border='0' width='100%'><form method='post' ENCTYPE="multipart/form-data">
2981             <tr><td><input type='radio' name='TYPE' value='host' checked /></td>
2982                 <td class='base'>$Lang::tr{'host to net vpn'}</td></tr>
2983             <tr><td><input type='radio' name='TYPE' value='net' /></td>
2984                 <td class='base'>$Lang::tr{'net to net vpn'}</td></tr>
2985                 <tr><td><input type='radio' name='TYPE' value='net2net' /></td>         
2986                 <td class='base'>$Lang::tr{'net to net vpn'} (Upload Client Package)</td></tr>
2987           <tr><td>&nbsp;</td><td class='base'><input type='file' name='FH' size='30'></td></tr>
2988           <tr><td>&nbsp;</td><td>Import Connection Name <img src='/blob.gif' /></td></tr>
2989     <tr><td>&nbsp;</td><td class='base'><input type='text' name='n2nname' size='30'>$Lang::tr{'openvpn default'}: Client Packagename</td></tr>
2990           <tr><td colspan='3'><hr /></td></tr>
2991     <tr><td align='right' colspan='3'><input type='submit' name='ACTION' value='$Lang::tr{'add'}' /></td></tr>
2992           <tr><td class='base' colspan='3' align='left'><img src='/blob.gif' alt='*' />&nbsp;$Lang::tr{'this field may be blank'}</td></tr>
2993             </form></table>
2994 END
2995         ;
2996         
2997
2998 } else {
2999         print <<END;
3000                     <b>$Lang::tr{'connection type'}:</b><br />
3001             <table border='0' width='100%'><form method='post' ENCTYPE="multipart/form-data">
3002             <tr><td><input type='radio' name='TYPE' value='host' checked /></td> <td class='base'>$Lang::tr{'host to net vpn'}</td></tr>
3003             <tr><td align='right' colspan'3'><input type='submit' name='ACTION' value='$Lang::tr{'add'}' /></td></tr>
3004             </form></table>
3005 END
3006         ;
3007
3008 }
3009
3010         &Header::closebox();
3011         print "<div align='center'><a href='/cgi-bin/ovpnmain.cgi'>$Lang::tr{'back'}</a></div>";
3012         &Header::closebigbox();
3013         &Header::closepage();
3014         exit (0);
3015
3016 ###
3017 # m.a.d net2net
3018 ###
3019
3020 }  elsif (($cgiparams{'ACTION'} eq $Lang::tr{'add'}) && ($cgiparams{'TYPE'} eq 'net2net')){
3021
3022         my @firen2nconf;
3023         my @confdetails;
3024         my $uplconffilename ='';
3025         my $uplconffilename2 ='';
3026         my $uplp12name = '';
3027         my $uplp12name2 = '';
3028         my @rem_subnet;
3029         my @rem_subnet2;
3030         my @tmposupnet3;        
3031         my $key;
3032         my @n2nname;
3033
3034         &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);    
3035
3036 # Check if a file is uploaded
3037
3038         if (ref ($cgiparams{'FH'}) ne 'Fh') {
3039                 $errormessage = $Lang::tr{'there was no file upload'};
3040                 goto N2N_ERROR;
3041     }
3042
3043 # Move uploaded IPfire n2n package to temporary file
3044
3045     (my $fh, my $filename) = tempfile( );
3046     if (copy ($cgiparams{'FH'}, $fh) != 1) {
3047                 $errormessage = $!;
3048                 goto N2N_ERROR;
3049     }
3050
3051         my $zip = Archive::Zip->new();
3052         my $zipName = $filename;
3053         my $status = $zip->read( $zipName );
3054         if ($status != AZ_OK) {   
3055                 $errormessage = "Read of $zipName failed\n";
3056                 goto N2N_ERROR;
3057         }
3058
3059         my $tempdir = tempdir( CLEANUP => 1 );
3060         my @files = $zip->memberNames();
3061         for(@files) {
3062         $zip->extractMemberWithoutPaths($_,"$tempdir/$_");
3063         }
3064         my $countfiles = @files;
3065
3066 # Check if we have not more then 2 files
3067
3068         if ( $countfiles == 2){
3069                 foreach (@files){
3070                         if ( $_ =~ /.conf$/){
3071                                 $uplconffilename = $_;
3072                         }
3073                         if ( $_ =~ /.p12$/){
3074                                 $uplp12name = $_;
3075                         }                       
3076                 }
3077                 if (($uplconffilename eq '') || ($uplp12name eq '')){
3078                         $errormessage = "Either no *.conf or no *.p12 file found\n";
3079                         goto N2N_ERROR;
3080                 }
3081
3082                 open(FILE, "$tempdir/$uplconffilename") or die 'Unable to open*.conf file';
3083                 @firen2nconf = <FILE>;
3084                 close (FILE);
3085                 chomp(@firen2nconf);
3086
3087         } else {
3088
3089                 $errormessage = "Filecount does not match only 2 files are allowed\n";
3090                 goto N2N_ERROR;
3091         }
3092
3093 ###
3094 # m.a.d net2net
3095 ###
3096   
3097  if ($cgiparams{'n2nname'} ne ''){
3098
3099   $uplconffilename2 = "$cgiparams{'n2nname'}.conf"; 
3100   $uplp12name2 = "$cgiparams{'n2nname'}.p12"; 
3101   $n2nname[0] = $cgiparams{'n2nname'};
3102   my @n2nname2 = split(/\./,$uplconffilename);
3103   $n2nname2[0] =~ s/\n|\r//g;
3104   my $input1 = "${General::swroot}/ovpn/certs/$uplp12name";
3105         my $output1 = "${General::swroot}/ovpn/certs/$uplp12name2";
3106         my $input2 = "$n2nname2[0]n2n";
3107   my $output2 = "$n2nname[0]n2n";
3108   my $filename = "$tempdir/$uplconffilename";
3109   open(FILE, "< $filename") or die 'Unable to open config file.';
3110         my @current = <FILE>;
3111         close(FILE);
3112         foreach (@current) {s/$input1/$output1/g;}
3113         foreach (@current) {s/$input2/$output2/g;}
3114   open (OUT, "> $filename") || die 'Unable to open config file.';
3115   print OUT @current;
3116   close OUT;
3117
3118     }else{
3119     $uplconffilename2 =  $uplconffilename;
3120     $uplp12name2 = $uplp12name;
3121     @n2nname = split(/\./,$uplconffilename);
3122     $n2nname[0] =~ s/\n|\r//g;
3123    } 
3124     unless(-d "${General::swroot}/ovpn/n2nconf/"){mkdir "${General::swroot}/ovpn/n2nconf", 0755 or die "Unable to create dir $!";}
3125     unless(-d "${General::swroot}/ovpn/n2nconf/$n2nname[0]"){mkdir "${General::swroot}/ovpn/n2nconf/$n2nname[0]", 0770 or die "Unable to create dir $!";}   
3126
3127         move("$tempdir/$uplconffilename", "${General::swroot}/ovpn/n2nconf/$n2nname[0]/$uplconffilename2");
3128
3129         if ($? ne 0) {
3130             $errormessage = "*.conf move failed: $!";
3131             unlink ($filename);
3132             goto N2N_ERROR;
3133         }
3134         
3135         move("$tempdir/$uplp12name", "${General::swroot}/ovpn/certs/$uplp12name2");
3136         chmod 0600, "${General::swroot}/ovpn/certs/$uplp12name";
3137         
3138         if ($? ne 0) {
3139             $errormessage = "$Lang::tr{'certificate file move failed'}: $!";
3140             unlink ($filename);
3141             goto N2N_ERROR;
3142         }       
3143         
3144 my $complzoactive;
3145 my $mssfixactive;
3146 my $authactive;
3147 my $n2nfragment;
3148 my $authactive;
3149 my @n2nmtudisc = split(/ /, (grep { /^mtu-disc/ } @firen2nconf)[0]);
3150 my @n2nproto2 = split(/ /, (grep { /^proto/ } @firen2nconf)[0]);
3151 my @n2nproto = split(/-/, $n2nproto2[1]);
3152 my @n2nport = split(/ /, (grep { /^port/ } @firen2nconf)[0]);
3153 my @n2ntunmtu = split(/ /, (grep { /^tun-mtu/ } @firen2nconf)[0]);
3154 my @n2ncomplzo = grep { /^comp-lzo/ } @firen2nconf;
3155 if ($n2ncomplzo[0] =~ /comp-lzo/){$complzoactive = "on";} else {$complzoactive = "off";}        
3156 my @n2nmssfix  = grep { /^mssfix/ } @firen2nconf;
3157 if ($n2nmssfix[0] =~ /mssfix/){$mssfixactive = "on";} else {$mssfixactive = "off";}
3158 #my @n2nmssfix = split(/ /, (grep { /^mssfix/ } @firen2nconf)[0]);
3159 my @n2nfragment = split(/ /, (grep { /^fragment/ } @firen2nconf)[0]);
3160 my @n2nremote = split(/ /, (grep { /^remote/ } @firen2nconf)[0]);
3161 my @n2novpnsuball = split(/ /, (grep { /^ifconfig/ } @firen2nconf)[0]);
3162 my @n2novpnsub =  split(/\./,$n2novpnsuball[1]);
3163 my @n2nremsub = split(/ /, (grep { /^route/ } @firen2nconf)[0]);
3164 my @n2nmgmt =  split(/ /, (grep { /^management/ } @firen2nconf)[0]);
3165 my @n2nlocalsub  = split(/ /, (grep { /^# remsub/ } @firen2nconf)[0]);
3166 my @n2ncipher = split(/ /, (grep { /^cipher/ } @firen2nconf)[0]);
3167 my @n2nauth = split(/ /, (grep { /^auth/ } @firen2nconf)[0]);;
3168
3169 ###
3170 # m.a.d delete CR and LF from arrays for this chomp doesnt work
3171 ###
3172
3173 $n2nremote[1] =~ s/\n|\r//g;
3174 $n2novpnsub[0] =~ s/\n|\r//g;
3175 $n2novpnsub[1] =~ s/\n|\r//g;
3176 $n2novpnsub[2] =~ s/\n|\r//g;
3177 $n2nproto[0] =~ s/\n|\r//g;
3178 $n2nport[1] =~ s/\n|\r//g;
3179 $n2ntunmtu[1] =~ s/\n|\r//g;
3180 $n2nremsub[1] =~ s/\n|\r//g;
3181 $n2nremsub[2] =~ s/\n|\r//g;
3182 $n2nlocalsub[2] =~ s/\n|\r//g;
3183 $n2nfragment[1] =~ s/\n|\r//g;
3184 $n2nmgmt[2] =~ s/\n|\r//g;
3185 $n2nmtudisc[1] =~ s/\n|\r//g;
3186 $n2ncipher[1] =~ s/\n|\r//g;
3187 $n2nauth[1] =~ s/\n|\r//g;
3188 chomp ($complzoactive);
3189 chomp ($mssfixactive);
3190
3191 ###
3192 # m.a.d net2net
3193 ###
3194
3195 ###
3196 # Check if there is no other entry with this name
3197 ###
3198
3199         foreach my $dkey (keys %confighash) {
3200                 if ($confighash{$dkey}[1] eq $n2nname[0]) {
3201                         $errormessage = $Lang::tr{'a connection with this name already exists'};
3202                         unlink ("${General::swroot}/ovpn/n2nconf/$n2nname[0]/$n2nname[0].conf") or die "Removing Configfile fail: $!";
3203             unlink ("${General::swroot}/ovpn/certs/$n2nname[0].p12") or die "Removing Certfile fail: $!";
3204       rmdir ("${General::swroot}/ovpn/n2nconf/$n2nname[0]") || die "Removing Directory fail: $!";
3205                         goto N2N_ERROR;                 
3206                 }
3207         }
3208
3209 ###
3210 # Check if OpenVPN Subnet is valid
3211 ###
3212
3213 foreach my $dkey (keys %confighash) {
3214                 if ($confighash{$dkey}[27] eq "$n2novpnsub[0].$n2novpnsub[1].$n2novpnsub[2].0/255.255.255.0") {
3215                         $errormessage = 'The OpenVPN Subnet is already in use';
3216                         unlink ("${General::swroot}/ovpn/n2nconf/$n2nname[0]/$n2nname[0].conf") or die "Removing Configfile fail: $!";
3217             unlink ("${General::swroot}/ovpn/certs/$n2nname[0].p12") or die "Removing Certfile fail: $!";
3218       rmdir ("${General::swroot}/ovpn/n2nconf/$n2nname[0]") || die "Removing Directory fail: $!";
3219                         goto N2N_ERROR;                 
3220                 }
3221         }
3222
3223 ###
3224 # Check if Dest Port is vaild
3225 ###
3226
3227 foreach my $dkey (keys %confighash) {
3228                 if ($confighash{$dkey}[29] eq $n2nport[1] ) {
3229                         $errormessage = 'The OpenVPN Port is already in use';
3230                         unlink ("${General::swroot}/ovpn/n2nconf/$n2nname[0]/$n2nname[0].conf") or die "Removing Configfile fail: $!";
3231             unlink ("${General::swroot}/ovpn/certs/$n2nname[0].p12") or die "Removing Certfile fail: $!";
3232       rmdir ("${General::swroot}/ovpn/n2nconf/$n2nname[0]") || die "Removing Directory fail: $!";
3233                         goto N2N_ERROR;                 
3234                 }
3235         }
3236         
3237         
3238         
3239   $key = &General::findhasharraykey (\%confighash);
3240
3241         foreach my $i (0 .. 42) { $confighash{$key}[$i] = "";}
3242
3243         $confighash{$key}[0] = 'off';
3244         $confighash{$key}[1] = $n2nname[0];
3245         $confighash{$key}[2] = $n2nname[0];     
3246         $confighash{$key}[3] = 'net';
3247         $confighash{$key}[4] = 'cert';  
3248         $confighash{$key}[6] = 'client';                
3249         $confighash{$key}[8] =  $n2nlocalsub[2];
3250         $confighash{$key}[10] = $n2nremote[1];
3251         $confighash{$key}[11] = "$n2nremsub[1]/$n2nremsub[2]";          
3252         $confighash{$key}[22] = $n2nmgmt[2];
3253         $confighash{$key}[23] = $mssfixactive;
3254         $confighash{$key}[24] = $n2nfragment[1];
3255         $confighash{$key}[25] = 'IPFire n2n Client';
3256         $confighash{$key}[26] = 'red';
3257         $confighash{$key}[27] = "$n2novpnsub[0].$n2novpnsub[1].$n2novpnsub[2].0/255.255.255.0";
3258         $confighash{$key}[28] = $n2nproto[0];
3259         $confighash{$key}[29] = $n2nport[1];
3260         $confighash{$key}[30] = $complzoactive;
3261         $confighash{$key}[31] = $n2ntunmtu[1];
3262         $confighash{$key}[38] = $n2nmtudisc[1];
3263         $confighash{$key}[39] = $n2nauth[1];
3264         $confighash{$key}[40] = $n2ncipher[1];
3265         $confighash{$key}[41] = 'disabled';
3266
3267   &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
3268  
3269   N2N_ERROR:
3270                 
3271         &Header::showhttpheaders();
3272         &Header::openpage('Validate imported configuration', 1, '');
3273         &Header::openbigbox('100%', 'LEFT', '', $errormessage);
3274         if ($errormessage) {
3275             &Header::openbox('100%', 'LEFT', $Lang::tr{'error messages'});
3276             print "<class name='base'>$errormessage";
3277             print "&nbsp;</class>";
3278             &Header::closebox();                
3279
3280         } else 
3281   {             
3282                 &Header::openbox('100%', 'LEFT', 'import ipfire net2net config');
3283         }
3284         if ($errormessage eq ''){
3285         print <<END;
3286                 <!-- ipfire net2net config gui -->
3287                 <table width='100%'>
3288                 <tr><td width='25%'>&nbsp;</td><td width='25%'>&nbsp;</td></tr>
3289     <tr><td class='boldbase'>$Lang::tr{'name'}:</td><td><b>$n2nname[0]</b></td></tr>
3290     <tr><td>&nbsp;</td><td>&nbsp;</td></tr>