X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=html%2Fcgi-bin%2Fovpnmain.cgi;h=7a2833ce61bd5c283ef72112d41fd7e48df96092;hb=0fd28c360e123d770017207b434ff1de0cb7ed38;hp=eac962e6c7ba9f16fb7f0bd3778adaaf5df80b2f;hpb=d8ef6a9537537ed43d7766ced22d3500b965ed1a;p=people%2Fpmueller%2Fipfire-2.x.git diff --git a/html/cgi-bin/ovpnmain.cgi b/html/cgi-bin/ovpnmain.cgi index eac962e6c7..7a2833ce61 100644 --- a/html/cgi-bin/ovpnmain.cgi +++ b/html/cgi-bin/ovpnmain.cgi @@ -35,7 +35,7 @@ require '/var/ipfire/general-functions.pl'; require "${General::swroot}/lang.pl"; require "${General::swroot}/header.pl"; require "${General::swroot}/countries.pl"; -require "${General::swroot}/geoip-functions.pl"; +require "${General::swroot}/location-functions.pl"; # enable only the following on debugging purpose #use warnings; @@ -47,7 +47,7 @@ undef (@dummy); my %color = (); my %mainsettings = (); &General::readhash("${General::swroot}/main/settings", \%mainsettings); -&General::readhash("/srv/web/ipfire/html/themes/".$mainsettings{'THEME'}."/include/colors.txt", \%color); +&General::readhash("/srv/web/ipfire/html/themes/ipfire/include/colors.txt", \%color); ### ### Initialize variables @@ -64,6 +64,8 @@ my %cahash=(); my %selected=(); my $warnmessage = ''; my $errormessage = ''; +my $cryptoerror = ''; +my $cryptowarning = ''; my %settings=(); my $routes_push_file = ''; my $confighost="${General::swroot}/fwhosts/customhosts"; @@ -97,6 +99,8 @@ $cgiparams{'DCIPHER'} = ''; $cgiparams{'DAUTH'} = ''; $cgiparams{'TLSAUTH'} = ''; $routes_push_file = "${General::swroot}/ovpn/routes_push"; +# Perform crypto and configration test +&pkiconfigcheck; # Add CCD files if not already presant unless (-e $routes_push_file) { @@ -170,7 +174,12 @@ sub cleanssldatabase print FILE ""; close FILE; } + if (open(FILE, ">${General::swroot}/ovpn/certs/index.txt.attr")) { + print FILE ""; + close FILE; + } unlink ("${General::swroot}/ovpn/certs/index.txt.old"); + unlink ("${General::swroot}/ovpn/certs/index.txt.attr.old"); unlink ("${General::swroot}/ovpn/certs/serial.old"); unlink ("${General::swroot}/ovpn/certs/01.pem"); } @@ -183,9 +192,13 @@ sub newcleanssldatabase close FILE; } if (! -s ">${General::swroot}/ovpn/certs/index.txt") { - system ("touch ${General::swroot}/ovpn/certs/index.txt"); + &General::system("touch", "${General::swroot}/ovpn/certs/index.txt"); + } + if (! -s ">${General::swroot}/ovpn/certs/index.txt.attr") { + &General::system("touch", "${General::swroot}/ovpn/certs/index.txt.attr"); } unlink ("${General::swroot}/ovpn/certs/index.txt.old"); + unlink ("${General::swroot}/ovpn/certs/index.txt.attr.old"); unlink ("${General::swroot}/ovpn/certs/serial.old"); } @@ -199,6 +212,57 @@ sub deletebackupcert } } +### +### Check for PKI and configure problems +### + +sub pkiconfigcheck +{ + # Warning if DH parameter is 1024 bit + if (-f "${General::swroot}/ovpn/ca/$cgiparams{'DH_NAME'}") { + my @dhparameter = &General::system_output("/usr/bin/openssl", "dhparam", "-text", "-in", "${General::swroot}/ovpn/ca/$cgiparams{'DH_NAME'}"); + my $dhbit; + + # Loop through the output and search for the DH bit lenght. + foreach my $line (@dhparameter) { + if ($line =~ (/(\d+)/)) { + # Assign match to dhbit value. + $dhbit = $1; + + last; + } + } + + # Check if the used key lenght is at least 2048 bit. + if ($dhbit < 2048) { + $cryptoerror = "$Lang::tr{'ovpn error dh'}"; + goto CRYPTO_ERROR; + } + } + + # Warning if md5 is in usage + if (-f "${General::swroot}/ovpn/certs/servercert.pem") { + my @signature = &General::system_output("/usr/bin/openssl", "x509", "-noout", "-text", "-in", "${General::swroot}/ovpn/certs/servercert.pem"); + if (grep(/md5WithRSAEncryption/, @signature) ) { + $cryptoerror = "$Lang::tr{'ovpn error md5'}"; + goto CRYPTO_ERROR; + } + } + + CRYPTO_ERROR: + + # Warning if certificate is not compliant to RFC3280 TLS rules + if (-f "${General::swroot}/ovpn/certs/servercert.pem") { + my @extendkeyusage = &General::system_output("/usr/bin/openssl", "x509", "-noout", "-text", "-in", "${General::swroot}/ovpn/certs/servercert.pem"); + if ( ! grep(/TLS Web Server Authentication/, @extendkeyusage)) { + $cryptowarning = "$Lang::tr{'ovpn warning rfc3280'}"; + goto CRYPTO_WARNING; + } + } + + CRYPTO_WARNING: +} + sub writeserverconf { my %sovpnsettings = (); my @temp = (); @@ -228,14 +292,7 @@ sub writeserverconf { print CONF "server $tempovpnsubnet[0] $tempovpnsubnet[1]\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 "tun-mtu 1500\n"; } - elsif ($sovpnsettings{'FRAGMENT'} ne '' && $sovpnsettings{'DPROTOCOL'} ne 'tcp') - { print CONF "tun-mtu 1500\n"; } - else - { print CONF "tun-mtu $sovpnsettings{'DMTU'}\n"; } + print CONF "tun-mtu $sovpnsettings{'DMTU'}\n"; if ($vpnsettings{'ROUTES_PUSH'} ne '') { @temp = split(/\n/,$vpnsettings{'ROUTES_PUSH'}); @@ -268,6 +325,8 @@ sub writeserverconf { } if ($sovpnsettings{MSSFIX} eq 'on') { print CONF "mssfix\n"; + } else { + print CONF "mssfix 0\n"; } if ($sovpnsettings{FRAGMENT} ne '' && $sovpnsettings{'DPROTOCOL'} ne 'tcp') { print CONF "fragment $sovpnsettings{'FRAGMENT'}\n"; @@ -280,11 +339,10 @@ sub writeserverconf { print CONF "status /var/run/ovpnserver.log 30\n"; print CONF "ncp-disable\n"; print CONF "cipher $sovpnsettings{DCIPHER}\n"; - if ($sovpnsettings{'DAUTH'} eq '') { - print CONF ""; - } else { print CONF "auth $sovpnsettings{'DAUTH'}\n"; - } + # Set TLSv2 as minimum + print CONF "tls-version-min 1.2\n"; + if ($sovpnsettings{'TLSAUTH'} eq 'on') { print CONF "tls-auth ${General::swroot}/ovpn/certs/ta.key\n"; } @@ -306,10 +364,10 @@ sub writeserverconf { print CONF "push \"dhcp-option WINS $sovpnsettings{DHCP_WINS}\"\n"; } - if ($sovpnsettings{DHCP_WINS} eq '') { + if ($sovpnsettings{MAX_CLIENTS} eq '') { print CONF "max-clients 100\n"; } - if ($sovpnsettings{DHCP_WINS} ne '') { + if ($sovpnsettings{MAX_CLIENTS} ne '') { print CONF "max-clients $sovpnsettings{MAX_CLIENTS}\n"; } print CONF "tls-verify /usr/lib/openvpn/verify\n"; @@ -323,6 +381,11 @@ sub writeserverconf { } else { print CONF "verb 3\n"; } + + print CONF "# Log clients connecting/disconnecting\n"; + print CONF "client-connect \"/usr/sbin/openvpn-metrics client-connect\"\n"; + print CONF "client-disconnect \"/usr/sbin/openvpn-metrics client-disconnect\"\n"; + # Print server.conf.local if entries exist to server.conf if ( !-z $local_serverconf && $sovpnsettings{'ADDITIONAL_CONFIGS'} eq 'on') { open (LSC, "$local_serverconf"); @@ -417,10 +480,7 @@ sub addccdnet $errormessage=$Lang::tr{'ccd err invalidnet'}; return; } - - $errormessage=&General::checksubnets($ccdname,$ccdnet); - - + if (!$errormessage) { my %ccdconfhash=(); $baseaddress=&General::getnetworkip($ccdip,$subcidr); @@ -444,6 +504,13 @@ sub modccdnet my $oldname=$_[1]; my %ccdconfhash=(); my %ccdhash=(); + + # Check if the new name is valid. + if(!&General::validhostname($newname)) { + $errormessage=$Lang::tr{'ccd err invalidname'}; + return; + } + &General::readhasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash); foreach my $key (keys %ccdconfhash) { if ($ccdconfhash{$key}[0] eq $oldname) { @@ -679,7 +746,7 @@ sub writecollectdconf { close(COLLECTDVPN); # Reload collectd afterwards - system("/usr/local/bin/collectdctrl restart &>/dev/null"); + &General::system("/usr/local/bin/collectdctrl", "restart"); } #hier die refresh page @@ -709,11 +776,11 @@ if ($cgiparams{'ACTION'} eq $Lang::tr{'start ovpn server'} || #start openvpn server if ($cgiparams{'ACTION'} eq $Lang::tr{'start ovpn server'}){ &emptyserverlog(); - system('/usr/local/bin/openvpnctrl', '-s'); + &General::system("/usr/local/bin/openvpnctrl", "-s"); } #stop openvpn server if ($cgiparams{'ACTION'} eq $Lang::tr{'stop ovpn server'}){ - system('/usr/local/bin/openvpnctrl', '-k'); + &General::system("/usr/local/bin/openvpnctrl", "-k"); &emptyserverlog(); } # #restart openvpn server @@ -739,13 +806,12 @@ if ($cgiparams{'ACTION'} eq $Lang::tr{'save-adv-options'}) { $vpnsettings{'MAX_CLIENTS'} = $cgiparams{'MAX_CLIENTS'}; $vpnsettings{'REDIRECT_GW_DEF1'} = $cgiparams{'REDIRECT_GW_DEF1'}; $vpnsettings{'CLIENT2CLIENT'} = $cgiparams{'CLIENT2CLIENT'}; + $vpnsettings{'DCOMPLZO'} = $cgiparams{'DCOMPLZO'}; $vpnsettings{'ADDITIONAL_CONFIGS'} = $cgiparams{'ADDITIONAL_CONFIGS'}; $vpnsettings{'DHCP_DOMAIN'} = $cgiparams{'DHCP_DOMAIN'}; $vpnsettings{'DHCP_DNS'} = $cgiparams{'DHCP_DNS'}; $vpnsettings{'DHCP_WINS'} = $cgiparams{'DHCP_WINS'}; $vpnsettings{'ROUTES_PUSH'} = $cgiparams{'ROUTES_PUSH'}; - $vpnsettings{'DAUTH'} = $cgiparams{'DAUTH'}; - $vpnsettings{'TLSAUTH'} = $cgiparams{'TLSAUTH'}; my @temp=(); if ($cgiparams{'FRAGMENT'} eq '') { @@ -833,7 +899,7 @@ if ($cgiparams{'ACTION'} eq $Lang::tr{'save-adv-options'}) { undef $vpnsettings{'ROUTES_PUSH'}; &write_routepushfile; } - if ((length($cgiparams{'MAX_CLIENTS'}) == 0) || (($cgiparams{'MAX_CLIENTS'}) < 1 ) || (($cgiparams{'MAX_CLIENTS'}) > 255 )) { + if ((length($cgiparams{'MAX_CLIENTS'}) == 0) || (($cgiparams{'MAX_CLIENTS'}) < 1 ) || (($cgiparams{'MAX_CLIENTS'}) > 1024 )) { $errormessage = $Lang::tr{'invalid input for max clients'}; goto ADV_ERROR; } @@ -853,17 +919,6 @@ if ($cgiparams{'ACTION'} eq $Lang::tr{'save-adv-options'}) { $errormessage = $Lang::tr{'invalid input for keepalive 1:2'}; goto ADV_ERROR; } - # Create ta.key for tls-auth if not presant - if ($cgiparams{'TLSAUTH'} eq 'on') { - if ( ! -e "${General::swroot}/ovpn/certs/ta.key") { - system('/usr/sbin/openvpn', '--genkey', '--secret', "${General::swroot}/ovpn/certs/ta.key"); - if ($?) { - $errormessage = "$Lang::tr{'openssl produced an error'}: $?"; - goto ADV_ERROR; - } - } - } - &General::writehash("${General::swroot}/ovpn/settings", \%vpnsettings); &writeserverconf();#hier ok } @@ -927,7 +982,7 @@ unless(-d "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir "${General if ($cgiparams{'MTU'} eq '') {$tunmtu = '1500'} else {$tunmtu = $cgiparams{'MTU'}}; print SERVERCONF "tun-mtu $tunmtu\n"; if ($cgiparams{'FRAGMENT'} ne '') {print SERVERCONF "fragment $cgiparams{'FRAGMENT'}\n";} - if ($cgiparams{'MSSFIX'} eq 'on') {print SERVERCONF "mssfix\n"; }; + if ($cgiparams{'MSSFIX'} eq 'on') {print SERVERCONF "mssfix\n"; } else { print SERVERCONF "mssfix 0\n" }; } print SERVERCONF "# Auth. Server\n"; @@ -950,6 +1005,9 @@ unless(-d "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir "${General print SERVERCONF "auth $cgiparams{'DAUTH'}\n"; } + # Set TLSv1.2 as minimum + print SERVERCONF "tls-version-min 1.2\n"; + if ($cgiparams{'COMPLZO'} eq 'on') { print SERVERCONF "# Enable Compression\n"; print SERVERCONF "comp-lzo\n"; @@ -1023,14 +1081,14 @@ unless(-d "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir "${General if ($cgiparams{'MTU'} eq '') {$tunmtu = '1500'} else {$tunmtu = $cgiparams{'MTU'}}; print CLIENTCONF "tun-mtu $tunmtu\n"; if ($cgiparams{'FRAGMENT'} ne '') {print CLIENTCONF "fragment $cgiparams{'FRAGMENT'}\n";} - if ($cgiparams{'MSSFIX'} eq 'on') {print CLIENTCONF "mssfix\n"; }; + if ($cgiparams{'MSSFIX'} eq 'on') {print CLIENTCONF "mssfix\n"; } else { print CLIENTCONF "mssfix 0\n" }; } # Check host certificate if X509 is RFC3280 compliant. # If not, old --ns-cert-type directive will be used. # If appropriate key usage extension exists, new --remote-cert-tls directive will be used. - my $hostcert = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/certs/servercert.pem`; - if ($hostcert !~ /TLS Web Server Authentication/) { + my @hostcert = &General::system_output("/usr/bin/openssl", "x509", "-text", "-in", "${General::swroot}/ovpn/certs/servercert.pem"); + if ( ! grep(/TLS Web Server Authentication/, @hostcert)) { print CLIENTCONF "ns-cert-type server\n"; } else { print CLIENTCONF "remote-cert-tls server\n"; @@ -1052,6 +1110,9 @@ unless(-d "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir "${General print CLIENTCONF "auth $cgiparams{'DAUTH'}\n"; } + # Set TLSv1.2 as minimum + print CLIENTCONF "tls-version-min 1.2\n"; + if ($cgiparams{'COMPLZO'} eq 'on') { print CLIENTCONF "# Enable Compression\n"; print CLIENTCONF "comp-lzo\n"; @@ -1069,7 +1130,7 @@ unless(-d "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir "${General close(CLIENTCONF); } - + ### ### Save main settings ### @@ -1144,6 +1205,18 @@ if ($cgiparams{'ACTION'} eq $Lang::tr{'save'} && $cgiparams{'TYPE'} eq '' && $cg goto SETTINGS_ERROR; } + # Create ta.key for tls-auth if not presant + if ($cgiparams{'TLSAUTH'} eq 'on') { + if ( ! -e "${General::swroot}/ovpn/certs/ta.key") { + # This system call is safe, because all arguements are passed as an array. + system("/usr/sbin/openvpn", "--genkey", "--secret", "${General::swroot}/ovpn/certs/ta.key"); + if ($?) { + $errormessage = "$Lang::tr{'openssl produced an error'}: $?"; + goto SETTINGS_ERROR; + } + } + } + $vpnsettings{'ENABLED_BLUE'} = $cgiparams{'ENABLED_BLUE'}; $vpnsettings{'ENABLED_ORANGE'} =$cgiparams{'ENABLED_ORANGE'}; $vpnsettings{'ENABLED'} = $cgiparams{'ENABLED'}; @@ -1155,11 +1228,28 @@ if ($cgiparams{'ACTION'} eq $Lang::tr{'save'} && $cgiparams{'TYPE'} eq '' && $cg $vpnsettings{'DMTU'} = $cgiparams{'DMTU'}; $vpnsettings{'DCOMPLZO'} = $cgiparams{'DCOMPLZO'}; $vpnsettings{'DCIPHER'} = $cgiparams{'DCIPHER'}; + $vpnsettings{'DAUTH'} = $cgiparams{'DAUTH'}; + $vpnsettings{'TLSAUTH'} = $cgiparams{'TLSAUTH'}; #wrtie enable - if ( $vpnsettings{'ENABLED_BLUE'} eq 'on' ) {system("touch ${General::swroot}/ovpn/enable_blue 2>/dev/null");}else{system("unlink ${General::swroot}/ovpn/enable_blue 2>/dev/null");} - if ( $vpnsettings{'ENABLED_ORANGE'} eq 'on' ) {system("touch ${General::swroot}/ovpn/enable_orange 2>/dev/null");}else{system("unlink ${General::swroot}/ovpn/enable_orange 2>/dev/null");} - if ( $vpnsettings{'ENABLED'} eq 'on' ) {system("touch ${General::swroot}/ovpn/enable 2>/dev/null");}else{system("unlink ${General::swroot}/ovpn/enable 2>/dev/null");} + if ( $vpnsettings{'ENABLED_BLUE'} eq 'on' ) { + &General::system("touch", "${General::swroot}/ovpn/enable_blue"); + } else { + unlink("${General::swroot}/ovpn/enable_blue"); + } + + if ( $vpnsettings{'ENABLED_ORANGE'} eq 'on' ) { + &General::system("touch", "${General::swroot}/ovpn/enable_orange"); + } else { + unlink("${General::swroot}/ovpn/enable_orange"); + } + + if ( $vpnsettings{'ENABLED'} eq 'on' ) { + &General::system("touch", "${General::swroot}/ovpn/enable"); + } else { + unlink("${General::swroot}/ovpn/enable"); + } + #new settings for daemon &General::writehash("${General::swroot}/ovpn/settings", \%vpnsettings); &writeserverconf();#hier ok @@ -1172,7 +1262,7 @@ SETTINGS_ERROR: &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); # Kill all N2N connections - system("/usr/local/bin/openvpnctrl -kn2n &>/dev/null"); + &General::system("/usr/local/bin/openvpnctrl", "-kn2n"); foreach my $key (keys %confighash) { my $name = $confighash{$cgiparams{'$key'}}[1]; @@ -1181,7 +1271,7 @@ SETTINGS_ERROR: delete $confighash{$cgiparams{'$key'}}; } - system ("/usr/local/bin/openvpnctrl -drrd $name"); + &General::system("/usr/local/bin/openvpnctrl", "-drrd", "$name"); } while ($file = glob("${General::swroot}/ovpn/ca/*")) { unlink $file; @@ -1220,7 +1310,7 @@ SETTINGS_ERROR: close FILE; } while ($file = glob("${General::swroot}/ovpn/n2nconf/*")) { - system ("rm -rf $file"); + unlink($file); } # Remove everything from the collectd configuration @@ -1266,7 +1356,8 @@ END unlink "${General::swroot}/ovpn/ca/$cgiparams{'DH_NAME'}"; } # Create Diffie Hellmann Parameter - system('/usr/bin/openssl', 'dhparam', '-out', "${General::swroot}/ovpn/ca/dh1024.pem", "$cgiparams{'DHLENGHT'}"); + # The system call is safe, because all arguments are passed as an array. + system("/usr/bin/openssl", "dhparam", "-out", "${General::swroot}/ovpn/ca/dh1024.pem", "$cgiparams{'DHLENGHT'}"); if ($?) { $errormessage = "$Lang::tr{'openssl produced an error'}: $?"; unlink ("${General::swroot}/ovpn/ca/dh1024.pem"); @@ -1291,7 +1382,6 @@ END
$Lang::tr{'ovpn dh'}: + $Lang::tr{'comp-lzo'} + + $Lang::tr{'openvpn default'}: off ($Lang::tr{'attention'} exploitable via Voracle) + + $Lang::tr{'ovpn add conf'} @@ -2782,36 +2890,6 @@ print <
- - - - - - - - - - - -
$Lang::tr{'ovpn crypt options'}
$Lang::tr{'ovpn ha'} - $Lang::tr{'openvpn default'}: SHA1 (160 $Lang::tr{'bit'})
- - - - - - - - - - -
HMAC tls-auth

