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