3 use Archive
::Zip
qw(:ERROR_CODES :CONSTANTS);
6 use File
::Temp qw
/ tempfile tempdir /;
8 require '/var/ipfire/general-functions.pl';
10 my $errormessage = '';
11 my $errormessage2 = '';
12 my @subnets; # array of anonymous hashes {cn, from, to}
13 my @subnets2; # array of anonymous hashes {cn, from, to}
14 my %overlaps; # hash {cn} of anonymous arrays of subnets
15 my ($subnet, $from, $to, $i, $j);
16 &General
::readhash
("${General::swroot}/ethernet/settings", \
%netsettings);
19 if ($netsettings{'CONFIG_TYPE'} == 1) {return 1;}
20 if ($netsettings{'CONFIG_TYPE'} == 3) {return 1;}
21 if ($netsettings{'CONFIG_TYPE'} == 5) {return 1;}
22 if ($netsettings{'CONFIG_TYPE'} == 7) {return 1;}
28 if ($netsettings{'CONFIG_TYPE'} == 4) {return 1;}
29 if ($netsettings{'CONFIG_TYPE'} == 5) {return 1;}
30 if ($netsettings{'CONFIG_TYPE'} == 6) {return 1;}
31 if ($netsettings{'CONFIG_TYPE'} == 7) {return 1;}
39 while(abs($bytesize) >= 1024){
40 $bytesize=$bytesize/1024;
45 my @units = ("Bytes","KB","MB","GB","TB","PB","EB");
46 my $newsize=(int($bytesize*100 +0.5))/100;
47 return("$newsize $units[$i]");
52 unless ($hostname) { return "No hostname"};
53 my $res = new Net
::DNS
::Resolver
;
54 my $query = $res->search("$hostname");
56 foreach my $rr ($query->answer) {
57 ## Potential bug - we are only looking at A records:
58 return 0 if $rr->type eq "A";
61 return $res->errorstring;
67 if (open(FILE
, ">${General::swroot}/ovpn/certs/serial")) {
71 if (open(FILE
, ">${General::swroot}/ovpn/certs/index.txt")) {
75 unlink ("${General::swroot}/ovpn/certs/index.txt.old");
76 unlink ("${General::swroot}/ovpn/certs/serial.old");
77 unlink ("${General::swroot}/ovpn/certs/01.pem");
80 sub newcleanssldatabase
82 if (! -s
"${General::swroot}/ovpn/certs/serial" ) {
83 open(FILE
, ">${General::swroot}(ovpn/certs/serial");
87 if (! -s
">${General::swroot}/ovpn/certs/index.txt") {
88 system ("touch ${General::swroot}/ovpn/certs/index.txt");
90 unlink ("${General::swroot}/ovpn/certs/index.txt.old");
91 unlink ("${General::swroot}/ovpn/certs/serial.old");
96 if (open(FILE
, "${General::swroot}/ovpn/certs/serial.old")) {
97 my $hexvalue = <FILE
>;
100 unlink ("${General::swroot}/ovpn/certs/$hexvalue.pem");
105 my $KEY2 = $_[0]; # key2
106 my $SRC_PORT = $_[1]; # src_port
107 my $PROTOCOL = $_[2]; # protocol
108 my $SRC_IP = $_[3]; # sourceip
109 my $pfwfilename = "${General::swroot}/portfw/config";
110 open(FILE
, $pfwfilename) or die 'Unable to open config file.';
111 my @pfwcurrent = <FILE
>;
113 my $pfwkey1 = 0; # used for finding last sequence number used
114 foreach my $pfwline (@pfwcurrent)
116 my @pfwtemp = split(/\,/,$pfwline);
119 if ($KEY2 eq "0"){ # if key2 is 0 then it is a portfw addition
120 if ( $SRC_PORT eq $pfwtemp[3] &&
121 $PROTOCOL eq $pfwtemp[2] &&
122 $SRC_IP eq $pfwtemp[7])
124 $errormessage = "$Lang::tr{'source port in use'} $SRC_PORT";
126 # Check if key2 = 0, if it is then it is a port forward entry and we want the sequence number
127 if ( $pfwtemp[1] eq "0") {
128 $pfwkey1=$pfwtemp[0];
130 # Darren Critchley - Duplicate or overlapping Port range check
131 if ($pfwtemp[1] eq "0" &&
132 $PROTOCOL eq $pfwtemp[2] &&
133 $SRC_IP eq $pfwtemp[7] &&
136 &portchecks
($SRC_PORT, $pfwtemp[5]);
137 # &portchecks($pfwtemp[3], $pfwtemp[5]);
138 # &portchecks($pfwtemp[3], $SRC_IP);
142 # $errormessage="$KEY2 $SRC_PORT $PROTOCOL $SRC_IP";
144 return $errormessage;
149 my $portrange1 = $_[0]; # New port range
150 my $portrange2 = $_[1]; # existing port range
151 my @tempr1 = split(/\:/,$portrange1);
152 my @tempr2 = split(/\:/,$portrange2);
154 unless (&checkportinc
($tempr1[0], $portrange2)){ return 0;}
155 unless (&checkportinc
($tempr1[1], $portrange2)){ return 0;}
157 unless (&checkportinc
($tempr2[0], $portrange1)){ return 0;}
158 unless (&checkportinc
($tempr2[1], $portrange1)){ return 0;}
160 return 1; # Everything checks out!
163 # Darren Critchley - we want to make sure that a port entry is not within an already existing range
166 my $port1 = $_[0]; # Port
167 my $portrange2 = $_[1]; # Port range
168 my @tempr1 = split(/\:/,$portrange2);
170 if ($port1 < $tempr1[0] || $port1 > $tempr1[1]) {
176 # Darren Critchley - Duplicate or overlapping Port range check
179 my $p1 = $_[0]; # New port range
180 my $p2 = $_[1]; # existing port range
182 our ($prtrange1, $prtrange2);
184 # if (m/:/ && $prtrange1 == 1) { # comparing two port ranges
185 # unless (&checkportoverlap($p1,$p2)) {
186 # $errormessage = "$Lang::tr{'source port overlaps'} $p1";
189 if (m/:/ && $prtrange1 == 0 && $errormessage eq '') { # compare one port to a range
190 unless (&checkportinc
($p2,$p1)) {
191 $errormessage = "$Lang::tr{'srcprt within existing'} $p1";
195 if (! m/:/ && $prtrange1 == 1 && $errormessage eq '') { # compare one port to a range
196 unless (&checkportinc
($p1,$p2)) {
197 $errormessage = "$Lang::tr{'srcprt range overlaps'} $p2";
203 # Darren Critchley - certain ports are reserved for ipfire
204 # TCP 67,68,81,222,445
206 # Params passed in -> port, rangeyn, protocol
209 # port 67 and 68 same for tcp and udp, don't bother putting in an array
211 my @tcp_reserved = (81,222,445);
212 my $prt = $_[0]; # the port or range
213 my $ryn = $_[1]; # tells us whether or not it is a port range
214 my $prot = $_[2]; # protocol
215 my $srcdst = $_[3]; # source or destination
216 if ($ryn) { # disect port range
217 if ($srcdst eq "src") {
218 $msg = "$Lang::tr{'rsvd src port overlap'}";
220 $msg = "$Lang::tr{'rsvd dst port overlap'}";
222 my @tmprng = split(/\:/,$prt);
223 unless (67 < $tmprng[0] || 67 > $tmprng[1]) { $errormessage="$msg 67"; return; }
224 unless (68 < $tmprng[0] || 68 > $tmprng[1]) { $errormessage="$msg 68"; return; }
225 if ($prot eq "tcp") {
226 foreach my $prange (@tcp_reserved) {
227 unless ($prange < $tmprng[0] || $prange > $tmprng[1]) { $errormessage="$msg $prange"; return; }
231 if ($srcdst eq "src") {
232 $msg = "$Lang::tr{'reserved src port'}";
234 $msg = "$Lang::tr{'reserved dst port'}";
236 if ($prt == 67) { $errormessage="$msg 67"; return; }
237 if ($prt == 68) { $errormessage="$msg 68"; return; }
238 if ($prot eq "tcp") {
239 foreach my $prange (@tcp_reserved) {
240 if ($prange == $prt) {
241 $errormessage = "$msg $prange";
242 return $errormessage; }
246 return $errormessage;
249 sub writeserverconf
{
250 my %sovpnsettings = ();
251 &General
::readhash
("${General::swroot}/ovpn/settings", \
%sovpnsettings);
253 open(CONF
, ">${General::swroot}/ovpn/server.conf") or die "Unable to open ${General::swroot}/ovpn/server.conf: $!";
255 print CONF
"#OpenVPN Server conf\n";
257 print CONF
"daemon openvpnserver\n";
258 print CONF
"writepid /var/run/openvpn.pid\n";
259 print CONF
"#DAN prepare ZERINA for listening on blue and orange\n";
260 print CONF
";local $sovpnsettings{'VPN_IP'}\n";
261 print CONF
"dev $sovpnsettings{'DDEVICE'}\n";
262 print CONF
"$sovpnsettings{'DDEVICE'}-mtu $sovpnsettings{'DMTU'}\n";
263 print CONF
"proto $sovpnsettings{'DPROTOCOL'}\n";
264 print CONF
"port $sovpnsettings{'DDEST_PORT'}\n";
265 print CONF
"tls-server\n";
266 print CONF
"ca /var/ipfire/ovpn/ca/cacert.pem\n";
267 print CONF
"cert /var/ipfire/ovpn/certs/servercert.pem\n";
268 print CONF
"key /var/ipfire/ovpn/certs/serverkey.pem\n";
269 print CONF
"dh /var/ipfire/ovpn/ca/dh1024.pem\n";
270 my @tempovpnsubnet = split("\/",$sovpnsettings{'DOVPN_SUBNET'});
271 print CONF
"server $tempovpnsubnet[0] $tempovpnsubnet[1]\n";
272 print CONF
"push \"route $netsettings{'GREEN_NETADDRESS'} $netsettings{'GREEN_NETMASK'}\"\n";
273 if ($sovpnsettings{AD_ROUTE1
} ne '') {
274 my @tempovpnsubnet = split("\/",$sovpnsettings{'AD_ROUTE1'});
275 print CONF
"push \"route $tempovpnsubnet[0] $tempovpnsubnet[1]\"\n";
277 if ($sovpnsettings{AD_ROUTE2
} ne '') {
278 my @tempovpnsubnet = split("\/",$sovpnsettings{'AD_ROUTE2'});
279 print CONF
"push \"route $tempovpnsubnet[0] $tempovpnsubnet[1]\"\n";
281 if ($sovpnsettings{AD_ROUTE3
} ne '') {
282 my @tempovpnsubnet = split("\/",$sovpnsettings{'AD_ROUTE3'});
283 print CONF
"push \"route $tempovpnsubnet[0] $tempovpnsubnet[1]\"\n";
285 if ($sovpnsettings{CLIENT2CLIENT
} eq 'on') {
286 print CONF
"client-to-client\n";
288 if ($sovpnsettings{KEEPALIVE_1
} > 0 && $sovpnsettings{KEEPALIVE_2
} > 0) {
289 print CONF
"keepalive $sovpnsettings{'KEEPALIVE_1'} $sovpnsettings{'KEEPALIVE_2'}\n";
291 print CONF
"status-version 1\n";
292 print CONF
"status /var/log/ovpnserver.log 30\n";
293 print CONF
"cipher $sovpnsettings{DCIPHER}\n";
294 if ($sovpnsettings{DCOMPLZO
} eq 'on') {
295 print CONF
"comp-lzo\n";
297 if ($sovpnsettings{REDIRECT_GW_DEF1
} eq 'on') {
298 print CONF
"push \"redirect-gateway def1\"\n";
300 if ($sovpnsettings{DHCP_DOMAIN
} ne '') {
301 print CONF
"push \"dhcp-option DOMAIN $sovpnsettings{DHCP_DOMAIN}\"\n";
304 if ($sovpnsettings{DHCP_DNS
} ne '') {
305 print CONF
"push \"dhcp-option DNS $sovpnsettings{DHCP_DNS}\"\n";
308 if ($sovpnsettings{DHCP_WINS
} ne '') {
309 print CONF
"push \"dhcp-option WINS $sovpnsettings{DHCP_WINS}\"\n";
312 if ($sovpnsettings{DHCP_WINS
} eq '') {
313 print CONF
"max-clients 100\n";
316 if ($sovpnsettings{DHCP_WINS
} ne '') {
317 print CONF
"max-clients $sovpnsettings{MAX_CLIENTS}\n";
320 #################################################################################
321 # Added by Philipp Jenni #
323 # Contact: philipp.jenni-at-gmx.ch #
325 # Description: Add the FAST-IO Parameter from OpenVPN to der Server.Config. #
326 # Add the NICE Parameter from OpenVPN to der Server.Config. #
327 # Add the MTU-DISC Parameter from OpenVPN to der Server.Config. #
328 # Add the MSSFIX Parameter from OpenVPN to der Server.Config. #
329 # Add the FRAMGMENT Parameter from OpenVPN to der Server.Config. #
330 #################################################################################
331 if ($sovpnsettings{EXTENDED_FASTIO
} eq 'on') {
332 print CONF
"fast-io\n";
334 if ($sovpnsettings{EXTENDED_NICE
} != 0) {
335 print CONF
"nice $sovpnsettings{EXTENDED_NICE}\n";
337 if ($sovpnsettings{EXTENDED_MTUDISC
} eq 'on') {
338 print CONF
"mtu-disc yes\n";
340 if ($sovpnsettings{EXTENDED_MSSFIX
} ne '') {
341 print CONF
"mssfix $sovpnsettings{EXTENDED_MSSFIX}\n";
343 if ($sovpnsettings{EXTENDED_FRAGMENT
} ne '') {
344 print CONF
"fragment $sovpnsettings{EXTENDED_FRAGMENT}\n";
346 #################################################################################
347 # End of Inserted Data #
348 #################################################################################
350 print CONF
"tls-verify /var/ipfire/ovpn/verify\n";
351 print CONF
"crl-verify /var/ipfire/ovpn/crls/cacrl.pem\n";
352 print CONF
"user nobody\n";
353 print CONF
"group nobody\n";
354 print CONF
"persist-key\n";
355 print CONF
"persist-tun\n";
356 if ($sovpnsettings{LOG_VERB
} ne '') {
357 print CONF
"verb $sovpnsettings{LOG_VERB}\n";
359 print CONF
"verb 3\n";
366 sub writenet2netconf
{
368 my $zerinaclient = $_[1];
369 my %n2nconfighash = ();
374 my $tempdir = tempdir
( CLEANUP
=> 1 );
375 my $zippath = "$tempdir/";
376 &General
::readhasharray
("${General::swroot}/ovpn/ovpnconfig", \
%n2nconfighash);
378 $n2nkey = &General
::findhasharraykey
(\
%n2nconfighash);
379 foreach my $i (0 .. 25) { $n2nconfighash{$n2nkey}[$i] = "";}
381 my $zipname = "$n2nconfighash{$n2nkey}[1].zip";
382 my $zippathname = "$zippath$zipname";
383 if ($n2nconfighash{$n2nkey}[3] eq 'net') {
384 if ($zerinaclient eq '') {
385 if ( -d
"${General::swroot}/ovpn/n2nconf/$n2nconfighash{$n2nkey}[1]"){
386 while ($file = glob("${General::swroot}/ovpn/n2nconf/$n2nconfighash{$n2nkey}[1]/*.conf")) {
390 mkdir("${General::swroot}/ovpn/n2nconf/$n2nconfighash{$n2nkey}[1]", 0770);
392 open(CONF
, ">${General::swroot}/ovpn/n2nconf/$n2nconfighash{$n2nkey}[1]/$n2nconfighash{$n2nkey}[1].conf") or die "Unable to open ${General::swroot}/ovpn/n2nconf/$n2nconfighash{$n2nkey}[1]/$n2nconfighash{$n2nkey}[1].conf: $!";
394 $clientovpn = "$n2nconfighash{$n2nkey}[1].conf";
395 open(CONF
, ">$tempdir/$clientovpn") or die "Unable to open $tempdir/$clientovpn: $!";
398 print CONF
"dev tun\n";
399 print CONF
"tun-mtu $n2nconfighash{$n2nkey}[17]\n";
400 print CONF
"proto $n2nconfighash{$n2nkey}[14]\n";
401 print CONF
"port $n2nconfighash{$n2nkey}[15]\n";
402 my @tempovpnsubnet = split("\/",$n2nconfighash{$n2nkey}[13]);
403 my @ovpnip = split /\./,$tempovpnsubnet[0];
404 # if ((($zerinaclient eq '') && ($n2nconfighash{$n2nkey}[19] eq 'no'))) {
405 if ((($zerinaclient eq '') && ($n2nconfighash{$n2nkey}[6] eq 'server'))) {
406 print CONF
"ifconfig $ovpnip[0].$ovpnip[1].$ovpnip[2].1 $ovpnip[0].$ovpnip[1].$ovpnip[2].2\n";
407 print CONF
"remote $n2nconfighash{$n2nkey}[10]\n";
408 print CONF
"tls-server\n";
409 print CONF
"ca /var/ipfire/ovpn/ca/cacert.pem\n";
410 print CONF
"cert /var/ipfire/ovpn/certs/servercert.pem\n";
411 print CONF
"key /var/ipfire/ovpn/certs/serverkey.pem\n";
412 print CONF
"dh /var/ipfire/ovpn/ca/dh1024.pem\n";
413 my @tempremotesubnet = split("\/",$n2nconfighash{$n2nkey}[11]);
414 print CONF
"route $tempremotesubnet[0] $tempremotesubnet[1]\n";
416 print CONF
"ifconfig $ovpnip[0].$ovpnip[1].$ovpnip[2].2 $ovpnip[0].$ovpnip[1].$ovpnip[2].1\n";
417 #print CONF "$zerinaclient ufuk 10=$n2nconfighash{$n2nkey}[10] 18=$n2nconfighash{$n2nkey}[18] 19=$n2nconfighash{$n2nkey}[19] \n";
418 if ($zerinaclient ne 'true'){
419 if ($n2nconfighash{$n2nkey}[19] eq 'no'){
420 print CONF
"remote $n2nconfighash{$n2nkey}[10]\n";
422 print CONF
"remote $n2nconfighash{$n2nkey}[10]\n";
425 print CONF
"remote $n2nconfighash{$n2nkey}[18]\n";
427 print CONF
"tls-client\n";
428 if ($zerinaclient ne 'true'){
429 print CONF
"pkcs12 ${General::swroot}/ovpn/n2nconf/$n2nconfighash{$n2nkey}[1]/$n2nconfighash{$n2nkey}[1].p12\n";
431 print CONF
"pkcs12 $n2nconfighash{$n2nkey}[1].p12\n";
433 if ($n2nconfighash{$n2nkey}[19] eq 'no'){
434 my @tempremotesubnet = split("\/",$n2nconfighash{$n2nkey}[8]);
435 print CONF
"route $tempremotesubnet[0] $tempremotesubnet[1]\n";
437 my @tempremotesubnet = split("\/",$n2nconfighash{$n2nkey}[11]);
438 print CONF
"route $tempremotesubnet[0] $tempremotesubnet[1]\n";
441 if ($n2nconfighash{$n2nkey}[26] > 0 && $n2nconfighash{$n2nkey}[27] > 0) {
442 print CONF
"keepalive $n2nconfighash{$n2nkey}[26] $n2nconfighash{$n2nkey}[27]\n";
444 print CONF
"keepalive 10 60\n";
446 print CONF
"cipher $n2nconfighash{$n2nkey}[20]\n";
447 if ($n2nconfighash{$n2nkey}[16] eq 'on') {
448 print CONF
"comp-lzo\n";
450 if ($n2nconfighash{$n2nkey}[42] ne '') {
451 print CONF
"verb $n2nconfighash{$n2nkey}[42]\n";
453 print CONF
"verb 3\n";
455 if ($n2nconfighash{$n2nkey}[19] eq 'no'){
456 print CONF
"#$n2nconfighash{$n2nkey}[11]\n";
458 print CONF
"#$n2nconfighash{$n2nkey}[8]\n";
460 if ($zerinaclient ne 'true') {
461 print CONF
"daemon OVPN_$n2nconfighash{$n2nkey}[1]\n";
462 print CONF
"#status ${General::swroot}/ovpn/n2nconf/$n2nconfighash{$n2nkey}[1]/$n2nconfighash{$n2nkey}[1].log 2\n";
465 if ($zerinaclient eq 'true') {
466 my $zip = Archive
::Zip
->new();
467 $zip->addFile( "${General::swroot}/ovpn/certs/$n2nconfighash{$n2nkey}[1].p12", "$n2nconfighash{$n2nkey}[1].p12") or die "Can't add file ${General::swroot}/ovpn/certs/$n2nconfighash{$n2nkey}[1].p12\n";
468 $zip->addFile( "$tempdir/$clientovpn", $clientovpn) or die "Can't add file $clientovpn\n";
469 my $status = $zip->writeToFileNamed($zippathname);
470 open(DLFILE
, "<$zippathname") or die "Unable to open $zippathname: $!";
471 @fileholder = <DLFILE
>;
472 print "Content-Type:application/x-download\n";
473 print "Content-Disposition:attachment;filename=$zipname\n\n";
480 sub removenet2netconf
{
481 my %n2nconfighash = ();
484 &General
::readhasharray
("${General::swroot}/ovpn/ovpnconfig", \
%n2nconfighash);
485 if ($n2nconfighash{$key}[3] eq 'net') {
486 if ( -d
"${General::swroot}/ovpn/n2nconf/$n2nconfighash{$key}[1]"){
487 while ($file = glob("${General::swroot}/ovpn/n2nconf/$n2nconfighash{$key}[1]/*")) {
490 rmdir("${General::swroot}/ovpn/n2nconf/$n2nconfighash{$key}[1]");
496 if (open(FILE
, ">/var/log/ovpnserver.log")) {
506 &General
::readhasharray
("${General::swroot}/ovpn/caconfig", \
%cahash);
507 if ( -f
"${General::swroot}/ovpn/ca/$cahash{$key}[0]cert.pem") {
508 &Header
::showhttpheaders
();
509 &Header
::openpage
($Lang::tr
{'vpn configuration main'}, 1, '');
510 &Header
::openbigbox
('100%', 'LEFT', '', $errormessage);
511 &Header
::openbox
('100%', 'LEFT', "$Lang::tr{'ca certificate'}:");
512 my $output = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/ca/$cahash{$key}[0]cert.pem`;
513 $output = &Header
::cleanhtml
($output,"y");
514 print "<pre>$output</pre>\n";
516 print "<div align='center'><a href='/cgi-bin/ovpnmain.cgi'>$Lang::tr{'back'}</a></div>";
517 &Header
::closebigbox
();
518 &Header
::closepage
();
521 $errormessage = $Lang::tr
{'invalid key'};
524 sub displayroothost
{
525 my $roothost = $_[0];
527 &Header
::showhttpheaders
();
528 &Header
::openpage
($Lang::tr
{'vpn configuration main'}, 1, '');
529 &Header
::openbigbox
('100%', 'LEFT', '', '');
530 if ($roothost eq $Lang::tr
{'show root certificate'}) {
531 &Header
::openbox
('100%', 'LEFT', "$Lang::tr{'root certificate'}:");
532 $output = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/ca/cacert.pem`;
534 &Header
::openbox
('100%', 'LEFT', "$Lang::tr{'host certificate'}:");
535 $output = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/certs/servercert.pem`;
537 $output = &Header
::cleanhtml
($output,"y");
538 print "<pre>$output</pre>\n";
540 print "<div align='center'><a href='/cgi-bin/ovpnmain.cgi'>$Lang::tr{'back'}</a></div>";
541 &Header
::closebigbox
();
542 &Header
::closepage
();
548 my %n2nconfighash = ();
549 &General
::readhasharray
("${General::swroot}/ovpn/ovpnconfig", \
%n2nconfighash);
550 my $n2nactive = `/bin/ps ax|grep $n2nconfighash{$key}[1].conf|grep -v grep|awk \'{print \$1}\'`;
551 if ($n2nactive ne ''){
552 system('/usr/local/bin/openvpnctrl', '-kn2n', $n2nactive);
557 my $cidrmask = $_[0];
558 my $cidrmask2 = $cidrmask;
559 if ("/$cidrmask" =~ /^\
/(\d+)/){#cidr
560 if ($cidrmask2 = &cidr2mask
("/$cidrmask")) {
563 if ($cidrmask =~ /^\d+\.\d+\.\d+\.\d+/){#mask
568 if ($cidrmask =~ /^\d+\.\d+\.\d+\.\d+/){#mask
575 my( $one32 ) = 0xffffffff;
578 if ( $cidr eq "/0" ) {
582 if ( $cidr !~ /\/(\d
+)/ ) {
591 #-- convert to subnet-style mask
592 $n = $one32 << (32 - $bits);
593 $d[3] = $n % 256; $n = int( $n / 256);
594 $d[2] = $n % 256; $n = int( $n / 256);
595 $d[1] = $n % 256; $n = int( $n / 256);
601 # ----------------------------------------------------------------------------
602 # $cidr = &mask2cidr( $mask )
603 # ----------------------------------------------------------------------------
609 if ( $mask eq "0.0.0.0" ) {
613 if ( ! &validMask
( $mask ) ) {
617 @d = split /\./, $mask;
618 $n = ((((($d[0] * 256) + $d[1]) * 256) + $d[2]) * 256) + $d[3];
620 while ( ($n % 2) == 0 ) {
628 # ----------------------------------------------------------------------------
629 # $yesno = &validMask( $mask )
630 # ----------------------------------------------------------------------------
636 @d = split /\./, $mask;
637 $n = ((((($d[0] * 256) + $d[1]) * 256) + $d[2]) * 256) + $d[3];
638 $str = sprintf "%b", $n;
639 return ( $str =~ /^1+0*$/ );
643 # read all subnets from AD, convert to integer range, and sort.
644 foreach $subnet (@subnets2) {
645 ($from, $to) = &subnet2range
($subnet);
646 push @subnets, { cn
=> $subnet, from
=> $from, to
=> $to };
648 @subnets = sort { $a->{from
} <=> $b->{from
} } @subnets;
650 # compare all possible subnets for overlap; depend on sort order.
651 for ($i=0; $i<=$#subnets; $i++) {
652 for ($j=$i+1; $j<=$#subnets; $j++) {
653 last if $subnets[$i]->{to
} < $subnets[$j]->{from
}; # no possible overlap anymore;
654 push @
{$overlaps{$subnets[$i]->{cn
}}}, $subnets[$j]->{cn
} if $subnets[$i]->{to
} >= $subnets[$j]->{from
};
658 if (scalar (keys %overlaps)) {
659 foreach $subnet (sort keys %overlaps) {
660 #$errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire IPSEC : %s\n", $subnet, join (", ", sort @{$overlaps{$subnet}});
661 $errormessage = "$subnet : $overlaps{$subnet}[0]";
665 return $errormessage;
668 # &subnet2range ($subnet)
669 # convert subnets to integers in order to compare them later.
670 # A subnet looks like this: 10.1.2.0/24
671 # returns beginning and end of subnet as integer
674 my $subnet = shift (@_);
677 $subnet =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)\/(\d
+)$/ || die "bad subnet $subnet\n";
678 $from = $1*2**24 + $2*2**16 + $3*2**8 + $4;
679 $to = $from + 2**(32-$5) - 1;
684 my $tmpovpnsubnet0 = $_[0];
685 my $tmpovpnsubnet1 = $_[1];
686 my %vpnconfighash = ();
688 my @tmpremotevpnsubnet;
689 &General
::readhasharray
("${General::swroot}/vpn/config", \
%vpnconfighash);
691 if (&General
::IpInSubnet
( $netsettings{'GREEN_ADDRESS'},
692 $tmpovpnsubnet0, $tmpovpnsubnet1)) {
693 $errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire Green Network $netsettings{'GREEN_ADDRESS'}";
694 return $errormessage;
697 if (&haveBlueNet
()) {
698 if (&General
::IpInSubnet
( $netsettings{'BLUE_ADDRESS'},
699 $tmpovpnsubnet0, $tmpovpnsubnet1)) {
700 $errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire Blue Network $netsettings{'BLUE_ADDRESS'}";
701 return $errormessage;
704 if (&haveOrangeNet
()) {
705 if (&General
::IpInSubnet
( $netsettings{'ORANGE_ADDRESS'},
706 $tmpovpnsubnet0, $tmpovpnsubnet1)) {
707 $errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire Orange Network $netsettings{'ORANGE_ADDRESS'}";
708 return $errormessage;
711 open(ALIASES
, "${General::swroot}/ethernet/aliases") or die 'Unable to open aliases file.';
715 my @tempalias = split(/\,/,$_);
716 if ($tempalias[1] eq 'on') {
717 if (&General
::IpInSubnet
($tempalias[0] ,
718 $tmpovpnsubnet0, $tmpovpnsubnet1)) {
719 $errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire alias entry $tempalias[0]";
726 #check against ipsec connections
727 foreach my $key (keys %vpnconfighash) {
728 #$confighash{$key}[8] = $cgiparams{'LOCAL_SUBNET'};
729 #$confighash{$key}[3]#host or net
730 #$confighash{$key}[11] = $cgiparams{'REMOTE_SUBNET'};
731 #$confighash{$key}[10] = $cgiparams{'REMOTE'};
733 $tmpcidr = &mask2cidr
($tmpovpnsubnet1);
734 push @subnets2, "$tmpovpnsubnet0$tmpcidr";
735 @tmpremotevpnsubnet = split("\/",$vpnconfighash{$key}[8]);
736 $tmpcidr = &mask2cidr
($tmpremotevpnsubnet[1]);
737 push @subnets2, "$tmpremotevpnsubnet[0]$tmpcidr";
738 $errormessage2 = &overlapping
();
739 if ($errormessage2 ne '') {
740 $errormessage = "$Lang::tr{'ovpn subnet overlap'}IPSCEC Connection=$vpnconfighash{$key}[1] $Lang::tr{'local subnet'} $errormessage2 ";
744 if ($vpnconfighash{$key}[3] eq 'net'){
745 if (&General
::IpInSubnet
($vpnconfighash{$key}[10],$tmpovpnsubnet0, $tmpovpnsubnet1)) {
746 $errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire IPSEC Connection/IP: $vpnconfighash{$key}[1]/$vpnconfighash{$key}[10]";
749 #check agains ipsec local subent
750 push @subnets2, "$tmpovpnsubnet0$tmpcidr";
751 @tmpremotevpnsubnet = split("\/",$vpnconfighash{$key}[11]);
752 $tmpcidr = &mask2cidr
($tmpremotevpnsubnet[1]);
753 push @subnets2, "$tmpremotevpnsubnet[0]$tmpcidr";
754 $errormessage2 = &overlapping
();
755 if ($errormessage2 ne '') {
756 $errormessage = "$Lang::tr{'ovpn subnet overlap'}IPSCEC Connection=$vpnconfighash{$key}[1] $Lang::tr{'remote subnet'} $errormessage2 ";
760 push @subnets2, "$tmpovpnsubnet0$tmpcidr";
761 @tmpremotevpnsubnet = split("\/",$vpnconfighash{$key}[8]);
762 $tmpcidr = &mask2cidr
($tmpremotevpnsubnet[1]);
763 push @subnets2, "$tmpremotevpnsubnet[0]$tmpcidr";
764 $errormessage2 = &overlapping
();
765 if ($errormessage2 ne '') {
766 $errormessage = "$Lang::tr{'ovpn subnet overlap'}IPSCEC Connection=$vpnconfighash{$key}[1] $Lang::tr{'local subnet'} $errormessage2 ";
772 #check against OpenVPN Connections (aware check against itself)
773 return $errormessage;