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