X-Git-Url: http://git.ipfire.org/?p=people%2Fteissler%2Fipfire-2.x.git;a=blobdiff_plain;f=html%2Fcgi-bin%2Fovpnmain.cgi;h=899bf3efa2b5bc34b12aadf9c810057d1e0b3c9b;hp=4bfb6aa2c6c970ed62d43ef48c6d3b2b01c1dcb0;hb=1ca546126e98aa23155de0238e929e446ac40d94;hpb=9c166bf2a6a3d8d8df1ad29b6e631671cc33536d diff --git a/html/cgi-bin/ovpnmain.cgi b/html/cgi-bin/ovpnmain.cgi index 4bfb6aa2c..899bf3efa 100644 --- a/html/cgi-bin/ovpnmain.cgi +++ b/html/cgi-bin/ovpnmain.cgi @@ -2,7 +2,7 @@ ############################################################################### # # # IPFire.org - A linux based firewall # -# Copyright (C) 2007-2011 IPFire Team # +# Copyright (C) 2007-2013 IPFire Team # # # # This program is free software: you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # @@ -30,16 +30,17 @@ use File::Copy; use File::Temp qw/ tempfile tempdir /; use strict; use Archive::Zip qw(:ERROR_CODES :CONSTANTS); +use Sort::Naturally; require '/var/ipfire/general-functions.pl'; require "${General::swroot}/lang.pl"; require "${General::swroot}/header.pl"; require "${General::swroot}/countries.pl"; # enable only the following on debugging purpose -use warnings; -use CGI::Carp 'fatalsToBrowser'; +#use warnings; +#use CGI::Carp 'fatalsToBrowser'; #workaround to suppress a warning when a variable is used only once -my @dummy = ( ${Header::colourgreen} ); +my @dummy = ( ${Header::colourgreen}, ${Header::colourblue} ); undef (@dummy); my %color = (); @@ -50,6 +51,9 @@ my %mainsettings = (); ### ### Initialize variables ### +my %ccdconfhash=(); +my %ccdroutehash=(); +my %ccdroute2hash=(); my %netsettings=(); my %cgiparams=(); my %vpnsettings=(); @@ -61,6 +65,10 @@ my $warnmessage = ''; my $errormessage = ''; my %settings=(); my $routes_push_file = ''; +my $confighost="${General::swroot}/fwhosts/customhosts"; +my $configgrp="${General::swroot}/fwhosts/customgroups"; +my $customnet="${General::swroot}/fwhosts/customnetworks"; +my $name; &General::readhash("${General::swroot}/ethernet/settings", \%netsettings); $cgiparams{'ENABLED'} = 'off'; $cgiparams{'ENABLED_BLUE'} = 'off'; @@ -77,8 +85,13 @@ $cgiparams{'DHCP_WINS'} = ''; $cgiparams{'ROUTES_PUSH'} = ''; $cgiparams{'DCOMPLZO'} = 'off'; $cgiparams{'MSSFIX'} = ''; +$cgiparams{'number'} = ''; +$cgiparams{'PMTU_DISCOVERY'} = ''; $routes_push_file = "${General::swroot}/ovpn/routes_push"; unless (-e $routes_push_file) { system("touch $routes_push_file"); } +unless (-e "${General::swroot}/ovpn/ccd.conf") { system("touch ${General::swroot}/ovpn/ccd.conf"); } +unless (-e "${General::swroot}/ovpn/ccdroute") { system("touch ${General::swroot}/ovpn/ccdroute"); } +unless (-e "${General::swroot}/ovpn/ccdroute2") { system("touch ${General::swroot}/ovpn/ccdroute2"); } &Header::getcgihash(\%cgiparams, {'wantfile' => 1, 'filevar' => 'FH'}); @@ -115,21 +128,6 @@ sub sizeformat{ return("$newsize $units[$i]"); } -sub valid_dns_host { - my $hostname = $_[0]; - unless ($hostname) { return "No hostname"}; - my $res = new Net::DNS::Resolver; - my $query = $res->search("$hostname"); - if ($query) { - foreach my $rr ($query->answer) { - ## Potential bug - we are only looking at A records: - return 0 if $rr->type eq "A"; - } - } else { - return $res->errorstring; - } -} - sub cleanssldatabase { if (open(FILE, ">${General::swroot}/ovpn/certs/serial")) { @@ -168,49 +166,29 @@ sub deletebackupcert unlink ("${General::swroot}/ovpn/certs/$hexvalue.pem"); } } - sub checkportfw { - my $KEY2 = $_[0]; # key2 - my $SRC_PORT = $_[1]; # src_port - my $PROTOCOL = $_[2]; # protocol - my $SRC_IP = $_[3]; # sourceip - - my $pfwfilename = "${General::swroot}/portfw/config"; - open(FILE, $pfwfilename) or die 'Unable to open config file.'; - my @pfwcurrent = ; - close(FILE); - my $pfwkey1 = 0; # used for finding last sequence number used - foreach my $pfwline (@pfwcurrent) - { - my @pfwtemp = split(/\,/,$pfwline); - - chomp ($pfwtemp[8]); - if ($KEY2 eq "0"){ # if key2 is 0 then it is a portfw addition - if ( $SRC_PORT eq $pfwtemp[3] && - $PROTOCOL eq $pfwtemp[2] && - $SRC_IP eq $pfwtemp[7]) - { - $errormessage = "$Lang::tr{'source port in use'} $SRC_PORT"; - } - # Check if key2 = 0, if it is then it is a port forward entry and we want the sequence number - if ( $pfwtemp[1] eq "0") { - $pfwkey1=$pfwtemp[0]; - } - # Darren Critchley - Duplicate or overlapping Port range check - if ($pfwtemp[1] eq "0" && - $PROTOCOL eq $pfwtemp[2] && - $SRC_IP eq $pfwtemp[7] && - $errormessage eq '') - { - &portchecks($SRC_PORT, $pfwtemp[5]); -# &portchecks($pfwtemp[3], $pfwtemp[5]); -# &portchecks($pfwtemp[3], $SRC_IP); + my $DPORT = shift; + my $DPROT = shift; + my %natconfig =(); + my $confignat = "${General::swroot}/forward/config"; + $DPROT= uc ($DPROT); + &General::readhasharray($confignat, \%natconfig); + foreach my $key (sort keys %natconfig){ + my @portarray = split (/\|/,$natconfig{$key}[30]); + foreach my $value (@portarray){ + if ($value =~ /:/i){ + my ($a,$b) = split (":",$value); + if ($DPROT eq $natconfig{$key}[12] && $DPORT gt $a && $DPORT lt $b){ + $errormessage= "$Lang::tr{'source port in use'} $DPORT"; + } + }else{ + if ($DPROT eq $natconfig{$key}[12] && $DPORT eq $value){ + $errormessage= "$Lang::tr{'source port in use'} $DPORT"; + } + } } } - } -# $errormessage="$KEY2 $SRC_PORT $PROTOCOL $SRC_IP"; - - return; + return; } sub checkportoverlap @@ -242,32 +220,6 @@ sub checkportinc return 0; } } -# Darren Critchley - Duplicate or overlapping Port range check -sub portchecks -{ - my $p1 = $_[0]; # New port range - my $p2 = $_[1]; # existing port range -# $_ = $_[0]; - our ($prtrange1, $prtrange2); - $prtrange1 = 0; -# if (m/:/ && $prtrange1 == 1) { # comparing two port ranges -# unless (&checkportoverlap($p1,$p2)) { -# $errormessage = "$Lang::tr{'source port overlaps'} $p1"; -# } -# } - if (m/:/ && $prtrange1 == 0 && $errormessage eq '') { # compare one port to a range - unless (&checkportinc($p2,$p1)) { - $errormessage = "$Lang::tr{'srcprt within existing'} $p1"; - } - } - $prtrange1 = 1; - if (! m/:/ && $prtrange1 == 1 && $errormessage eq '') { # compare one port to a range - unless (&checkportinc($p1,$p2)) { - $errormessage = "$Lang::tr{'srcprt range overlaps'} $p2"; - } - } - return; -} # Darren Critchley - certain ports are reserved for IPFire # TCP 67,68,81,222,445 @@ -313,7 +265,6 @@ sub disallowreserved return; } - sub writeserverconf { my %sovpnsettings = (); my @temp = (); @@ -329,11 +280,11 @@ sub writeserverconf { print CONF "#DAN prepare OpenVPN for listening on blue and orange\n"; print CONF ";local $sovpnsettings{'VPN_IP'}\n"; print CONF "dev $sovpnsettings{'DDEVICE'}\n"; - print CONF "$sovpnsettings{'DDEVICE'}-mtu $sovpnsettings{'DMTU'}\n"; print CONF "proto $sovpnsettings{'DPROTOCOL'}\n"; print CONF "port $sovpnsettings{'DDEST_PORT'}\n"; print CONF "script-security 3 system\n"; print CONF "ifconfig-pool-persist /var/ipfire/ovpn/ovpn-leases.db 3600\n"; + print CONF "client-config-dir /var/ipfire/ovpn/ccd\n"; print CONF "tls-server\n"; print CONF "ca /var/ipfire/ovpn/ca/cacert.pem\n"; print CONF "cert /var/ipfire/ovpn/certs/servercert.pem\n"; @@ -341,26 +292,64 @@ sub writeserverconf { print CONF "dh /var/ipfire/ovpn/ca/dh1024.pem\n"; my @tempovpnsubnet = split("\/",$sovpnsettings{'DOVPN_SUBNET'}); print CONF "server $tempovpnsubnet[0] $tempovpnsubnet[1]\n"; - print CONF "push \"route $netsettings{'GREEN_NETADDRESS'} $netsettings{'GREEN_NETMASK'}\"\n"; - + #print CONF "push \"route $netsettings{'GREEN_NETADDRESS'} $netsettings{'GREEN_NETMASK'}\"\n"; + + # Check if we are using mssfix, fragment or mtu-disc and set the corretct mtu of 1500. + # If we doesn't use one of them, we can use the configured mtu value. + if ($sovpnsettings{'MSSFIX'} eq 'on') + { print CONF "$sovpnsettings{'DDEVICE'}-mtu 1500\n"; } + elsif ($sovpnsettings{'FRAGMENT'} ne '' && $sovpnsettings{'DPROTOCOL'} ne 'tcp') + { print CONF "$sovpnsettings{'DDEVICE'}-mtu 1500\n"; } + elsif (($sovpnsettings{'PMTU_DISCOVERY'} eq 'yes') || + ($sovpnsettings{'PMTU_DISCOVERY'} eq 'maybe') || + ($sovpnsettings{'PMTU_DISCOVERY'} eq 'no' )) + { print CONF "$sovpnsettings{'DDEVICE'}-mtu 1500\n"; } + else + { print CONF "$sovpnsettings{'DDEVICE'}-mtu $sovpnsettings{'DMTU'}\n"; } + if ($vpnsettings{'ROUTES_PUSH'} ne '') { - @temp = split(/\n/,$vpnsettings{'ROUTES_PUSH'}); - foreach (@temp) - { - @tempovpnsubnet = split("\/",&General::ipcidr2msk($_)); - print CONF "push \"route " . $tempovpnsubnet[0]. " " . $tempovpnsubnet[1] . "\"\n"; + @temp = split(/\n/,$vpnsettings{'ROUTES_PUSH'}); + foreach (@temp) + { + @tempovpnsubnet = split("\/",&General::ipcidr2msk($_)); + print CONF "push \"route " . $tempovpnsubnet[0]. " " . $tempovpnsubnet[1] . "\"\n"; + } } - } +# a.marx ccd + my %ccdconfhash=(); + &General::readhasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash); + foreach my $key (keys %ccdconfhash) { + my $a=$ccdconfhash{$key}[1]; + my ($b,$c) = split (/\//, $a); + print CONF "route $b ".&General::cidrtosub($c)."\n"; + } + my %ccdroutehash=(); + &General::readhasharray("${General::swroot}/ovpn/ccdroute", \%ccdroutehash); + foreach my $key (keys %ccdroutehash) { + foreach my $i ( 1 .. $#{$ccdroutehash{$key}}){ + my ($a,$b)=split (/\//,$ccdroutehash{$key}[$i]); + print CONF "route $a $b\n"; + } + } +# ccd end - if ($sovpnsettings{CLIENT2CLIENT} eq 'on') { + if ($sovpnsettings{CLIENT2CLIENT} eq 'on') { print CONF "client-to-client\n"; } if ($sovpnsettings{MSSFIX} eq 'on') { print CONF "mssfix\n"; } if ($sovpnsettings{FRAGMENT} ne '' && $sovpnsettings{'DPROTOCOL'} ne 'tcp') { - print CONF "fragment $sovpnsettings{'FRAGMENT'}\n"; + print CONF "fragment $sovpnsettings{'FRAGMENT'}\n"; + } + + # Check if a valid operating mode has been choosen and use it. + if (($sovpnsettings{'PMTU_DISCOVERY'} eq 'yes') || + ($sovpnsettings{'PMTU_DISCOVERY'} eq 'maybe') || + ($sovpnsettings{'PMTU_DISCOVERY'} eq 'no' )) { + print CONF "mtu-disc $sovpnsettings{'PMTU_DISCOVERY'}\n"; } + if ($sovpnsettings{KEEPALIVE_1} > 0 && $sovpnsettings{KEEPALIVE_2} > 0) { print CONF "keepalive $sovpnsettings{'KEEPALIVE_1'} $sovpnsettings{'KEEPALIVE_2'}\n"; } @@ -406,7 +395,7 @@ sub writeserverconf { close(CONF); } -# + sub emptyserverlog{ if (open(FILE, ">/var/log/ovpnserver.log")) { flock FILE, 2; @@ -416,6 +405,274 @@ sub emptyserverlog{ } +sub delccdnet +{ + my %ccdconfhash = (); + my %ccdhash = (); + my $ccdnetname=$_[0]; + if (-f "${General::swroot}/ovpn/ovpnconfig"){ + &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%ccdhash); + foreach my $key (keys %ccdhash) { + if ($ccdhash{$key}[32] eq $ccdnetname) { + $errormessage=$Lang::tr{'ccd err hostinnet'}; + return; + } + } + } + &General::readhasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash); + foreach my $key (keys %ccdconfhash) { + if ($ccdconfhash{$key}[0] eq $ccdnetname){ + delete $ccdconfhash{$key}; + } + } + &General::writehasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash); + + &writeserverconf; + return 0; +} + +sub addccdnet +{ + my %ccdconfhash=(); + my @ccdconf=(); + my $ccdname=$_[0]; + my $ccdnet=$_[1]; + my $subcidr; + my @ip2=(); + my $checkup; + my $ccdip; + my $baseaddress; + + + #check name + if ($ccdname eq '') + { + $errormessage=$errormessage.$Lang::tr{'ccd err name'}."
"; + return + } + + if(!&General::validhostname($ccdname)) + { + $errormessage=$Lang::tr{'ccd err invalidname'}; + return; + } + + ($ccdip,$subcidr) = split (/\//,$ccdnet); + $subcidr=&General::iporsubtocidr($subcidr); + #check subnet + if ($subcidr > 30) + { + $errormessage=$Lang::tr{'ccd err invalidnet'}; + return; + } + #check ip + if (!&General::validipandmask($ccdnet)){ + $errormessage=$Lang::tr{'ccd err invalidnet'}; + return; + } + + $errormessage=&General::checksubnets($ccdname,$ccdnet); + + + if (!$errormessage) { + my %ccdconfhash=(); + $baseaddress=&General::getnetworkip($ccdip,$subcidr); + &General::readhasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash); + my $key = &General::findhasharraykey (\%ccdconfhash); + foreach my $i (0 .. 1) { $ccdconfhash{$key}[$i] = "";} + $ccdconfhash{$key}[0] = $ccdname; + $ccdconfhash{$key}[1] = $baseaddress."/".$subcidr; + &General::writehasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash); + &writeserverconf; + $cgiparams{'ccdname'}=''; + $cgiparams{'ccdsubnet'}=''; + return 1; + } +} + +sub modccdnet +{ + + my $newname=$_[0]; + my $oldname=$_[1]; + my %ccdconfhash=(); + my %ccdhash=(); + &General::readhasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash); + foreach my $key (keys %ccdconfhash) { + if ($ccdconfhash{$key}[0] eq $oldname) { + foreach my $key1 (keys %ccdconfhash) { + if ($ccdconfhash{$key1}[0] eq $newname){ + $errormessage=$errormessage.$Lang::tr{'ccd err netadrexist'}; + return; + }else{ + $ccdconfhash{$key}[0]= $newname; + &General::writehasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash); + last; + } + } + } + } + + &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%ccdhash); + foreach my $key (keys %ccdhash) { + if ($ccdhash{$key}[32] eq $oldname) { + $ccdhash{$key}[32]=$newname; + &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%ccdhash); + last; + } + } + + return 0; +} +sub ccdmaxclients +{ + my $ccdnetwork=$_[0]; + my @octets=(); + my @subnet=(); + @octets=split("\/",$ccdnetwork); + @subnet= split /\./, &General::cidrtosub($octets[1]); + my ($a,$b,$c,$d,$e); + $a=256-$subnet[0]; + $b=256-$subnet[1]; + $c=256-$subnet[2]; + $d=256-$subnet[3]; + $e=($a*$b*$c*$d)/4; + return $e-1; +} + +sub getccdadresses +{ + my $ipin=$_[0]; + my ($ip1,$ip2,$ip3,$ip4)=split /\./, $ipin; + my $cidr=$_[1]; + chomp($cidr); + my $count=$_[2]; + my $hasip=$_[3]; + chomp($hasip); + my @iprange=(); + my %ccdhash=(); + &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%ccdhash); + $iprange[0]=$ip1.".".$ip2.".".$ip3.".".2; + for (my $i=1;$i<=$count;$i++) { + my $tmpip=$iprange[$i-1]; + my $stepper=$i*4; + $iprange[$i]= &General::getnextip($tmpip,4); + } + my $r=0; + foreach my $key (keys %ccdhash) { + $r=0; + foreach my $tmp (@iprange){ + my ($net,$sub) = split (/\//,$ccdhash{$key}[33]); + if ($net eq $tmp) { + if ( $hasip ne $ccdhash{$key}[33] ){ + splice (@iprange,$r,1); + } + } + $r++; + } + } + return @iprange; +} + +sub fillselectbox +{ + my $boxname=$_[1]; + my ($ccdip,$subcidr) = split("/",$_[0]); + my $tz=$_[2]; + my @allccdips=&getccdadresses($ccdip,$subcidr,&ccdmaxclients($ccdip."/".$subcidr),$tz); + print""; +} + +sub hostsinnet +{ + my $name=$_[0]; + my %ccdhash=(); + my $i=0; + &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%ccdhash); + foreach my $key (keys %ccdhash) { + if ($ccdhash{$key}[32] eq $name){ $i++;} + } + return $i; +} + +sub check_routes_push +{ + my $val=$_[0]; + my ($ip,$cidr) = split (/\//, $val); + ##check for existing routes in routes_push + if (-e "${General::swroot}/ovpn/routes_push") { + open(FILE,"${General::swroot}/ovpn/routes_push"); + while () { + $_=~s/\s*$//g; + + my ($ip2,$cidr2) = split (/\//,"$_"); + my $val2=$ip2."/".&General::iporsubtodec($cidr2); + + if($val eq $val2){ + return 0; + } + #subnetcheck + if (&General::IpInSubnet ($ip,$ip2,&General::iporsubtodec($cidr2))){ + return 0; + } + }; + close(FILE); + } + return 1; +} + +sub check_ccdroute +{ + my %ccdroutehash=(); + my $val=$_[0]; + my ($ip,$cidr) = split (/\//, $val); + #check for existing routes in ccdroute + &General::readhasharray("${General::swroot}/ovpn/ccdroute", \%ccdroutehash); + foreach my $key (keys %ccdroutehash) { + foreach my $i (1 .. $#{$ccdroutehash{$key}}) { + if (&General::iporsubtodec($val) eq $ccdroutehash{$key}[$i] && $ccdroutehash{$key}[0] ne $cgiparams{'NAME'}){ + return 0; + } + my ($ip2,$cidr2) = split (/\//,$ccdroutehash{$key}[$i]); + #subnetcheck + if (&General::IpInSubnet ($ip,$ip2,$cidr2)&& $ccdroutehash{$key}[0] ne $cgiparams{'NAME'} ){ + return 0; + } + } + } + return 1; +} +sub check_ccdconf +{ + my %ccdconfhash=(); + my $val=$_[0]; + my ($ip,$cidr) = split (/\//, $val); + #check for existing routes in ccdroute + &General::readhasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash); + foreach my $key (keys %ccdconfhash) { + if (&General::iporsubtocidr($val) eq $ccdconfhash{$key}[1]){ + return 0; + } + my ($ip2,$cidr2) = split (/\//,$ccdconfhash{$key}[1]); + #subnetcheck + if (&General::IpInSubnet ($ip,$ip2,&General::cidrtosub($cidr2))){ + return 0; + } + + } + return 1; +} + ### # m.a.d net2net ### @@ -450,6 +707,7 @@ sub read_routepushfile while () { $vpnsettings{'ROUTES_PUSH'} .= $_ }; close(FILE); $cgiparams{'ROUTES_PUSH'} = $vpnsettings{'ROUTES_PUSH'}; + } } @@ -489,11 +747,11 @@ if ($cgiparams{'ACTION'} eq $Lang::tr{'start ovpn server'} || &emptyserverlog(); } # #restart openvpn server - if ($cgiparams{'ACTION'} eq $Lang::tr{'restart ovpn server'}){ +# if ($cgiparams{'ACTION'} eq $Lang::tr{'restart ovpn server'}){ #workarund, till SIGHUP also works when running as nobody - system('/usr/local/bin/openvpnctrl', '-r'); - &emptyserverlog(); - } +# system('/usr/local/bin/openvpnctrl', '-r'); +# &emptyserverlog(); +# } } ### @@ -515,6 +773,7 @@ if ($cgiparams{'ACTION'} eq $Lang::tr{'save-adv-options'}) { $vpnsettings{'DHCP_DNS'} = $cgiparams{'DHCP_DNS'}; $vpnsettings{'DHCP_WINS'} = $cgiparams{'DHCP_WINS'}; $vpnsettings{'ROUTES_PUSH'} = $cgiparams{'ROUTES_PUSH'}; + $vpnsettings{'PMTU_DISCOVERY'} = $cgiparams{'PMTU_DISCOVERY'}; my @temp=(); if ($cgiparams{'FRAGMENT'} eq '') { @@ -532,8 +791,19 @@ if ($cgiparams{'ACTION'} eq $Lang::tr{'save-adv-options'}) { } else { $vpnsettings{'MSSFIX'} = $cgiparams{'MSSFIX'}; } + + if (($cgiparams{'PMTU_DISCOVERY'} eq 'yes') || + ($cgiparams{'PMTU_DISCOVERY'} eq 'maybe') || + ($cgiparams{'PMTU_DISCOVERY'} eq 'no' )) { + + if (($cgiparams{'MSSFIX'} eq 'on') || ($cgiparams{'FRAGMENT'} ne '')) { + $errormessage = $Lang::tr{'ovpn mtu-disc with mssfix or fragment'}; + goto ADV_ERROR; + } + } + if ($cgiparams{'DHCP_DOMAIN'} ne ''){ - unless (&General::validfqdn($cgiparams{'DHCP_DOMAIN'}) || &General::validip($cgiparams{'DHCP_DOMAIN'})) { + unless (&General::validdomainname($cgiparams{'DHCP_DOMAIN'}) || &General::validip($cgiparams{'DHCP_DOMAIN'})) { $errormessage = $Lang::tr{'invalid input for dhcp domain'}; goto ADV_ERROR; } @@ -553,25 +823,52 @@ if ($cgiparams{'ACTION'} eq $Lang::tr{'save-adv-options'}) { if ($cgiparams{'ROUTES_PUSH'} ne ''){ @temp = split(/\n/,$cgiparams{'ROUTES_PUSH'}); undef $vpnsettings{'ROUTES_PUSH'}; - foreach (@temp) + + foreach my $tmpip (@temp) { s/^\s+//g; s/\s+$//g; - if ($_) + + if ($tmpip) { - unless (&General::validipandmask($_)) { - $errormessage = $Lang::tr{'ovpn errmsg invalid ip or mask'}; - goto ADV_ERROR; + $tmpip=~s/\s*$//g; + unless (&General::validipandmask($tmpip)) { + $errormessage = "$tmpip ".$Lang::tr{'ovpn errmsg invalid ip or mask'}; + goto ADV_ERROR; } - my ($ip, $cidr) = split("\/",&General::ipcidr2msk($_)); + my ($ip, $cidr) = split("\/",&General::ipcidr2msk($tmpip)); + if ($ip eq $netsettings{'GREEN_NETADDRESS'} && $cidr eq $netsettings{'GREEN_NETMASK'}) { $errormessage = $Lang::tr{'ovpn errmsg green already pushed'}; - goto ADV_ERROR; + goto ADV_ERROR; + } +# a.marx ccd + my %ccdroutehash=(); + &General::readhasharray("${General::swroot}/ovpn/ccdroute", \%ccdroutehash); + foreach my $key (keys %ccdroutehash) { + foreach my $i (1 .. $#{$ccdroutehash{$key}}) { + if ( $ip."/".$cidr eq $ccdroutehash{$key}[$i] ){ + $errormessage="Route $ip\/$cidr ".$Lang::tr{'ccd err inuse'}." $ccdroutehash{$key}[0]" ; + goto ADV_ERROR; + } + my ($ip2,$cidr2) = split(/\//,$ccdroutehash{$key}[$i]); + if (&General::IpInSubnet ($ip,$ip2,$cidr2)){ + $errormessage="Route $ip\/$cidr ".$Lang::tr{'ccd err inuse'}." $ccdroutehash{$key}[0]" ; + goto ADV_ERROR; + } + } } - $vpnsettings{'ROUTES_PUSH'} .= $_."\n"; + +# ccd end + + $vpnsettings{'ROUTES_PUSH'} .= $tmpip."\n"; } - } - &write_routepushfile; + } + &write_routepushfile; undef $vpnsettings{'ROUTES_PUSH'}; + } + else { + undef $vpnsettings{'ROUTES_PUSH'}; + &write_routepushfile; } if ((length($cgiparams{'MAX_CLIENTS'}) == 0) || (($cgiparams{'MAX_CLIENTS'}) < 1 ) || (($cgiparams{'MAX_CLIENTS'}) > 255 )) { $errormessage = $Lang::tr{'invalid input for max clients'}; @@ -625,7 +922,11 @@ unless(-d "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir "${General print SERVERCONF "persist-key\n"; print SERVERCONF "script-security 2\n"; print SERVERCONF "# IP/DNS for remote Server Gateway\n"; + + if ($cgiparams{'REMOTE'} ne '') { print SERVERCONF "remote $cgiparams{'REMOTE'}\n"; + } + print SERVERCONF "float\n"; print SERVERCONF "# IP adresses of the VPN Subnet\n"; print SERVERCONF "ifconfig $ovsubnet.1 $ovsubnet.2\n"; @@ -651,6 +952,17 @@ unless(-d "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir "${General if ($cgiparams{'FRAGMENT'} ne '') {print SERVERCONF "fragment $cgiparams{'FRAGMENT'}\n";} if ($cgiparams{'MSSFIX'} eq 'on') {print SERVERCONF "mssfix\n"; }; } + + # Check if a valid operating mode has been choosen and use it. + if (($cgiparams{'PMTU_DISCOVERY'} eq 'yes') || + ($cgiparams{'PMTU_DISCOVERY'} eq 'maybe') || + ($cgiparams{'PMTU_DISCOVERY'} eq 'no' )) { + if(($cgiparams{'MSSFIX'} ne 'on') || ($cgiparams{'FRAGMENT'} eq '')) { + if($cgiparams{'MTU'} eq '1500') { + print SERVERCONF "mtu-disc $cgiparams{'PMTU_DISCOVERY'}\n"; + } + } + } print SERVERCONF "# Auth. Server\n"; print SERVERCONF "tls-server\n"; print SERVERCONF "ca ${General::swroot}/ovpn/ca/cacert.pem\n"; @@ -729,6 +1041,17 @@ unless(-d "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir "${General if ($cgiparams{'FRAGMENT'} ne '') {print CLIENTCONF "fragment $cgiparams{'FRAGMENT'}\n";} if ($cgiparams{'MSSFIX'} eq 'on') {print CLIENTCONF "mssfix\n"; }; } + + # Check if a valid operating mode has been choosen and use it. + if (($cgiparams{'PMTU_DISCOVERY'} eq 'yes') || + ($cgiparams{'PMTU_DISCOVERY'} eq 'maybe') || + ($cgiparams{'PMTU_DISCOVERY'} eq 'no' )) { + if(($cgiparams{'MSSFIX'} ne 'on') || ($cgiparams{'FRAGMENT'} eq '')) { + if ($cgiparams{'MTU'} eq '1500') { + print CLIENTCONF "mtu-disc $cgiparams{'PMTU_DISCOVERY'}\n"; + } + } + } print CLIENTCONF "ns-cert-type server\n"; print CLIENTCONF "# Auth. Client\n"; @@ -776,7 +1099,7 @@ if ($cgiparams{'ACTION'} eq $Lang::tr{'save'} && $cgiparams{'TYPE'} eq '' && $cg if ($cgiparams{'ENABLED'} eq 'on'){ - &checkportfw(0,$cgiparams{'DDEST_PORT'},$cgiparams{'DPROTOCOL'},'0.0.0.0'); + &checkportfw($cgiparams{'DDEST_PORT'},$cgiparams{'DPROTOCOL'}); } if ($errormessage) { goto SETTINGS_ERROR; } @@ -1566,29 +1889,26 @@ END my $n2nactive = `/bin/ps ax|grep $confighash{$cgiparams{'KEY'}}[1]|grep -v grep|awk \'{print \$1}\'`; if ($confighash{$cgiparams{'KEY'}}) { + if ($confighash{$cgiparams{'KEY'}}[0] eq 'off') { + $confighash{$cgiparams{'KEY'}}[0] = 'on'; + &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); - - if ($confighash{$cgiparams{'KEY'}}[0] eq 'off') { - $confighash{$cgiparams{'KEY'}}[0] = 'on'; - &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); - - if ($confighash{$cgiparams{'KEY'}}[3] eq 'net'){ + if ($confighash{$cgiparams{'KEY'}}[3] eq 'net'){ system('/usr/local/bin/openvpnctrl', '-sn2n', $confighash{$cgiparams{'KEY'}}[1]); - } - - } else { + } + } else { - $confighash{$cgiparams{'KEY'}}[0] = 'off'; - &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); + $confighash{$cgiparams{'KEY'}}[0] = 'off'; + &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); - if ($confighash{$cgiparams{'KEY'}}[3] eq 'net'){ + if ($confighash{$cgiparams{'KEY'}}[3] eq 'net'){ if ($n2nactive ne ''){ - system('/usr/local/bin/openvpnctrl', '-kn2n', $confighash{$cgiparams{'KEY'}}[1]); - } + system('/usr/local/bin/openvpnctrl', '-kn2n', $confighash{$cgiparams{'KEY'}}[1]); + } - } else { + } else { $errormessage = $Lang::tr{'invalid key'}; - } + } } } @@ -1660,6 +1980,15 @@ if ($confighash{$cgiparams{'KEY'}}[3] eq 'net'){ if ($confighash{$cgiparams{'KEY'}}[24] ne '') {print CLIENTCONF "fragment $confighash{$cgiparams{'KEY'}}[24]\n";} if ($confighash{$cgiparams{'KEY'}}[23] eq 'on') {print CLIENTCONF "mssfix\n";} } + if (($confighash{$cgiparams{'KEY'}}[38] eq 'yes') || + ($confighash{$cgiparams{'KEY'}}[38] eq 'maybe') || + ($confighash{$cgiparams{'KEY'}}[38] eq 'no' )) { + if (($confighash{$cgiparams{'KEY'}}[23] ne 'on') || ($confighash{$cgiparams{'KEY'}}[24] eq '')) { + if ($tunmtu eq '1500' ) { + print CLIENTCONF "mtu-disc $confighash{$cgiparams{'KEY'}}[38]\n"; + } + } + } print CLIENTCONF "ns-cert-type server\n"; print CLIENTCONF "# Auth. Client\n"; print CLIENTCONF "tls-client\n"; @@ -1713,12 +2042,26 @@ else my $zip = Archive::Zip->new(); - print CLIENTCONF "#OpenVPN Server conf\r\n"; + print CLIENTCONF "#OpenVPN Client conf\r\n"; print CLIENTCONF "tls-client\r\n"; print CLIENTCONF "client\r\n"; + print CLIENTCONF "nobind\r\n"; print CLIENTCONF "dev $vpnsettings{'DDEVICE'}\r\n"; print CLIENTCONF "proto $vpnsettings{'DPROTOCOL'}\r\n"; - print CLIENTCONF "$vpnsettings{'DDEVICE'}-mtu $vpnsettings{'DMTU'}\r\n"; + + # Check if we are using fragment, mssfix or mtu-disc and set MTU to 1500 + # or use configured value. + if ($vpnsettings{FRAGMENT} ne '' && $vpnsettings{DPROTOCOL} ne 'tcp' ) + { print CLIENTCONF "$vpnsettings{'DDEVICE'}-mtu 1500\r\n"; } + elsif ($vpnsettings{MSSFIX} eq 'on') + { print CLIENTCONF "$vpnsettings{'DDEVICE'}-mtu 1500\r\n"; } + elsif (($vpnsettings{'PMTU_DISCOVERY'} eq 'yes') || + ($vpnsettings{'PMTU_DISCOVERY'} eq 'maybe') || + ($vpnsettings{'PMTU_DISCOVERY'} eq 'no' )) + { print CLIENTCONF "$vpnsettings{'DDEVICE'}-mtu 1500\r\n"; } + else + { print CLIENTCONF "$vpnsettings{'DDEVICE'}-mtu $vpnsettings{'DMTU'}\r\n"; } + if ( $vpnsettings{'ENABLED'} eq 'on'){ print CLIENTCONF "remote $vpnsettings{'VPN_IP'} $vpnsettings{'DDEST_PORT'}\r\n"; if ( $vpnsettings{'ENABLED_BLUE'} eq 'on' && (&haveBlueNet())){ @@ -1762,6 +2105,15 @@ else if ($vpnsettings{FRAGMENT} ne '' && $vpnsettings{DPROTOCOL} ne 'tcp' ) { print CLIENTCONF "fragment $vpnsettings{'FRAGMENT'}\r\n"; } + + # Check if a valid operating mode has been choosen and use it. + if (($vpnsettings{'PMTU_DISCOVERY'} eq 'yes') || + ($vpnsettings{'PMTU_DISCOVERY'} eq 'maybe') || + ($vpnsettings{'PMTU_DISCOVERY'} eq 'no' )) { + if(($vpnsettings{MSSFIX} ne 'on') || ($vpnsettings{FRAGMENT} eq '')) { + print CLIENTCONF "mtu-disc $vpnsettings{'PMTU_DISCOVERY'}\r\n"; + } + } close(CLIENTCONF); $zip->addFile( "$tempdir/$clientovpn", $clientovpn) or die "Can't add file $clientovpn\n"; @@ -1809,10 +2161,41 @@ else } unlink ("${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem"); - unlink ("${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12"); + unlink ("${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12"); + +# A.Marx CCD delete ccd files and routes + + + if (-f "${General::swroot}/ovpn/ccd/$confighash{$cgiparams{'KEY'}}[2]") + { + unlink "${General::swroot}/ovpn/ccd/$confighash{$cgiparams{'KEY'}}[2]"; + } + + &General::readhasharray("${General::swroot}/ovpn/ccdroute", \%ccdroutehash); + foreach my $key (keys %ccdroutehash) { + if ($ccdroutehash{$key}[0] eq $confighash{$cgiparams{'KEY'}}[1]){ + delete $ccdroutehash{$key}; + } + } + &General::writehasharray("${General::swroot}/ovpn/ccdroute", \%ccdroutehash); + + &General::readhasharray("${General::swroot}/ovpn/ccdroute2", \%ccdroute2hash); + foreach my $key (keys %ccdroute2hash) { + if ($ccdroute2hash{$key}[0] eq $confighash{$cgiparams{'KEY'}}[1]){ + delete $ccdroute2hash{$key}; + } + } + &General::writehasharray("${General::swroot}/ovpn/ccdroute2", \%ccdroute2hash); + &writeserverconf; + + +# CCD end + + delete $confighash{$cgiparams{'KEY'}}; my $temp2 = `/usr/bin/openssl ca -gencrl -out ${General::swroot}/ovpn/crls/cacrl.pem -config ${General::swroot}/ovpn/openssl/ovpn.cnf`; &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); + #&writeserverconf(); } else { $errormessage = $Lang::tr{'invalid key'}; @@ -1879,9 +2262,11 @@ else %cgiparams = (); %cahash = (); %confighash = (); + my $disabled; &General::readhash("${General::swroot}/ovpn/settings", \%cgiparams); read_routepushfile; - + + # if ($cgiparams{'CLIENT2CLIENT'} eq '') { # $cgiparams{'CLIENT2CLIENT'} = 'on'; # } @@ -1889,7 +2274,6 @@ ADV_ERROR: if ($cgiparams{'MAX_CLIENTS'} eq '') { $cgiparams{'MAX_CLIENTS'} = '100'; } - if ($cgiparams{'KEEPALIVE_1'} eq '') { $cgiparams{'KEEPALIVE_1'} = '10'; } @@ -1897,7 +2281,10 @@ ADV_ERROR: $cgiparams{'KEEPALIVE_2'} = '60'; } if ($cgiparams{'LOG_VERB'} eq '') { - $cgiparams{'LOG_VERB'} = '3'; + $cgiparams{'LOG_VERB'} = '3'; + } + if ($cgiparams{'PMTU_DISCOVERY'} eq '') { + $cgiparams{'PMTU_DISCOVERY'} = 'off'; } $checked{'CLIENT2CLIENT'}{'off'} = ''; $checked{'CLIENT2CLIENT'}{'on'} = ''; @@ -1909,6 +2296,7 @@ ADV_ERROR: $checked{'MSSFIX'}{'off'} = ''; $checked{'MSSFIX'}{'on'} = ''; $checked{'MSSFIX'}{$cgiparams{'MSSFIX'}} = 'CHECKED'; + $checked{'PMTU_DISCOVERY'}{$cgiparams{'PMTU_DISCOVERY'}} = 'checked=\'checked\''; $selected{'LOG_VERB'}{'1'} = ''; $selected{'LOG_VERB'}{'2'} = ''; $selected{'LOG_VERB'}{'3'} = ''; @@ -1922,9 +2310,7 @@ ADV_ERROR: $selected{'LOG_VERB'}{'11'} = ''; $selected{'LOG_VERB'}{'0'} = ''; $selected{'LOG_VERB'}{$cgiparams{'LOG_VERB'}} = 'SELECTED'; - - - + &Header::showhttpheaders(); &Header::openpage($Lang::tr{'status ovpn'}, 1, ''); &Header::openbigbox('100%', 'LEFT', '', $errormessage); @@ -1937,7 +2323,7 @@ ADV_ERROR: &Header::openbox('100%', 'LEFT', $Lang::tr{'advanced server'}); print < - +
@@ -1946,7 +2332,7 @@ ADV_ERROR: - + @@ -1971,7 +2357,7 @@ if ($cgiparams{'ROUTES_PUSH'} ne '') print $cgiparams{'ROUTES_PUSH'}; } -print < @@ -1982,7 +2368,7 @@ print <$Lang::tr{'misc-options'} - + @@ -1997,7 +2383,7 @@ print < - @@ -2011,7 +2397,15 @@ print <mssfix - + + + + + + + + +
$Lang::tr{'dhcp-options'}
Domain
DNS
Client-To-Client
Keppalive
+
Keepalive
(ping/ping-restart)
Default: on
$Lang::tr{'ovpn mtu-disc'} $Lang::tr{'ovpn mtu-disc yes'} $Lang::tr{'ovpn mtu-disc maybe'} $Lang::tr{'ovpn mtu-disc no'} $Lang::tr{'ovpn mtu-disc off'}