]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - html/cgi-bin/ovpnmain.cgi
kernel: update to 2.6.32.42.
[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 } elsif (($cgiparams{'ACTION'} eq $Lang::tr{'add'}) ||
1866 ($cgiparams{'ACTION'} eq $Lang::tr{'edit'}) ||
1867 ($cgiparams{'ACTION'} eq $Lang::tr{'save'} && $cgiparams{'ADVANCED'} eq '')) {
1868
1869 &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings);
1870 &General::readhasharray("${General::swroot}/ovpn/caconfig", \%cahash);
1871 &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
1872
1873 if ($cgiparams{'ACTION'} eq $Lang::tr{'edit'}) {
1874 if (! $confighash{$cgiparams{'KEY'}}[0]) {
1875 $errormessage = $Lang::tr{'invalid key'};
1876 goto VPNCONF_END;
1877 }
1878
1879 $cgiparams{'ENABLED'} = $confighash{$cgiparams{'KEY'}}[0];
1880 $cgiparams{'NAME'} = $confighash{$cgiparams{'KEY'}}[1];
1881 $cgiparams{'TYPE'} = 'host';
1882 $cgiparams{'AUTH'} = $confighash{$cgiparams{'KEY'}}[4];
1883 $cgiparams{'PSK'} = $confighash{$cgiparams{'KEY'}}[5];
1884 $cgiparams{'SIDE'} = $confighash{$cgiparams{'KEY'}}[6];
1885 $cgiparams{'LOCAL_SUBNET'} = $confighash{$cgiparams{'KEY'}}[8];
1886 $cgiparams{'REMOTE'} = $confighash{$cgiparams{'KEY'}}[10];
1887 $cgiparams{'REMOTE_SUBNET'} = $confighash{$cgiparams{'KEY'}}[11];
1888 $cgiparams{'REMARK'} = $confighash{$cgiparams{'KEY'}}[25];
1889 $cgiparams{'INTERFACE'} = $confighash{$cgiparams{'KEY'}}[26];
1890 #new fields
1891 $cgiparams{'OVPN_SUBNET'} = $confighash{$cgiparams{'KEY'}}[27];
1892 $cgiparams{'PROTOCOL'} = $confighash{$cgiparams{'KEY'}}[28];
1893 $cgiparams{'DEST_PORT'} = $confighash{$cgiparams{'KEY'}}[29];
1894 $cgiparams{'COMPLZO'} = $confighash{$cgiparams{'KEY'}}[30];
1895 $cgiparams{'MTU'} = $confighash{$cgiparams{'KEY'}}[31];
1896 #new fields
1897 #ab hiere error uebernehmen
1898 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'save'}) {
1899 $cgiparams{'REMARK'} = &Header::cleanhtml($cgiparams{'REMARK'});
1900 if ($cgiparams{'TYPE'} !~ /^(host|net)$/) {
1901 $errormessage = $Lang::tr{'connection type is invalid'};
1902 goto VPNCONF_ERROR;
1903 }
1904
1905
1906 if ($cgiparams{'NAME'} !~ /^[a-zA-Z0-9]+$/) {
1907 $errormessage = $Lang::tr{'name must only contain characters'};
1908 goto VPNCONF_ERROR;
1909 }
1910
1911 if ($cgiparams{'NAME'} =~ /^(host|01|block|private|clear|packetdefault)$/) {
1912 $errormessage = $Lang::tr{'name is invalid'};
1913 goto VPNCONF_ERROR;
1914 }
1915
1916 if (length($cgiparams{'NAME'}) >60) {
1917 $errormessage = $Lang::tr{'name too long'};
1918 goto VPNCONF_ERROR;
1919 }
1920
1921 # Check if there is no other entry with this name
1922 if (! $cgiparams{'KEY'}) {
1923 foreach my $key (keys %confighash) {
1924 if ($confighash{$key}[1] eq $cgiparams{'NAME'}) {
1925 $errormessage = $Lang::tr{'a connection with this name already exists'};
1926 goto VPNCONF_ERROR;
1927 }
1928 }
1929 }
1930
1931 if ($cgiparams{'REMOTE'}) {
1932 if (! &General::validip($cgiparams{'REMOTE'})) {
1933 if (! &General::validfqdn ($cgiparams{'REMOTE'})) {
1934 $errormessage = $Lang::tr{'invalid input for remote host/ip'};
1935 goto VPNCONF_ERROR;
1936 } else {
1937 if (&valid_dns_host($cgiparams{'REMOTE'})) {
1938 $warnmessage = "$Lang::tr{'check vpn lr'} $cgiparams{'REMOTE'}. $Lang::tr{'dns check failed'}";
1939 }
1940 }
1941 }
1942 }
1943 if ($cgiparams{'TYPE'} ne 'host') {
1944 unless (&General::validipandmask($cgiparams{'LOCAL_SUBNET'})) {
1945 $errormessage = $Lang::tr{'local subnet is invalid'};
1946 goto VPNCONF_ERROR;}
1947 }
1948 # Check if there is no other entry without IP-address and PSK
1949 if ($cgiparams{'REMOTE'} eq '') {
1950 foreach my $key (keys %confighash) {
1951 if(($cgiparams{'KEY'} ne $key) &&
1952 ($confighash{$key}[4] eq 'psk' || $cgiparams{'AUTH'} eq 'psk') &&
1953 $confighash{$key}[10] eq '') {
1954 $errormessage = $Lang::tr{'you can only define one roadwarrior connection when using pre-shared key authentication'};
1955 goto VPNCONF_ERROR;
1956 }
1957 }
1958 }
1959
1960 if ($cgiparams{'ENABLED'} !~ /^(on|off)$/) {
1961 $errormessage = $Lang::tr{'invalid input'};
1962 goto VPNCONF_ERROR;
1963 }
1964 if ($cgiparams{'EDIT_ADVANCED'} !~ /^(on|off)$/) {
1965 $errormessage = $Lang::tr{'invalid input'};
1966 goto VPNCONF_ERROR;
1967 }
1968
1969 #fixplausi
1970 if ($cgiparams{'AUTH'} eq 'psk') {
1971 # if (! length($cgiparams{'PSK'}) ) {
1972 # $errormessage = $Lang::tr{'pre-shared key is too short'};
1973 # goto VPNCONF_ERROR;
1974 # }
1975 # if ($cgiparams{'PSK'} =~ /['",&]/) {
1976 # $errormessage = $Lang::tr{'invalid characters found in pre-shared key'};
1977 # goto VPNCONF_ERROR;
1978 # }
1979 } elsif ($cgiparams{'AUTH'} eq 'certreq') {
1980 if ($cgiparams{'KEY'}) {
1981 $errormessage = $Lang::tr{'cant change certificates'};
1982 goto VPNCONF_ERROR;
1983 }
1984 if (ref ($cgiparams{'FH'}) ne 'Fh') {
1985 $errormessage = $Lang::tr{'there was no file upload'};
1986 goto VPNCONF_ERROR;
1987 }
1988
1989 # Move uploaded certificate request to a temporary file
1990 (my $fh, my $filename) = tempfile( );
1991 if (copy ($cgiparams{'FH'}, $fh) != 1) {
1992 $errormessage = $!;
1993 goto VPNCONF_ERROR;
1994 }
1995
1996 # Sign the certificate request and move it
1997 # Sign the host certificate request
1998 system('/usr/bin/openssl', 'ca', '-days', '999999',
1999 '-batch', '-notext',
2000 '-in', $filename,
2001 '-out', "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem",
2002 '-config',"${General::swroot}/ovpn/openssl/ovpn.cnf");
2003 if ($?) {
2004 $errormessage = "$Lang::tr{'openssl produced an error'}: $?";
2005 unlink ($filename);
2006 unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem");
2007 &newcleanssldatabase();
2008 goto VPNCONF_ERROR;
2009 } else {
2010 unlink ($filename);
2011 &deletebackupcert();
2012 }
2013
2014 my $temp = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem`;
2015 $temp =~ /Subject:.*CN=(.*)[\n]/;
2016 $temp = $1;
2017 $temp =~ s+/Email+, E+;
2018 $temp =~ s/ ST=/ S=/;
2019 $cgiparams{'CERT_NAME'} = $temp;
2020 $cgiparams{'CERT_NAME'} =~ s/,//g;
2021 $cgiparams{'CERT_NAME'} =~ s/\'//g;
2022 if ($cgiparams{'CERT_NAME'} eq '') {
2023 $errormessage = $Lang::tr{'could not retrieve common name from certificate'};
2024 goto VPNCONF_ERROR;
2025 }
2026 } elsif ($cgiparams{'AUTH'} eq 'certfile') {
2027 if ($cgiparams{'KEY'}) {
2028 $errormessage = $Lang::tr{'cant change certificates'};
2029 goto VPNCONF_ERROR;
2030 }
2031 if (ref ($cgiparams{'FH'}) ne 'Fh') {
2032 $errormessage = $Lang::tr{'there was no file upload'};
2033 goto VPNCONF_ERROR;
2034 }
2035 # Move uploaded certificate to a temporary file
2036 (my $fh, my $filename) = tempfile( );
2037 if (copy ($cgiparams{'FH'}, $fh) != 1) {
2038 $errormessage = $!;
2039 goto VPNCONF_ERROR;
2040 }
2041
2042 # Verify the certificate has a valid CA and move it
2043 my $validca = 0;
2044 my $test = `/usr/bin/openssl verify -CAfile ${General::swroot}/ovpn/ca/cacert.pem $filename`;
2045 if ($test =~ /: OK/) {
2046 $validca = 1;
2047 } else {
2048 foreach my $key (keys %cahash) {
2049 $test = `/usr/bin/openssl verify -CAfile ${General::swroot}/ovpn/ca/$cahash{$key}[0]cert.pem $filename`;
2050 if ($test =~ /: OK/) {
2051 $validca = 1;
2052 }
2053 }
2054 }
2055 if (! $validca) {
2056 $errormessage = $Lang::tr{'certificate does not have a valid ca associated with it'};
2057 unlink ($filename);
2058 goto VPNCONF_ERROR;
2059 } else {
2060 move($filename, "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem");
2061 if ($? ne 0) {
2062 $errormessage = "$Lang::tr{'certificate file move failed'}: $!";
2063 unlink ($filename);
2064 goto VPNCONF_ERROR;
2065 }
2066 }
2067
2068 my $temp = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem`;
2069 $temp =~ /Subject:.*CN=(.*)[\n]/;
2070 $temp = $1;
2071 $temp =~ s+/Email+, E+;
2072 $temp =~ s/ ST=/ S=/;
2073 $cgiparams{'CERT_NAME'} = $temp;
2074 $cgiparams{'CERT_NAME'} =~ s/,//g;
2075 $cgiparams{'CERT_NAME'} =~ s/\'//g;
2076 if ($cgiparams{'CERT_NAME'} eq '') {
2077 unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem");
2078 $errormessage = $Lang::tr{'could not retrieve common name from certificate'};
2079 goto VPNCONF_ERROR;
2080 }
2081 } elsif ($cgiparams{'AUTH'} eq 'certgen') {
2082
2083 $cgiparams{'CERT_NAME'} =~ s/ //g;
2084
2085 if ($cgiparams{'KEY'}) {
2086 $errormessage = $Lang::tr{'cant change certificates'};
2087 goto VPNCONF_ERROR;
2088 }
2089 # Validate input since the form was submitted
2090 if (length($cgiparams{'CERT_NAME'}) >60) {
2091 $errormessage = $Lang::tr{'name too long'};
2092 goto VPNCONF_ERROR;
2093 }
2094 if ($cgiparams{'CERT_NAME'} !~ /^[a-zA-Z0-9 ,\.\-_]+$/) {
2095 $errormessage = $Lang::tr{'invalid input for name'};
2096 goto VPNCONF_ERROR;
2097 }
2098 if ($cgiparams{'CERT_EMAIL'} ne '' && (! &General::validemail($cgiparams{'CERT_EMAIL'}))) {
2099 $errormessage = $Lang::tr{'invalid input for e-mail address'};
2100 goto VPNCONF_ERROR;
2101 }
2102 if (length($cgiparams{'CERT_EMAIL'}) > 40) {
2103 $errormessage = $Lang::tr{'e-mail address too long'};
2104 goto VPNCONF_ERROR;
2105 }
2106 if ($cgiparams{'CERT_OU'} ne '' && $cgiparams{'CERT_OU'} !~ /^[a-zA-Z0-9 ,\.\-_]*$/) {
2107 $errormessage = $Lang::tr{'invalid input for department'};
2108 goto VPNCONF_ERROR;
2109 }
2110 if (length($cgiparams{'CERT_ORGANIZATION'}) >60) {
2111 $errormessage = $Lang::tr{'organization too long'};
2112 goto VPNCONF_ERROR;
2113 }
2114 if ($cgiparams{'CERT_ORGANIZATION'} !~ /^[a-zA-Z0-9 ,\.\-_]+$/) {
2115 $errormessage = $Lang::tr{'invalid input for organization'};
2116 goto VPNCONF_ERROR;
2117 }
2118 if ($cgiparams{'CERT_CITY'} ne '' && $cgiparams{'CERT_CITY'} !~ /^[a-zA-Z0-9 ,\.\-_]*$/) {
2119 $errormessage = $Lang::tr{'invalid input for city'};
2120 goto VPNCONF_ERROR;
2121 }
2122 if ($cgiparams{'CERT_STATE'} ne '' && $cgiparams{'CERT_STATE'} !~ /^[a-zA-Z0-9 ,\.\-_]*$/) {
2123 $errormessage = $Lang::tr{'invalid input for state or province'};
2124 goto VPNCONF_ERROR;
2125 }
2126 if ($cgiparams{'CERT_COUNTRY'} !~ /^[A-Z]*$/) {
2127 $errormessage = $Lang::tr{'invalid input for country'};
2128 goto VPNCONF_ERROR;
2129 }
2130 if ($cgiparams{'CERT_PASS1'} ne '' && $cgiparams{'CERT_PASS2'} ne ''){
2131 if (length($cgiparams{'CERT_PASS1'}) < 5) {
2132 $errormessage = $Lang::tr{'password too short'};
2133 goto VPNCONF_ERROR;
2134 }
2135 }
2136 if ($cgiparams{'CERT_PASS1'} ne $cgiparams{'CERT_PASS2'}) {
2137 $errormessage = $Lang::tr{'passwords do not match'};
2138 goto VPNCONF_ERROR;
2139 }
2140
2141 # Replace empty strings with a .
2142 (my $ou = $cgiparams{'CERT_OU'}) =~ s/^\s*$/\./;
2143 (my $city = $cgiparams{'CERT_CITY'}) =~ s/^\s*$/\./;
2144 (my $state = $cgiparams{'CERT_STATE'}) =~ s/^\s*$/\./;
2145
2146 # Create the Host certificate request client
2147 my $pid = open(OPENSSL, "|-");
2148 $SIG{ALRM} = sub { $errormessage = $Lang::tr{'broken pipe'}; goto VPNCONF_ERROR;};
2149 if ($pid) { # parent
2150 print OPENSSL "$cgiparams{'CERT_COUNTRY'}\n";
2151 print OPENSSL "$state\n";
2152 print OPENSSL "$city\n";
2153 print OPENSSL "$cgiparams{'CERT_ORGANIZATION'}\n";
2154 print OPENSSL "$ou\n";
2155 print OPENSSL "$cgiparams{'CERT_NAME'}\n";
2156 print OPENSSL "$cgiparams{'CERT_EMAIL'}\n";
2157 print OPENSSL ".\n";
2158 print OPENSSL ".\n";
2159 close (OPENSSL);
2160 if ($?) {
2161 $errormessage = "$Lang::tr{'openssl produced an error'}: $?";
2162 unlink ("${General::swroot}ovpn/certs/$cgiparams{'NAME'}key.pem");
2163 unlink ("${General::swroot}ovpn/certs/$cgiparams{'NAME'}req.pem");
2164 goto VPNCONF_ERROR;
2165 }
2166 } else { # child
2167 unless (exec ('/usr/bin/openssl', 'req', '-nodes', '-rand', '/proc/interrupts:/proc/net/rt_cache',
2168 '-newkey', 'rsa:1024',
2169 '-keyout', "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}key.pem",
2170 '-out', "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}req.pem",
2171 '-config',"${General::swroot}/ovpn/openssl/ovpn.cnf")) {
2172 $errormessage = "$Lang::tr{'cant start openssl'}: $!";
2173 unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}key.pem");
2174 unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}req.pem");
2175 goto VPNCONF_ERROR;
2176 }
2177 }
2178
2179 # Sign the host certificate request
2180 system('/usr/bin/openssl', 'ca', '-days', '999999',
2181 '-batch', '-notext',
2182 '-in', "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}req.pem",
2183 '-out', "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem",
2184 '-config',"${General::swroot}/ovpn/openssl/ovpn.cnf");
2185 if ($?) {
2186 $errormessage = "$Lang::tr{'openssl produced an error'}: $?";
2187 unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}key.pem");
2188 unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}req.pem");
2189 unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem");
2190 &newcleanssldatabase();
2191 goto VPNCONF_ERROR;
2192 } else {
2193 unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}req.pem");
2194 &deletebackupcert();
2195 }
2196
2197 # Create the pkcs12 file
2198 system('/usr/bin/openssl', 'pkcs12', '-export',
2199 '-inkey', "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}key.pem",
2200 '-in', "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem",
2201 '-name', $cgiparams{'NAME'},
2202 '-passout', "pass:$cgiparams{'CERT_PASS1'}",
2203 '-certfile', "${General::swroot}/ovpn/ca/cacert.pem",
2204 '-caname', "$vpnsettings{'ROOTCERT_ORGANIZATION'} CA",
2205 '-out', "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}.p12");
2206 if ($?) {
2207 $errormessage = "$Lang::tr{'openssl produced an error'}: $?";
2208 unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}key.pem");
2209 unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem");
2210 unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}.p12");
2211 goto VPNCONF_ERROR;
2212 } else {
2213 unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}key.pem");
2214 }
2215 } elsif ($cgiparams{'AUTH'} eq 'cert') {
2216 ;# Nothing, just editing
2217 } else {
2218 $errormessage = $Lang::tr{'invalid input for authentication method'};
2219 goto VPNCONF_ERROR;
2220 }
2221
2222 # Check if there is no other entry with this common name
2223 if ((! $cgiparams{'KEY'}) && ($cgiparams{'AUTH'} ne 'psk')) {
2224 foreach my $key (keys %confighash) {
2225 if ($confighash{$key}[2] eq $cgiparams{'CERT_NAME'}) {
2226 $errormessage = $Lang::tr{'a connection with this common name already exists'};
2227 goto VPNCONF_ERROR;
2228 }
2229 }
2230 }
2231
2232 # Save the config
2233 my $key = $cgiparams{'KEY'};
2234 if (! $key) {
2235 $key = &General::findhasharraykey (\%confighash);
2236 foreach my $i (0 .. 31) { $confighash{$key}[$i] = "";}
2237 }
2238 $confighash{$key}[0] = $cgiparams{'ENABLED'};
2239 $confighash{$key}[1] = $cgiparams{'NAME'};
2240 if ((! $cgiparams{'KEY'}) && $cgiparams{'AUTH'} ne 'psk') {
2241 $confighash{$key}[2] = $cgiparams{'CERT_NAME'};
2242 }
2243 $confighash{$key}[3] = 'host';
2244 if ($cgiparams{'AUTH'} eq 'psk') {
2245 $confighash{$key}[4] = 'psk';
2246 $confighash{$key}[5] = $cgiparams{'PSK'};
2247 } else {
2248 $confighash{$key}[4] = 'cert';
2249 }
2250 $confighash{$key}[8] = $cgiparams{'LOCAL_SUBNET'};
2251 $confighash{$key}[10] = $cgiparams{'REMOTE'};
2252 $confighash{$key}[25] = $cgiparams{'REMARK'};
2253 $confighash{$key}[26] = $cgiparams{'INTERFACE'};
2254 # new fields
2255 $confighash{$key}[27] = $cgiparams{'OVPN_SUBNET'};
2256 $confighash{$key}[28] = $cgiparams{'PROTOCOL'};
2257 $confighash{$key}[29] = $cgiparams{'DEST_PORT'};
2258 $confighash{$key}[30] = $cgiparams{'COMPLZO'};
2259 $confighash{$key}[31] = $cgiparams{'MTU'};
2260 # new fileds
2261 &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
2262 if ($cgiparams{'EDIT_ADVANCED'} eq 'on') {
2263 $cgiparams{'KEY'} = $key;
2264 $cgiparams{'ACTION'} = $Lang::tr{'advanced'};
2265 }
2266 goto VPNCONF_END;
2267 } else {
2268 $cgiparams{'ENABLED'} = 'on';
2269 $cgiparams{'SIDE'} = 'left';
2270 if ( ! -f "${General::swroot}/ovpn/ca/cakey.pem" ) {
2271 $cgiparams{'AUTH'} = 'psk';
2272 } elsif ( ! -f "${General::swroot}/ovpn/ca/cacert.pem") {
2273 $cgiparams{'AUTH'} = 'certfile';
2274 } else {
2275 $cgiparams{'AUTH'} = 'certgen';
2276 }
2277 $cgiparams{'LOCAL_SUBNET'} ="$netsettings{'GREEN_NETADDRESS'}/$netsettings{'GREEN_NETMASK'}";
2278 $cgiparams{'CERT_ORGANIZATION'} = $vpnsettings{'ROOTCERT_ORGANIZATION'};
2279 $cgiparams{'CERT_CITY'} = $vpnsettings{'ROOTCERT_CITY'};
2280 $cgiparams{'CERT_STATE'} = $vpnsettings{'ROOTCERT_STATE'};
2281 $cgiparams{'CERT_COUNTRY'} = $vpnsettings{'ROOTCERT_COUNTRY'};
2282 }
2283
2284 VPNCONF_ERROR:
2285 $checked{'ENABLED'}{'off'} = '';
2286 $checked{'ENABLED'}{'on'} = '';
2287 $checked{'ENABLED'}{$cgiparams{'ENABLED'}} = 'CHECKED';
2288 $checked{'ENABLED_BLUE'}{'off'} = '';
2289 $checked{'ENABLED_BLUE'}{'on'} = '';
2290 $checked{'ENABLED_BLUE'}{$cgiparams{'ENABLED_BLUE'}} = 'CHECKED';
2291 $checked{'ENABLED_ORANGE'}{'off'} = '';
2292 $checked{'ENABLED_ORANGE'}{'on'} = '';
2293 $checked{'ENABLED_ORANGE'}{$cgiparams{'ENABLED_ORANGE'}} = 'CHECKED';
2294
2295
2296 $checked{'EDIT_ADVANCED'}{'off'} = '';
2297 $checked{'EDIT_ADVANCED'}{'on'} = '';
2298 $checked{'EDIT_ADVANCED'}{$cgiparams{'EDIT_ADVANCED'}} = 'CHECKED';
2299
2300 $selected{'SIDE'}{'server'} = '';
2301 $selected{'SIDE'}{'client'} = '';
2302 $selected{'SIDE'}{$cgiparams{'SIDE'}} = 'SELECTED';
2303
2304 $checked{'AUTH'}{'psk'} = '';
2305 $checked{'AUTH'}{'certreq'} = '';
2306 $checked{'AUTH'}{'certgen'} = '';
2307 $checked{'AUTH'}{'certfile'} = '';
2308 $checked{'AUTH'}{$cgiparams{'AUTH'}} = 'CHECKED';
2309
2310 $selected{'INTERFACE'}{$cgiparams{'INTERFACE'}} = 'SELECTED';
2311
2312 $checked{'COMPLZO'}{'off'} = '';
2313 $checked{'COMPLZO'}{'on'} = '';
2314 $checked{'COMPLZO'}{$cgiparams{'COMPLZO'}} = 'CHECKED';
2315
2316
2317 if (1) {
2318 &Header::showhttpheaders();
2319 &Header::openpage($Lang::tr{'vpn configuration main'}, 1, '');
2320 &Header::openbigbox('100%', 'LEFT', '', $errormessage);
2321 if ($errormessage) {
2322 &Header::openbox('100%', 'LEFT', $Lang::tr{'error messages'});
2323 print "<class name='base'>$errormessage";
2324 print "&nbsp;</class>";
2325 &Header::closebox();
2326 }
2327
2328 if ($warnmessage) {
2329 &Header::openbox('100%', 'LEFT', "$Lang::tr{'warning messages'}:");
2330 print "<class name='base'>$warnmessage";
2331 print "&nbsp;</class>";
2332 &Header::closebox();
2333 }
2334
2335 print "<form method='post' enctype='multipart/form-data'>";
2336 print "<input type='hidden' name='TYPE' value='host' />";
2337
2338 if ($cgiparams{'KEY'}) {
2339 print "<input type='hidden' name='KEY' value='$cgiparams{'KEY'}' />";
2340 print "<input type='hidden' name='AUTH' value='$cgiparams{'AUTH'}' />";
2341 }
2342
2343 &Header::openbox('100%', 'LEFT', "$Lang::tr{'connection'}:");
2344 print "<table width='100%'>\n";
2345 print "<tr><td width='25%' class='boldbase'>$Lang::tr{'name'}:</td>";
2346 if ($cgiparams{'KEY'}) {
2347 print "<td width='35%' class='base'><input type='hidden' name='NAME' value='$cgiparams{'NAME'}' />$cgiparams{'NAME'}</td>\n";
2348 } else {
2349 print "<td width='35%'><input type='text' name='NAME' value='$cgiparams{'NAME'}' maxlength='20' size='30' /></td>";
2350 }
2351 # print "<tr><td>$Lang::tr{'interface'}</td>";
2352 # print "<td><select name='INTERFACE'>";
2353 # print "<option value='RED' $selected{'INTERFACE'}{'RED'}>RED</option>";
2354 # if ($netsettings{'BLUE_DEV'} ne '') {
2355 # print "<option value='BLUE' $selected{'INTERFACE'}{'BLUE'}>BLUE</option>";
2356 # }
2357 # print "<option value='GREEN' $selected{'INTERFACE'}{'GREEN'}>GREEN</option>";
2358 # print "<option value='ORANGE' $selected{'INTERFACE'}{'ORANGE'}>ORANGE</option>";
2359 # print "</select></td></tr>";
2360 # print <<END
2361 print "<tr><td class='boldbase'>$Lang::tr{'remark title'}&nbsp;<img src='/blob.gif' /></td>";
2362 print "<td colspan='3'><input type='text' name='REMARK' value='$cgiparams{'REMARK'}' size='55' maxlength='50' /></td></tr>";
2363
2364 # if ($cgiparams{'TYPE'} eq 'net') {
2365 print "<tr><td>$Lang::tr{'enabled'} <input type='checkbox' name='ENABLED' $checked{'ENABLED'}{'on'} /></td>\n";
2366
2367 # if ($cgiparams{'KEY'}) {
2368 # print "<td colspan='3'>&nbsp;</td></tr></table>";
2369 # } else {
2370 # print "<td colspan='3'><input type='checkbox' name='EDIT_ADVANCED' $checked{'EDIT_ADVANCED'}{'on'} /> $Lang::tr{'edit advanced settings when done'}</tr></table>";
2371 # }
2372 # }else{
2373 print "<td colspan='3'>&nbsp;</td></tr></table>";
2374 # }
2375
2376
2377
2378 &Header::closebox();
2379
2380 if ($cgiparams{'KEY'} && $cgiparams{'AUTH'} eq 'psk') {
2381 # &Header::openbox('100%', 'LEFT', $Lang::tr{'authentication'});
2382 # print <<END
2383 # <table width='100%' cellpadding='0' cellspacing='5' border='0'>
2384 # <tr><td class='base' width='50%'>$Lang::tr{'use a pre-shared key'}</td>
2385 # <td class='base' width='50%'><input type='text' name='PSK' size='30' value='$cgiparams{'PSK'}' /></td></tr>
2386 # </table>
2387 END
2388 # ;
2389 # &Header::closebox();
2390 } elsif (! $cgiparams{'KEY'}) {
2391 my $disabled='';
2392 my $cakeydisabled='';
2393 my $cacrtdisabled='';
2394 if ( ! -f "${General::swroot}/ovpn/ca/cakey.pem" ) { $cakeydisabled = "disabled='disabled'" } else { $cakeydisabled = "" };
2395 if ( ! -f "${General::swroot}/ovpn/ca/cacert.pem" ) { $cacrtdisabled = "disabled='disabled'" } else { $cacrtdisabled = "" };
2396 &Header::openbox('100%', 'LEFT', $Lang::tr{'authentication'});
2397 print <<END
2398 <table width='100%' cellpadding='0' cellspacing='5' border='0'>
2399 <tr><td colspan='3' bgcolor='#000000'><img src='/images/null.gif' width='1' height='1' border='0' /></td></tr>
2400 <tr><td><input type='radio' name='AUTH' value='certreq' $checked{'AUTH'}{'certreq'} $cakeydisabled /></td>
2401 <td class='base'>$Lang::tr{'upload a certificate request'}</td>
2402 <td class='base' rowspan='2'><input type='file' name='FH' size='30' $cacrtdisabled></td></tr>
2403 <tr><td><input type='radio' name='AUTH' value='certfile' $checked{'AUTH'}{'certfile'} $cacrtdisabled /></td>
2404 <td class='base'>$Lang::tr{'upload a certificate'}</td></tr>
2405 <tr><td colspan='3' bgcolor='#000000'><img src='/images/null.gif' width='1' height='1' BORDER='0' /></td></tr>
2406 <tr><td><input type='radio' name='AUTH' value='certgen' $checked{'AUTH'}{'certgen'} $cakeydisabled /></td>
2407 <td class='base'>$Lang::tr{'generate a certificate'}</td><td>&nbsp;</td></tr>
2408 <tr><td>&nbsp;</td>
2409 <td class='base'>$Lang::tr{'users fullname or system hostname'}:</td>
2410 <td class='base' nowrap='nowrap'><input type='text' name='CERT_NAME' value='$cgiparams{'CERT_NAME'}' SIZE='32' $cakeydisabled /></td></tr>
2411 <tr><td>&nbsp;</td>
2412 <td class='base'>$Lang::tr{'users email'}:&nbsp;<img src='/blob.gif' /></td>
2413 <td class='base' nowrap='nowrap'><input type='text' name='CERT_EMAIL' value='$cgiparams{'CERT_EMAIL'}' SIZE='32' $cakeydisabled /></td></tr>
2414 <tr><td>&nbsp;</td>
2415 <td class='base'>$Lang::tr{'users department'}:&nbsp;<img src='/blob.gif' /></td>
2416 <td class='base' nowrap='nowrap'><input type='text' name='CERT_OU' value='$cgiparams{'CERT_OU'}' SIZE='32' $cakeydisabled /></td></tr>
2417 <tr><td>&nbsp;</td>
2418 <td class='base'>$Lang::tr{'organization name'}:&nbsp;<img src='/blob.gif' /></td>
2419 <td class='base' nowrap='nowrap'><input type='text' name='CERT_ORGANIZATION' value='$cgiparams{'CERT_ORGANIZATION'}' SIZE='32' $cakeydisabled /></td></tr>
2420 <tr><td>&nbsp;</td>
2421 <td class='base'>$Lang::tr{'city'}:&nbsp;<img src='/blob.gif'></td>
2422 <td class='base' nowrap='nowrap'><input type='text' name='CERT_CITY' value='$cgiparams{'CERT_CITY'}' SIZE='32' $cakeydisabled /></td></tr>
2423 <tr><td>&nbsp;</td>
2424 <td class='base'>$Lang::tr{'state or province'}:&nbsp;<img src='/blob.gif' /></td>
2425 <td class='base' nowrap='nowrap'><input type='text' name='CERT_STATE' value='$cgiparams{'CERT_STATE'}' SIZE='32' $cakeydisabled /></td></tr>
2426 <tr><td>&nbsp;</td>
2427 <td class='base'>$Lang::tr{'country'}:</td>
2428 <td class='base'><select name='CERT_COUNTRY' $cakeydisabled>
2429 END
2430
2431 ;
2432 foreach my $country (sort keys %{Countries::countries}) {
2433 print "<option value='$Countries::countries{$country}'";
2434 if ( $Countries::countries{$country} eq $cgiparams{'CERT_COUNTRY'} ) {
2435 print " selected='selected'";
2436 }
2437 print ">$country</option>";
2438 }
2439 print <<END
2440 </select></td></tr>
2441 <tr><td>&nbsp;</td>
2442
2443 <td class='base'>$Lang::tr{'valid till'} (days):</td>
2444 <td class='base' nowrap='nowrap'><input type='text' name='DAYS_VALID' value='$cgiparams{'DAYS_VALID'}' size='32' $cakeydisabled /></td></tr>
2445
2446 <tr><td>&nbsp;</td>
2447 <td class='base'>$Lang::tr{'pkcs12 file password'}:</td>
2448 <td class='base' nowrap='nowrap'><input type='password' name='CERT_PASS1' value='$cgiparams{'CERT_PASS1'}' size='32' $cakeydisabled /></td></tr>
2449 <tr><td>&nbsp;</td><td class='base'>$Lang::tr{'pkcs12 file password'}:<BR>($Lang::tr{'confirmation'})</td>
2450 <td class='base' nowrap='nowrap'><input type='password' name='CERT_PASS2' value='$cgiparams{'CERT_PASS2'}' size='32' $cakeydisabled /></td></tr>
2451 </table>
2452 END
2453 ;
2454 &Header::closebox();
2455 }
2456
2457 print "<div align='center'><input type='submit' name='ACTION' value='$Lang::tr{'save'}' />";
2458 if ($cgiparams{'KEY'}) {
2459 # print "<input type='submit' name='ACTION' value='$Lang::tr{'advanced'}' />";
2460 }
2461 print "<input type='submit' name='ACTION' value='$Lang::tr{'cancel'}' /></div></form>";
2462 &Header::closebigbox();
2463 &Header::closepage();
2464 exit (0);
2465 }
2466 VPNCONF_END:
2467 }
2468
2469 # SETTINGS_ERROR:
2470 ###
2471 ### Default status page
2472 ###
2473 %cgiparams = ();
2474 %cahash = ();
2475 %confighash = ();
2476 &General::readhash("${General::swroot}/ovpn/settings", \%cgiparams);
2477 &General::readhasharray("${General::swroot}/ovpn/caconfig", \%cahash);
2478 &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
2479
2480 my @status = `/bin/cat /var/log/ovpnserver.log`;
2481
2482 if ($cgiparams{'VPN_IP'} eq '' && -e "${General::swroot}/red/active") {
2483 if (open(IPADDR, "${General::swroot}/red/local-ipaddress")) {
2484 my $ipaddr = <IPADDR>;
2485 close IPADDR;
2486 chomp ($ipaddr);
2487 $cgiparams{'VPN_IP'} = (gethostbyaddr(pack("C4", split(/\./, $ipaddr)), 2))[0];
2488 if ($cgiparams{'VPN_IP'} eq '') {
2489 $cgiparams{'VPN_IP'} = $ipaddr;
2490 }
2491 }
2492 }
2493
2494 #default setzen
2495 if ($cgiparams{'DCIPHER'} eq '') {
2496 $cgiparams{'DCIPHER'} = 'BF-CBC';
2497 }
2498 # if ($cgiparams{'DCOMPLZO'} eq '') {
2499 # $cgiparams{'DCOMPLZO'} = 'on';
2500 # }
2501 if ($cgiparams{'DDEST_PORT'} eq '') {
2502 $cgiparams{'DDEST_PORT'} = '1194';
2503 }
2504 if ($cgiparams{'DMTU'} eq '') {
2505 $cgiparams{'DMTU'} = '1400';
2506 }
2507 if ($cgiparams{'DOVPN_SUBNET'} eq '') {
2508 $cgiparams{'DOVPN_SUBNET'} = '10.' . int(rand(256)) . '.' . int(rand(256)) . '.0/255.255.255.0';
2509 }
2510
2511 $checked{'ENABLED'}{'off'} = '';
2512 $checked{'ENABLED'}{'on'} = '';
2513 $checked{'ENABLED'}{$cgiparams{'ENABLED'}} = 'CHECKED';
2514 $checked{'ENABLED_BLUE'}{'off'} = '';
2515 $checked{'ENABLED_BLUE'}{'on'} = '';
2516 $checked{'ENABLED_BLUE'}{$cgiparams{'ENABLED_BLUE'}} = 'CHECKED';
2517 $checked{'ENABLED_ORANGE'}{'off'} = '';
2518 $checked{'ENABLED_ORANGE'}{'on'} = '';
2519 $checked{'ENABLED_ORANGE'}{$cgiparams{'ENABLED_ORANGE'}} = 'CHECKED';
2520
2521
2522 #new settings
2523 $selected{'DDEVICE'}{'tun'} = '';
2524 $selected{'DDEVICE'}{'tap'} = '';
2525 $selected{'DDEVICE'}{$cgiparams{'DDEVICE'}} = 'SELECTED';
2526
2527 $selected{'DPROTOCOL'}{'udp'} = '';
2528 $selected{'DPROTOCOL'}{'tcp'} = '';
2529 $selected{'DPROTOCOL'}{$cgiparams{'DPROTOCOL'}} = 'SELECTED';
2530
2531 $selected{'DCIPHER'}{'DES-CBC'} = '';
2532 $selected{'DCIPHER'}{'DES-EDE-CBC'} = '';
2533 $selected{'DCIPHER'}{'DES-EDE3-CBC'} = '';
2534 $selected{'DCIPHER'}{'DESX-CBC'} = '';
2535 $selected{'DCIPHER'}{'RC2-CBC'} = '';
2536 $selected{'DCIPHER'}{'RC2-40-CBC'} = '';
2537 $selected{'DCIPHER'}{'RC2-64-CBC'} = '';
2538 $selected{'DCIPHER'}{'BF-CBC'} = '';
2539 $selected{'DCIPHER'}{'CAST5-CBC'} = '';
2540 $selected{'DCIPHER'}{'AES-128-CBC'} = '';
2541 $selected{'DCIPHER'}{'AES-192-CBC'} = '';
2542 $selected{'DCIPHER'}{'AES-256-CBC'} = '';
2543 $selected{'DCIPHER'}{$cgiparams{'DCIPHER'}} = 'SELECTED';
2544 $checked{'DCOMPLZO'}{'off'} = '';
2545 $checked{'DCOMPLZO'}{'on'} = '';
2546 $checked{'DCOMPLZO'}{$cgiparams{'DCOMPLZO'}} = 'CHECKED';
2547
2548 #new settings
2549 &Header::showhttpheaders();
2550 &Header::openpage($Lang::tr{'status ovpn'}, 1, '');
2551 &Header::openbigbox('100%', 'LEFT', '', $errormessage);
2552
2553 if ($errormessage) {
2554 &Header::openbox('100%', 'LEFT', $Lang::tr{'error messages'});
2555 print "<class name='base'>$errormessage\n";
2556 print "&nbsp;</class>\n";
2557 &Header::closebox();
2558 }
2559
2560 my $sactive = "<table cellpadding='2' cellspacing='0' bgcolor='${Header::colourred}' width='50%'><tr><td align='center'><b><font color='#FFFFFF'>$Lang::tr{'stopped'}</font></b></td></tr></table>";
2561 my $srunning = "no";
2562 my $activeonrun = "";
2563 if ( -e "/var/run/openvpn.pid"){
2564 $sactive = "<table cellpadding='2' cellspacing='0' bgcolor='${Header::colourgreen}' width='50%'><tr><td align='center'><b><font color='#FFFFFF'>$Lang::tr{'running'}</font></b></td></tr></table>";
2565 $srunning ="yes";
2566 $activeonrun = "";
2567 } else {
2568 $activeonrun = "disabled='disabled'";
2569 }
2570 &Header::openbox('100%', 'LEFT', $Lang::tr{'global settings'});
2571 print <<END
2572 <table width='100%'>
2573 <form method='post'>
2574 <td width='25%'>&nbsp;</td>
2575 <td width='25%'>&nbsp;</td>
2576 <td width='25%'>&nbsp;</td></tr>
2577 <tr><td class='boldbase'>$Lang::tr{'ovpn server status'}</td>
2578 <td align='left'>$sactive</td>
2579 <tr><td class='boldbase'>$Lang::tr{'ovpn on red'}</td>
2580 <td><input type='checkbox' name='ENABLED' $checked{'ENABLED'}{'on'} /></td>
2581 END
2582 ;
2583 if (&haveBlueNet()) {
2584 print "<tr><td class='boldbase'>$Lang::tr{'ovpn on blue'}</td>";
2585 print "<td><input type='checkbox' name='ENABLED_BLUE' $checked{'ENABLED_BLUE'}{'on'} /></td>";
2586 }
2587 if (&haveOrangeNet()) {
2588 print "<tr><td class='boldbase'>$Lang::tr{'ovpn on orange'}</td>";
2589 print "<td><input type='checkbox' name='ENABLED_ORANGE' $checked{'ENABLED_ORANGE'}{'on'} /></td>";
2590 }
2591 print <<END
2592 <tr><td class='base' nowrap='nowrap' colspan='2'>$Lang::tr{'local vpn hostname/ip'}:<br /><input type='text' name='VPN_IP' value='$cgiparams{'VPN_IP'}' size='30' /></td>
2593 <td class='boldbase' nowrap='nowrap' colspan='2'>$Lang::tr{'ovpn subnet'}<br /><input type='TEXT' name='DOVPN_SUBNET' value='$cgiparams{'DOVPN_SUBNET'}' size='30' /></td></tr>
2594 <tr><td class='boldbase' nowrap='nowrap'>$Lang::tr{'ovpn device'}</td>
2595 <td><select name='DDEVICE' ><option value='tun' $selected{'DDEVICE'}{'tun'}>TUN</option>
2596 <!-- this is still not working
2597 <option value='tap' $selected{'DDEVICE'}{'tap'}>TAP</option></select>--> </td>
2598 <tr><td class='boldbase' nowrap='nowrap'>$Lang::tr{'protocol'}</td>
2599 <td><select name='DPROTOCOL'><option value='udp' $selected{'DPROTOCOL'}{'udp'}>UDP</option>
2600 <option value='tcp' $selected{'DPROTOCOL'}{'tcp'}>TCP</option></select></td>
2601 <td class='boldbase'>$Lang::tr{'destination port'}:</td>
2602 <td><input type='TEXT' name='DDEST_PORT' value='$cgiparams{'DDEST_PORT'}' size='5' /></td></tr>
2603 <tr><td class='boldbase' nowrap='nowrap'>$Lang::tr{'MTU'}&nbsp;</td>
2604 <td> <input type='TEXT' name='DMTU' VALUE='$cgiparams{'DMTU'}'size='5' /></TD>
2605 <tr><td class='boldbase' nowrap='nowrap'>$Lang::tr{'comp-lzo'}</td>
2606 <td><input type='checkbox' name='DCOMPLZO' $checked{'DCOMPLZO'}{'on'} /></td>
2607 <td class='boldbase' nowrap='nowrap'>$Lang::tr{'cipher'}</td>
2608 <td><select name='DCIPHER'><option value='DES-CBC' $selected{'DCIPHER'}{'DES-CBC'}>DES-CBC</option>
2609 <option value='DES-EDE-CBC' $selected{'DCIPHER'}{'DES-EDE-CBC'}>DES-EDE-CBC</option>
2610 <option value='DES-EDE3-CBC' $selected{'DCIPHER'}{'DES-EDE3-CBC'}>DES-EDE3-CBC</option>
2611 <option value='DESX-CBC' $selected{'DCIPHER'}{'DESX-CBC'}>DESX-CBC</option>
2612 <option value='RC2-CBC' $selected{'DCIPHER'}{'RC2-CBC'}>RC2-CBC</option>
2613 <option value='RC2-40-CBC' $selected{'DCIPHER'}{'RC2-40-CBC'}>RC2-40-CBC</option>
2614 <option value='RC2-64-CBC' $selected{'DCIPHER'}{'RC2-64-CBC'}>RC2-64-CBC</option>
2615 <option value='BF-CBC' $selected{'DCIPHER'}{'BF-CBC'}>BF-CBC</option>
2616 <option value='CAST5-CBC' $selected{'DCIPHER'}{'CAST5-CBC'}>CAST5-CBC</option>
2617 <option value='AES-128-CBC' $selected{'DCIPHER'}{'AES-128-CBC'}>AES-128-CBC</option>
2618 <option value='AES-192-CBC' $selected{'DCIPHER'}{'AES-192-CBC'}>AES-192-CBC</option>
2619 <option value='AES-256-CBC' $selected{'DCIPHER'}{'AES-256-CBC'}>AES-256-CBC</option></select></td>
2620 END
2621 ;
2622
2623 if ( $srunning eq "yes" ) {
2624 print "<tr><td align='left'><input type='submit' name='ACTION' value='$Lang::tr{'save'}' disabled='disabled' /></td>";
2625 print "<td><input type='submit' name='ACTION' value='$Lang::tr{'advanced server'}' disabled='disabled'/></td>";
2626 print "<td><input type='submit' name='ACTION' value='$Lang::tr{'stop ovpn server'}' /></td>";
2627 print "<td><input type='submit' name='ACTION' value='$Lang::tr{'restart ovpn server'}' /></td></tr>";
2628 } else{
2629 print "<tr><td align='left'><input type='submit' name='ACTION' value='$Lang::tr{'save'}' /></td>";
2630 print "<td><input type='submit' name='ACTION' value='$Lang::tr{'advanced server'}' /></td>";
2631 if (( -e "${General::swroot}/ovpn/ca/cacert.pem" &&
2632 -e "${General::swroot}/ovpn/ca/dh1024.pem" &&
2633 -e "${General::swroot}/ovpn/certs/servercert.pem" &&
2634 -e "${General::swroot}/ovpn/certs/serverkey.pem") &&
2635 (( $cgiparams{'ENABLED'} eq 'on') ||
2636 ( $cgiparams{'ENABLED_BLUE'} eq 'on') ||
2637 ( $cgiparams{'ENABLED_ORANGE'} eq 'on'))){
2638 print "<td><input type='submit' name='ACTION' value='$Lang::tr{'start ovpn server'}' /></td>";
2639 print "<td><input type='submit' name='ACTION' value='$Lang::tr{'restart ovpn server'}' /></td></tr>";
2640 } else {
2641 print "<td><input type='submit' name='ACTION' value='$Lang::tr{'start ovpn server'}' disabled='disabled' /></td>";
2642 print "<td><input type='submit' name='ACTION' value='$Lang::tr{'restart ovpn server'}' disabled='disabled' /></td></tr>";
2643 }
2644 }
2645 print "</form></table>";
2646 &Header::closebox();
2647 &Header::openbox('100%', 'LEFT', "$Lang::tr{'certificate authorities'}:");
2648 print <<EOF#'
2649 <table width='100%' border='0' cellspacing='1' cellpadding='0'>
2650 <tr>
2651 <td width='25%' class='boldbase' align='center'><b>$Lang::tr{'name'}</b></td>
2652 <td width='65%' class='boldbase' align='center'><b>$Lang::tr{'subject'}</b></td>
2653 <td width='10%' class='boldbase' colspan='3' align='center'><b>$Lang::tr{'action'}</b></td>
2654 </tr>
2655 EOF
2656 ;
2657 if (-f "${General::swroot}/ovpn/ca/cacert.pem") {
2658 my $casubject = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/ca/cacert.pem`;
2659 $casubject =~ /Subject: (.*)[\n]/;
2660 $casubject = $1;
2661 $casubject =~ s+/Email+, E+;
2662 $casubject =~ s/ ST=/ S=/;
2663
2664 print <<END
2665 <tr bgcolor='$color{'color22'}'>
2666 <td class='base'>$Lang::tr{'root certificate'}</td>
2667 <td class='base'>$casubject</td>
2668 <form method='post' name='frmrootcrta'><td width='3%' align='center'>
2669 <input type='hidden' name='ACTION' value='$Lang::tr{'show root certificate'}' />
2670 <input type='image' name='$Lang::tr{'edit'}' src='/images/info.gif' alt='$Lang::tr{'show root certificate'}' title='$Lang::tr{'show root certificate'}' width='20' height='20' border='0' />
2671 </td></form>
2672 <form method='post' name='frmrootcrtb'><td width='3%' align='center'>
2673 <input type='image' name='$Lang::tr{'download root certificate'}' src='/images/media-floppy.png' alt='$Lang::tr{'download root certificate'}' title='$Lang::tr{'download root certificate'}' border='0' />
2674 <input type='hidden' name='ACTION' value='$Lang::tr{'download root certificate'}' />
2675 </td></form>
2676 <td width='4%'>&nbsp;</td></tr>
2677 END
2678 ;
2679 } else {
2680 # display rootcert generation buttons
2681 print <<END
2682 <tr bgcolor='$color{'color22'}'>
2683 <td class='base'>$Lang::tr{'root certificate'}:</td>
2684 <td class='base'>$Lang::tr{'not present'}</td>
2685 <td colspan='3'>&nbsp;</td></tr>
2686 END
2687 ;
2688 }
2689
2690 if (-f "${General::swroot}/ovpn/certs/servercert.pem") {
2691 my $hostsubject = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/certs/servercert.pem`;
2692 $hostsubject =~ /Subject: (.*)[\n]/;
2693 $hostsubject = $1;
2694 $hostsubject =~ s+/Email+, E+;
2695 $hostsubject =~ s/ ST=/ S=/;
2696
2697 print <<END
2698 <tr bgcolor='$color{'color20'}'>
2699 <td class='base'>$Lang::tr{'host certificate'}</td>
2700 <td class='base'>$hostsubject</td>
2701 <form method='post' name='frmhostcrta'><td width='3%' align='center'>
2702 <input type='hidden' name='ACTION' value='$Lang::tr{'show host certificate'}' />
2703 <input type='image' name='$Lang::tr{'show host certificate'}' src='/images/info.gif' alt='$Lang::tr{'show host certificate'}' title='$Lang::tr{'show host certificate'}' width='20' height='20' border='0' />
2704 </td></form>
2705 <form method='post' name='frmhostcrtb'><td width='3%' align='center'>
2706 <input type='image' name='$Lang::tr{'download host certificate'}' src='/images/media-floppy.png' alt='$Lang::tr{'download host certificate'}' title='$Lang::tr{'download host certificate'}' border='0' />
2707 <input type='hidden' name='ACTION' value='$Lang::tr{'download host certificate'}' />
2708 </td></form>
2709 <td width='4%'>&nbsp;</td></tr>
2710 END
2711 ;
2712 } else {
2713 # Nothing
2714 print <<END
2715 <tr bgcolor='$color{'color20'}'>
2716 <td width='25%' class='base'>$Lang::tr{'host certificate'}:</td>
2717 <td class='base'>$Lang::tr{'not present'}</td>
2718 </td><td colspan='3'>&nbsp;</td></tr>
2719 END
2720 ;
2721 }
2722
2723 if (! -f "${General::swroot}/ovpn/ca/cacert.pem") {
2724 print "<tr><td colspan='5' align='center'><form method='post'>";
2725 print "<input type='submit' name='ACTION' value='$Lang::tr{'generate root/host certificates'}' />";
2726 print "</form></td></tr>\n";
2727 }
2728
2729 if (keys %cahash > 0) {
2730 foreach my $key (keys %cahash) {
2731 if (($key + 1) % 2) {
2732 print "<tr bgcolor='$color{'color20'}'>\n";
2733 } else {
2734 print "<tr bgcolor='$color{'color22'}'>\n";
2735 }
2736 print "<td class='base'>$cahash{$key}[0]</td>\n";
2737 print "<td class='base'>$cahash{$key}[1]</td>\n";
2738 print <<END
2739 <form method='post' name='cafrm${key}a'><td align='center'>
2740 <input type='image' name='$Lang::tr{'show ca certificate'}' src='/images/info.gif' alt='$Lang::tr{'show ca certificate'}' title='$Lang::tr{'show ca certificate'}' border='0' />
2741 <input type='hidden' name='ACTION' value='$Lang::tr{'show ca certificate'}' />
2742 <input type='hidden' name='KEY' value='$key' />
2743 </td></form>
2744 <form method='post' name='cafrm${key}b'><td align='center'>
2745 <input type='image' name='$Lang::tr{'download ca certificate'}' src='/images/media-floppy.png' alt='$Lang::tr{'download ca certificate'}' title='$Lang::tr{'download ca certificate'}' border='0' />
2746 <input type='hidden' name='ACTION' value='$Lang::tr{'download ca certificate'}' />
2747 <input type='hidden' name='KEY' value='$key' />
2748 </td></form>
2749 <form method='post' name='cafrm${key}c'><td align='center'>
2750 <input type='hidden' name='ACTION' value='$Lang::tr{'remove ca certificate'}' />
2751 <input type='image' name='$Lang::tr{'remove ca certificate'}' src='/images/delete.gif' alt='$Lang::tr{'remove ca certificate'}' title='$Lang::tr{'remove ca certificate'}' width='20' height='20' border='0' />
2752 <input type='hidden' name='KEY' value='$key' />
2753 </td></form></tr>
2754 END
2755 ;
2756 }
2757 }
2758
2759 print "</table>";
2760
2761 # If the file contains entries, print Key to action icons
2762 if ( -f "${General::swroot}/ovpn/ca/cacert.pem") {
2763 print <<END
2764 <table>
2765 <tr>
2766 <td class='boldbase'>&nbsp; <b>$Lang::tr{'legend'}:</b></td>
2767 <td>&nbsp; &nbsp; <img src='/images/info.gif' alt='$Lang::tr{'show certificate'}' /></td>
2768 <td class='base'>$Lang::tr{'show certificate'}</td>
2769 <td>&nbsp; &nbsp; <img src='/images/media-floppy.png' alt='$Lang::tr{'download certificate'}' /></td>
2770 <td class='base'>$Lang::tr{'download certificate'}</td>
2771 </tr>
2772 </table>
2773 END
2774 ;
2775 }
2776 print <<END
2777 <form method='post' enctype='multipart/form-data'>
2778 <table width='100%' border='0' cellspacing='1' cellpadding='0'>
2779 <tr><td class='base' nowrap='nowrap'>$Lang::tr{'ca name'}:</td>
2780 <td nowrap='nowrap'><input type='text' name='CA_NAME' value='$cgiparams{'CA_NAME'}' size='15' />
2781 <td nowrap='nowrap'><input type='file' name='FH' size='30' /></td>
2782 <td nowrap='nowrap'><input type='submit' name='ACTION' value='$Lang::tr{'upload ca certificate'}' /><br /><input type='submit' name='ACTION' value='$Lang::tr{'show crl'}' /></td>
2783 </tr></table></form>
2784 END
2785 ;
2786
2787 &Header::closebox();
2788 if ( $srunning eq "yes" ) {
2789 print "<div align='center'><form method='post'><input type='submit' name='ACTION' value='$Lang::tr{'reset'}' disabled='disabled' /></div></form>\n";
2790 }else{
2791 print "<div align='center'><form method='post'><input type='submit' name='ACTION' value='$Lang::tr{'reset'}' /></div></form>\n";
2792 }
2793 if ( -f "${General::swroot}/ovpn/ca/cacert.pem" ) {
2794 &Header::openbox('100%', 'LEFT', $Lang::tr{'Client status and controlc' });
2795 print <<END
2796 <table width='100%' border='0' cellspacing='1' cellpadding='0'>
2797 <tr>
2798 <td width='10%' class='boldbase' align='center'><b>$Lang::tr{'name'}</b></td>
2799 <td width='15%' class='boldbase' align='center'><b>$Lang::tr{'type'}</b></td>
2800 <td width='18%' class='boldbase' align='center'><b>$Lang::tr{'common name'}</b></td>
2801 <td width='17%' class='boldbase' align='center'><b>$Lang::tr{'valid till'}</b></td>
2802 <td width='25%' class='boldbase' align='center'><b>$Lang::tr{'remark'}</b><br /><img src='/images/null.gif' width='125' height='1' border='0' alt='L2089' /></td>
2803 <td width='10%' class='boldbase' align='center'><b>$Lang::tr{'status'}</b></td>
2804 <td width='5%' class='boldbase' colspan='6' align='center'><b>$Lang::tr{'action'}</b></td>
2805 </tr>
2806 END
2807 ;
2808 my $id = 0;
2809 my $gif;
2810 foreach my $key (keys %confighash) {
2811 if ($confighash{$key}[0] eq 'on') { $gif = 'on.gif'; } else { $gif = 'off.gif'; }
2812
2813 if ($id % 2) {
2814 print "<tr bgcolor='$color{'color20'}'>\n";
2815 } else {
2816 print "<tr bgcolor='$color{'color22'}'>\n";
2817 }
2818 print "<td align='center' nowrap='nowrap'>$confighash{$key}[1]</td>";
2819 print "<td align='center' nowrap='nowrap'>" . $Lang::tr{"$confighash{$key}[3]"} . " (" . $Lang::tr{"$confighash{$key}[4]"} . ")</td>";
2820 if ($confighash{$key}[4] eq 'cert') {
2821 print "<td align='left' nowrap='nowrap'>$confighash{$key}[2]</td>";
2822 } else {
2823 print "<td align='left'>&nbsp;</td>";
2824 }
2825 my $cavalid = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/certs/$confighash{$key}[1]cert.pem`;
2826 $cavalid =~ /Not After : (.*)[\n]/;
2827 $cavalid = $1;
2828 print "<td align='center'>$cavalid</td>";
2829 print "<td align='center'>$confighash{$key}[25]</td>";
2830 my $active = "<table cellpadding='2' cellspacing='0' bgcolor='${Header::colourred}' width='100%'><tr><td align='center'><b><font color='#FFFFFF'>$Lang::tr{'capsclosed'}</font></b></td></tr></table>";
2831 if ($confighash{$key}[0] eq 'off') {
2832 $active = "<table cellpadding='2' cellspacing='0' bgcolor='${Header::colourblue}' width='100%'><tr><td align='center'><b><font color='#FFFFFF'>$Lang::tr{'capsclosed'}</font></b></td></tr></table>";
2833 } else {
2834 my $cn;
2835 my @match = ();
2836 foreach my $line (@status) {
2837 chomp($line);
2838 if ( $line =~ /^(.+),(\d+\.\d+\.\d+\.\d+\:\d+),(\d+),(\d+),(.+)/) {
2839 @match = split(m/^(.+),(\d+\.\d+\.\d+\.\d+\:\d+),(\d+),(\d+),(.+)/, $line);
2840 if ($match[1] ne "Common Name") {
2841 $cn = $match[1];
2842 }
2843 $cn =~ s/[_]/ /g;
2844 if ($cn eq "$confighash{$key}[2]") {
2845 $active = "<table cellpadding='2' cellspacing='0' bgcolor='${Header::colourgreen}' width='100%'><tr><td align='center'><b><font color='#FFFFFF'>$Lang::tr{'capsopen'}</font></b></td></tr></table>";
2846 }
2847 }
2848 }
2849 }
2850 my $disable_clientdl = "disabled='disabled'";
2851 if (( $cgiparams{'ENABLED'} eq 'on') ||
2852 ( $cgiparams{'ENABLED_BLUE'} eq 'on') ||
2853 ( $cgiparams{'ENABLED_ORANGE'} eq 'on')){
2854 $disable_clientdl = "";
2855 }
2856 print <<END
2857 <td align='center'>$active</td>
2858
2859 <form method='post' name='frm${key}a'><td align='center'>
2860 <input type='image' name='$Lang::tr{'dl client arch'}' $disable_clientdl src='/images/openvpn.png' alt='$Lang::tr{'dl client arch'}' title='$Lang::tr{'dl client arch'}' border='0' />
2861 <input type='hidden' name='ACTION' value='$Lang::tr{'dl client arch'}' $disable_clientdl />
2862 <input type='hidden' name='KEY' value='$key' $disable_clientdl />
2863 </td></form>
2864 END
2865 ;
2866 if ($confighash{$key}[4] eq 'cert') {
2867 print <<END
2868 <form method='post' name='frm${key}b'><td align='center'>
2869 <input type='image' name='$Lang::tr{'show certificate'}' src='/images/info.gif' alt='$Lang::tr{'show certificate'}' title='$Lang::tr{'show certificate'}' border='0' />
2870 <input type='hidden' name='ACTION' value='$Lang::tr{'show certificate'}' />
2871 <input type='hidden' name='KEY' value='$key' />
2872 </td></form>
2873 END
2874 ; } else {
2875 print "<td>&nbsp;</td>";
2876 }
2877 if ($confighash{$key}[4] eq 'cert' && -f "${General::swroot}/ovpn/certs/$confighash{$key}[1].p12") {
2878 print <<END
2879 <form method='post' name='frm${key}c'><td align='center'>
2880 <input type='image' name='$Lang::tr{'download pkcs12 file'}' src='/images/media-floppy.png' alt='$Lang::tr{'download pkcs12 file'}' title='$Lang::tr{'download pkcs12 file'}' border='0' />
2881 <input type='hidden' name='ACTION' value='$Lang::tr{'download pkcs12 file'}' />
2882 <input type='hidden' name='KEY' value='$key' />
2883 </td></form>
2884 END
2885 ; } elsif ($confighash{$key}[4] eq 'cert') {
2886 print <<END
2887 <form method='post' name='frm${key}c'><td align='center'>
2888 <input type='image' name='$Lang::tr{'download certificate'}' src='/images/media-floppy.png' alt='$Lang::tr{'download certificate'}' title='$Lang::tr{'download certificate'}' border='0' />
2889 <input type='hidden' name='ACTION' value='$Lang::tr{'download certificate'}' />
2890 <input type='hidden' name='KEY' value='$key' />
2891 </td></form>
2892 END
2893 ; } else {
2894 print "<td>&nbsp;</td>";
2895 }
2896 print <<END
2897 <form method='post' name='frm${key}d'><td align='center'>
2898 <input type='image' name='$Lang::tr{'toggle enable disable'}' src='/images/$gif' alt='$Lang::tr{'toggle enable disable'}' title='$Lang::tr{'toggle enable disable'}' border='0' />
2899 <input type='hidden' name='ACTION' value='$Lang::tr{'toggle enable disable'}' />
2900 <input type='hidden' name='KEY' value='$key' />
2901 </td></form>
2902
2903 <form method='post' name='frm${key}e'><td align='center'>
2904 <input type='hidden' name='ACTION' value='$Lang::tr{'edit'}' />
2905 <input type='image' name='$Lang::tr{'edit'}' src='/images/edit.gif' alt='$Lang::tr{'edit'}' title='$Lang::tr{'edit'}' width='20' height='20' border='0'/>
2906 <input type='hidden' name='KEY' value='$key' />
2907 </td></form>
2908 <form method='post' name='frm${key}f'><td align='center'>
2909 <input type='hidden' name='ACTION' value='$Lang::tr{'remove'}' />
2910 <input type='image' name='$Lang::tr{'remove'}' src='/images/delete.gif' alt='$Lang::tr{'remove'}' title='$Lang::tr{'remove'}' width='20' height='20' border='0' />
2911 <input type='hidden' name='KEY' value='$key' />
2912 </td></form>
2913 </tr>
2914 END
2915 ;
2916 $id++;
2917 }
2918 ;
2919
2920 # If the config file contains entries, print Key to action icons
2921 if ( $id ) {
2922 print <<END
2923 <table>
2924 <tr>
2925 <td class='boldbase'>&nbsp; <b>$Lang::tr{'legend'}:</b></td>
2926 <td>&nbsp; <img src='/images/on.gif' alt='$Lang::tr{'click to disable'}' /></td>
2927 <td class='base'>$Lang::tr{'click to disable'}</td>
2928 <td>&nbsp; &nbsp; <img src='/images/info.gif' alt='$Lang::tr{'show certificate'}' /></td>
2929 <td class='base'>$Lang::tr{'show certificate'}</td>
2930 <td>&nbsp; &nbsp; <img src='/images/edit.gif' alt='$Lang::tr{'edit'}' /></td>
2931 <td class='base'>$Lang::tr{'edit'}</td>
2932 <td>&nbsp; &nbsp; <img src='/images/delete.gif' alt='$Lang::tr{'remove'}' /></td>
2933 <td class='base'>$Lang::tr{'remove'}</td>
2934 </tr>
2935 <tr>
2936 <td>&nbsp; </td>
2937 <td>&nbsp; <img src='/images/off.gif' alt='?OFF' /></td>
2938 <td class='base'>$Lang::tr{'click to enable'}</td>
2939 <td> <img src='/images/media-floppy.png' alt='?FLOPPY' /></td>
2940 <td class='base'>$Lang::tr{'download certificate'}</td>
2941 <td> <img src='/images/openvpn.png' alt='?RELOAD'/></td>
2942 <td class='base'>$Lang::tr{'dl client arch'}</td>
2943 </tr>
2944 </table>
2945 END
2946 ;
2947 }
2948
2949 print <<END
2950 <table width='100%'>
2951 <form method='post'>
2952 <tr><td width='50%' ><input type='submit' name='ACTION' value='$Lang::tr{'add'}' /></td>
2953 <td width='50%' ><input type='submit' name='ACTION' value='$Lang::tr{'ovpn con stat'}' $activeonrun /></td></tr>
2954 </form>
2955 </table>
2956 END
2957 ;
2958 &Header::closebox();
2959 }
2960 &Header::closepage();