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