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