END if ( -e "/var/run/openvpn.pid"){ @@ -3034,8 +3112,8 @@ END $users[$uid]{'Proto'} = $proto; # get country code for "RealAddress"... - my $ccode = &GeoIP::lookup((split ':', $users[$uid]{'RealAddress'})[0]); - my $flag_icon = &GeoIP::get_flag_icon($ccode); + my $ccode = &Location::Functions::lookup_country_code((split ':', $users[$uid]{'RealAddress'})[0]); + my $flag_icon = &Location::Functions::get_flag_icon($ccode); $users[$uid]{'Country'} = "$ccode"; $uid++; } @@ -3098,7 +3176,12 @@ END if ( -f "${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem") { print "Content-Disposition: filename=" . $confighash{$cgiparams{'KEY'}}[1] . "cert.pem\r\n"; print "Content-Type: application/octet-stream\r\n\r\n"; - print `/bin/cat ${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem`; + + open(FILE, "${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem"); + my @tmp = ; + close(FILE); + + print "@tmp"; exit (0); } @@ -3219,9 +3302,8 @@ END &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); -# Check if a file is uploaded - - if (ref ($cgiparams{'FH'}) ne 'Fh') { + # Check if a file is uploaded + unless (ref ($cgiparams{'FH'})) { $errormessage = $Lang::tr{'there was no file upload'}; goto N2N_ERROR; } @@ -3337,7 +3419,6 @@ my $complzoactive; my $mssfixactive; my $authactive; my $n2nfragment; -my @n2nmtudisc = split(/ /, (grep { /^mtu-disc/ } @firen2nconf)[0]); my @n2nproto2 = split(/ /, (grep { /^proto/ } @firen2nconf)[0]); my @n2nproto = split(/-/, $n2nproto2[1]); my @n2nport = split(/ /, (grep { /^port/ } @firen2nconf)[0]); @@ -3373,7 +3454,6 @@ $n2nremsub[2] =~ s/\n|\r//g; $n2nlocalsub[2] =~ s/\n|\r//g; $n2nfragment[1] =~ s/\n|\r//g; $n2nmgmt[2] =~ s/\n|\r//g; -$n2nmtudisc[1] =~ s/\n|\r//g; $n2ncipher[1] =~ s/\n|\r//g; $n2nauth[1] =~ s/\n|\r//g; chomp ($complzoactive); @@ -3450,7 +3530,6 @@ foreach my $dkey (keys %confighash) { $confighash{$key}[29] = $n2nport[1]; $confighash{$key}[30] = $complzoactive; $confighash{$key}[31] = $n2ntunmtu[1]; - $confighash{$key}[38] = $n2nmtudisc[1]; $confighash{$key}[39] = $n2nauth[1]; $confighash{$key}[40] = $n2ncipher[1]; $confighash{$key}[41] = 'disabled'; @@ -3490,9 +3569,8 @@ foreach my $dkey (keys %confighash) { MSSFIX:$confighash{$key}[23] Fragment:$confighash{$key}[24] $Lang::tr{'MTU'}$confighash{$key}[31] - $Lang::tr{'ovpn mtu-disc'}$confighash{$key}[38] Management Port $confighash{$key}[22] - $Lang::tr{'ovpn hmac'}:$confighash{$key}[39] + $Lang::tr{'ovpn tls auth'}:$confighash{$key}[39] $Lang::tr{'cipher'}$confighash{$key}[40]    @@ -3765,41 +3843,42 @@ if ($cgiparams{'TYPE'} eq 'host') { #CCD End - if ($cgiparams{'TYPE'} !~ /^(host|net)$/) { - $errormessage = $Lang::tr{'connection type is invalid'}; - if ($cgiparams{'TYPE'} eq 'net') { - unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!"; - rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!"; - } - goto VPNCONF_ERROR; + if ($cgiparams{'TYPE'} !~ /^(host|net)$/) { + $errormessage = $Lang::tr{'connection type is invalid'}; + if ($cgiparams{'TYPE'} eq 'net') { + unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!"; + rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!"; + goto VPNCONF_ERROR; + } + goto VPNCONF_ERROR; } - if ($cgiparams{'NAME'} !~ /^[a-zA-Z0-9]+$/) { - $errormessage = $Lang::tr{'name must only contain characters'}; - if ($cgiparams{'TYPE'} eq 'net') { - unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!"; - rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!"; - } - goto VPNCONF_ERROR; - } + $errormessage = $Lang::tr{'name must only contain characters'}; + if ($cgiparams{'TYPE'} eq 'net') { + goto VPNCONF_ERROR; + } + goto VPNCONF_ERROR; + } if ($cgiparams{'NAME'} =~ /^(host|01|block|private|clear|packetdefault)$/) { - $errormessage = $Lang::tr{'name is invalid'}; - if ($cgiparams{'TYPE'} eq 'net') { - unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!"; - rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!"; - } - goto VPNCONF_ERROR; + $errormessage = $Lang::tr{'name is invalid'}; + if ($cgiparams{'TYPE'} eq 'net') { + unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!"; + rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!"; + goto VPNCONF_ERROR; + } + goto VPNCONF_ERROR; } if (length($cgiparams{'NAME'}) >60) { - $errormessage = $Lang::tr{'name too long'}; - if ($cgiparams{'TYPE'} eq 'net') { - unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!"; - rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!"; - } - goto VPNCONF_ERROR; + $errormessage = $Lang::tr{'name too long'}; + if ($cgiparams{'TYPE'} eq 'net') { + unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!"; + rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!"; + goto VPNCONF_ERROR; + } + goto VPNCONF_ERROR; } ### @@ -3980,6 +4059,16 @@ if ($cgiparams{'TYPE'} eq 'net') { goto VPNCONF_ERROR; } + # Check for N2N that OpenSSL maximum of valid days will not be exceeded + if ($cgiparams{'TYPE'} eq 'net') { + if ($cgiparams{'DAYS_VALID'} >= '999999') { + $errormessage = $Lang::tr{'invalid input for valid till days'}; + unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!"; + rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!"; + goto VPNCONF_ERROR; + } + } + if ($cgiparams{'ENABLED'} !~ /^(on|off)$/) { $errormessage = $Lang::tr{'invalid input'}; goto VPNCONF_ERROR; @@ -4004,7 +4093,7 @@ if ($cgiparams{'TYPE'} eq 'net') { $errormessage = $Lang::tr{'cant change certificates'}; goto VPNCONF_ERROR; } - if (ref ($cgiparams{'FH'}) ne 'Fh') { + unless (ref ($cgiparams{'FH'})) { $errormessage = $Lang::tr{'there was no file upload'}; goto VPNCONF_ERROR; } @@ -4018,6 +4107,7 @@ if ($cgiparams{'TYPE'} eq 'net') { # Sign the certificate request and move it # Sign the host certificate request + # The system call is safe, because all arguments are passed as an array. system('/usr/bin/openssl', 'ca', '-days', "$cgiparams{'DAYS_VALID'}", '-batch', '-notext', '-in', $filename, @@ -4034,11 +4124,19 @@ if ($cgiparams{'TYPE'} eq 'net') { &deletebackupcert(); } - my $temp = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem`; - $temp =~ /Subject:.*CN=(.*)[\n]/; - $temp = $1; - $temp =~ s+/Email+, E+; - $temp =~ s/ ST=/ S=/; + my @temp = &General::system_output("/usr/bin/openssl", "x509", "-text", "-in", "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem"); + my $temp; + + foreach my $line (@temp) { + if ($line =~ /Subject:.*CN\s?=\s?(.*)[\n]/) { + $temp = $1; + $temp =~ s+/Email+, E+; + $temp =~ s/ ST=/ S=/; + + last; + } + } + $cgiparams{'CERT_NAME'} = $temp; $cgiparams{'CERT_NAME'} =~ s/,//g; $cgiparams{'CERT_NAME'} =~ s/\'//g; @@ -4051,7 +4149,7 @@ if ($cgiparams{'TYPE'} eq 'net') { $errormessage = $Lang::tr{'cant change certificates'}; goto VPNCONF_ERROR; } - if (ref ($cgiparams{'FH'}) ne 'Fh') { + unless (ref ($cgiparams{'FH'})) { $errormessage = $Lang::tr{'there was no file upload'}; goto VPNCONF_ERROR; } @@ -4064,13 +4162,13 @@ if ($cgiparams{'TYPE'} eq 'net') { # Verify the certificate has a valid CA and move it my $validca = 0; - my $test = `/usr/bin/openssl verify -CAfile ${General::swroot}/ovpn/ca/cacert.pem $filename`; - if ($test =~ /: OK/) { + my @test = &General::system_output("/usr/bin/openssl", "verify", "-CAfile", "${General::swroot}/ovpn/ca/cacert.pem", "$filename"); + if (grep(/: OK/, @test)) { $validca = 1; } else { foreach my $key (keys %cahash) { - $test = `/usr/bin/openssl verify -CAfile ${General::swroot}/ovpn/ca/$cahash{$key}[0]cert.pem $filename`; - if ($test =~ /: OK/) { + @test = &General::system_output("/usr/bin/openssl", "verify", "-CAfile", "${General::swroot}/ovpn/ca/$cahash{$key}[0]cert.pem", "$filename"); + if (grep(/: OK/, @test)) { $validca = 1; } } @@ -4088,11 +4186,19 @@ if ($cgiparams{'TYPE'} eq 'net') { } } - my $temp = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem`; - $temp =~ /Subject:.*CN=(.*)[\n]/; - $temp = $1; - $temp =~ s+/Email+, E+; - $temp =~ s/ ST=/ S=/; + my @temp = &General::system_output("/usr/bin/openssl", "x509", "-text", "-in", "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem"); + my $temp; + + foreach my $line (@temp) { + if ($line =~ /Subject:.*CN\s?=\s?(.*)[\n]/) { + $temp = $1; + $temp =~ s+/Email+, E+; + $temp =~ s/ ST=/ S=/; + + last; + } + } + $cgiparams{'CERT_NAME'} = $temp; $cgiparams{'CERT_NAME'} =~ s/,//g; $cgiparams{'CERT_NAME'} =~ s/\'//g; @@ -4157,11 +4263,29 @@ if ($cgiparams{'TYPE'} eq 'net') { $errormessage = $Lang::tr{'passwords do not match'}; goto VPNCONF_ERROR; } - if ($cgiparams{'DAYS_VALID'} ne '' && $cgiparams{'DAYS_VALID'} !~ /^[0-9]+$/) { + if ($cgiparams{'DAYS_VALID'} eq '' && $cgiparams{'DAYS_VALID'} !~ /^[0-9]+$/) { $errormessage = $Lang::tr{'invalid input for valid till days'}; goto VPNCONF_ERROR; } + # Check for RW that OpenSSL maximum of valid days will not be exceeded + if ($cgiparams{'TYPE'} eq 'host') { + if ($cgiparams{'DAYS_VALID'} >= '999999') { + $errormessage = $Lang::tr{'invalid input for valid till days'}; + goto VPNCONF_ERROR; + } + } + + # Check for RW if client name is already set + if ($cgiparams{'TYPE'} eq 'host') { + foreach my $key (keys %confighash) { + if ($confighash{$key}[1] eq $cgiparams{'NAME'}) { + $errormessage = $Lang::tr{'a connection with this name already exists'}; + goto VPNCONF_ERROR; + } + } + } + # Replace empty strings with a . (my $ou = $cgiparams{'CERT_OU'}) =~ s/^\s*$/\./; (my $city = $cgiparams{'CERT_CITY'}) =~ s/^\s*$/\./; @@ -4201,6 +4325,7 @@ if ($cgiparams{'TYPE'} eq 'net') { } # Sign the host certificate request + # The system call is safe, because all arguments are passed as an array. system('/usr/bin/openssl', 'ca', '-days', "$cgiparams{'DAYS_VALID'}", '-batch', '-notext', '-in', "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}req.pem", @@ -4219,6 +4344,7 @@ if ($cgiparams{'TYPE'} eq 'net') { } # Create the pkcs12 file + # The system call is safe, because all arguments are passed as an array. system('/usr/bin/openssl', 'pkcs12', '-export', '-inkey', "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}key.pem", '-in', "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem", @@ -4384,21 +4510,24 @@ if ($cgiparams{'TYPE'} eq 'net') { if ($cgiparams{'TYPE'} eq 'net') { - if (-e "/var/run/$confighash{$key}[1]n2n.pid") { - system('/usr/local/bin/openvpnctrl', '-kn2n', $confighash{$cgiparams{'KEY'}}[1]); + if (-e "/var/run/$confighash{$key}[1]n2n.pid") { + &General::system("/usr/local/bin/openvpnctrl", "-kn2n", "$confighash{$cgiparams{'KEY'}}[1]"); - &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); - my $key = $cgiparams{'KEY'}; - if (! $key) { - $key = &General::findhasharraykey (\%confighash); - foreach my $i (0 .. 31) { $confighash{$key}[$i] = "";} - } - $confighash{$key}[0] = 'on'; - &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); + &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); + my $key = $cgiparams{'KEY'}; + if (! $key) { + $key = &General::findhasharraykey (\%confighash); + foreach my $i (0 .. 31) { + $confighash{$key}[$i] = ""; + } + } + + $confighash{$key}[0] = 'on'; + &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); - system('/usr/local/bin/openvpnctrl', '-sn2n', $confighash{$cgiparams{'KEY'}}[1]); - } - } + &General::system("/usr/local/bin/openvpnctrl", "-sn2n", "$confighash{$cgiparams{'KEY'}}[1]"); + } + } ### # m.a.d n2n end @@ -4433,7 +4562,7 @@ if ($cgiparams{'TYPE'} eq 'net') { $cgiparams{'CERT_CITY'} = $vpnsettings{'ROOTCERT_CITY'}; $cgiparams{'CERT_STATE'} = $vpnsettings{'ROOTCERT_STATE'}; $cgiparams{'CERT_COUNTRY'} = $vpnsettings{'ROOTCERT_COUNTRY'}; - $cgiparams{'DAYS_VALID'} = $vpnsettings{'DAYS_VALID'}; + $cgiparams{'DAYS_VALID'} = $vpnsettings{'DAYS_VALID'} = '730'; } VPNCONF_ERROR: @@ -4504,12 +4633,10 @@ if ($cgiparams{'TYPE'} eq 'net') { $selected{'DAUTH'}{'SHA384'} = ''; $selected{'DAUTH'}{'SHA256'} = ''; $selected{'DAUTH'}{'SHA1'} = ''; - # If no hash algorythm has been choosen yet, select - # the old default value (SHA1) for compatiblity reasons. - if ($cgiparams{'DAUTH'} eq '') { - $cgiparams{'DAUTH'} = 'SHA1'; - } $selected{'DAUTH'}{$cgiparams{'DAUTH'}} = 'SELECTED'; + $checked{'TLSAUTH'}{'off'} = ''; + $checked{'TLSAUTH'}{'on'} = ''; + $checked{'TLSAUTH'}{$cgiparams{'TLSAUTH'}} = 'CHECKED'; if (1) { &Header::showhttpheaders(); @@ -4813,7 +4940,7 @@ END if ($cgiparams{'TYPE'} eq 'host') { print < -  $Lang::tr{'valid till'} (days): +  $Lang::tr{'valid till'} (days): *   $Lang::tr{'pkcs12 file password'}: @@ -4828,7 +4955,7 @@ END }else{ print < -  $Lang::tr{'valid till'} (days): +  $Lang::tr{'valid till'} (days): *         @@ -5017,7 +5144,9 @@ END &General::readhasharray("${General::swroot}/ovpn/caconfig", \%cahash); &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); - my @status = `/bin/cat /var/run/ovpnserver.log`; + open(FILE, "/var/run/ovpnserver.log"); + my @status = ; + close(FILE); if ($cgiparams{'VPN_IP'} eq '' && -e "${General::swroot}/red/active") { if (open(IPADDR, "${General::swroot}/red/local-ipaddress")) { @@ -5045,8 +5174,20 @@ END $cgiparams{'MSSFIX'} = 'off'; } if ($cgiparams{'DAUTH'} eq '') { - $cgiparams{'DAUTH'} = 'SHA512'; - } + if (-z "${General::swroot}/ovpn/ovpnconfig") { + $cgiparams{'DAUTH'} = 'SHA512'; + } + foreach my $key (keys %confighash) { + if ($confighash{$key}[3] ne 'host') { + $cgiparams{'DAUTH'} = 'SHA512'; + } else { + $cgiparams{'DAUTH'} = 'SHA1'; + } + } + } + if ($cgiparams{'TLSAUTH'} eq '') { + $cgiparams{'TLSAUTH'} = 'off'; + } if ($cgiparams{'DOVPN_SUBNET'} eq '') { $cgiparams{'DOVPN_SUBNET'} = '10.' . int(rand(256)) . '.' . int(rand(256)) . '.0/255.255.255.0'; } @@ -5089,6 +5230,10 @@ END $selected{'DAUTH'}{'SHA1'} = ''; $selected{'DAUTH'}{$cgiparams{'DAUTH'}} = 'SELECTED'; + $checked{'TLSAUTH'}{'off'} = ''; + $checked{'TLSAUTH'}{'on'} = ''; + $checked{'TLSAUTH'}{$cgiparams{'TLSAUTH'}} = 'CHECKED'; + $checked{'DCOMPLZO'}{'off'} = ''; $checked{'DCOMPLZO'}{'on'} = ''; $checked{'DCOMPLZO'}{$cgiparams{'DCOMPLZO'}} = 'CHECKED'; @@ -5109,6 +5254,20 @@ END &Header::closebox(); } + if ($cryptoerror) { + &Header::openbox('100%', 'LEFT', $Lang::tr{'crypto error'}); + print "$cryptoerror"; + print " "; + &Header::closebox(); + } + + if ($cryptowarning) { + &Header::openbox('100%', 'LEFT', $Lang::tr{'crypto warning'}); + print "$cryptowarning"; + print " "; + &Header::closebox(); + } + if ($warnmessage) { &Header::openbox('100%', 'LEFT', $Lang::tr{'warning messages'}); print "$warnmessage
"; @@ -5149,8 +5308,16 @@ END if (&haveOrangeNet()) { print "$Lang::tr{'ovpn on orange'}"; print ""; - } - print <
+ + $Lang::tr{'net config'}: + +
+ $Lang::tr{'local vpn hostname/ip'}:
$Lang::tr{'ovpn subnet'}
$Lang::tr{'protocol'} @@ -5160,6 +5327,24 @@ END $Lang::tr{'MTU'}  + + +
+ + $Lang::tr{'ovpn crypt options'}: + +
+ + + $Lang::tr{'ovpn ha'} + + $Lang::tr{'cipher'} - $Lang::tr{'comp-lzo'} - + +
+ + $Lang::tr{'ovpn tls auth'} + + +

END ; @@ -5268,9 +5458,17 @@ END #} else { #print " "; #} - my $cavalid = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/certs/$confighash{$key}[1]cert.pem`; - $cavalid =~ /Not After : (.*)[\n]/; - $cavalid = $1; + my @cavalid = &General::system_output("/usr/bin/openssl", "x509", "-text", "-in", "${General::swroot}/ovpn/certs/$confighash{$key}[1]cert.pem"); + my $cavalid; + + foreach my $line (@cavalid) { + if ($line =~ /Not After : (.*)[\n]/) { + $cavalid = $1; + + last; + } + } + print "$confighash{$key}[25]"; $col1="bgcolor='${Header::colourred}'"; my $active = "$Lang::tr{'capsclosed'}"; @@ -5481,11 +5679,19 @@ END my $col4="bgcolor='$color{'color20'}'"; if (-f "${General::swroot}/ovpn/ca/cacert.pem") { - my $casubject = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/ca/cacert.pem`; - $casubject =~ /Subject: (.*)[\n]/; - $casubject = $1; - $casubject =~ s+/Email+, E+; - $casubject =~ s/ ST=/ S=/; + my @casubject = &General::system_output("/usr/bin/openssl", "x509", "-text", "-in", "${General::swroot}/ovpn/ca/cacert.pem"); + my $casubject; + + foreach my $line (@casubject) { + if ($line =~ /Subject: (.*)[\n]/) { + $casubject = $1; + $casubject =~ s+/Email+, E+; + $casubject =~ s/ ST=/ S=/; + + last; + } + } + print < $Lang::tr{'root certificate'} @@ -5515,11 +5721,18 @@ END } if (-f "${General::swroot}/ovpn/certs/servercert.pem") { - my $hostsubject = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/certs/servercert.pem`; - $hostsubject =~ /Subject: (.*)[\n]/; - $hostsubject = $1; - $hostsubject =~ s+/Email+, E+; - $hostsubject =~ s/ ST=/ S=/; + my @hostsubject = &General::system_output("/usr/bin/openssl", "x509", "-text", "-in", "${General::swroot}/ovpn/certs/servercert.pem"); + my $hostsubject; + + foreach my $line (@hostsubject) { + if ($line =~ /Subject: (.*)[\n]/) { + $hostsubject = $1; + $hostsubject =~ s+/Email+, E+; + $hostsubject =~ s/ ST=/ S=/; + + last; + } + } print < @@ -5551,10 +5764,16 @@ END # Adding DH parameter to chart if (-f "${General::swroot}/ovpn/ca/dh1024.pem") { - my $dhsubject = `/usr/bin/openssl dhparam -text -in ${General::swroot}/ovpn/ca/dh1024.pem`; - $dhsubject =~ / (.*)[\n]/; - $dhsubject = $1; + my @dhsubject = &General::system_output("/usr/bin/openssl", "dhparam", "-text", "-in", "${General::swroot}/ovpn/ca/dh1024.pem"); + my $dhsubject; + foreach my $line (@dhsubject) { + if ($line =~ / (.*)[\n]/) { + $dhsubject = $1; + + last; + } + } print < @@ -5584,9 +5803,19 @@ END # Adding ta.key to chart if (-f "${General::swroot}/ovpn/certs/ta.key") { - my $tasubject = `/bin/cat ${General::swroot}/ovpn/certs/ta.key`; - $tasubject =~ /# (.*)[\n]/; - $tasubject = $1; + open(FILE, "${General::swroot}/ovpn/certs/ta.key"); + my @tasubject = ; + close(FILE); + + my $tasubject; + foreach my $line (@tasubject) { + if($line =~ /# (.*)[\n]/) { + $tasubject = $1; + + last; + } + } + print <