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